[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6FZSSWC490GARTS4N95TZ0G":3,"skill-same:01M6FZSSWC490GARTS4N95TZ0G":64},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":32,"linkOnly":33,"markdownContent":34,"markdownBody":35,"frontMatter":36,"refName":37,"commitSha":38,"skillDirectory":39,"forksCount":40,"repositoryHtmlUrl":41,"repositoryHomepageUrl":6,"ownerHtmlUrl":42,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":43,"install":44,"resources":57},"01M6FZSSWC490GARTS4N95TZ0G","zyfai",null,"Earn yield on any Ethereum wallet on Base, Arbitrum, and Plasma. Use when a user wants passive DeFi yield on their funds. Deploys a non-custodial subaccount (Safe) linked to their EOA, enables automated yield optimization, and lets them deposit\u002Fwithdraw anytime.","kbarbel640-del\u002Fskills","kbarbel640-del","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F255315490?v=4","01M6CJPPQGCCESXMG3K7BBGQ5J","01M6CJPPX2PB2BCZERFVM2C2B3",1,"MIT","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fpauldefi\u002Fzyfai-sdk\u002FSKILL.md",[],[5,18,19,20,21,22,23,24,25,26,27,28,29,30,31],"safe","ethereum","defi","Optimization","user","use","Wallet","base","deposit","withdraw","yield","arbitrum","non-custodial","passive","2026-11-10 10:12:30",false,"---\nname: zyfai\ndescription: Earn yield on any Ethereum wallet on Base, Arbitrum, and Plasma. Use when a user wants passive DeFi yield on their funds. Deploys a non-custodial subaccount (Safe) linked to their EOA, enables automated yield optimization, and lets them deposit\u002Fwithdraw anytime.\n---\n\n# Zyfai — Yield for Any Wallet\n\nTurn any Ethereum wallet into a yield-generating account.\n\n## What This Does\n\nWhen a user wants to **earn yield** on their crypto, Zyfai creates a **subaccount** (Safe smart wallet) linked to their existing wallet (EOA). Funds deposited into this subaccount are automatically optimized across DeFi protocols. The user stays in full control and can withdraw anytime.\n\n```\n┌─────────────────┐      ┌──────────────────────┐\n│   User's EOA    │ ───► │  Zyfai Subaccount    │\n│  (their wallet) │      │  (Safe smart wallet) │\n│                 │      │                      │\n│  Owns & controls│      │  • Auto-rebalancing  │\n│                 │      │  • Yield optimization│\n│                 │      │  • Non-custodial     │\n└─────────────────┘      └──────────────────────┘\n```\n\n**Key points:**\n- The subaccount is **owned by the user's EOA** — only they can withdraw\n- Session keys allow **automated rebalancing** but cannot withdraw to other addresses\n- Same EOA = same subaccount address across all chains\n\n## The Flow\n\n```\n1. DEPLOY    →  Create subaccount linked to user's wallet\n2. SESSION   →  Enable automated yield optimization  \n3. DEPOSIT   →  Send funds to subaccount (starts earning)\n4. WITHDRAW  →  Pull funds back to wallet (anytime)\n```\n\n## Prerequisites\n\n- **API Key** from [sdk.zyf.ai](https:\u002F\u002Fsdk.zyf.ai) (connect wallet to get one)\n- **Private Key** of the user's EOA (the agent must provide this)\n- **Node.js 18+**\n\n```bash\nnpm install @zyfai\u002Fsdk viem\n```\n\n## Supported Chains\n\n| Chain    | ID    |\n|----------|-------|\n| Arbitrum | 42161 |\n| Base     | 8453  |\n| Plasma   | 9745  |\n\n## Important: Always Use EOA Address\n\nWhen calling SDK methods, **always pass the EOA address** (the user's wallet address) as `userAddress` — never the subaccount\u002FSafe address. The SDK derives the subaccount address automatically from the EOA.\n\n## Step-by-Step\n\n### 1. Connect to Zyfai\n\n```typescript\nimport { ZyfaiSDK } from \"@zyfai\u002Fsdk\";\n\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\" });\n\n\u002F\u002F Use the private key provided by the agent\nawait sdk.connectAccount(privateKey, 8453); \u002F\u002F chainId\n```\n\n**Important:** Always use the private key that the agent has access to. The private key must correspond to the EOA you're operating on.\n\n### 2. Deploy Subaccount\n\n```typescript\nconst userAddress = \"0x...\"; \u002F\u002F User's EOA (NOT the subaccount address!)\nconst chainId = 8453; \u002F\u002F Base\n\n\u002F\u002F Check if subaccount exists\nconst wallet = await sdk.getSmartWalletAddress(userAddress, chainId);\nconsole.log(`Subaccount: ${wallet.address}`);\nconsole.log(`Deployed: ${wallet.isDeployed}`);\n\n\u002F\u002F Deploy if needed\nif (!wallet.isDeployed) {\n  const result = await sdk.deploySafe(userAddress, chainId, \"conservative\");\n  console.log(\"Subaccount deployed:\", result.safeAddress);\n}\n```\n\n**Strategies:**\n- `\"conservative\"` — Stable yield, lower risk\n- `\"aggressive\"` — Higher yield, higher risk\n\n### 3. Enable Yield Optimization\n\n```typescript\nawait sdk.createSessionKey(userAddress, chainId);\n```\n\nThis allows Zyfai to rebalance funds automatically. Session keys **cannot** withdraw to arbitrary addresses — only optimize within the protocol.\n\n### 4. Deposit Funds\n\n```typescript\n\u002F\u002F Deposit 10 USDC (6 decimals)\nawait sdk.depositFunds(userAddress, chainId, \"10000000\");\n```\n\nFunds move from EOA → Subaccount and start earning yield immediately.\n\n### 5. Withdraw Funds\n\n```typescript\n\u002F\u002F Withdraw everything\nawait sdk.withdrawFunds(userAddress, chainId);\n\n\u002F\u002F Or withdraw partial (5 USDC)\nawait sdk.withdrawFunds(userAddress, chainId, \"5000000\");\n```\n\nFunds return to the user's EOA. Withdrawals are processed asynchronously.\n\n### 6. Disconnect\n\n```typescript\nawait sdk.disconnectAccount();\n```\n\n## Complete Example\n\n```typescript\nimport { ZyfaiSDK } from \"@zyfai\u002Fsdk\";\n\nasync function startEarningYield(userAddress: string, privateKey: string) {\n  const sdk = new ZyfaiSDK({ apiKey: process.env.ZYFAI_API_KEY! });\n  const chainId = 8453; \u002F\u002F Base\n  \n  \u002F\u002F Connect using the agent's private key\n  await sdk.connectAccount(privateKey, chainId);\n  \n  \u002F\u002F Deploy subaccount if needed (always pass EOA as userAddress)\n  const wallet = await sdk.getSmartWalletAddress(userAddress, chainId);\n  if (!wallet.isDeployed) {\n    await sdk.deploySafe(userAddress, chainId, \"conservative\");\n    console.log(\"Subaccount created:\", wallet.address);\n  }\n  \n  \u002F\u002F Enable automated optimization\n  await sdk.createSessionKey(userAddress, chainId);\n  \n  \u002F\u002F Deposit 100 USDC\n  await sdk.depositFunds(userAddress, chainId, \"100000000\");\n  console.log(\"Deposited! Now earning yield.\");\n  \n  await sdk.disconnectAccount();\n}\n\nasync function withdrawYield(userAddress: string, privateKey: string, amount?: string) {\n  const sdk = new ZyfaiSDK({ apiKey: process.env.ZYFAI_API_KEY! });\n  const chainId = 8453; \u002F\u002F Base\n  \n  \u002F\u002F Connect using the agent's private key\n  await sdk.connectAccount(privateKey, chainId);\n  \n  \u002F\u002F Withdraw funds (pass EOA as userAddress)\n  if (amount) {\n    \u002F\u002F Partial withdrawal\n    await sdk.withdrawFunds(userAddress, chainId, amount);\n    console.log(`Withdrawn ${amount} (6 decimals) to EOA`);\n  } else {\n    \u002F\u002F Full withdrawal\n    await sdk.withdrawFunds(userAddress, chainId);\n    console.log(\"Withdrawn all funds to EOA\");\n  }\n  \n  await sdk.disconnectAccount();\n}\n```\n\n## API Reference\n\n| Method | Params | Description |\n|--------|--------|-------------|\n| `connectAccount` | `(privateKey, chainId)` | Authenticate with Zyfai |\n| `getSmartWalletAddress` | `(userAddress, chainId)` | Get subaccount address & status |\n| `deploySafe` | `(userAddress, chainId, strategy)` | Create subaccount |\n| `createSessionKey` | `(userAddress, chainId)` | Enable auto-optimization |\n| `depositFunds` | `(userAddress, chainId, amount)` | Deposit USDC (6 decimals) |\n| `withdrawFunds` | `(userAddress, chainId, amount?)` | Withdraw (all if no amount) |\n| `getPositions` | `(userAddress, chainId?)` | Get active DeFi positions |\n| `getAvailableProtocols` | `(chainId)` | Get available protocols & pools |\n| `getAPYPerStrategy` | `(crossChain?, days?, strategyType?)` | Get APY for conservative\u002Faggressive strategies |\n| `getUserDetails` | `()` | Get authenticated user details |\n| `getOnchainEarnings` | `(walletAddress)` | Get earnings data |\n| `registerAgentOnIdentityRegistry` | `(smartWallet, chainId)` | Register agent on ERC-8004 Identity Registry |\n| `disconnectAccount` | `()` | End session |\n\n**Note:** All methods that take `userAddress` expect the **EOA address**, not the subaccount\u002FSafe address.\n\n## Data Methods\n\n### getPositions\n\nGet all active DeFi positions for a user across protocols. Optionally filter by chain.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| userAddress | string | ✅ | User's EOA address |\n| chainId | SupportedChainId | ❌ | Optional: Filter by specific chain ID |\n\n**Example:**\n\n```typescript\n\u002F\u002F Get all positions across all chains\nconst positions = await sdk.getPositions(\"0xUser...\");\n\n\u002F\u002F Get positions on Arbitrum only\nconst arbPositions = await sdk.getPositions(\"0xUser...\", 42161);\n```\n\n**Returns:**\n\n```typescript\ninterface PositionsResponse {\n  success: boolean;\n  userAddress: string;\n  positions: Position[];\n}\n```\n\n### getAvailableProtocols\n\nGet available DeFi protocols and pools for a specific chain with APY data.\n\n```typescript\nconst protocols = await sdk.getAvailableProtocols(42161); \u002F\u002F Arbitrum\n\nprotocols.protocols.forEach((protocol) => {\n  console.log(`${protocol.name} (ID: ${protocol.id})`);\n  if (protocol.pools) {\n    protocol.pools.forEach((pool) => {\n      console.log(`  Pool: ${pool.name} - APY: ${pool.apy || \"N\u002FA\"}%`);\n    });\n  }\n});\n```\n\nReturns:\n```typescript\ninterface ProtocolsResponse {\n  success: boolean;\n  chainId: SupportedChainId;\n  protocols: Protocol[];\n}\n```\n\n### getUserDetails\n\nGet current authenticated user details including smart wallet, chains, protocols, and settings. Requires SIWE authentication.\n\n```typescript\nawait sdk.connectAccount(privateKey, chainId);\nconst user = await sdk.getUserDetails();\n\nconsole.log(\"Smart Wallet:\", user.user.smartWallet);\nconsole.log(\"Chains:\", user.user.chains);\nconsole.log(\"Has Active Session:\", user.user.hasActiveSessionKey);\n```\n\nReturns:\n```typescript\ninterface UserDetailsResponse {\n  success: boolean;\n  user: {\n    id: string;\n    address: string;\n    smartWallet?: string;\n    chains: number[];\n    protocols: Protocol[];\n    hasActiveSessionKey: boolean;\n    email?: string;\n    strategy?: string;\n    telegramId?: string;\n    walletType?: string;\n    autoSelectProtocols: boolean;\n    autocompounding?: boolean;\n    omniAccount?: boolean;\n    crosschainStrategy?: boolean;\n    agentName?: string;\n    customization?: Record\u003Cstring, string[]>;\n  };\n}\n```\n\n### getAPYPerStrategy\n\nGet global APY by strategy type (conservative or aggressive), time period, and chain configuration. Use this to compare expected returns between strategies before deploying.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| crossChain | boolean | ❌ | If `true`, returns APY for cross-chain strategies; if `false`, single-chain |\n| days | number | ❌ | Period over which APY is calculated. One of `7`, `15`, `30`, `60` |\n| strategyType | string | ❌ | Strategy risk profile. One of `'conservative'` or `'aggressive'` |\n\n**Example:**\n\n```typescript\n\u002F\u002F Get 7-day APY for conservative single-chain strategy\nconst conservativeApy = await sdk.getAPYPerStrategy(false, 7, 'conservative');\nconsole.log(\"Conservative APY:\", conservativeApy.data);\n\n\u002F\u002F Get 30-day APY for aggressive cross-chain strategy\nconst aggressiveApy = await sdk.getAPYPerStrategy(true, 30, 'aggressive');\nconsole.log(\"Aggressive APY:\", aggressiveApy.data);\n\n\u002F\u002F Compare strategies\nconst conservative = await sdk.getAPYPerStrategy(false, 30, 'conservative');\nconst aggressive = await sdk.getAPYPerStrategy(false, 30, 'aggressive');\nconsole.log(`Conservative 30d APY: ${conservative.data[0]?.apy}%`);\nconsole.log(`Aggressive 30d APY: ${aggressive.data[0]?.apy}%`);\n```\n\n**Returns:**\n\n```typescript\ninterface APYPerStrategyResponse {\n  success: boolean;\n  count: number;\n  data: APYPerStrategy[];\n}\n\ninterface APYPerStrategy {\n  strategyType: string;\n  apy: number;\n  period: number;\n  crossChain: boolean;\n}\n```\n\n### getOnchainEarnings\n\nGet onchain earnings for a wallet including total, current, and lifetime earnings.\n\n```typescript\nconst earnings = await sdk.getOnchainEarnings(smartWalletAddress);\n\nconsole.log(\"Total earnings:\", earnings.data.totalEarnings);\nconsole.log(\"Current earnings:\", earnings.data.currentEarnings);\nconsole.log(\"Lifetime earnings:\", earnings.data.lifetimeEarnings);\n```\n\nReturns:\n```typescript\ninterface OnchainEarningsResponse {\n  success: boolean;\n  data: {\n    walletAddress: string;\n    totalEarnings: number;\n    currentEarnings: number;\n    lifetimeEarnings: number;\n    unrealizedEarnings?: number;\n    currentEarningsByChain?: Record\u003Cstring, number>;\n    unrealizedEarningsByChain?: Record\u003Cstring, number>;\n    lastCheckTimestamp?: string;\n  };\n}\n```\n\n### registerAgentOnIdentityRegistry (ERC-8004)\n\nRegister your Zyfai deployed agent on the Identity Registry following the ERC-8004 standard. This is used for OpenClaw agent registration. The method fetches a tokenUri containing the agent's metadata stored on IPFS, then registers it on-chain.\n\n**Supported Chains:**\n\n| Chain | Chain ID |\n|-------|----------|\n| Base | 8453 |\n| Arbitrum | 42161 |\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| smartWallet | string | ✅ | The Zyfai deployed smart wallet address to register as an agent |\n| chainId | SupportedChainId | ✅ | Chain ID (only 8453 or 42161) |\n\n**Example:**\n\n```typescript\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\" });\nawait sdk.connectAccount(privateKey, 8453);\n\n\u002F\u002F Get smart wallet address\nconst walletInfo = await sdk.getSmartWalletAddress(userAddress, 8453);\nconst smartWallet = walletInfo.address;\n\n\u002F\u002F Register agent on Identity Registry\nconst result = await sdk.registerAgentOnIdentityRegistry(smartWallet, 8453);\n\nconsole.log(\"Registration successful:\");\nconsole.log(\"  Tx Hash:\", result.txHash);\nconsole.log(\"  Chain ID:\", result.chainId);\nconsole.log(\"  Smart Wallet:\", result.smartWallet);\n```\n\n**Returns:**\n\n```typescript\ninterface RegisterAgentResponse {\n  success: boolean;\n  txHash: string;\n  chainId: number;\n  smartWallet: string;\n}\n```\n\n**How It Works:**\n\n1. Fetches a `tokenUri` from the Zyfai API (agent metadata stored on IPFS)\n2. Encodes the `register(tokenUri)` call for the Identity Registry contract\n3. Sends the transaction from the connected wallet\n4. Waits for on-chain confirmation\n\n## Security\n\n- **Non-custodial** — User's EOA owns the subaccount\n- **Session keys are limited** — Can rebalance, cannot withdraw elsewhere\n- **Deterministic** — Same EOA = same subaccount on every chain\n\n## Troubleshooting\n\n### Subaccount address mismatch across chains\n\nThe subaccount address should be **identical** across all chains for the same EOA. If you see different addresses:\n\n```typescript\n\u002F\u002F Check addresses on both chains\nconst baseWallet = await sdk.getSmartWalletAddress(userAddress, 8453);\nconst arbWallet = await sdk.getSmartWalletAddress(userAddress, 42161);\n\nif (baseWallet.address !== arbWallet.address) {\n  console.error(\"Address mismatch! Contact support.\");\n}\n```\n\n**If addresses don't match:**\n1. Try redeploying on the affected chain\n2. If the issue persists, contact support on Telegram: [@paul_zyfai](https:\u002F\u002Ft.me\u002Fpaul_zyfai)\n\n### \"Deposit address not found\" error\n\nThis means the wallet isn't registered in the backend. Solution:\n1. Call `deploySafe()` first — even if the Safe is already deployed on-chain, this registers it with the backend\n2. Then retry `createSessionKey()`\n\n### \"Invalid signature\" error\n\nThis typically means:\n- The private key doesn't match the EOA you're passing\n- The Safe address on-chain doesn't match what the SDK expects\n\nVerify you're using the correct private key for the EOA.\n\n## Resources\n\n- Get API Key: [sdk.zyf.ai](https:\u002F\u002Fsdk.zyf.ai)\n- Docs: [docs.zyf.ai](https:\u002F\u002Fdocs.zyf.ai)\n- Demo: [github.com\u002Fondefy\u002Fzyfai-sdk-demo](https:\u002F\u002Fgithub.com\u002Fondefy\u002Fzyfai-sdk-demo)\n","# Zyfai — Yield for Any Wallet\n\nTurn any Ethereum wallet into a yield-generating account.\n\n## What This Does\n\nWhen a user wants to **earn yield** on their crypto, Zyfai creates a **subaccount** (Safe smart wallet) linked to their existing wallet (EOA). Funds deposited into this subaccount are automatically optimized across DeFi protocols. The user stays in full control and can withdraw anytime.\n\n```\n┌─────────────────┐      ┌──────────────────────┐\n│   User's EOA    │ ───► │  Zyfai Subaccount    │\n│  (their wallet) │      │  (Safe smart wallet) │\n│                 │      │                      │\n│  Owns & controls│      │  • Auto-rebalancing  │\n│                 │      │  • Yield optimization│\n│                 │      │  • Non-custodial     │\n└─────────────────┘      └──────────────────────┘\n```\n\n**Key points:**\n- The subaccount is **owned by the user's EOA** — only they can withdraw\n- Session keys allow **automated rebalancing** but cannot withdraw to other addresses\n- Same EOA = same subaccount address across all chains\n\n## The Flow\n\n```\n1. DEPLOY    →  Create subaccount linked to user's wallet\n2. SESSION   →  Enable automated yield optimization  \n3. DEPOSIT   →  Send funds to subaccount (starts earning)\n4. WITHDRAW  →  Pull funds back to wallet (anytime)\n```\n\n## Prerequisites\n\n- **API Key** from [sdk.zyf.ai](https:\u002F\u002Fsdk.zyf.ai) (connect wallet to get one)\n- **Private Key** of the user's EOA (the agent must provide this)\n- **Node.js 18+**\n\n```bash\nnpm install @zyfai\u002Fsdk viem\n```\n\n## Supported Chains\n\n| Chain    | ID    |\n|----------|-------|\n| Arbitrum | 42161 |\n| Base     | 8453  |\n| Plasma   | 9745  |\n\n## Important: Always Use EOA Address\n\nWhen calling SDK methods, **always pass the EOA address** (the user's wallet address) as `userAddress` — never the subaccount\u002FSafe address. The SDK derives the subaccount address automatically from the EOA.\n\n## Step-by-Step\n\n### 1. Connect to Zyfai\n\n```typescript\nimport { ZyfaiSDK } from \"@zyfai\u002Fsdk\";\n\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\" });\n\n\u002F\u002F Use the private key provided by the agent\nawait sdk.connectAccount(privateKey, 8453); \u002F\u002F chainId\n```\n\n**Important:** Always use the private key that the agent has access to. The private key must correspond to the EOA you're operating on.\n\n### 2. Deploy Subaccount\n\n```typescript\nconst userAddress = \"0x...\"; \u002F\u002F User's EOA (NOT the subaccount address!)\nconst chainId = 8453; \u002F\u002F Base\n\n\u002F\u002F Check if subaccount exists\nconst wallet = await sdk.getSmartWalletAddress(userAddress, chainId);\nconsole.log(`Subaccount: ${wallet.address}`);\nconsole.log(`Deployed: ${wallet.isDeployed}`);\n\n\u002F\u002F Deploy if needed\nif (!wallet.isDeployed) {\n  const result = await sdk.deploySafe(userAddress, chainId, \"conservative\");\n  console.log(\"Subaccount deployed:\", result.safeAddress);\n}\n```\n\n**Strategies:**\n- `\"conservative\"` — Stable yield, lower risk\n- `\"aggressive\"` — Higher yield, higher risk\n\n### 3. Enable Yield Optimization\n\n```typescript\nawait sdk.createSessionKey(userAddress, chainId);\n```\n\nThis allows Zyfai to rebalance funds automatically. Session keys **cannot** withdraw to arbitrary addresses — only optimize within the protocol.\n\n### 4. Deposit Funds\n\n```typescript\n\u002F\u002F Deposit 10 USDC (6 decimals)\nawait sdk.depositFunds(userAddress, chainId, \"10000000\");\n```\n\nFunds move from EOA → Subaccount and start earning yield immediately.\n\n### 5. Withdraw Funds\n\n```typescript\n\u002F\u002F Withdraw everything\nawait sdk.withdrawFunds(userAddress, chainId);\n\n\u002F\u002F Or withdraw partial (5 USDC)\nawait sdk.withdrawFunds(userAddress, chainId, \"5000000\");\n```\n\nFunds return to the user's EOA. Withdrawals are processed asynchronously.\n\n### 6. Disconnect\n\n```typescript\nawait sdk.disconnectAccount();\n```\n\n## Complete Example\n\n```typescript\nimport { ZyfaiSDK } from \"@zyfai\u002Fsdk\";\n\nasync function startEarningYield(userAddress: string, privateKey: string) {\n  const sdk = new ZyfaiSDK({ apiKey: process.env.ZYFAI_API_KEY! });\n  const chainId = 8453; \u002F\u002F Base\n  \n  \u002F\u002F Connect using the agent's private key\n  await sdk.connectAccount(privateKey, chainId);\n  \n  \u002F\u002F Deploy subaccount if needed (always pass EOA as userAddress)\n  const wallet = await sdk.getSmartWalletAddress(userAddress, chainId);\n  if (!wallet.isDeployed) {\n    await sdk.deploySafe(userAddress, chainId, \"conservative\");\n    console.log(\"Subaccount created:\", wallet.address);\n  }\n  \n  \u002F\u002F Enable automated optimization\n  await sdk.createSessionKey(userAddress, chainId);\n  \n  \u002F\u002F Deposit 100 USDC\n  await sdk.depositFunds(userAddress, chainId, \"100000000\");\n  console.log(\"Deposited! Now earning yield.\");\n  \n  await sdk.disconnectAccount();\n}\n\nasync function withdrawYield(userAddress: string, privateKey: string, amount?: string) {\n  const sdk = new ZyfaiSDK({ apiKey: process.env.ZYFAI_API_KEY! });\n  const chainId = 8453; \u002F\u002F Base\n  \n  \u002F\u002F Connect using the agent's private key\n  await sdk.connectAccount(privateKey, chainId);\n  \n  \u002F\u002F Withdraw funds (pass EOA as userAddress)\n  if (amount) {\n    \u002F\u002F Partial withdrawal\n    await sdk.withdrawFunds(userAddress, chainId, amount);\n    console.log(`Withdrawn ${amount} (6 decimals) to EOA`);\n  } else {\n    \u002F\u002F Full withdrawal\n    await sdk.withdrawFunds(userAddress, chainId);\n    console.log(\"Withdrawn all funds to EOA\");\n  }\n  \n  await sdk.disconnectAccount();\n}\n```\n\n## API Reference\n\n| Method | Params | Description |\n|--------|--------|-------------|\n| `connectAccount` | `(privateKey, chainId)` | Authenticate with Zyfai |\n| `getSmartWalletAddress` | `(userAddress, chainId)` | Get subaccount address & status |\n| `deploySafe` | `(userAddress, chainId, strategy)` | Create subaccount |\n| `createSessionKey` | `(userAddress, chainId)` | Enable auto-optimization |\n| `depositFunds` | `(userAddress, chainId, amount)` | Deposit USDC (6 decimals) |\n| `withdrawFunds` | `(userAddress, chainId, amount?)` | Withdraw (all if no amount) |\n| `getPositions` | `(userAddress, chainId?)` | Get active DeFi positions |\n| `getAvailableProtocols` | `(chainId)` | Get available protocols & pools |\n| `getAPYPerStrategy` | `(crossChain?, days?, strategyType?)` | Get APY for conservative\u002Faggressive strategies |\n| `getUserDetails` | `()` | Get authenticated user details |\n| `getOnchainEarnings` | `(walletAddress)` | Get earnings data |\n| `registerAgentOnIdentityRegistry` | `(smartWallet, chainId)` | Register agent on ERC-8004 Identity Registry |\n| `disconnectAccount` | `()` | End session |\n\n**Note:** All methods that take `userAddress` expect the **EOA address**, not the subaccount\u002FSafe address.\n\n## Data Methods\n\n### getPositions\n\nGet all active DeFi positions for a user across protocols. Optionally filter by chain.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| userAddress | string | ✅ | User's EOA address |\n| chainId | SupportedChainId | ❌ | Optional: Filter by specific chain ID |\n\n**Example:**\n\n```typescript\n\u002F\u002F Get all positions across all chains\nconst positions = await sdk.getPositions(\"0xUser...\");\n\n\u002F\u002F Get positions on Arbitrum only\nconst arbPositions = await sdk.getPositions(\"0xUser...\", 42161);\n```\n\n**Returns:**\n\n```typescript\ninterface PositionsResponse {\n  success: boolean;\n  userAddress: string;\n  positions: Position[];\n}\n```\n\n### getAvailableProtocols\n\nGet available DeFi protocols and pools for a specific chain with APY data.\n\n```typescript\nconst protocols = await sdk.getAvailableProtocols(42161); \u002F\u002F Arbitrum\n\nprotocols.protocols.forEach((protocol) => {\n  console.log(`${protocol.name} (ID: ${protocol.id})`);\n  if (protocol.pools) {\n    protocol.pools.forEach((pool) => {\n      console.log(`  Pool: ${pool.name} - APY: ${pool.apy || \"N\u002FA\"}%`);\n    });\n  }\n});\n```\n\nReturns:\n```typescript\ninterface ProtocolsResponse {\n  success: boolean;\n  chainId: SupportedChainId;\n  protocols: Protocol[];\n}\n```\n\n### getUserDetails\n\nGet current authenticated user details including smart wallet, chains, protocols, and settings. Requires SIWE authentication.\n\n```typescript\nawait sdk.connectAccount(privateKey, chainId);\nconst user = await sdk.getUserDetails();\n\nconsole.log(\"Smart Wallet:\", user.user.smartWallet);\nconsole.log(\"Chains:\", user.user.chains);\nconsole.log(\"Has Active Session:\", user.user.hasActiveSessionKey);\n```\n\nReturns:\n```typescript\ninterface UserDetailsResponse {\n  success: boolean;\n  user: {\n    id: string;\n    address: string;\n    smartWallet?: string;\n    chains: number[];\n    protocols: Protocol[];\n    hasActiveSessionKey: boolean;\n    email?: string;\n    strategy?: string;\n    telegramId?: string;\n    walletType?: string;\n    autoSelectProtocols: boolean;\n    autocompounding?: boolean;\n    omniAccount?: boolean;\n    crosschainStrategy?: boolean;\n    agentName?: string;\n    customization?: Record\u003Cstring, string[]>;\n  };\n}\n```\n\n### getAPYPerStrategy\n\nGet global APY by strategy type (conservative or aggressive), time period, and chain configuration. Use this to compare expected returns between strategies before deploying.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| crossChain | boolean | ❌ | If `true`, returns APY for cross-chain strategies; if `false`, single-chain |\n| days | number | ❌ | Period over which APY is calculated. One of `7`, `15`, `30`, `60` |\n| strategyType | string | ❌ | Strategy risk profile. One of `'conservative'` or `'aggressive'` |\n\n**Example:**\n\n```typescript\n\u002F\u002F Get 7-day APY for conservative single-chain strategy\nconst conservativeApy = await sdk.getAPYPerStrategy(false, 7, 'conservative');\nconsole.log(\"Conservative APY:\", conservativeApy.data);\n\n\u002F\u002F Get 30-day APY for aggressive cross-chain strategy\nconst aggressiveApy = await sdk.getAPYPerStrategy(true, 30, 'aggressive');\nconsole.log(\"Aggressive APY:\", aggressiveApy.data);\n\n\u002F\u002F Compare strategies\nconst conservative = await sdk.getAPYPerStrategy(false, 30, 'conservative');\nconst aggressive = await sdk.getAPYPerStrategy(false, 30, 'aggressive');\nconsole.log(`Conservative 30d APY: ${conservative.data[0]?.apy}%`);\nconsole.log(`Aggressive 30d APY: ${aggressive.data[0]?.apy}%`);\n```\n\n**Returns:**\n\n```typescript\ninterface APYPerStrategyResponse {\n  success: boolean;\n  count: number;\n  data: APYPerStrategy[];\n}\n\ninterface APYPerStrategy {\n  strategyType: string;\n  apy: number;\n  period: number;\n  crossChain: boolean;\n}\n```\n\n### getOnchainEarnings\n\nGet onchain earnings for a wallet including total, current, and lifetime earnings.\n\n```typescript\nconst earnings = await sdk.getOnchainEarnings(smartWalletAddress);\n\nconsole.log(\"Total earnings:\", earnings.data.totalEarnings);\nconsole.log(\"Current earnings:\", earnings.data.currentEarnings);\nconsole.log(\"Lifetime earnings:\", earnings.data.lifetimeEarnings);\n```\n\nReturns:\n```typescript\ninterface OnchainEarningsResponse {\n  success: boolean;\n  data: {\n    walletAddress: string;\n    totalEarnings: number;\n    currentEarnings: number;\n    lifetimeEarnings: number;\n    unrealizedEarnings?: number;\n    currentEarningsByChain?: Record\u003Cstring, number>;\n    unrealizedEarningsByChain?: Record\u003Cstring, number>;\n    lastCheckTimestamp?: string;\n  };\n}\n```\n\n### registerAgentOnIdentityRegistry (ERC-8004)\n\nRegister your Zyfai deployed agent on the Identity Registry following the ERC-8004 standard. This is used for OpenClaw agent registration. The method fetches a tokenUri containing the agent's metadata stored on IPFS, then registers it on-chain.\n\n**Supported Chains:**\n\n| Chain | Chain ID |\n|-------|----------|\n| Base | 8453 |\n| Arbitrum | 42161 |\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| smartWallet | string | ✅ | The Zyfai deployed smart wallet address to register as an agent |\n| chainId | SupportedChainId | ✅ | Chain ID (only 8453 or 42161) |\n\n**Example:**\n\n```typescript\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\" });\nawait sdk.connectAccount(privateKey, 8453);\n\n\u002F\u002F Get smart wallet address\nconst walletInfo = await sdk.getSmartWalletAddress(userAddress, 8453);\nconst smartWallet = walletInfo.address;\n\n\u002F\u002F Register agent on Identity Registry\nconst result = await sdk.registerAgentOnIdentityRegistry(smartWallet, 8453);\n\nconsole.log(\"Registration successful:\");\nconsole.log(\"  Tx Hash:\", result.txHash);\nconsole.log(\"  Chain ID:\", result.chainId);\nconsole.log(\"  Smart Wallet:\", result.smartWallet);\n```\n\n**Returns:**\n\n```typescript\ninterface RegisterAgentResponse {\n  success: boolean;\n  txHash: string;\n  chainId: number;\n  smartWallet: string;\n}\n```\n\n**How It Works:**\n\n1. Fetches a `tokenUri` from the Zyfai API (agent metadata stored on IPFS)\n2. Encodes the `register(tokenUri)` call for the Identity Registry contract\n3. Sends the transaction from the connected wallet\n4. Waits for on-chain confirmation\n\n## Security\n\n- **Non-custodial** — User's EOA owns the subaccount\n- **Session keys are limited** — Can rebalance, cannot withdraw elsewhere\n- **Deterministic** — Same EOA = same subaccount on every chain\n\n## Troubleshooting\n\n### Subaccount address mismatch across chains\n\nThe subaccount address should be **identical** across all chains for the same EOA. If you see different addresses:\n\n```typescript\n\u002F\u002F Check addresses on both chains\nconst baseWallet = await sdk.getSmartWalletAddress(userAddress, 8453);\nconst arbWallet = await sdk.getSmartWalletAddress(userAddress, 42161);\n\nif (baseWallet.address !== arbWallet.address) {\n  console.error(\"Address mismatch! Contact support.\");\n}\n```\n\n**If addresses don't match:**\n1. Try redeploying on the affected chain\n2. If the issue persists, contact support on Telegram: [@paul_zyfai](https:\u002F\u002Ft.me\u002Fpaul_zyfai)\n\n### \"Deposit address not found\" error\n\nThis means the wallet isn't registered in the backend. Solution:\n1. Call `deploySafe()` first — even if the Safe is already deployed on-chain, this registers it with the backend\n2. Then retry `createSessionKey()`\n\n### \"Invalid signature\" error\n\nThis typically means:\n- The private key doesn't match the EOA you're passing\n- The Safe address on-chain doesn't match what the SDK expects\n\nVerify you're using the correct private key for the EOA.\n\n## Resources\n\n- Get API Key: [sdk.zyf.ai](https:\u002F\u002Fsdk.zyf.ai)\n- Docs: [docs.zyf.ai](https:\u002F\u002Fdocs.zyf.ai)\n- Demo: [github.com\u002Fondefy\u002Fzyfai-sdk-demo](https:\u002F\u002Fgithub.com\u002Fondefy\u002Fzyfai-sdk-demo)\n",{"name":5,"description":7},"main","e7e336ac628c3e3bd771aff1aaa469c93778f94a","skills\u002Fpauldefi\u002Fzyfai-sdk",0,"https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del","2026-08-23 22:39:37",{"source":8,"skillName":5,"commands":45,"prompt":55,"zipAvailable":56},[46,49,52],{"tool":47,"command":48},"npx","npx skills add kbarbel640-del\u002Fskills --skill zyfai",{"tool":50,"command":51},"bunx","bunx skills add kbarbel640-del\u002Fskills --skill zyfai",{"tool":53,"command":54},"pnpm","pnpm dlx skills add kbarbel640-del\u002Fskills --skill zyfai","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fpauldefi\u002Fzyfai-sdk\u002FSKILL.md",true,[58],{"path":59,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":62,"sourceHtmlUrl":63},"_meta.json","REFERENCE","参考文档",639,"https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fpauldefi\u002Fzyfai-sdk\u002F_meta.json",[65,96,124,145,151,171],{"skillNo":66,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":76,"publishedAt":32},"01M6G8J55967D6281ACMKAKTEQ","crowd-prompting","A marketplace where AI agents improve prompts, system instructions, tool descriptions, and other text-based content with domain expertise from real-world operations — and earn tokens for valuable contributions.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzzadrian\u002Fcrowd-prompting\u002FSKILL.md",[71],{"categoryNo":72,"categoryName":73,"taxonomyType":74,"taxonomyTypeDesc":75},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],"crowd prompting","prompting","api","with","tokens","domain","world","prompts","operations","instructions","text","tool","system","improve","productivity","marketplace","https","content","ai agents",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":107,"publishedAt":32},"01M6G8J0PKPAYVET6BWE8W4C26","dilemm-ai","Compete in DilemmAI, the prisoner's dilemma AI arena at dilemm.ai. Use when an OpenClaw agent wants to create an account, design and submit strategy prompts for their bot, enter matchmaking, analyze historical matches and leaderboards, and iterate on bot strategy. Requires headless browser automation (no API available yet).","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzyori\u002Fdilemm-ai\u002FSKILL.md",[102],{"categoryNo":103,"categoryName":104,"taxonomyType":105,"taxonomyTypeDesc":106},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[108,79,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,84,23],"dilemm ai","arena","analyze","browser","openclaw agent","create","automation","browser automation","bot","openclaw","design","strategy","headless","compete","submit","matchmaking",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":133,"publishedAt":32},"01M6G8HWAF3K9SW7NP3Z83CPJ6","arxiv-paper-reviews","Interact with arXiv Crawler API to fetch papers, read reviews, and submit comments. Use when working with arXiv papers, fetching paper lists by date\u002Fcategory\u002Finterest, viewing paper details with comments, or submitting paper reviews via API at http:\u002F\u002F150.158.152.82:8000.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzxrys\u002Fweak-accept\u002FSKILL.md",[130],{"categoryNo":131,"categoryName":132,"taxonomyType":105,"taxonomyTypeDesc":106},"01JBSEEDCAT000000000000021","资料检索与研究",[134,135,136,137,138,139,140,80,141,122,23,142,79,143,144],"arxiv paper reviews","reviews","arxiv","paper","crawler","papers","comments","fetch","read","http","via",{"skillNo":146,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":147,"categories":148,"keywords":150,"publishedAt":32},"01M6G8HQJ7N7WMY6YV7D7SSJ16","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzxrys\u002Farxiv-paper-reviews\u002FSKILL.md",[149],{"categoryNo":131,"categoryName":132,"taxonomyType":105,"taxonomyTypeDesc":106},[137,136,135,134,144,139,140,80,138,122,23,141,142,79,143],{"skillNo":152,"name":153,"nameZh":6,"description":154,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":155,"categories":156,"keywords":157,"publishedAt":32},"01M6G8HM95Y64JNVFC2HN4E2BG","git-summary","Get a quick summary of the current Git repository including status, recent commits, branches, and contributors.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzweack\u002Fgit-summary\u002FSKILL.md",[],[158,159,160,161,162,163,164,165,166,167,168,169,170],"git","summary","git summary","commits","repository","win32","status","linux","contributors","true","quick","get","branches",{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":175,"categories":176,"keywords":181,"publishedAt":32},"01M6G8HGEGF05CNEJCGVYFSC4R","agent-constitution","Interact with AgentConstitution governance contracts on Base Sepolia. Check compliance, read rules, log actions, query governance state.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fztsalexey\u002Fagent-constitution\u002FSKILL.md",[177,178],{"categoryNo":103,"categoryName":104,"taxonomyType":105,"taxonomyTypeDesc":106},{"categoryNo":179,"categoryName":180,"taxonomyType":74,"taxonomyTypeDesc":75},"01JBSEEDCAT000000000000037","律师与法务",[182,183,184,185,80,186,25,37,187,142,188,189,190,191,192,93,193,194,195],"agent constitution","constitution","contracts","tree","query","log","check","Rules","projects","compliance","actions","state","governance","github"]