Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/connector-ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
const [sessionCode, setSessionCode] = useState<string>('');
const [showFunding, setShowFunding] = useState(false);
const [showDashboard, setShowDashboard] = useState(false);
const [feeTokens, setFeeTokens] = useState<any | null>(null);

Check warning on line 148 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const [selectedUseCase, setSelectedUseCase] = useState(0);
const [selectedAgent, setSelectedAgent] = useState<string>('claude');
const [copied, setCopied] = useState(false);
Expand Down Expand Up @@ -178,7 +178,7 @@
}
setCliPkHex(cli_pk_hex);
})
.catch((e: any) => setError(`Failed to load session key: ${e?.message || String(e)}`));

Check warning on line 181 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
}, [rid]);

// Fetch USD portfolio balance when wallet address is first known
Expand Down Expand Up @@ -229,7 +229,7 @@
} catch {
setFeeTokens(null);
}
} catch (e: any) {

Check warning on line 232 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
setError(e?.message || String(e));
}
})();
Expand All @@ -254,12 +254,12 @@
const VALUE_FORWARDER = '0xABAAd93EeE2a569cF0632f39B10A9f5D734777ca';
const USDC = (await resolveErc20Symbol(chainId, 'USDC'))?.address;
const USDT = (await resolveErc20Symbol(chainId, 'USDT'))?.address;
const basePermissions: any[] = [{ target: VALUE_FORWARDER, rules: [] }];

Check warning on line 257 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const searchParams = new URLSearchParams(window.location.search);
const erc20 = searchParams.get('erc20');
const erc20To = searchParams.get('erc20To');
const erc20Amount = searchParams.get('erc20Amount');
const oneOffErc20Permissions: any[] =

Check warning on line 262 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
erc20 && erc20To && erc20Amount
? (() => {
const tokenAddr = erc20.toLowerCase() === 'usdc' ? USDC : erc20;
Expand All @@ -268,7 +268,7 @@
const f = (fRaw + '0'.repeat(decimals)).slice(0, decimals);
const valueLimit = BigInt(i || '0') * 10n ** BigInt(decimals) + BigInt(f || '0');
return [
Utils.PermissionBuilder.for(tokenAddr as any)

Check warning on line 271 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
.forFunction('function transfer(address to, uint256 value)')
.withUintNParam(
'value',
Expand All @@ -279,7 +279,7 @@
)
.withAddressParam(
'to',
erc20To as any,

Check warning on line 282 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
Permission.ParameterOperation.EQUAL,
false
)
Expand All @@ -293,8 +293,8 @@
const nativeLimit = searchParams.get('nativeLimit') || searchParams.get('polLimit');
const tokenLimitsRaw = searchParams.get('tokenLimits');
const USDC_E_POLYGON = '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174';
const openTokenPermissions: any[] = [];

Check warning on line 296 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
const dynamicTokenPermissions: any[] = [];

Check warning on line 297 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (tokenLimitsRaw) {
const parts = tokenLimitsRaw
.split(',')
Expand All @@ -306,7 +306,7 @@
const td = await resolveErc20Symbol(chainId, sym);
if (!td) throw new Error(`${sym} not found for this chain in token-directory`);
dynamicTokenPermissions.push(
Utils.PermissionBuilder.for(td.address as any)

Check warning on line 309 in packages/connector-ui/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
.forFunction('function transfer(address to, uint256 value)')
.withUintNParam(
'value',
Expand Down Expand Up @@ -806,7 +806,7 @@
{
title: 'Docs',
desc: 'Full CLI reference, quickstart guide, and architecture docs to get your agent onchain fast.',
href: 'https://polygon-labs.mintlify.io/wallets/agentic-wallets'
href: 'https://docs.polygon.technology/payment-services/agentic-payments/polygon-agent-cli'
}
].map((card) => (
<a
Expand Down
39 changes: 27 additions & 12 deletions packages/polygon-agent-cli/skills/polygon-defi/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,17 @@ polygon-agent withdraw --position <aToken> --amount 0.5 --chain mainnet --broadc
polygon-agent withdraw --position <vault> --amount max --chain polygon --broadcast
```

Whitelist the **pool** (Aave) or **vault** contract on the session if the wallet rejects the call (`polygon-agent wallet create --contract <poolOrVault>`).
### Session Prerequisites for DeFi

**Same chain as the transaction:** if you use `withdraw --chain mainnet`, create or refresh the session with **`wallet create --chain mainnet`** (not only Polygon defaults). Include **`--contract`** for the **pool** and for the **underlying ERC-20** on that chain (e.g. mainnet USDC `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`) so fee / helper transfers are allowed. Tight **`--usdc-limit`** can block those — omit or relax for yield exits.
Before running deposits, swaps, or withdrawals, create the wallet session with `--defi` so the relevant token and vault contracts are whitelisted:

```bash
polygon-agent wallet create --defi
```

Without `--defi`, only USDC and USDC.e are whitelisted by default. The `--defi` flag adds USDT, WETH, and all supported yield vault addresses (Aave and Morpho on Polygon mainnet).

**Same chain as the transaction:** if you use `withdraw --chain mainnet`, create or refresh the session with **`wallet create --chain mainnet --defi`**. Include **`--contract`** for the **underlying ERC-20** on that chain (e.g. mainnet USDC `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`) since `--defi` only covers Polygon mainnet contracts. Tight **`--usdc-limit`** can block fee/helper transfers — omit or relax for yield exits.

### Session Whitelisting

Expand All @@ -160,20 +168,23 @@ polygon-agent deposit --asset USDC --amount 0.3
# → note the token contract address (e.g. USDC: 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359)
# → note the depositAddress (e.g. Aave V3: 0x794a61358d6845594f94dc1db02a252b5b4814ad)

# 2. Re-create wallet session with BOTH contracts whitelisted
polygon-agent wallet create --contract <tokenAddress> --contract <depositAddress>
# 2. Re-create wallet session with DeFi contracts whitelisted (covers both token and vault)
polygon-agent wallet create --defi

# 3. Retry
polygon-agent deposit --asset USDC --amount 0.3 --broadcast
```

Common token contracts on Polygon mainnet (already auto-whitelisted in sessions created by the CLI):
- USDC: `0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359`
- USDT: `0xc2132D05D31c914a87C6611C10748AEb04B58e8F`
- WETH: `0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619`
To add a contract not covered by `--defi`, use `--contract` alongside it:

```bash
polygon-agent wallet create --defi --contract <extraAddress>
```

### Yield Vault Contract Whitelist

The following contracts are included when `--defi` is passed:

#### Polygon Mainnet (chainId 137)

| Protocol | Asset | Address |
Expand All @@ -188,6 +199,9 @@ Common token contracts on Polygon mainnet (already auto-whitelisted in sessions
## Full DeFi Flow Example

```bash
# 0. Create session with DeFi contracts whitelisted
polygon-agent wallet create --defi --usdc-limit 5

# 1. Check balances
polygon-agent balances

Expand All @@ -209,16 +223,17 @@ polygon-agent swap --from USDC --to USDC --amount 0.5 --to-chain arbitrum --broa

| Flag | Purpose |
|------|---------|
| `--defi` | Whitelist DeFi contracts (USDT, WETH, yield vaults on Polygon mainnet). Required for swaps and deposits. |
| `--usdc-limit <amt>` | 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 <addr>` | 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
# New session for DeFi operations (swaps, deposits) with USDC gas paymaster
polygon-agent wallet create --defi --usdc-limit 5

# Replace an existing session
polygon-agent wallet create --force --usdc-limit 5
polygon-agent wallet create --defi --force --usdc-limit 5
```

---
Expand All @@ -229,7 +244,7 @@ polygon-agent wallet create --force --usdc-limit 5
|-------|-------|-----|
| `Insufficient <token>: 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 <tokenAddress> --contract <depositAddress>` |
| `Transaction rejected by relay` | Session permissions missing for pool or token contract | Re-create with `--defi` or add `--contract <addr>` for a specific address |
| `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 |
Expand Down
31 changes: 18 additions & 13 deletions packages/polygon-agent-cli/src/commands/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,23 @@ const AUTO_WHITELISTED_CONTRACTS = [
// NOTE: Trails deposit contract for swap --from POL is dynamic (changes per route/quote)
// and cannot be reliably pre-whitelisted here.

// Polygon mainnet (chainId 137) — ERC-20 token contracts (needed for approve() in deposits/swaps)
// Polygon mainnet (chainId 137) — default tokens
'0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', // USDC (native)
'0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174' // USDC.e (bridged)
];

// Additional contracts whitelisted when --defi flag is passed.
// Covers ERC-20s and yield vaults needed for swaps, bridges, and deposits.
const DEFI_CONTRACTS = [
// Polygon mainnet (chainId 137) — additional ERC-20 token contracts
'0xc2132D05D31c914a87C6611C10748AEb04B58e8F', // USDT
'0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', // WETH

// Polygon mainnet (chainId 137) — yield vaults
'0x794a61358d6845594f94dc1db02a252b5b4814ad', // Aave V3 Pool (all markets)
'0x781fb7f6d845e3be129289833b04d43aa8558c42', // Morpho Compound USDC
'0xf5c81d25ee174d83f1fd202ca94ae6070d073ccf', // Morpho Compound WETH
'0x3f33f9f7e2d7cfbcbdf8ea8b870a6e3d449664c2', // Morpho Compound POL

// Katana (chainId 747474) — Morpho vaults
'0x1ecdc3f2b5e90bfb55ff45a7476ff98a8957388e', // Gauntlet USDT (~$97M TVL)
'0x61d4f9d3797ba4da152238c53a6f93fb665c3c1d', // Steakhouse Prime USDC (~$54M TVL)
'0xfade0c546f44e33c134c4036207b314ac643dc2e', // Yearn OG ETH (~$16M TVL)
'0xce2b8e464fc7b5e58710c24b7e5ebfb6027f29d7', // Yearn OG USDC (~$16M TVL)
'0xe4248e2105508fcbad3fe95691551d1af14015f7', // Gauntlet USDC (~$8M TVL)
'0x8ed68f91afbe5871dce31ae007a936ebe8511d47', // Yearn OG USDT (~$8M TVL)
'0xc5e7ab07030305fc925175b25b93b285d40dcdff', // Gauntlet WETH (~$6M TVL)
'0xef77f8c53af95f3348cee0fb2a02ee02ab9cdca5' // Hyperithm vbUSDC Apex (~$3M TVL)
'0x3f33f9f7e2d7cfbcbdf8ea8b870a6e3d449664c2' // Morpho Compound POL
];

// Session permission options shared by create subcommands
Expand All @@ -80,6 +77,7 @@ interface SessionPermissionArgs {
'usdt-limit'?: string;
'token-limit'?: string[];
contract?: string[];
defi?: boolean;
'usdc-to'?: string;
'usdc-amount'?: string;
'access-key'?: string;
Expand Down Expand Up @@ -109,6 +107,10 @@ function addSessionPermissionOptions<T>(yargs: Argv<T>): Argv<T & SessionPermiss
array: true,
describe: 'Whitelist contract, repeatable'
})
.option('defi', {
type: 'boolean',
describe: 'Whitelist DeFi contracts (swaps, yield vaults) in addition to defaults'
})
.option('usdc-to', {
type: 'string',
describe: 'One-off USDC transfer recipient'
Expand Down Expand Up @@ -145,8 +147,11 @@ function applySessionPermissionParams(url: URL, argv: SessionPermissionArgs): vo
.filter(Boolean);
if (tokenLimits.length) url.searchParams.set('tokenLimits', tokenLimits.join(','));

const baseContracts = argv.defi
? [...AUTO_WHITELISTED_CONTRACTS, ...DEFI_CONTRACTS]
: AUTO_WHITELISTED_CONTRACTS;
const userContracts = (argv.contract || []).map((s) => String(s || '').trim()).filter(Boolean);
const allContracts = [...new Set([...AUTO_WHITELISTED_CONTRACTS, ...userContracts])];
const allContracts = [...new Set([...baseContracts, ...userContracts])];
url.searchParams.set('contracts', allContracts.join(','));
}

Expand Down
Loading