{"id":"98f84be9-79c0-46d3-b39f-a9310efd3bbd","entityType":"agent","slug":"clawhub-pauldefi-zyfai-sdk","name":"Zyfai Yield Automation","canonicalUrl":"https://www.xpersona.co/agent/clawhub-pauldefi-zyfai-sdk","canonicalPath":"/agent/clawhub-pauldefi-zyfai-sdk","generatedAt":"2026-10-09T16:09:19.553Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":null},"description":"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... Skill: Zyfai Yield Automation Owner: PaulDeFi Summary: 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... Tags: latest:1.0.8 Version history: v1.0.8 | 2026-02-19T17:36:35.942Z | user - Added support for connecting to Zyfai using a wallet provider (e.g., MetaMask), a viem WalletClient, or a raw private key. - U","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.9K downloads reported by the source. Last updated 4/15/2026.","installCommand":"clawhub skill install kn788ynsr62y24k11bfmrtc9ph80cvdh:zyfai-sdk","sourceUrl":"https://clawhub.ai/PaulDeFi/zyfai-sdk","homepage":"https://clawhub.ai/PaulDeFi/zyfai-sdk","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/PaulDeFi/zyfai-sdk","kind":"source"}],"safetyScore":84,"overallRank":62,"popularityScore":65,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"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... "},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":null},"stars":null,"forks":null,"downloads":1869,"packageName":null,"latestVersion":"1.0.8","tractionLabel":"1.9K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-02-28T19:56:01.650Z","emptyReason":null},"lastUpdatedAt":"2026-04-15T00:45:39.800Z","lastCrawledAt":"2026-02-28T19:56:01.650Z","lastIndexedAt":null,"nextCrawlAt":"2026-03-01T19:56:01.650Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.8","createdAt":"2026-02-19T17:36:35.942Z","changelog":"- Added support for connecting to Zyfai using a wallet provider (e.g., MetaMask), a viem WalletClient, or a raw private key. - Updated documentation to recommend secure wallet connection methods, including integration with AWS KMS, GCP, Turnkey, Privy, or other Wallet-as-a-Service solutions for production. - Added explicit security guidance and a comparison table for connection options. - Clarified instructions and examples for connecting via wallet providers, WalletClients, and private keys. - No functional changes to SDK logic; documentation improvements only. - Added .DS_Store file (no effect on functionality).","fileCount":2,"zipByteSize":8152},{"version":"1.0.7","createdAt":"2026-02-18T17:19:36.338Z","changelog":"zyfai-sdk 1.0.7 Changelog - Added instructions for agents to create an API key programmatically via a POST endpoint, removing the need for manual key generation. - Updated the prerequisites section to include details on automated API key creation and emphasize secure storage of generated keys. - Example usage and SDK initialization now mention a referralSource parameter. - No code/API changes; documentation improvements only.","fileCount":2,"zipByteSize":6990},{"version":"1.0.6","createdAt":"2026-02-12T08:57:55.778Z","changelog":"- Added explicit instructions to always verify session key activation with getUserDetails().user.hasActiveSessionKey after calling createSessionKey, including a retry and failure-handling process. - Updated code examples and main setup flow to include session key activation checks and error handling. - Expanded API reference with updateUserProfile for updating strategy, protocols, splitting, and cross-chain settings. - Improved clarity on the importance of session key activation for automated yield optimization.","fileCount":null,"zipByteSize":null},{"version":"1.0.5","createdAt":"2026-02-06T11:45:35.126Z","changelog":"zyfai-sdk v1.0.5 - Added registerAgentOnIdentityRegistry(smartWallet, chainId) to the API reference, enabling agent registration on ERC-8004 Identity Registry. - No other functional or documentation changes detected.","fileCount":null,"zipByteSize":null},{"version":"1.0.4","createdAt":"2026-02-04T08:52:22.586Z","changelog":"zyfai-sdk 1.0.4 - Added the `getAPYPerStrategy` method to the API, allowing users to retrieve APY data for conservative and aggressive strategies. - No other changes detected; documentation and flow remain consistent with previous versions.","fileCount":null,"zipByteSize":null},{"version":"1.0.3","createdAt":"2026-02-02T12:40:47.383Z","changelog":"No user-facing or code changes detected in this version. - No modifications identified in SKILL.md or other files. - Version remains consistent with previous release.","fileCount":null,"zipByteSize":null},{"version":"1.0.2","createdAt":"2026-02-02T10:52:49.856Z","changelog":"- Update clarifies that all SDK methods must use the user's EOA address, not the subaccount/Safe address, and always with an EOA private key available to the agent. - Adds troubleshooting section with solutions for common errors (address mismatch, \"deposit address not found\", and \"invalid signature\"). - Expands usage examples for deposit and withdrawal, showing recommended patterns for handling EOA addresses and private keys. - Updates terminology to consistently use \"Zyfai\" and clarifies agent responsibilities in the workflow. - No file/code changes; documentation improvements only.","fileCount":null,"zipByteSize":null},{"version":"1.0.1","createdAt":"2026-02-02T09:09:07.448Z","changelog":"- Updated description to emphasize passive DeFi yield for any Ethereum wallet. - Rewrote documentation for clearer onboarding and step-by-step usage. - Simplified terminology: \"subaccount\" now refers to the non-custodial Safe wallet. - Added detailed API reference table for easier integration. - Streamlined examples and security notes for better understanding. - No code or file changes; documentation and usage instructions only.","fileCount":null,"zipByteSize":null}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install kn788ynsr62y24k11bfmrtc9ph80cvdh:zyfai-sdk","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-09T16:09:19.552Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-pauldefi-zyfai-sdk/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":null},"readme":"Skill: Zyfai Yield Automation\n\nOwner: PaulDeFi\n\nSummary: 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...\n\nTags: latest:1.0.8\n\nVersion history:\n\nv1.0.8 | 2026-02-19T17:36:35.942Z | user\n\n- Added support for connecting to Zyfai using a wallet provider (e.g., MetaMask), a viem WalletClient, or a raw private key.\n- Updated documentation to recommend secure wallet connection methods, including integration with AWS KMS, GCP, Turnkey, Privy, or other Wallet-as-a-Service solutions for production.\n- Added explicit security guidance and a comparison table for connection options.\n- Clarified instructions and examples for connecting via wallet providers, WalletClients, and private keys.\n- No functional changes to SDK logic; documentation improvements only.\n- Added .DS_Store file (no effect on functionality).\n\nv1.0.7 | 2026-02-18T17:19:36.338Z | user\n\nzyfai-sdk 1.0.7 Changelog\n\n- Added instructions for agents to create an API key programmatically via a POST endpoint, removing the need for manual key generation.\n- Updated the prerequisites section to include details on automated API key creation and emphasize secure storage of generated keys.\n- Example usage and SDK initialization now mention a referralSource parameter.\n- No code/API changes; documentation improvements only.\n\nv1.0.6 | 2026-02-12T08:57:55.778Z | user\n\n- Added explicit instructions to always verify session key activation with getUserDetails().user.hasActiveSessionKey after calling createSessionKey, including a retry and failure-handling process.\n- Updated code examples and main setup flow to include session key activation checks and error handling.\n- Expanded API reference with updateUserProfile for updating strategy, protocols, splitting, and cross-chain settings.\n- Improved clarity on the importance of session key activation for automated yield optimization.\n\nv1.0.5 | 2026-02-06T11:45:35.126Z | user\n\nzyfai-sdk v1.0.5\n\n- Added registerAgentOnIdentityRegistry(smartWallet, chainId) to the API reference, enabling agent registration on ERC-8004 Identity Registry.\n- No other functional or documentation changes detected.\n\nv1.0.4 | 2026-02-04T08:52:22.586Z | user\n\nzyfai-sdk 1.0.4\n\n- Added the `getAPYPerStrategy` method to the API, allowing users to retrieve APY data for conservative and aggressive strategies.\n- No other changes detected; documentation and flow remain consistent with previous versions.\n\nv1.0.3 | 2026-02-02T12:40:47.383Z | user\n\nNo user-facing or code changes detected in this version.\n\n- No modifications identified in SKILL.md or other files.\n- Version remains consistent with previous release.\n\nv1.0.2 | 2026-02-02T10:52:49.856Z | user\n\n- Update clarifies that all SDK methods must use the user's EOA address, not the subaccount/Safe address, and always with an EOA private key available to the agent.\n- Adds troubleshooting section with solutions for common errors (address mismatch, \"deposit address not found\", and \"invalid signature\").\n- Expands usage examples for deposit and withdrawal, showing recommended patterns for handling EOA addresses and private keys.\n- Updates terminology to consistently use \"Zyfai\" and clarifies agent responsibilities in the workflow.\n- No file/code changes; documentation improvements only.\n\nv1.0.1 | 2026-02-02T09:09:07.448Z | user\n\n- Updated description to emphasize passive DeFi yield for any Ethereum wallet.\n- Rewrote documentation for clearer onboarding and step-by-step usage.\n- Simplified terminology: \"subaccount\" now refers to the non-custodial Safe wallet.\n- Added detailed API reference table for easier integration.\n- Streamlined examples and security notes for better understanding.\n- No code or file changes; documentation and usage instructions only.\n\nv1.0.0 | 2026-02-02T08:45:55.356Z | user\n\nzyfai-sdk 1.0.0 initial release:\n\n- Deploy non-custodial DeFi Safe smart wallets on Arbitrum, Base, and Plasma.\n- Enable automated yield optimization with strategy selection (\"conservative\" or \"aggressive\").\n- Supports depositing and withdrawing funds, including partial withdrawals.\n- Automated rebalancing via session keys, restricted to the Zyf AI ecosystem.\n- Deterministic wallet addresses for the same EOA across supported chains.\n- Comprehensive documentation and usage examples provided.\n\nArchive index:\n\nArchive v1.0.8: 2 files, 8152 bytes\n\nFiles: SKILL.md (25683b), _meta.json (128b)\n\nFile v1.0.8:SKILL.md\n\n---\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/withdraw 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** — Get one programmatically (see below) or manually at [sdk.zyf.ai](https://sdk.zyf.ai)\n- **Wallet Connection** — Either a wallet provider (browser) or secure key management (server)\n- **Node.js 18+**\n\n```bash\nnpm install @zyfai/sdk viem\n```\n\n### Programmatic API Key Creation (Agent-Native)\n\nAgents can create their own API key without human intervention. You need the wallet address (public key) of the agent.\n\n```bash\nPOST https://sdk.zyf.ai/api/sdk-api-keys/create\nContent-Type: application/json\n\n{\n  \"clientName\": \"my-agent\",\n  \"walletAddress\": \"0x...\",\n  \"email\": \"agent@example.com\"\n}\n```\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"SDK API key created successfully. Store the apiKey securely - it cannot be retrieved later!\",\n  \"data\": {\n    \"id\": \"936...\",\n    \"apiKey\": \"zyfai_361ad41d083c2fe.....\",\n    \"keyPrefix\": \"zyfai_361ad4\",\n    \"clientName\": \"my-agent\",\n    \"ownerWalletAddress\": \"0x...\"\n  }\n}\n```\n\n> **Important:** Store the `apiKey` securely — it cannot be retrieved later. The key is linked to the provided wallet address.\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/Safe address. The SDK derives the subaccount address automatically from the EOA.\n\n## Wallet Connection Options\n\nThe SDK supports multiple ways to connect a wallet. Choose based on your security requirements and deployment context.\n\n### Option 1: Wallet Provider (Recommended for Browser/dApps)\n\nUse an injected wallet provider like MetaMask. The private key never leaves the user's wallet.\n\n```typescript\nimport { ZyfaiSDK } from \"@zyfai/sdk\";\n\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\", referralSource: \"openclaw-skill\" });\n\n// Connect using injected wallet provider (MetaMask, WalletConnect, etc.)\nawait sdk.connectAccount(window.ethereum, 8453);\n```\n\n**Security:** The private key stays in the user's wallet. The SDK only requests signatures when needed.\n\n### Option 2: Viem WalletClient (Recommended for Server Agents)\n\nUse a pre-configured viem WalletClient. This is the recommended approach for server-side agents as it allows integration with secure key management solutions.\n\n```typescript\nimport { ZyfaiSDK } from \"@zyfai/sdk\";\nimport { createWalletClient, http } from \"viem\";\nimport { base } from \"viem/chains\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\n// Create wallet client with your preferred key management\n// Option A: From environment variable (simple but requires secure env management)\nconst account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);\n\n// Option B: From KMS (AWS, GCP, etc.) - recommended for production\n// const account = await getAccountFromKMS();\n\n// Option C: From Wallet-as-a-Service (Turnkey, Privy, etc.)\n// const account = await turnkeyClient.getAccount();\n\nconst walletClient = createWalletClient({\n  account,\n  chain: base,\n  transport: http(),\n});\n\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\", referralSource: \"openclaw-skill\" });\n\n// Connect using the WalletClient\nawait sdk.connectAccount(walletClient, 8453);\n```\n\n**Security:** The WalletClient abstraction allows you to integrate with secure key management solutions like:\n- **AWS KMS** / **GCP Cloud KMS** — Hardware-backed key storage\n- **Turnkey** / **Privy** / **Dynamic** — Wallet-as-a-Service providers\n- **Hardware wallets** — Via WalletConnect or similar\n\n### Option 3: Private Key String (Development Only)\n\nDirect private key usage.\n\n```typescript\nimport { ZyfaiSDK } from \"@zyfai/sdk\";\n\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\", referralSource: \"openclaw-skill\" });\n\n// WARNING: Only use for development. Never hardcode private keys in production.\nawait sdk.connectAccount(process.env.PRIVATE_KEY, 8453);\n```\n\n**Security Warning:** Raw private keys in environment variables are a security risk. For production autonomous agents, use Option 2 with a proper key management solution.\n\n### Security Comparison\n\n| Method | Security Level | Use Case |\n|--------|---------------|----------|\n| Wallet Provider | High | Browser dApps, user-facing apps |\n| WalletClient + KMS | High | Production server agents |\n| WalletClient + WaaS | High | Production server agents |\n| Private Key String | Low | Development/testing only |\n\n## Step-by-Step\n\n### 1. Connect to Zyfai\n\n```typescript\nimport { ZyfaiSDK } from \"@zyfai/sdk\";\nimport { createWalletClient, http } from \"viem\";\nimport { base } from \"viem/chains\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\", referralSource: \"openclaw-skill\" });\n\n// For browser: use wallet provider\nawait sdk.connectAccount(window.ethereum, 8453);\n\n// For server: use WalletClient (see Wallet Connection Options above)\nconst walletClient = createWalletClient({\n  account: privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`),\n  chain: base,\n  transport: http(),\n});\nawait sdk.connectAccount(walletClient, 8453);\n```\n\n### 2. Deploy Subaccount\n\n```typescript\nconst userAddress = \"0x...\"; // User's EOA (NOT the subaccount address!)\nconst chainId = 8453; // Base\n\n// Check if subaccount exists\nconst wallet = await sdk.getSmartWalletAddress(userAddress, chainId);\nconsole.log(`Subaccount: ${wallet.address}`);\nconsole.log(`Deployed: ${wallet.isDeployed}`);\n\n// 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// Always verify the session key was activated\nconst user = await sdk.getUserDetails();\nif (!user.user.hasActiveSessionKey) {\n  // Session key not active — retry the process\n  console.log(\"Session key not active, retrying...\");\n  await sdk.createSessionKey(userAddress, chainId);\n  \n  // Verify again\n  const userRetry = await sdk.getUserDetails();\n  if (!userRetry.user.hasActiveSessionKey) {\n    throw new Error(\"Session key activation failed after retry. Contact support.\");\n  }\n}\nconsole.log(\"Session key active:\", user.user.hasActiveSessionKey);\n```\n\nThis allows Zyfai to rebalance funds automatically. Session keys **cannot** withdraw to arbitrary addresses — only optimize within the protocol.\n\n> **Important:** Always verify the session key is active by checking `getUserDetails().user.hasActiveSessionKey` after calling `createSessionKey`. If it returns `false`, retry the process. A session key must be active for automated yield optimization to work.\n\n### 4. Deposit Funds\n\n```typescript\n// 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// Withdraw everything\nawait sdk.withdrawFunds(userAddress, chainId);\n\n// 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/sdk\";\nimport { createWalletClient, http } from \"viem\";\nimport { base } from \"viem/chains\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\nasync function startEarningYield(userAddress: string) {\n  const sdk = new ZyfaiSDK({ apiKey: process.env.ZYFAI_API_KEY! });\n  const chainId = 8453; // Base\n  \n  // Connect using WalletClient (recommended for server agents)\n  const walletClient = createWalletClient({\n    account: privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`),\n    chain: base,\n    transport: http(),\n  });\n  await sdk.connectAccount(walletClient, chainId);\n  \n  // 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  // Enable automated optimization\n  await sdk.createSessionKey(userAddress, chainId);\n  \n  // Verify session key is active\n  const user = await sdk.getUserDetails();\n  if (!user.user.hasActiveSessionKey) {\n    console.log(\"Session key not active, retrying...\");\n    await sdk.createSessionKey(userAddress, chainId);\n    const userRetry = await sdk.getUserDetails();\n    if (!userRetry.user.hasActiveSessionKey) {\n      throw new Error(\"Session key activation failed. Contact support.\");\n    }\n  }\n  \n  // 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, amount?: string) {\n  const sdk = new ZyfaiSDK({ apiKey: process.env.ZYFAI_API_KEY! });\n  const chainId = 8453; // Base\n  \n  // Connect using WalletClient\n  const walletClient = createWalletClient({\n    account: privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`),\n    chain: base,\n    transport: http(),\n  });\n  await sdk.connectAccount(walletClient, chainId);\n  \n  // Withdraw funds (pass EOA as userAddress)\n  if (amount) {\n    // Partial withdrawal\n    await sdk.withdrawFunds(userAddress, chainId, amount);\n    console.log(`Withdrawn ${amount} (6 decimals) to EOA`);\n  } else {\n    // 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` | `(walletClientOrProvider, 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/aggressive strategies |\n| `getUserDetails` | `()` | Get authenticated user details |\n| `getOnchainEarnings` | `(walletAddress)` | Get earnings data |\n| `updateUserProfile` | `(params)` | Update strategy, protocols, splitting, cross-chain settings |\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/Safe 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 | Yes | User's EOA address |\n| chainId | SupportedChainId | No | Optional: Filter by specific chain ID |\n\n**Example:**\n\n```typescript\n// Get all positions across all chains\nconst positions = await sdk.getPositions(\"0xUser...\");\n\n// 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); // 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/A\"}%`);\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(walletClient, 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<string, string[]>;\n  };\n}\n```\n\n### updateUserProfile\n\nUpdate the authenticated user's profile settings including strategy, protocols, splitting, and cross-chain options. Requires SIWE authentication.\n\n```typescript\nsdk.updateUserProfile(params: UpdateUserProfileRequest): Promise<UpdateUserProfileResponse>\n```\n\n**Parameters:**\n\n```typescript\ninterface UpdateUserProfileRequest {\n  /** Investment strategy: \"conservative\" for safer yields, \"aggressive\" for higher risk/reward */\n  strategy?: \"conservative\" | \"aggressive\";\n\n  /** Array of protocol IDs to use for yield optimization */\n  protocols?: string[];\n\n  /** Enable omni-account feature for cross-chain operations */\n  omniAccount?: boolean;\n\n  /** Enable automatic compounding of earned yields (default: true) */\n  autocompounding?: boolean;\n\n  /** Custom name for your agent */\n  agentName?: string;\n\n  /** Enable cross-chain strategy execution */\n  crosschainStrategy?: boolean;\n\n  /** Enable position splitting across multiple protocols */\n  splitting?: boolean;\n\n  /** Minimum number of splits when position splitting is enabled (1-4) */\n  minSplits?: number;\n}\n```\n\n**Returns:**\n\n```typescript\ninterface UpdateUserProfileResponse {\n  success: boolean;\n  userId: string;\n  smartWallet?: string;\n  chains?: number[];\n  strategy?: string;\n  protocols?: string[];\n  omniAccount?: boolean;\n  autocompounding?: boolean;\n  agentName?: string;\n  crosschainStrategy?: boolean;\n  executorProxy?: boolean;\n  splitting?: boolean;\n  minSplits?: number;\n}\n```\n\n**Examples:**\n\n```typescript\n// Update strategy from conservative to aggressive\nawait sdk.updateUserProfile({\n  strategy: \"aggressive\",\n});\n\n// Configure specific protocols\nconst protocolsResponse = await sdk.getAvailableProtocols(8453);\nconst selectedProtocols = protocolsResponse.protocols\n  .filter(p => [\"Aave\", \"Compound\", \"Moonwell\"].includes(p.name))\n  .map(p => p.id);\n\nawait sdk.updateUserProfile({\n  protocols: selectedProtocols,\n});\n\n// Enable position splitting (distribute across multiple protocols)\nawait sdk.updateUserProfile({\n  splitting: true,\n  minSplits: 3, // Split across at least 3 protocols\n});\n\n// Verify changes\nconst userDetails = await sdk.getUserDetails();\nconsole.log(\"Strategy:\", userDetails.user.strategy);\nconsole.log(\"Splitting:\", userDetails.user.splitting);\n```\n\n> **Cross-chain strategies:** Only enable cross-chain when the user **explicitly requests** it. For cross-chain to work, **both** `crosschainStrategy` and `omniAccount` must be set to `true`. Never enable cross-chain settings by default.\n\n```typescript\n// Enable cross-chain ONLY when explicitly requested by the user\nawait sdk.updateUserProfile({\n  crosschainStrategy: true,\n  omniAccount: true,\n});\n\n// Now funds can be rebalanced across configured chains\nconst user = await sdk.getUserDetails();\nconsole.log(\"Operating on chains:\", user.user.chains);\n```\n\n**Notes:**\n- **Strategy:** Can be changed anytime. Subsequent rebalancing uses the new active strategy.\n- **Protocols:** Use `getAvailableProtocols(chainId)` to get valid protocol IDs before updating.\n- **Smart Splitting (minSplits = 1):** Default mode. To maximize returns, funds are automatically distributed across multiple DeFi pools — but only when beneficial. The system intelligently decides when splitting is advantageous based on current market conditions and opportunities. Funds may not split if no opportunity exists.\n- **Forced Splitting (minSplits > 1):** When `minSplits` is set to 2, 3, or 4, funds are always distributed across at least that many pools for improved risk diversification (up to 4 DeFi pools). This guarantees your funds will be split regardless of market conditions.\n- **Cross-chain:** Requires **both** `crosschainStrategy: true` AND `omniAccount: true`. Only activate when the user explicitly asks for cross-chain yield optimization. Chains are configured during initial setup and cannot be changed via this method.\n- **Auto-compounding:** Enabled by default. When `true`, yields are reinvested automatically.\n- Smart wallet address, chains, and `executorProxy` cannot be updated via this method.\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 | No | If `true`, returns APY for cross-chain strategies; if `false`, single-chain |\n| days | number | No | Period over which APY is calculated. One of `7`, `15`, `30`, `60` |\n| strategyType | string | No | Strategy risk profile. One of `'conservative'` or `'aggressive'` |\n\n**Example:**\n\n```typescript\n// 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// 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// 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<string, number>;\n    unrealizedEarningsByChain?: Record<string, 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 | Yes | The Zyfai deployed smart wallet address to register as an agent |\n| chainId | SupportedChainId | Yes | Chain ID (only 8453 or 42161) |\n\n**Example:**\n\n```typescript\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\" });\nawait sdk.connectAccount(walletClient, 8453);\n\n// Get smart wallet address\nconst walletInfo = await sdk.getSmartWalletAddress(userAddress, 8453);\nconst smartWallet = walletInfo.address;\n\n// 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- **Flexible key management** — Use wallet providers, WalletClients, or KMS integrations\n\n### Key Management Best Practices\n\nFor **production autonomous agents**, we recommend:\n\n1. **Use a WalletClient** with a secure key source (not raw private keys)\n2. **Integrate with KMS** (AWS KMS, GCP Cloud KMS) for hardware-backed key storage\n3. **Consider Wallet-as-a-Service** providers like Turnkey, Privy, or Dynamic\n4. **Never hardcode** private keys in source code\n5. **Rotate keys** periodically and implement key revocation procedures\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// 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://t.me/paul_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 wallet/signer 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 wallet for the EOA.\n\n## Resources\n\n- **Get API Key:** [sdk.zyf.ai](https://sdk.zyf.ai) or programmatically via `POST /api/sdk-api-keys/create`\n- **Docs:** [docs.zyf.ai](https://docs.zyf.ai)\n- **Demo:** [github.com/ondefy/zyfai-sdk-demo](https://github.com/ondefy/zyfai-sdk-demo)\n- **MCP Server:** [mcp.zyf.ai](https://mcp.zyf.ai/mcp) — Use with Claude or other MCP-compatible agents\n- **Agent Registration:** [zyf.ai/.well-known/agent-registration.json](https://www.zyf.ai/.well-known/agent-registration.json)\n\nFile v1.0.8:_meta.json\n\n{\n  \"ownerId\": \"kn788ynsr62y24k11bfmrtc9ph80cvdh\",\n  \"slug\": \"zyfai-sdk\",\n  \"version\": \"1.0.8\",\n  \"publishedAt\": 1771522595942\n}\n\nArchive v1.0.7: 2 files, 6990 bytes\n\nFiles: SKILL.md (21347b), _meta.json (128b)\n\nFile v1.0.7:SKILL.md\n\n---\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/withdraw 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** — Get one programmatically (see below) or manually at [sdk.zyf.ai](https://sdk.zyf.ai)\n- **Private Key** of the user's EOA (the agent must provide this)\n- **Node.js 18+**\n\n```bash\nnpm install @zyfai/sdk viem\n```\n\n### Programmatic API Key Creation (Agent-Native)\n\nAgents can create their own API key without human intervention:\n\n```bash\nPOST https://sdk.zyf.ai/api/sdk-api-keys/create\nContent-Type: application/json\n\n{\n  \"clientName\": \"my-agent\",\n  \"walletAddress\": \"0x...\",\n  \"email\": \"agent@example.com\"\n}\n```\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"SDK API key created successfully. Store the apiKey securely - it cannot be retrieved later!\",\n  \"data\": {\n    \"id\": \"936...\",\n    \"apiKey\": \"zyfai_361ad41d083c2fe.....\",\n    \"keyPrefix\": \"zyfai_361ad4\",\n    \"clientName\": \"my-agent\",\n    \"ownerWalletAddress\": \"0x...\"\n  }\n}\n```\n\n> **Important:** Store the `apiKey` securely — it cannot be retrieved later. The key is linked to the provided wallet address.\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/Safe 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/sdk\";\n\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\", referralSource: \"openclaw-skill\" });\n\n// Use the private key provided by the agent\nawait sdk.connectAccount(privateKey, 8453); // 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...\"; // User's EOA (NOT the subaccount address!)\nconst chainId = 8453; // Base\n\n// Check if subaccount exists\nconst wallet = await sdk.getSmartWalletAddress(userAddress, chainId);\nconsole.log(`Subaccount: ${wallet.address}`);\nconsole.log(`Deployed: ${wallet.isDeployed}`);\n\n// 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// Always verify the session key was activated\nconst user = await sdk.getUserDetails();\nif (!user.user.hasActiveSessionKey) {\n  // Session key not active — retry the process\n  console.log(\"Session key not active, retrying...\");\n  await sdk.createSessionKey(userAddress, chainId);\n  \n  // Verify again\n  const userRetry = await sdk.getUserDetails();\n  if (!userRetry.user.hasActiveSessionKey) {\n    throw new Error(\"Session key activation failed after retry. Contact support.\");\n  }\n}\nconsole.log(\"Session key active:\", user.user.hasActiveSessionKey);\n```\n\nThis allows Zyfai to rebalance funds automatically. Session keys **cannot** withdraw to arbitrary addresses — only optimize within the protocol.\n\n> **Important:** Always verify the session key is active by checking `getUserDetails().user.hasActiveSessionKey` after calling `createSessionKey`. If it returns `false`, retry the process. A session key must be active for automated yield optimization to work.\n\n### 4. Deposit Funds\n\n```typescript\n// 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// Withdraw everything\nawait sdk.withdrawFunds(userAddress, chainId);\n\n// 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/sdk\";\n\nasync function startEarningYield(userAddress: string, privateKey: string) {\n  const sdk = new ZyfaiSDK({ apiKey: process.env.ZYFAI_API_KEY! });\n  const chainId = 8453; // Base\n  \n  // Connect using the agent's private key\n  await sdk.connectAccount(privateKey, chainId);\n  \n  // 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  // Enable automated optimization\n  await sdk.createSessionKey(userAddress, chainId);\n  \n  // Verify session key is active\n  const user = await sdk.getUserDetails();\n  if (!user.user.hasActiveSessionKey) {\n    console.log(\"Session key not active, retrying...\");\n    await sdk.createSessionKey(userAddress, chainId);\n    const userRetry = await sdk.getUserDetails();\n    if (!userRetry.user.hasActiveSessionKey) {\n      throw new Error(\"Session key activation failed. Contact support.\");\n    }\n  }\n  \n  // 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; // Base\n  \n  // Connect using the agent's private key\n  await sdk.connectAccount(privateKey, chainId);\n  \n  // Withdraw funds (pass EOA as userAddress)\n  if (amount) {\n    // Partial withdrawal\n    await sdk.withdrawFunds(userAddress, chainId, amount);\n    console.log(`Withdrawn ${amount} (6 decimals) to EOA`);\n  } else {\n    // 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/aggressive strategies |\n| `getUserDetails` | `()` | Get authenticated user details |\n| `getOnchainEarnings` | `(walletAddress)` | Get earnings data |\n| `updateUserProfile` | `(params)` | Update strategy, protocols, splitting, cross-chain settings |\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/Safe 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// Get all positions across all chains\nconst positions = await sdk.getPositions(\"0xUser...\");\n\n// 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); // 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/A\"}%`);\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<string, string[]>;\n  };\n}\n```\n\n### updateUserProfile\n\nUpdate the authenticated user's profile settings including strategy, protocols, splitting, and cross-chain options. Requires SIWE authentication.\n\n```typescript\nsdk.updateUserProfile(params: UpdateUserProfileRequest): Promise<UpdateUserProfileResponse>\n```\n\n**Parameters:**\n\n```typescript\ninterface UpdateUserProfileRequest {\n  /** Investment strategy: \"conservative\" for safer yields, \"aggressive\" for higher risk/reward */\n  strategy?: \"conservative\" | \"aggressive\";\n\n  /** Array of protocol IDs to use for yield optimization */\n  protocols?: string[];\n\n  /** Enable omni-account feature for cross-chain operations */\n  omniAccount?: boolean;\n\n  /** Enable automatic compounding of earned yields (default: true) */\n  autocompounding?: boolean;\n\n  /** Custom name for your agent */\n  agentName?: string;\n\n  /** Enable cross-chain strategy execution */\n  crosschainStrategy?: boolean;\n\n  /** Enable position splitting across multiple protocols */\n  splitting?: boolean;\n\n  /** Minimum number of splits when position splitting is enabled (1-4) */\n  minSplits?: number;\n}\n```\n\n**Returns:**\n\n```typescript\ninterface UpdateUserProfileResponse {\n  success: boolean;\n  userId: string;\n  smartWallet?: string;\n  chains?: number[];\n  strategy?: string;\n  protocols?: string[];\n  omniAccount?: boolean;\n  autocompounding?: boolean;\n  agentName?: string;\n  crosschainStrategy?: boolean;\n  executorProxy?: boolean;\n  splitting?: boolean;\n  minSplits?: number;\n}\n```\n\n**Examples:**\n\n```typescript\n// Update strategy from conservative to aggressive\nawait sdk.updateUserProfile({\n  strategy: \"aggressive\",\n});\n\n// Configure specific protocols\nconst protocolsResponse = await sdk.getAvailableProtocols(8453);\nconst selectedProtocols = protocolsResponse.protocols\n  .filter(p => [\"Aave\", \"Compound\", \"Moonwell\"].includes(p.name))\n  .map(p => p.id);\n\nawait sdk.updateUserProfile({\n  protocols: selectedProtocols,\n});\n\n// Enable position splitting (distribute across multiple protocols)\nawait sdk.updateUserProfile({\n  splitting: true,\n  minSplits: 3, // Split across at least 3 protocols\n});\n\n// Verify changes\nconst userDetails = await sdk.getUserDetails();\nconsole.log(\"Strategy:\", userDetails.user.strategy);\nconsole.log(\"Splitting:\", userDetails.user.splitting);\n```\n\n> **Cross-chain strategies:** Only enable cross-chain when the user **explicitly requests** it. For cross-chain to work, **both** `crosschainStrategy` and `omniAccount` must be set to `true`. Never enable cross-chain settings by default.\n\n```typescript\n// Enable cross-chain ONLY when explicitly requested by the user\nawait sdk.updateUserProfile({\n  crosschainStrategy: true,\n  omniAccount: true,\n});\n\n// Now funds can be rebalanced across configured chains\nconst user = await sdk.getUserDetails();\nconsole.log(\"Operating on chains:\", user.user.chains);\n```\n\n**Notes:**\n- **Strategy:** Can be changed anytime. Subsequent rebalancing uses the new active strategy.\n- **Protocols:** Use `getAvailableProtocols(chainId)` to get valid protocol IDs before updating.\n- **Smart Splitting (minSplits = 1):** Default mode. To maximize returns, funds are automatically distributed across multiple DeFi pools — but only when beneficial. The system intelligently decides when splitting is advantageous based on current market conditions and opportunities. Funds may not split if no opportunity exists.\n- **Forced Splitting (minSplits > 1):** When `minSplits` is set to 2, 3, or 4, funds are always distributed across at least that many pools for improved risk diversification (up to 4 DeFi pools). This guarantees your funds will be split regardless of market conditions.\n- **Cross-chain:** Requires **both** `crosschainStrategy: true` AND `omniAccount: true`. Only activate when the user explicitly asks for cross-chain yield optimization. Chains are configured during initial setup and cannot be changed via this method.\n- **Auto-compounding:** Enabled by default. When `true`, yields are reinvested automatically.\n- Smart wallet address, chains, and `executorProxy` cannot be updated via this method.\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// 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// 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// 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<string, number>;\n    unrealizedEarningsByChain?: Record<string, 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// Get smart wallet address\nconst walletInfo = await sdk.getSmartWalletAddress(userAddress, 8453);\nconst smartWallet = walletInfo.address;\n\n// 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// 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://t.me/paul_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://sdk.zyf.ai) or programmatically via `POST /api/sdk-api-keys/create`\n- **Docs:** [docs.zyf.ai](https://docs.zyf.ai)\n- **Demo:** [github.com/ondefy/zyfai-sdk-demo](https://github.com/ondefy/zyfai-sdk-demo)\n- **MCP Server:** [mcp.zyf.ai](https://mcp.zyf.ai/mcp) — Use with Claude or other MCP-compatible agents\n- **Agent Registration:** [zyf.ai/.well-known/agent-registration.json](https://www.zyf.ai/.well-known/agent-registration.json)\n\nFile v1.0.7:_meta.json\n\n{\n  \"ownerId\": \"kn788ynsr62y24k11bfmrtc9ph80cvdh\",\n  \"slug\": \"zyfai-sdk\",\n  \"version\": \"1.0.7\",\n  \"publishedAt\": 1771435176338\n}","readmeExcerpt":"Skill: Zyfai Yield Automation Owner: PaulDeFi Summary: 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... Tags: latest:1.0.8 Version history: v1.0.8 | 2026-02-19T17:36:35.942Z | user - Added support for connecting to Zyfai using a wallet provider (e.g., MetaMask), a viem WalletClient, or a raw private key. - U","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"┌─────────────────┐      ┌──────────────────────┐\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└─────────────────┘      └──────────────────────┘"},{"language":"text","snippet":"1. 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)"},{"language":"bash","snippet":"npm install @zyfai/sdk viem"},{"language":"bash","snippet":"POST https://sdk.zyf.ai/api/sdk-api-keys/create\nContent-Type: application/json\n\n{\n  \"clientName\": \"my-agent\",\n  \"walletAddress\": \"0x...\",\n  \"email\": \"agent@example.com\"\n}"},{"language":"json","snippet":"{\n  \"success\": true,\n  \"message\": \"SDK API key created successfully. Store the apiKey securely - it cannot be retrieved later!\",\n  \"data\": {\n    \"id\": \"936...\",\n    \"apiKey\": \"zyfai_361ad41d083c2fe.....\",\n    \"keyPrefix\": \"zyfai_361ad4\",\n    \"clientName\": \"my-agent\",\n    \"ownerWalletAddress\": \"0x...\"\n  }\n}"},{"language":"typescript","snippet":"import { ZyfaiSDK } from \"@zyfai/sdk\";\n\nconst sdk = new ZyfaiSDK({ apiKey: \"your-api-key\", referralSource: \"openclaw-skill\" });\n\n// Connect using injected wallet provider (MetaMask, WalletConnect, etc.)\nawait sdk.connectAccount(window.ethereum, 8453);"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\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/withdraw 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** — Get one programmatically (see below) or manually at [sdk.zyf.ai](https://sdk.zyf.ai)\n- **Wallet Connection** — Either a wallet provider (browser) or secure key management (server)\n- **Node.js 18+**\n\n```bash\nnpm install @zyfai/sdk viem\n```\n\n### Programmatic API Key Creation (Agent-Native)\n\nAgents can create their own API key without human intervention. You need the wallet address (public key) of the agent.\n\n```bash\nPOST https://sdk.zyf.ai/api/sdk-api-keys/create\nContent-Type: application/json\n\n{\n  \"clientName\": \"my-agent\",\n  \"walletAddress\": \"0x...\",\n  \"email\": \"agent@example.com\"\n}\n```\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"SDK API key created successfully. Store the apiKey securely - it cannot be retrieved later!\",\n  \"data\": {\n    \"id\": \"936...\",\n    \"apiKey\": \"zyfai_361ad41d083c2fe.....\",\n    \"keyPrefix\": \"zyfai_361ad4\",\n    \"clientName\": \"my-agent\",\n    \"ownerWalletAddress\": \"0x...\"\n  }\n}\n```\n\n> **Important:** Store the `apiKey` securely — it cannot be retrieved later. The key is linked to the provided wallet address.\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/Safe address. The SDK derives the suba"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn788ynsr62y24k11bfmrtc9ph80cvdh\",\n  \"slug\": \"zyfai-sdk\",\n  \"version\": \"1.0.8\",\n  \"publishedAt\": 1771522595942\n}"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"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... Skill: Zyfai Yield Automation Owner: PaulDeFi Summary: 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... Tags: latest:1.0.8 Version history: v1.0.8 | 2026-02-19T17:36:35.942Z | user - Added support for connecting to Zyfai using a wallet provider (e.g., MetaMask), a viem WalletClient, or a raw private key. - U","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1092,"uniquenessScore":50,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-04-15T00:45:39.800Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-09T16:09:19.553Z","emptyReason":null},"items":[{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-10T18:48:31.762Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}