From 8011838f1ded843fc9666d0f3cb215e8cf871701 Mon Sep 17 00:00:00 2001 From: James Lawton Date: Mon, 27 Apr 2026 11:37:37 +0100 Subject: [PATCH 1/4] fix(deposit): pre-flight balance checks, gas reserve, session guard, and actionable errors Addresses seven friction points surfaced in a real first-run test session: - deposit restricted to Polygon mainnet (chainId 137); clear error for other chains - pre-flight balance check before transaction encoding; fails fast with an actionable message instead of waiting for a relay rejection - auto-reserve 0.05 USDC for gas when wallet has no native POL balance (USDC paymaster path); prints a note and reduces the deposit amount - remap opaque relay errors ("Identity signers not found", "Request aborted", code 1005) to messages that name the fix command - "no pools found" error now suggests polygon-agent balances as a diagnostic step - wallet create guards against silently replacing an existing session; requires --force to proceed and warns that the old balance is not accessible - dapp-client fee cap raised from 0.0001 to 0.1 token units (0.1 USDC for 6-decimal tokens); "Unable to determine fee option" now names the fix - connector-ui use-case prompt removes Katana and $100M TVL filter (unsupported by the earn pool API provider) - SKILL.md: documents --usdc-limit and --force on wallet create, removes Katana vault table, expands troubleshooting table with actionable error rows --- packages/connector-ui/src/App.tsx | 2 +- .../skills/polygon-defi/SKILL.md | 42 +++++---- .../src/commands/operations.ts | 92 +++++++++++++++++-- .../polygon-agent-cli/src/commands/wallet.ts | 24 +++++ .../polygon-agent-cli/src/lib/dapp-client.ts | 9 +- skills/polygon-defi/SKILL.md | 42 +++++---- 6 files changed, 169 insertions(+), 42 deletions(-) diff --git a/packages/connector-ui/src/App.tsx b/packages/connector-ui/src/App.tsx index 1b3163a..f1a13ca 100644 --- a/packages/connector-ui/src/App.tsx +++ b/packages/connector-ui/src/App.tsx @@ -124,7 +124,7 @@ const USE_CASES: { label: string; display: string; icon: ElementType }[] = [ { label: 'Automate yield strategies', display: - 'Deposit USDC into the highest-TVL lending vault on Polygon or Katana with TVL above $100M and report the APY and pool address. Then set up a daily cron job to automatically re-evaluate and deposit into the best vault each morning.', + 'Deposit USDC into the highest-yield active lending vault on Polygon and report the APY and pool address. Then set up a daily cron job to automatically re-evaluate and deposit into the best vault each morning.', icon: TrendingUp } ]; diff --git a/packages/polygon-agent-cli/skills/polygon-defi/SKILL.md b/packages/polygon-agent-cli/skills/polygon-defi/SKILL.md index 6601419..661bf00 100644 --- a/packages/polygon-agent-cli/skills/polygon-defi/SKILL.md +++ b/packages/polygon-agent-cli/skills/polygon-defi/SKILL.md @@ -106,7 +106,9 @@ interface PoolTokenInfo { ## Deposit to Earn Yield -Pool discovery uses `TrailsApi.getEarnPools` — picks the most liquid pool (highest TVL) for the asset on the current chain. No hardcoded addresses — the pool is resolved at runtime. +Pool discovery uses `TrailsApi.getEarnPools` — picks the most liquid pool (highest TVL) for the asset. Only Polygon mainnet (chainId 137) is supported. No hardcoded addresses — the pool is resolved at runtime. + +**Gas requirement:** The wallet needs POL for gas, or a session created with `--usdc-limit` to enable USDC paymaster. If the wallet has no POL, create the session with `--usdc-limit 5`. When USDC paymaster is active and the deposit amount would consume the full balance, the CLI auto-reserves 0.05 USDC for gas and prints a note. ```bash # Dry-run — shows pool name, APY, TVL, and deposit address before committing @@ -181,19 +183,6 @@ Common token contracts on Polygon mainnet (already auto-whitelisted in sessions | Morpho Compound WETH | WETH | `0xf5c81d25ee174d83f1fd202ca94ae6070d073ccf` | | Morpho Compound POL | POL | `0x3f33f9f7e2d7cfbcbdf8ea8b870a6e3d449664c2` | -#### Katana (chainId 747474) — Morpho Vaults - -| Vault | Asset | TVL | Address | -|-------|-------|-----|---------| -| Gauntlet USDT | USDT | ~$97M | `0x1ecdc3f2b5e90bfb55ff45a7476ff98a8957388e` | -| Steakhouse Prime USDC | USDC | ~$54M | `0x61d4f9d3797ba4da152238c53a6f93fb665c3c1d` | -| Yearn OG ETH | WETH | ~$16M | `0xfade0c546f44e33c134c4036207b314ac643dc2e` | -| Yearn OG USDC | USDC | ~$16M | `0xce2b8e464fc7b5e58710c24b7e5ebfb6027f29d7` | -| Gauntlet USDC | USDC | ~$8M | `0xe4248e2105508fcbad3fe95691551d1af14015f7` | -| Yearn OG USDT | USDT | ~$8M | `0x8ed68f91afbe5871dce31ae007a936ebe8511d47` | -| Gauntlet WETH | WETH | ~$6M | `0xc5e7ab07030305fc925175b25b93b285d40dcdff` | -| Hyperithm vbUSDC Apex | USDC | ~$3M | `0xef77f8c53af95f3348cee0fb2a02ee02ab9cdca5` | - --- ## Full DeFi Flow Example @@ -216,11 +205,32 @@ polygon-agent swap --from USDC --to USDC --amount 0.5 --to-chain arbitrum --broa --- +## wallet create — Key Options + +| Flag | Purpose | +|------|---------| +| `--usdc-limit ` | Enable USDC gas paymaster. Required when the wallet has no POL. Recommended: `--usdc-limit 5`. | +| `--force` | Replace an existing session without prompting. By default, re-creating a session is blocked if one already exists — the old wallet balance is not accessible from a new session. | +| `--contract ` | Whitelist an additional contract (repeatable). Use this if a deposit is rejected due to a missing contract permission. | + +```bash +# New session with USDC gas and deposit contracts pre-whitelisted +polygon-agent wallet create --usdc-limit 5 + +# Replace an existing session +polygon-agent wallet create --force --usdc-limit 5 +``` + +--- + ## Troubleshooting | Error | Cause | Fix | |-------|-------|-----| -| `Deposit session rejected` | Pool or token contract not whitelisted | Re-create wallet with `--contract --contract ` (both required) | +| `Insufficient : wallet has X` | Balance too low for the requested deposit amount | Run `polygon-agent balances` and adjust `--amount` | +| `Wallet has no POL for gas` | No native gas and no USDC paymaster | Fund with POL (`polygon-agent fund`) or re-create session with `--usdc-limit 5` | +| `Transaction rejected by relay` | Session permissions missing for pool or token contract | Re-create with `--contract --contract ` | +| `Unable to pay gas` | No usable fee token found | Fund with POL or add `--usdc-limit 5` to session | +| `Wallet already exists` | Re-creating would orphan the old session | Use `--force` only after confirming old wallet funds are swept or unneeded | | `Protocol X not yet supported` | Trails returned a protocol other than aave/morpho | Use `polygon-agent swap` to obtain the yield-bearing token manually | -| `Fee option errors` | Wallet has insufficient balance | Run `polygon-agent balances` and fund the wallet | | `swap`: no route found | Insufficient liquidity for the pair | Try a different amount or token pair | diff --git a/packages/polygon-agent-cli/src/commands/operations.ts b/packages/polygon-agent-cli/src/commands/operations.ts index 1492e7c..16a1fde 100644 --- a/packages/polygon-agent-cli/src/commands/operations.ts +++ b/packages/polygon-agent-cli/src/commands/operations.ts @@ -1083,7 +1083,7 @@ export const depositCommand: CommandModule = { handler: async (argv) => { const walletName = (argv.wallet as string) || 'main'; const assetSymbol = ((argv.asset as string) || 'USDC').toUpperCase(); - const amountArg = argv.amount as string; + let amountArg = argv.amount as string; const protocolFilter = argv.protocol as string | undefined; const broadcast = argv.broadcast as boolean; @@ -1095,6 +1095,12 @@ export const depositCommand: CommandModule = { const { chainId } = network; const walletAddress = session.walletAddress; + if (chainId !== 137) { + throw new Error( + `deposit only supports Polygon mainnet (chainId 137). Pass --chain polygon or omit --chain.` + ); + } + const asset = await getTokenConfig({ chainId, symbol: assetSymbol, @@ -1128,9 +1134,10 @@ export const depositCommand: CommandModule = { if (pools.length === 0) { throw new Error( - `No active earn pools found for ${assetSymbol} on ${network.name}` + - (protocolFilter ? ` (protocol filter: ${protocolFilter})` : '') + - `. Try 'polygon-agent swap --from ${assetSymbol} --to ' as an alternative.` + `No active ${assetSymbol} earn pools found on ${network.name}` + + (protocolFilter ? ` (protocol: ${protocolFilter})` : '') + + `. Confirm wallet state: polygon-agent balances. ` + + `Alternative: polygon-agent swap --from ${assetSymbol} --to .` ); } @@ -1139,7 +1146,58 @@ export const depositCommand: CommandModule = { const pool = pools[0]; const proto = (pool.protocol || '').toLowerCase(); - const { encodeFunctionData, parseUnits: viemParseUnits } = await import('viem'); + const { + encodeFunctionData, + parseUnits: viemParseUnits, + formatUnits: viemFormatUnits, + createPublicClient, + http + } = await import('viem'); + const { polygon: polygonViemChain } = await import('viem/chains'); + + // Pre-flight: verify balance and auto-reserve gas buffer when wallet has no native token + try { + const publicClient = createPublicClient({ chain: polygonViemChain, transport: http() }); + const [usdcBal, nativeBal] = await Promise.all([ + publicClient.readContract({ + address: asset.address as `0x${string}`, + abi: ERC20_BALANCE_OF_ABI, + functionName: 'balanceOf', + args: [walletAddress as `0x${string}`] + }), + publicClient.getBalance({ address: walletAddress as `0x${string}` }) + ]); + const requestedUnits = viemParseUnits(amountArg, asset.decimals); + const GAS_RESERVE = viemParseUnits('0.05', asset.decimals); + if (usdcBal < requestedUnits) { + const available = viemFormatUnits(usdcBal, asset.decimals); + throw new Error( + `Insufficient ${assetSymbol}: wallet has ${available} ${assetSymbol}, deposit requires ${amountArg}. ` + + `Run: polygon-agent balances` + ); + } + if (nativeBal === 0n && requestedUnits + GAS_RESERVE > usdcBal) { + // Wallet has no POL — USDC paymaster will pay gas; auto-reduce to leave 0.05 buffer + const adjusted = usdcBal - GAS_RESERVE; + if (adjusted <= 0n) { + throw new Error( + `Insufficient ${assetSymbol} for deposit plus 0.05 gas reserve. ` + + `Fund with POL for native gas: polygon-agent fund` + ); + } + amountArg = viemFormatUnits(adjusted, asset.decimals); + process.stderr.write( + `Note: reduced deposit to ${amountArg} ${assetSymbol} (0.05 reserved for USDC gas)\n` + ); + } + } catch (e) { + if ((e as Error).message?.match(/^Insufficient/)) throw e; + // RPC unreachable — warn and continue + process.stderr.write( + `Warning: balance pre-flight check skipped (${(e as Error).message})\n` + ); + } + const amountUnits = viemParseUnits(amountArg, asset.decimals); const ERC20_APPROVE_ABI = [ @@ -1267,11 +1325,31 @@ export const depositCommand: CommandModule = { preferNativeFee: false }); } catch (txErr) { - if ((txErr as Error).message?.includes('No signer supported')) { + const txMsg = (txErr as Error).message || ''; + if (txMsg.includes('No signer supported')) { throw new Error( `Session does not permit calls to ${pool.depositAddress} (${pool.protocol} pool) or ${asset.address} (${assetSymbol} approve). ` + `Re-create the wallet session with: polygon-agent wallet create --contract ${asset.address} --contract ${pool.depositAddress}\n` + - `Original error: ${(txErr as Error).message}` + `Original error: ${txMsg}` + ); + } + if (txMsg.includes('Identity signers not found') || txMsg.includes('signers not found')) { + throw new Error( + `Wallet has no POL for gas and no USDC paymaster is configured. ` + + `Fund with POL: polygon-agent fund\n` + + `Or enable USDC gas: polygon-agent wallet create --usdc-limit 5\n` + + `Original error: ${txMsg}` + ); + } + if ( + txMsg.includes('Request aborted') || + txMsg.includes('AbortedError') || + txMsg.includes('code 1005') + ) { + throw new Error( + `Transaction rejected by relay — likely a session permission issue. ` + + `Re-create the wallet session: polygon-agent wallet create --contract ${asset.address} --contract ${pool.depositAddress}\n` + + `Original error: ${txMsg}` ); } throw txErr; diff --git a/packages/polygon-agent-cli/src/commands/wallet.ts b/packages/polygon-agent-cli/src/commands/wallet.ts index d257460..0d5cca5 100644 --- a/packages/polygon-agent-cli/src/commands/wallet.ts +++ b/packages/polygon-agent-cli/src/commands/wallet.ts @@ -249,9 +249,28 @@ interface CreateArgs extends SessionPermissionArgs { chain: string; 'print-url': boolean; timeout: number; + force?: boolean; } async function handleCreate(argv: CreateArgs): Promise { + if (!argv.force) { + const existing = await loadWalletSession(argv.name); + if (existing) { + const msg = + `Wallet '${argv.name}' already exists (${existing.walletAddress}). ` + + `Re-creating replaces the session — the old wallet balance will not be accessible from the new session. ` + + `Use --force to proceed.`; + if (isTTY()) { + process.stderr.write(`\nError: ${msg}\n\n`); + process.exit(1); + } else { + console.log( + JSON.stringify({ ok: false, error: msg, existingAddress: existing.walletAddress }) + ); + process.exit(1); + } + } + } if (argv['print-url']) { await handleCreateNoWait(argv); } else { @@ -558,6 +577,11 @@ export const walletCommand: CommandModule = { default: 300, describe: 'Seconds to wait for approval before timing out' }) + .option('force', { + type: 'boolean', + default: false, + describe: 'Replace existing session without prompting' + }) ), handler: (argv) => handleCreate(argv as unknown as CreateArgs) }) diff --git a/packages/polygon-agent-cli/src/lib/dapp-client.ts b/packages/polygon-agent-cli/src/lib/dapp-client.ts index f842531..6c342ec 100644 --- a/packages/polygon-agent-cli/src/lib/dapp-client.ts +++ b/packages/polygon-agent-cli/src/lib/dapp-client.ts @@ -376,7 +376,8 @@ export async function runDappClientTx({ if (paymentAddress && erc20Token) { const decimals = typeof erc20Token.decimals === 'number' ? erc20Token.decimals : 6; - const feeValue = decimals >= 2 ? 10 ** (decimals - 2) : 1; + // 0.1 token units as fee cap (e.g. 0.1 USDC = 100000 for 6 decimals) + const feeValue = decimals >= 1 ? 10 ** (decimals - 1) : 1; feeOpt = { token: erc20Token, to: paymentAddress, @@ -399,7 +400,11 @@ export async function runDappClientTx({ const feeOptions = await client.getFeeOptions(chainId, transactions as any); feeOpt = feeOptions?.[0]; } catch (e) { - throw new Error(`Unable to determine fee option: ${(e as Error)?.message}`); + throw new Error( + `Unable to pay gas: wallet has no POL (native gas) and no usable fee token. ` + + `Fund with POL: polygon-agent fund, or enable USDC gas: polygon-agent wallet create --usdc-limit 5. ` + + `Technical: ${(e as Error)?.message}` + ); } } diff --git a/skills/polygon-defi/SKILL.md b/skills/polygon-defi/SKILL.md index 6601419..661bf00 100644 --- a/skills/polygon-defi/SKILL.md +++ b/skills/polygon-defi/SKILL.md @@ -106,7 +106,9 @@ interface PoolTokenInfo { ## Deposit to Earn Yield -Pool discovery uses `TrailsApi.getEarnPools` — picks the most liquid pool (highest TVL) for the asset on the current chain. No hardcoded addresses — the pool is resolved at runtime. +Pool discovery uses `TrailsApi.getEarnPools` — picks the most liquid pool (highest TVL) for the asset. Only Polygon mainnet (chainId 137) is supported. No hardcoded addresses — the pool is resolved at runtime. + +**Gas requirement:** The wallet needs POL for gas, or a session created with `--usdc-limit` to enable USDC paymaster. If the wallet has no POL, create the session with `--usdc-limit 5`. When USDC paymaster is active and the deposit amount would consume the full balance, the CLI auto-reserves 0.05 USDC for gas and prints a note. ```bash # Dry-run — shows pool name, APY, TVL, and deposit address before committing @@ -181,19 +183,6 @@ Common token contracts on Polygon mainnet (already auto-whitelisted in sessions | Morpho Compound WETH | WETH | `0xf5c81d25ee174d83f1fd202ca94ae6070d073ccf` | | Morpho Compound POL | POL | `0x3f33f9f7e2d7cfbcbdf8ea8b870a6e3d449664c2` | -#### Katana (chainId 747474) — Morpho Vaults - -| Vault | Asset | TVL | Address | -|-------|-------|-----|---------| -| Gauntlet USDT | USDT | ~$97M | `0x1ecdc3f2b5e90bfb55ff45a7476ff98a8957388e` | -| Steakhouse Prime USDC | USDC | ~$54M | `0x61d4f9d3797ba4da152238c53a6f93fb665c3c1d` | -| Yearn OG ETH | WETH | ~$16M | `0xfade0c546f44e33c134c4036207b314ac643dc2e` | -| Yearn OG USDC | USDC | ~$16M | `0xce2b8e464fc7b5e58710c24b7e5ebfb6027f29d7` | -| Gauntlet USDC | USDC | ~$8M | `0xe4248e2105508fcbad3fe95691551d1af14015f7` | -| Yearn OG USDT | USDT | ~$8M | `0x8ed68f91afbe5871dce31ae007a936ebe8511d47` | -| Gauntlet WETH | WETH | ~$6M | `0xc5e7ab07030305fc925175b25b93b285d40dcdff` | -| Hyperithm vbUSDC Apex | USDC | ~$3M | `0xef77f8c53af95f3348cee0fb2a02ee02ab9cdca5` | - --- ## Full DeFi Flow Example @@ -216,11 +205,32 @@ polygon-agent swap --from USDC --to USDC --amount 0.5 --to-chain arbitrum --broa --- +## wallet create — Key Options + +| Flag | Purpose | +|------|---------| +| `--usdc-limit ` | Enable USDC gas paymaster. Required when the wallet has no POL. Recommended: `--usdc-limit 5`. | +| `--force` | Replace an existing session without prompting. By default, re-creating a session is blocked if one already exists — the old wallet balance is not accessible from a new session. | +| `--contract ` | Whitelist an additional contract (repeatable). Use this if a deposit is rejected due to a missing contract permission. | + +```bash +# New session with USDC gas and deposit contracts pre-whitelisted +polygon-agent wallet create --usdc-limit 5 + +# Replace an existing session +polygon-agent wallet create --force --usdc-limit 5 +``` + +--- + ## Troubleshooting | Error | Cause | Fix | |-------|-------|-----| -| `Deposit session rejected` | Pool or token contract not whitelisted | Re-create wallet with `--contract --contract ` (both required) | +| `Insufficient : wallet has X` | Balance too low for the requested deposit amount | Run `polygon-agent balances` and adjust `--amount` | +| `Wallet has no POL for gas` | No native gas and no USDC paymaster | Fund with POL (`polygon-agent fund`) or re-create session with `--usdc-limit 5` | +| `Transaction rejected by relay` | Session permissions missing for pool or token contract | Re-create with `--contract --contract ` | +| `Unable to pay gas` | No usable fee token found | Fund with POL or add `--usdc-limit 5` to session | +| `Wallet already exists` | Re-creating would orphan the old session | Use `--force` only after confirming old wallet funds are swept or unneeded | | `Protocol X not yet supported` | Trails returned a protocol other than aave/morpho | Use `polygon-agent swap` to obtain the yield-bearing token manually | -| `Fee option errors` | Wallet has insufficient balance | Run `polygon-agent balances` and fund the wallet | | `swap`: no route found | Insufficient liquidity for the pair | Try a different amount or token pair | From 9d26bfcb42f8fd516c4d5298891acca07b71c80b Mon Sep 17 00:00:00 2001 From: James Lawton Date: Mon, 27 Apr 2026 11:53:29 +0100 Subject: [PATCH 2/4] fix(deposit): remove Polygon-only chain restriction, support all Trails chains --- .../src/commands/operations.ts | 31 ++++++++++++------- skills/polygon-defi/SKILL.md | 2 +- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/packages/polygon-agent-cli/src/commands/operations.ts b/packages/polygon-agent-cli/src/commands/operations.ts index 16a1fde..94142d7 100644 --- a/packages/polygon-agent-cli/src/commands/operations.ts +++ b/packages/polygon-agent-cli/src/commands/operations.ts @@ -1095,12 +1095,6 @@ export const depositCommand: CommandModule = { const { chainId } = network; const walletAddress = session.walletAddress; - if (chainId !== 137) { - throw new Error( - `deposit only supports Polygon mainnet (chainId 137). Pass --chain polygon or omit --chain.` - ); - } - const asset = await getTokenConfig({ chainId, symbol: assetSymbol, @@ -1153,11 +1147,10 @@ export const depositCommand: CommandModule = { createPublicClient, http } = await import('viem'); - const { polygon: polygonViemChain } = await import('viem/chains'); - // Pre-flight: verify balance and auto-reserve gas buffer when wallet has no native token try { - const publicClient = createPublicClient({ chain: polygonViemChain, transport: http() }); + const viemChain = await viemChainForDeposit(chainId); + const publicClient = createPublicClient({ chain: viemChain, transport: http() }); const [usdcBal, nativeBal] = await Promise.all([ publicClient.readContract({ address: asset.address as `0x${string}`, @@ -1478,10 +1471,10 @@ const ERC4626_REDEEM_ABI = [ } ] as const; -async function viemChainForWithdraw(chainId: number) { +async function viemChainMap() { const { mainnet, polygon, arbitrum, optimism, base, avalanche, bsc, gnosis, polygonAmoy } = await import('viem/chains'); - const map = { + return { 1: mainnet, 137: polygon, 42161: arbitrum, @@ -1491,7 +1484,21 @@ async function viemChainForWithdraw(chainId: number) { 56: bsc, 100: gnosis, 80002: polygonAmoy - } as const; + } as const satisfies Record; +} + +async function viemChainForDeposit(chainId: number) { + const map = await viemChainMap(); + const c = map[chainId as keyof typeof map]; + if (!c) + throw new Error( + `deposit: chainId ${chainId} has no bundled viem chain config for pre-flight check.` + ); + return c; +} + +async function viemChainForWithdraw(chainId: number) { + const map = await viemChainMap(); const c = map[chainId as keyof typeof map]; if (!c) { throw new Error( diff --git a/skills/polygon-defi/SKILL.md b/skills/polygon-defi/SKILL.md index 661bf00..b19a97d 100644 --- a/skills/polygon-defi/SKILL.md +++ b/skills/polygon-defi/SKILL.md @@ -106,7 +106,7 @@ interface PoolTokenInfo { ## Deposit to Earn Yield -Pool discovery uses `TrailsApi.getEarnPools` — picks the most liquid pool (highest TVL) for the asset. Only Polygon mainnet (chainId 137) is supported. No hardcoded addresses — the pool is resolved at runtime. +Pool discovery uses `TrailsApi.getEarnPools` — picks the most liquid pool (highest TVL) for the asset on the requested chain. No hardcoded addresses — the pool is resolved at runtime. Supported chains: Polygon, Base, Arbitrum, Optimism, Ethereum mainnet (any chain Trails indexes). **Gas requirement:** The wallet needs POL for gas, or a session created with `--usdc-limit` to enable USDC paymaster. If the wallet has no POL, create the session with `--usdc-limit 5`. When USDC paymaster is active and the deposit amount would consume the full balance, the CLI auto-reserves 0.05 USDC for gas and prints a note. From 8ab81501925b0bf9a75ea765b2e81d89399a0621 Mon Sep 17 00:00:00 2001 From: James Lawton Date: Mon, 27 Apr 2026 12:01:10 +0100 Subject: [PATCH 3/4] revert(wallet): remove session replacement guard --- .../polygon-agent-cli/src/commands/wallet.ts | 24 ------------------- skills/polygon-defi/SKILL.md | 7 +----- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/packages/polygon-agent-cli/src/commands/wallet.ts b/packages/polygon-agent-cli/src/commands/wallet.ts index 0d5cca5..d257460 100644 --- a/packages/polygon-agent-cli/src/commands/wallet.ts +++ b/packages/polygon-agent-cli/src/commands/wallet.ts @@ -249,28 +249,9 @@ interface CreateArgs extends SessionPermissionArgs { chain: string; 'print-url': boolean; timeout: number; - force?: boolean; } async function handleCreate(argv: CreateArgs): Promise { - if (!argv.force) { - const existing = await loadWalletSession(argv.name); - if (existing) { - const msg = - `Wallet '${argv.name}' already exists (${existing.walletAddress}). ` + - `Re-creating replaces the session — the old wallet balance will not be accessible from the new session. ` + - `Use --force to proceed.`; - if (isTTY()) { - process.stderr.write(`\nError: ${msg}\n\n`); - process.exit(1); - } else { - console.log( - JSON.stringify({ ok: false, error: msg, existingAddress: existing.walletAddress }) - ); - process.exit(1); - } - } - } if (argv['print-url']) { await handleCreateNoWait(argv); } else { @@ -577,11 +558,6 @@ export const walletCommand: CommandModule = { default: 300, describe: 'Seconds to wait for approval before timing out' }) - .option('force', { - type: 'boolean', - default: false, - describe: 'Replace existing session without prompting' - }) ), handler: (argv) => handleCreate(argv as unknown as CreateArgs) }) diff --git a/skills/polygon-defi/SKILL.md b/skills/polygon-defi/SKILL.md index b19a97d..fd4cfe5 100644 --- a/skills/polygon-defi/SKILL.md +++ b/skills/polygon-defi/SKILL.md @@ -210,15 +210,11 @@ polygon-agent swap --from USDC --to USDC --amount 0.5 --to-chain arbitrum --broa | Flag | Purpose | |------|---------| | `--usdc-limit ` | Enable USDC gas paymaster. Required when the wallet has no POL. Recommended: `--usdc-limit 5`. | -| `--force` | Replace an existing session without prompting. By default, re-creating a session is blocked if one already exists — the old wallet balance is not accessible from a new session. | | `--contract ` | Whitelist an additional contract (repeatable). Use this if a deposit is rejected due to a missing contract permission. | ```bash -# New session with USDC gas and deposit contracts pre-whitelisted +# New session with USDC gas enabled polygon-agent wallet create --usdc-limit 5 - -# Replace an existing session -polygon-agent wallet create --force --usdc-limit 5 ``` --- @@ -231,6 +227,5 @@ polygon-agent wallet create --force --usdc-limit 5 | `Wallet has no POL for gas` | No native gas and no USDC paymaster | Fund with POL (`polygon-agent fund`) or re-create session with `--usdc-limit 5` | | `Transaction rejected by relay` | Session permissions missing for pool or token contract | Re-create with `--contract --contract ` | | `Unable to pay gas` | No usable fee token found | Fund with POL or add `--usdc-limit 5` to session | -| `Wallet already exists` | Re-creating would orphan the old session | Use `--force` only after confirming old wallet funds are swept or unneeded | | `Protocol X not yet supported` | Trails returned a protocol other than aave/morpho | Use `polygon-agent swap` to obtain the yield-bearing token manually | | `swap`: no route found | Insufficient liquidity for the pair | Try a different amount or token pair | From 9e2735d531277d178d7f6c308a5ac625d0e47526 Mon Sep 17 00:00:00 2001 From: James Lawton Date: Mon, 27 Apr 2026 12:02:24 +0100 Subject: [PATCH 4/4] fix(fund): point to wallet.polygon.technology instead of demo.trails.build --- .../polygon-agent-cli/src/commands/operations.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/polygon-agent-cli/src/commands/operations.ts b/packages/polygon-agent-cli/src/commands/operations.ts index 94142d7..ff23848 100644 --- a/packages/polygon-agent-cli/src/commands/operations.ts +++ b/packages/polygon-agent-cli/src/commands/operations.ts @@ -357,12 +357,8 @@ export const balancesCommand: CommandModule = { // --- fund --- export const fundCommand: CommandModule = { command: 'fund', - describe: 'Open Trails widget to fund wallet', - builder: (yargs) => - withWalletAndChain(yargs).option('token', { - type: 'string', - describe: 'Fund token address' - }), + describe: 'Get funding URL for wallet', + builder: (yargs) => withWalletAndChain(yargs), handler: async (argv) => { const walletName = argv.wallet as string; @@ -374,10 +370,7 @@ export const fundCommand: CommandModule = { const walletAddress = session.walletAddress; const chainId = session.chainId || 137; - const toToken = (argv.token as string) || '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359'; - const apiKey = process.env.SEQUENCE_PROJECT_ACCESS_KEY || ''; - - const fundingUrl = `https://demo.trails.build/?mode=swap&toAddress=${walletAddress}&toChainId=${chainId}&toToken=${toToken}&apiKey=${apiKey}&theme=light`; + const fundingUrl = `https://wallet.polygon.technology`; if (isTTY()) { await inkRender( @@ -392,7 +385,7 @@ export const fundCommand: CommandModule = { walletAddress, chainId, fundingUrl, - message: 'Open the funding URL in your browser to fund your wallet via Trails.' + message: `Visit ${fundingUrl} to fund your wallet (${walletAddress}).` }, null, 2