@zyfai/sdk 0.2.26 → 0.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -31,7 +31,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  DEFAULT_TOKEN_ADDRESSES: () => DEFAULT_TOKEN_ADDRESSES,
34
+ VAULT_ADDRESS: () => VAULT_ADDRESS,
34
35
  ZyfaiSDK: () => ZyfaiSDK,
36
+ createBankrProvider: () => createBankrProvider,
35
37
  getChainConfig: () => getChainConfig,
36
38
  getDefaultTokenAddress: () => getDefaultTokenAddress,
37
39
  getSupportedChainIds: () => getSupportedChainIds,
@@ -65,6 +67,7 @@ var ENDPOINTS = {
65
67
  PROTOCOLS: (chainId) => chainId ? `/protocols?chainId=${chainId}` : "/protocols",
66
68
  // Data (v1)
67
69
  DATA_POSITION: (walletAddress) => `/data/position?walletAddress=${walletAddress}`,
70
+ DATA_PORTFOLIO: (walletAddress) => `/data/wallet-portfolio?walletAddress=${walletAddress}`,
68
71
  DATA_HISTORY: (walletAddress, chainId) => `/data/history?walletAddress=${walletAddress}&chainId=${chainId}`,
69
72
  DATA_TVL: "/data/usd-tvl",
70
73
  DATA_VOLUME: (assetType) => `/data/volume?assetType=${assetType}`,
@@ -205,7 +208,7 @@ var HttpClient = class {
205
208
  case 429:
206
209
  throw new Error("Rate limit exceeded. Please try again later.");
207
210
  case 500:
208
- throw new Error("Internal server error. Please try again later.");
211
+ throw new Error(data?.message || data?.error || "Internal server error. Please try again later.");
209
212
  default:
210
213
  throw new Error(data.message || "An error occurred");
211
214
  }
@@ -389,6 +392,89 @@ var IDENTITY_REGISTRY_ABI = (0, import_viem.parseAbi)([
389
392
  "function register(string tokenUri, (string key, bytes value)[] metadata) external returns (uint256 agentId)"
390
393
  ]);
391
394
  var IDENTITY_REGISTRY_ADDRESS = "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432";
395
+ var VAULT_ABI = [
396
+ {
397
+ name: "deposit",
398
+ type: "function",
399
+ stateMutability: "nonpayable",
400
+ inputs: [
401
+ { name: "assets", type: "uint256" },
402
+ { name: "receiver", type: "address" }
403
+ ],
404
+ outputs: [{ name: "shares", type: "uint256" }]
405
+ },
406
+ {
407
+ name: "requestRedeem",
408
+ type: "function",
409
+ stateMutability: "nonpayable",
410
+ inputs: [
411
+ { name: "shares", type: "uint256" },
412
+ { name: "controller", type: "address" },
413
+ { name: "owner", type: "address" }
414
+ ],
415
+ outputs: [{ name: "requestId", type: "uint256" }]
416
+ },
417
+ {
418
+ name: "claim",
419
+ type: "function",
420
+ stateMutability: "nonpayable",
421
+ inputs: [{ name: "withdrawKey", type: "bytes32" }],
422
+ outputs: [{ name: "assets", type: "uint256" }]
423
+ },
424
+ {
425
+ name: "getWithdrawKey",
426
+ type: "function",
427
+ stateMutability: "view",
428
+ inputs: [
429
+ { name: "user", type: "address" },
430
+ { name: "nonce", type: "uint256" }
431
+ ],
432
+ outputs: [{ name: "", type: "bytes32" }]
433
+ },
434
+ {
435
+ name: "nonces",
436
+ type: "function",
437
+ stateMutability: "view",
438
+ inputs: [{ name: "user", type: "address" }],
439
+ outputs: [{ name: "", type: "uint256" }]
440
+ },
441
+ {
442
+ name: "isClaimable",
443
+ type: "function",
444
+ stateMutability: "view",
445
+ inputs: [{ name: "withdrawKey", type: "bytes32" }],
446
+ outputs: [{ name: "", type: "bool" }]
447
+ },
448
+ {
449
+ name: "isClaimed",
450
+ type: "function",
451
+ stateMutability: "view",
452
+ inputs: [{ name: "withdrawKey", type: "bytes32" }],
453
+ outputs: [{ name: "", type: "bool" }]
454
+ },
455
+ {
456
+ name: "maxRequestRedeem",
457
+ type: "function",
458
+ stateMutability: "view",
459
+ inputs: [{ name: "owner", type: "address" }],
460
+ outputs: [{ name: "", type: "uint256" }]
461
+ },
462
+ {
463
+ name: "balanceOf",
464
+ type: "function",
465
+ stateMutability: "view",
466
+ inputs: [{ name: "account", type: "address" }],
467
+ outputs: [{ name: "", type: "uint256" }]
468
+ },
469
+ {
470
+ name: "symbol",
471
+ type: "function",
472
+ stateMutability: "view",
473
+ inputs: [],
474
+ outputs: [{ name: "", type: "string" }]
475
+ }
476
+ ];
477
+ var VAULT_ADDRESS = "0xD580071c47d4a667858B5FafAb85BC9C609beC5D";
392
478
 
393
479
  // src/core/ZyfaiSDK.ts
394
480
  var import_accounts2 = require("viem/accounts");
@@ -769,6 +855,13 @@ function convertStrategyToPublic(obj) {
769
855
  return result;
770
856
  }
771
857
  }
858
+ function removeUnusedFields(obj) {
859
+ const result = { ...obj };
860
+ if ("hasStaleBalance" in result) {
861
+ delete result.hasStaleBalance;
862
+ }
863
+ return result;
864
+ }
772
865
  function convertAssetInternally(asset) {
773
866
  if (asset === "USDC") {
774
867
  return "usdc";
@@ -1400,6 +1493,7 @@ var _ZyfaiSDK = class _ZyfaiSDK {
1400
1493
  * @param userAddress - User's EOA address (the connected EOA, not the smart wallet address)
1401
1494
  * @param chainId - Target chain ID
1402
1495
  * @param strategy - Optional strategy selection: "conservative" (default) or "aggressive"
1496
+ * @param createSessionKey - If true, automatically creates a session key after deployment (default: false)
1403
1497
  * @returns Deployment response with Safe address and transaction hash
1404
1498
  *
1405
1499
  * @example
@@ -1409,9 +1503,12 @@ var _ZyfaiSDK = class _ZyfaiSDK {
1409
1503
  *
1410
1504
  * // Deploy with aggressive strategy
1411
1505
  * await sdk.deploySafe(userAddress, 8453, "aggressive");
1506
+ *
1507
+ * // Deploy and automatically create session key
1508
+ * await sdk.deploySafe(userAddress, 8453, "conservative", true);
1412
1509
  * ```
1413
1510
  */
1414
- async deploySafe(userAddress, chainId, strategy) {
1511
+ async deploySafe(userAddress, chainId, strategy, createSessionKey) {
1415
1512
  try {
1416
1513
  if (!userAddress) {
1417
1514
  throw new Error("User address is required");
@@ -1443,11 +1540,24 @@ var _ZyfaiSDK = class _ZyfaiSDK {
1443
1540
  }
1444
1541
  }
1445
1542
  if (alreadyDeployed) {
1543
+ let sessionKeyCreated2 = false;
1544
+ if (createSessionKey) {
1545
+ try {
1546
+ await this.createSessionKey(userAddress, chainId);
1547
+ sessionKeyCreated2 = true;
1548
+ } catch (sessionKeyError) {
1549
+ console.warn(
1550
+ "Failed to create session key:",
1551
+ sessionKeyError.message
1552
+ );
1553
+ }
1554
+ }
1446
1555
  return {
1447
1556
  success: true,
1448
1557
  safeAddress,
1449
1558
  txHash: "0x0",
1450
- status: "deployed"
1559
+ status: "deployed",
1560
+ sessionKeyCreated: sessionKeyCreated2
1451
1561
  };
1452
1562
  }
1453
1563
  const internalStrategy = strategy ? toInternalStrategy(strategy) : "safe_strategy";
@@ -1469,11 +1579,24 @@ var _ZyfaiSDK = class _ZyfaiSDK {
1469
1579
  initError.message
1470
1580
  );
1471
1581
  }
1582
+ let sessionKeyCreated = false;
1583
+ if (createSessionKey) {
1584
+ try {
1585
+ await this.createSessionKey(userAddress, chainId);
1586
+ sessionKeyCreated = true;
1587
+ } catch (sessionKeyError) {
1588
+ console.warn(
1589
+ "Failed to create session key after Safe deployment:",
1590
+ sessionKeyError.message
1591
+ );
1592
+ }
1593
+ }
1472
1594
  return {
1473
1595
  success: true,
1474
1596
  safeAddress: deploymentResult.safeAddress,
1475
1597
  txHash: deploymentResult.txHash || "0x0",
1476
- status: "deployed"
1598
+ status: "deployed",
1599
+ sessionKeyCreated
1477
1600
  };
1478
1601
  } catch (error) {
1479
1602
  console.error("Safe deployment failed:", error);
@@ -2001,6 +2124,49 @@ var _ZyfaiSDK = class _ZyfaiSDK {
2001
2124
  throw new Error(`Failed to get positions: ${error.message}`);
2002
2125
  }
2003
2126
  }
2127
+ /**
2128
+ * Get all active positions and portfolio for a user
2129
+ *
2130
+ * @param userAddress - User's EOA address
2131
+ * @param chainId - Optional: Filter by specific chain ID
2132
+ * @returns User's positions across all protocols
2133
+ *
2134
+ * @example
2135
+ * ```typescript
2136
+ * // Get all positions across all chains
2137
+ * const positions = await sdk.getPositions(userAddress);
2138
+ *
2139
+ * // Get positions on a specific chain
2140
+ * const basePositions = await sdk.getPositions(userAddress, 8453);
2141
+ * ```
2142
+ */
2143
+ async getPortfolio(userAddress) {
2144
+ try {
2145
+ if (!userAddress) {
2146
+ throw new Error("User address is required");
2147
+ }
2148
+ const smartWalletInfo = await this.getSmartWalletByEOA(userAddress);
2149
+ if (!smartWalletInfo.smartWallet) {
2150
+ return {
2151
+ success: true,
2152
+ userAddress,
2153
+ portfolio: {}
2154
+ };
2155
+ }
2156
+ console.log("Getting portfolio for", smartWalletInfo.smartWallet);
2157
+ const response = await this.httpClient.get(
2158
+ ENDPOINTS.DATA_PORTFOLIO(smartWalletInfo.smartWallet)
2159
+ );
2160
+ const convertedResponse = removeUnusedFields(response);
2161
+ return {
2162
+ success: true,
2163
+ userAddress,
2164
+ portfolio: convertedResponse
2165
+ };
2166
+ } catch (error) {
2167
+ throw new Error(`Failed to get positions: ${error.message}`);
2168
+ }
2169
+ }
2004
2170
  // ============================================================================
2005
2171
  // User Details Methods
2006
2172
  // ============================================================================
@@ -2319,9 +2485,6 @@ var _ZyfaiSDK = class _ZyfaiSDK {
2319
2485
  data: {
2320
2486
  walletAddress,
2321
2487
  totalEarningsByToken: response.total_earnings_by_token || {},
2322
- lifetimeEarningsByToken: response.lifetime_earnings_by_token || {},
2323
- currentEarningsByChain: response.current_earnings_by_chain || {},
2324
- unrealizedEarnings: response.unrealized_earnings || {},
2325
2488
  lastCheckTimestamp: response.last_check_timestamp,
2326
2489
  lastLogDate: response.last_log_date
2327
2490
  }
@@ -2360,9 +2523,6 @@ var _ZyfaiSDK = class _ZyfaiSDK {
2360
2523
  data: {
2361
2524
  walletAddress,
2362
2525
  totalEarningsByToken: data.total_earnings_by_token || {},
2363
- lifetimeEarningsByToken: data.lifetime_earnings_by_token || {},
2364
- currentEarningsByChain: data.current_earnings_by_chain || {},
2365
- unrealizedEarnings: data.unrealized_earnings || {},
2366
2526
  lastCheckTimestamp: data.last_check_timestamp,
2367
2527
  lastLogDate: data.last_log_date
2368
2528
  }
@@ -2395,10 +2555,17 @@ var _ZyfaiSDK = class _ZyfaiSDK {
2395
2555
  const response = await this.httpClient.dataGet(
2396
2556
  DATA_ENDPOINTS.DAILY_EARNINGS(walletAddress, startDate, endDate)
2397
2557
  );
2558
+ const filteredData = (response.data || []).map((entry) => ({
2559
+ wallet_address: entry.wallet_address,
2560
+ snapshot_date: entry.snapshot_date,
2561
+ total_earnings_by_token: entry.total_earnings_by_token,
2562
+ daily_total_delta_by_token: entry.daily_total_delta_by_token,
2563
+ created_at: entry.created_at
2564
+ }));
2398
2565
  return {
2399
2566
  success: true,
2400
2567
  walletAddress,
2401
- data: response.data || [],
2568
+ data: filteredData,
2402
2569
  count: response.count || 0,
2403
2570
  filters: {
2404
2571
  startDate: startDate || null,
@@ -3003,6 +3170,338 @@ var _ZyfaiSDK = class _ZyfaiSDK {
3003
3170
  );
3004
3171
  }
3005
3172
  }
3173
+ // ============================================
3174
+ // Vault Methods (Base only)
3175
+ // ============================================
3176
+ /**
3177
+ * Deposit assets into the Zyfai Vault
3178
+ * Currently only supports USDC on Base chain
3179
+ *
3180
+ * @param amount - Amount to deposit (in human readable format, e.g., "100" for 100 USDC)
3181
+ * @param asset - Asset to deposit (default: "USDC")
3182
+ * @returns Deposit transaction result
3183
+ *
3184
+ * @example
3185
+ * ```typescript
3186
+ * const result = await sdk.vaultDeposit("100", "USDC");
3187
+ * console.log("Deposited:", result.txHash);
3188
+ * ```
3189
+ */
3190
+ async vaultDeposit(amount, asset = "USDC", chainId = 8453) {
3191
+ if (!this.walletClient?.account) {
3192
+ throw new Error("Wallet not connected. Call connectAccount first.");
3193
+ }
3194
+ const userAddress = this.walletClient.account.address;
3195
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3196
+ const tokenAddress = getDefaultTokenAddress(chainId, asset);
3197
+ const decimals = 6;
3198
+ const parsedAmount = BigInt(Math.floor(parseFloat(amount) * 10 ** decimals));
3199
+ try {
3200
+ const allowance = await chainConfig.publicClient.readContract({
3201
+ address: tokenAddress,
3202
+ abi: ERC20_ABI,
3203
+ functionName: "allowance",
3204
+ args: [userAddress, VAULT_ADDRESS]
3205
+ });
3206
+ if (allowance < parsedAmount) {
3207
+ const approveTx = await this.walletClient.writeContract({
3208
+ address: tokenAddress,
3209
+ abi: ERC20_ABI,
3210
+ functionName: "approve",
3211
+ args: [VAULT_ADDRESS, parsedAmount],
3212
+ chain: chainConfig.chain,
3213
+ account: this.walletClient.account
3214
+ });
3215
+ await chainConfig.publicClient.waitForTransactionReceipt({
3216
+ hash: approveTx
3217
+ });
3218
+ }
3219
+ const depositTx = await this.walletClient.writeContract({
3220
+ address: VAULT_ADDRESS,
3221
+ abi: VAULT_ABI,
3222
+ functionName: "deposit",
3223
+ args: [parsedAmount, userAddress],
3224
+ chain: chainConfig.chain,
3225
+ account: this.walletClient.account
3226
+ });
3227
+ const receipt = await chainConfig.publicClient.waitForTransactionReceipt({
3228
+ hash: depositTx
3229
+ });
3230
+ if (receipt.status !== "success") {
3231
+ throw new Error("Vault deposit transaction failed");
3232
+ }
3233
+ return {
3234
+ success: true,
3235
+ txHash: depositTx,
3236
+ amount,
3237
+ asset,
3238
+ vaultAddress: VAULT_ADDRESS
3239
+ };
3240
+ } catch (error) {
3241
+ throw new Error(`Vault deposit failed: ${error.message}`);
3242
+ }
3243
+ }
3244
+ /**
3245
+ * Request withdrawal from the Zyfai Vault
3246
+ * Withdrawals are async - use getVaultWithdrawStatus and vaultClaim after
3247
+ *
3248
+ * @param shares - Amount of shares to redeem (optional, defaults to all shares)
3249
+ * @returns Withdraw request result with withdrawKey
3250
+ *
3251
+ * @example
3252
+ * ```typescript
3253
+ * const result = await sdk.vaultWithdraw();
3254
+ * console.log("Withdraw key:", result.withdrawKey);
3255
+ * // Later, check status and claim
3256
+ * ```
3257
+ */
3258
+ async vaultWithdraw(shares, chainId = 8453) {
3259
+ if (!this.walletClient?.account) {
3260
+ throw new Error("Wallet not connected. Call connectAccount first.");
3261
+ }
3262
+ const userAddress = this.walletClient.account.address;
3263
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3264
+ try {
3265
+ let sharesToRedeem;
3266
+ if (shares) {
3267
+ sharesToRedeem = BigInt(shares);
3268
+ } else {
3269
+ const maxShares = await chainConfig.publicClient.readContract({
3270
+ address: VAULT_ADDRESS,
3271
+ abi: VAULT_ABI,
3272
+ functionName: "maxRequestRedeem",
3273
+ args: [userAddress]
3274
+ });
3275
+ if (maxShares === 0n) {
3276
+ throw new Error("No shares available to redeem or withdrawals are paused");
3277
+ }
3278
+ sharesToRedeem = maxShares;
3279
+ }
3280
+ const redeemTx = await this.walletClient.writeContract({
3281
+ address: VAULT_ADDRESS,
3282
+ abi: VAULT_ABI,
3283
+ functionName: "requestRedeem",
3284
+ args: [sharesToRedeem, userAddress, userAddress],
3285
+ chain: chainConfig.chain,
3286
+ account: this.walletClient.account
3287
+ });
3288
+ await chainConfig.publicClient.waitForTransactionReceipt({
3289
+ hash: redeemTx
3290
+ });
3291
+ const nonceResult = await chainConfig.publicClient.readContract({
3292
+ address: VAULT_ADDRESS,
3293
+ abi: VAULT_ABI,
3294
+ functionName: "nonces",
3295
+ args: [userAddress]
3296
+ });
3297
+ const nonce = BigInt(nonceResult);
3298
+ if (nonce === 0n) {
3299
+ throw new Error("Nonce is 0 after requestRedeem - unexpected state");
3300
+ }
3301
+ const withdrawKey = await chainConfig.publicClient.readContract({
3302
+ address: VAULT_ADDRESS,
3303
+ abi: VAULT_ABI,
3304
+ functionName: "getWithdrawKey",
3305
+ args: [userAddress, nonce - 1n]
3306
+ });
3307
+ const isClaimable = await chainConfig.publicClient.readContract({
3308
+ address: VAULT_ADDRESS,
3309
+ abi: VAULT_ABI,
3310
+ functionName: "isClaimable",
3311
+ args: [withdrawKey]
3312
+ });
3313
+ return {
3314
+ success: true,
3315
+ txHash: redeemTx,
3316
+ withdrawKey,
3317
+ status: isClaimable ? "claimable" : "pending"
3318
+ };
3319
+ } catch (error) {
3320
+ throw new Error(`Vault withdraw request failed: ${error.message}`);
3321
+ }
3322
+ }
3323
+ /**
3324
+ * Get the status of a pending withdrawal
3325
+ *
3326
+ * @param withdrawKey - The withdraw key to check (optional, gets latest if not provided)
3327
+ * @returns Withdraw status
3328
+ *
3329
+ * @example
3330
+ * ```typescript
3331
+ * const status = await sdk.getVaultWithdrawStatus();
3332
+ * if (status.isClaimable) {
3333
+ * await sdk.vaultClaim(status.withdrawKey);
3334
+ * }
3335
+ * ```
3336
+ */
3337
+ async getVaultWithdrawStatus(withdrawKey, chainId = 8453) {
3338
+ if (!this.walletClient?.account) {
3339
+ throw new Error("Wallet not connected. Call connectAccount first.");
3340
+ }
3341
+ const userAddress = this.walletClient.account.address;
3342
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3343
+ try {
3344
+ const nonceResult = await chainConfig.publicClient.readContract({
3345
+ address: VAULT_ADDRESS,
3346
+ abi: VAULT_ABI,
3347
+ functionName: "nonces",
3348
+ args: [userAddress]
3349
+ });
3350
+ const nonce = BigInt(nonceResult);
3351
+ if (nonce === 0n) {
3352
+ return {
3353
+ success: true,
3354
+ withdrawKey: null,
3355
+ isClaimable: false,
3356
+ isPending: false,
3357
+ nonce: 0n
3358
+ };
3359
+ }
3360
+ let keyToCheck = withdrawKey;
3361
+ if (!keyToCheck) {
3362
+ keyToCheck = await chainConfig.publicClient.readContract({
3363
+ address: VAULT_ADDRESS,
3364
+ abi: VAULT_ABI,
3365
+ functionName: "getWithdrawKey",
3366
+ args: [userAddress, nonce - 1n]
3367
+ });
3368
+ }
3369
+ const [isClaimable, isClaimed] = await Promise.all([
3370
+ chainConfig.publicClient.readContract({
3371
+ address: VAULT_ADDRESS,
3372
+ abi: VAULT_ABI,
3373
+ functionName: "isClaimable",
3374
+ args: [keyToCheck]
3375
+ }),
3376
+ chainConfig.publicClient.readContract({
3377
+ address: VAULT_ADDRESS,
3378
+ abi: VAULT_ABI,
3379
+ functionName: "isClaimed",
3380
+ args: [keyToCheck]
3381
+ })
3382
+ ]);
3383
+ if (isClaimed) {
3384
+ return {
3385
+ success: true,
3386
+ withdrawKey: null,
3387
+ isClaimable: false,
3388
+ isPending: false,
3389
+ nonce
3390
+ };
3391
+ }
3392
+ return {
3393
+ success: true,
3394
+ withdrawKey: keyToCheck,
3395
+ isClaimable,
3396
+ isPending: !isClaimable,
3397
+ nonce
3398
+ };
3399
+ } catch (error) {
3400
+ throw new Error(`Failed to get withdraw status: ${error.message}`);
3401
+ }
3402
+ }
3403
+ /**
3404
+ * Claim a completed withdrawal from the Zyfai Vault
3405
+ *
3406
+ * @param withdrawKey - The withdraw key to claim
3407
+ * @returns Claim transaction result
3408
+ *
3409
+ * @example
3410
+ * ```typescript
3411
+ * const status = await sdk.getVaultWithdrawStatus();
3412
+ * if (status.isClaimable) {
3413
+ * const claim = await sdk.vaultClaim(status.withdrawKey);
3414
+ * console.log("Claimed:", claim.txHash);
3415
+ * }
3416
+ * ```
3417
+ */
3418
+ async vaultClaim(withdrawKey, chainId = 8453) {
3419
+ if (!this.walletClient?.account) {
3420
+ throw new Error("Wallet not connected. Call connectAccount first.");
3421
+ }
3422
+ if (!withdrawKey) {
3423
+ throw new Error("Withdraw key is required");
3424
+ }
3425
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3426
+ try {
3427
+ const isClaimable = await chainConfig.publicClient.readContract({
3428
+ address: VAULT_ADDRESS,
3429
+ abi: VAULT_ABI,
3430
+ functionName: "isClaimable",
3431
+ args: [withdrawKey]
3432
+ });
3433
+ if (!isClaimable) {
3434
+ const isClaimed = await chainConfig.publicClient.readContract({
3435
+ address: VAULT_ADDRESS,
3436
+ abi: VAULT_ABI,
3437
+ functionName: "isClaimed",
3438
+ args: [withdrawKey]
3439
+ });
3440
+ if (isClaimed) {
3441
+ throw new Error("This withdrawal has already been claimed");
3442
+ }
3443
+ throw new Error("Withdrawal is not yet claimable. Please wait for processing.");
3444
+ }
3445
+ const claimTx = await this.walletClient.writeContract({
3446
+ address: VAULT_ADDRESS,
3447
+ abi: VAULT_ABI,
3448
+ functionName: "claim",
3449
+ args: [withdrawKey],
3450
+ chain: chainConfig.chain,
3451
+ account: this.walletClient.account
3452
+ });
3453
+ const receipt = await chainConfig.publicClient.waitForTransactionReceipt({
3454
+ hash: claimTx
3455
+ });
3456
+ if (receipt.status !== "success") {
3457
+ throw new Error("Vault claim transaction failed");
3458
+ }
3459
+ return {
3460
+ success: true,
3461
+ txHash: claimTx,
3462
+ claimed: true
3463
+ };
3464
+ } catch (error) {
3465
+ throw new Error(`Vault claim failed: ${error.message}`);
3466
+ }
3467
+ }
3468
+ /**
3469
+ * Get vault shares info for the connected wallet
3470
+ *
3471
+ * @param userAddress - Optional user address (defaults to connected wallet)
3472
+ * @returns Vault shares balance and token symbol
3473
+ *
3474
+ * @example
3475
+ * ```typescript
3476
+ * const { shares, symbol } = await sdk.getVaultShares();
3477
+ * console.log(`Balance: ${shares} ${symbol}`);
3478
+ * ```
3479
+ */
3480
+ async getVaultShares(userAddress, chainId = 8453) {
3481
+ const address = userAddress || this.walletClient?.account?.address;
3482
+ if (!address) {
3483
+ throw new Error("User address required. Provide address or connect wallet first.");
3484
+ }
3485
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3486
+ const [shareBalance, tokenSymbol] = await Promise.all([
3487
+ chainConfig.publicClient.readContract({
3488
+ address: VAULT_ADDRESS,
3489
+ abi: VAULT_ABI,
3490
+ functionName: "balanceOf",
3491
+ args: [address]
3492
+ }),
3493
+ chainConfig.publicClient.readContract({
3494
+ address: VAULT_ADDRESS,
3495
+ abi: VAULT_ABI,
3496
+ functionName: "symbol"
3497
+ })
3498
+ ]);
3499
+ return {
3500
+ success: true,
3501
+ shares: shareBalance,
3502
+ symbol: tokenSymbol
3503
+ };
3504
+ }
3006
3505
  };
3007
3506
  // ============================================================================
3008
3507
  // Agent Identity Registry
@@ -3012,10 +3511,178 @@ var _ZyfaiSDK = class _ZyfaiSDK {
3012
3511
  */
3013
3512
  _ZyfaiSDK.IDENTITY_REGISTRY_CHAIN_IDS = [8453, 42161];
3014
3513
  var ZyfaiSDK = _ZyfaiSDK;
3514
+
3515
+ // src/providers/bankr.ts
3516
+ function createBankrProvider(config) {
3517
+ const {
3518
+ apiKey,
3519
+ baseUrl = "https://api.bankr.bot",
3520
+ chainId = 8453
3521
+ } = config;
3522
+ if (!apiKey) {
3523
+ throw new Error("Bankr API key is required");
3524
+ }
3525
+ let cachedWalletAddress = null;
3526
+ const fetchBankr = async (endpoint, body) => {
3527
+ const response = await fetch(`${baseUrl}${endpoint}`, {
3528
+ method: body ? "POST" : "GET",
3529
+ headers: {
3530
+ "Content-Type": "application/json",
3531
+ "X-API-Key": apiKey
3532
+ },
3533
+ body: body ? JSON.stringify(body) : void 0
3534
+ });
3535
+ if (!response.ok) {
3536
+ const errorData = await response.json().catch(() => ({}));
3537
+ throw new Error(errorData.message || errorData.error || `Bankr API error: ${response.status}`);
3538
+ }
3539
+ return response.json();
3540
+ };
3541
+ const getWalletAddress = async () => {
3542
+ if (cachedWalletAddress) {
3543
+ return cachedWalletAddress;
3544
+ }
3545
+ const data = await fetchBankr("/agent/me");
3546
+ const evmWallet = data.wallets?.find((w) => w.chain === "evm");
3547
+ if (!evmWallet?.address) {
3548
+ throw new Error("No EVM wallet found in Bankr account");
3549
+ }
3550
+ cachedWalletAddress = evmWallet.address;
3551
+ return evmWallet.address;
3552
+ };
3553
+ const provider = {
3554
+ /**
3555
+ * EIP-1193 request method
3556
+ * Routes RPC calls to appropriate Bankr API endpoints
3557
+ */
3558
+ async request({ method, params }) {
3559
+ switch (method) {
3560
+ case "eth_requestAccounts":
3561
+ case "eth_accounts": {
3562
+ const address = await getWalletAddress();
3563
+ return [address];
3564
+ }
3565
+ case "eth_chainId": {
3566
+ return `0x${chainId.toString(16)}`;
3567
+ }
3568
+ case "net_version": {
3569
+ return chainId.toString();
3570
+ }
3571
+ case "personal_sign": {
3572
+ const [messageHex, address] = params || [];
3573
+ let message = messageHex;
3574
+ if (typeof messageHex === "string" && messageHex.startsWith("0x")) {
3575
+ const isRawHash = messageHex.length === 66;
3576
+ if (!isRawHash) {
3577
+ try {
3578
+ message = Buffer.from(messageHex.slice(2), "hex").toString("utf8");
3579
+ } catch {
3580
+ message = messageHex;
3581
+ }
3582
+ }
3583
+ }
3584
+ const data = await fetchBankr("/agent/sign", {
3585
+ signatureType: "personal_sign",
3586
+ message
3587
+ });
3588
+ if (!data.success || !data.signature) {
3589
+ throw new Error(data.error || "Bankr signing failed");
3590
+ }
3591
+ return data.signature;
3592
+ }
3593
+ case "eth_signTypedData":
3594
+ case "eth_signTypedData_v4": {
3595
+ const [address, typedDataString] = params || [];
3596
+ const typedData = typeof typedDataString === "string" ? JSON.parse(typedDataString) : typedDataString;
3597
+ const data = await fetchBankr("/agent/sign", {
3598
+ signatureType: "eth_signTypedData_v4",
3599
+ typedData
3600
+ });
3601
+ if (!data.success || !data.signature) {
3602
+ throw new Error(data.error || "Bankr typed data signing failed");
3603
+ }
3604
+ return data.signature;
3605
+ }
3606
+ case "eth_sendTransaction": {
3607
+ const [tx] = params || [];
3608
+ const signData = await fetchBankr("/agent/sign", {
3609
+ signatureType: "eth_signTransaction",
3610
+ transaction: {
3611
+ to: tx.to,
3612
+ chainId: tx.chainId ? parseInt(tx.chainId, 16) : chainId,
3613
+ value: tx.value || "0",
3614
+ data: tx.data || "0x",
3615
+ gas: tx.gas,
3616
+ gasLimit: tx.gasLimit,
3617
+ maxFeePerGas: tx.maxFeePerGas,
3618
+ maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
3619
+ nonce: tx.nonce
3620
+ }
3621
+ });
3622
+ if (!signData.success || !signData.signature) {
3623
+ throw new Error(signData.error || "Bankr transaction signing failed");
3624
+ }
3625
+ const submitData = await fetchBankr("/agent/submit", {
3626
+ signedTransaction: signData.signature,
3627
+ chainId: tx.chainId ? parseInt(tx.chainId, 16) : chainId
3628
+ });
3629
+ if (!submitData.success) {
3630
+ throw new Error(submitData.error || "Bankr transaction submission failed");
3631
+ }
3632
+ return submitData.transactionHash || submitData.txHash;
3633
+ }
3634
+ case "eth_signTransaction": {
3635
+ const [tx] = params || [];
3636
+ const data = await fetchBankr("/agent/sign", {
3637
+ signatureType: "eth_signTransaction",
3638
+ transaction: {
3639
+ to: tx.to,
3640
+ chainId: tx.chainId ? parseInt(tx.chainId, 16) : chainId,
3641
+ value: tx.value || "0",
3642
+ data: tx.data || "0x",
3643
+ gas: tx.gas,
3644
+ gasLimit: tx.gasLimit,
3645
+ maxFeePerGas: tx.maxFeePerGas,
3646
+ maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
3647
+ nonce: tx.nonce
3648
+ }
3649
+ });
3650
+ if (!data.success || !data.signature) {
3651
+ throw new Error(data.error || "Bankr transaction signing failed");
3652
+ }
3653
+ return data.signature;
3654
+ }
3655
+ case "wallet_switchEthereumChain": {
3656
+ return null;
3657
+ }
3658
+ default:
3659
+ throw new Error(`Unsupported method: ${method}. Bankr provider supports: eth_requestAccounts, eth_accounts, eth_chainId, personal_sign, eth_signTypedData_v4, eth_sendTransaction, eth_signTransaction`);
3660
+ }
3661
+ },
3662
+ /**
3663
+ * Event listener stub (required by EIP-1193)
3664
+ * Bankr API doesn't support real-time events
3665
+ */
3666
+ on: (event, callback) => {
3667
+ },
3668
+ /**
3669
+ * Remove event listener stub (required by EIP-1193)
3670
+ */
3671
+ removeListener: (event, callback) => {
3672
+ },
3673
+ /**
3674
+ * Check if this is a Bankr provider
3675
+ */
3676
+ isBankr: true
3677
+ };
3678
+ return provider;
3679
+ }
3015
3680
  // Annotate the CommonJS export names for ESM import in node:
3016
3681
  0 && (module.exports = {
3017
3682
  DEFAULT_TOKEN_ADDRESSES,
3683
+ VAULT_ADDRESS,
3018
3684
  ZyfaiSDK,
3685
+ createBankrProvider,
3019
3686
  getChainConfig,
3020
3687
  getDefaultTokenAddress,
3021
3688
  getSupportedChainIds,