44
55import * as p from "@clack/prompts" ;
66import chalk from "chalk" ;
7- import { ContextApiError , type AccountStatus } from "context-markets" ;
7+ import type { AccountStatus } from "context-markets" ;
88import { formatEther } from "viem" ;
99import { generatePrivateKey , privateKeyToAccount } from "viem/accounts" ;
1010import { tradingClient , type ClientFlags } from "../client.js" ;
1111import { out , fail , getOutputMode , requirePositional , type ParsedArgs } from "../format.js" ;
1212import { loadConfig , saveConfig , configPath } from "../config.js" ;
13+ import { cleanErrorMessage } from "../error.js" ;
1314import { confirmAction } from "../ui/prompt.js" ;
1415
1516const MIN_ETH_FOR_GAS = 1_000_000_000_000n ; // 0.000001 ETH — just enough for a few txs
1617const PRIVATE_KEY_PATTERN = / ^ 0 x [ 0 - 9 a - f A - F ] { 64 } $ / ;
1718
18- function isRecord ( value : unknown ) : value is Record < string , unknown > {
19- return typeof value === "object" && value !== null ;
20- }
21-
2219export default async function handleSetup ( parsed : ParsedArgs ) : Promise < void > {
2320 const { subcommand, positional, flags } = parsed ;
2421
@@ -44,30 +41,6 @@ export default async function handleSetup(parsed: ParsedArgs): Promise<void> {
4441// Shared approve → mint → deposit flow
4542// ---------------------------------------------------------------------------
4643
47- /** Dig through error cause chain to find the most useful message */
48- function formatError ( err : unknown ) : string {
49- if ( ! ( err instanceof Error ) ) return String ( err ) ;
50-
51- // Walk the cause chain to find the deepest message
52- let deepest = err ;
53- let current : unknown = err ;
54- while ( current instanceof Error && current . cause ) {
55- current = current . cause ;
56- if ( current instanceof Error ) deepest = current ;
57- }
58-
59- if ( err instanceof ContextApiError ) {
60- const body = err . body ;
61- if ( isRecord ( body ) && typeof body . message === "string" ) return body . message ;
62- if ( typeof body === "string" ) return body ;
63- }
64-
65- // Use the deepest cause message if it's more specific
66- const deepMsg = deepest . message . split ( "\n" ) [ 0 ] ;
67- const topMsg = err . message . split ( "\n" ) [ 0 ] ;
68- return deepMsg !== topMsg && deepMsg . length > 5 ? `${ topMsg } : ${ deepMsg } ` : topMsg ;
69- }
70-
7144/**
7245 * Check ETH balance and wait for funding if needed.
7346 * Takes pre-fetched status to avoid redundant API calls.
@@ -126,7 +99,8 @@ async function approveWithRetry(ctx: ReturnType<typeof tradingClient>): Promise<
12699 return true ;
127100 } catch ( err ) {
128101 s . stop ( "Approval failed" ) ;
129- p . log . warning ( formatError ( err ) ) ;
102+ const msg = cleanErrorMessage ( err instanceof Error ? err . message : String ( err ) ) ;
103+ p . log . warning ( msg ) ;
130104
131105 const action = await p . select ( {
132106 message : "What would you like to do?" ,
@@ -254,7 +228,8 @@ async function onboardingFlow(ctx: ReturnType<typeof tradingClient>): Promise<bo
254228 deposited = true ;
255229 } catch ( err ) {
256230 sp . stop ( "Deposit failed" ) ;
257- p . log . warning ( formatError ( err ) ) ;
231+ const msg = cleanErrorMessage ( err instanceof Error ? err . message : String ( err ) ) ;
232+ p . log . warning ( msg ) ;
258233
259234 const action = await p . select ( {
260235 message : "What would you like to do?" ,
0 commit comments