@zyfai/sdk 0.2.25 → 0.2.27

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
  }
@@ -3003,6 +3163,338 @@ var _ZyfaiSDK = class _ZyfaiSDK {
3003
3163
  );
3004
3164
  }
3005
3165
  }
3166
+ // ============================================
3167
+ // Vault Methods (Base only)
3168
+ // ============================================
3169
+ /**
3170
+ * Deposit assets into the Zyfai Vault
3171
+ * Currently only supports USDC on Base chain
3172
+ *
3173
+ * @param amount - Amount to deposit (in human readable format, e.g., "100" for 100 USDC)
3174
+ * @param asset - Asset to deposit (default: "USDC")
3175
+ * @returns Deposit transaction result
3176
+ *
3177
+ * @example
3178
+ * ```typescript
3179
+ * const result = await sdk.vaultDeposit("100", "USDC");
3180
+ * console.log("Deposited:", result.txHash);
3181
+ * ```
3182
+ */
3183
+ async vaultDeposit(amount, asset = "USDC", chainId = 8453) {
3184
+ if (!this.walletClient?.account) {
3185
+ throw new Error("Wallet not connected. Call connectAccount first.");
3186
+ }
3187
+ const userAddress = this.walletClient.account.address;
3188
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3189
+ const tokenAddress = getDefaultTokenAddress(chainId, asset);
3190
+ const decimals = 6;
3191
+ const parsedAmount = BigInt(Math.floor(parseFloat(amount) * 10 ** decimals));
3192
+ try {
3193
+ const allowance = await chainConfig.publicClient.readContract({
3194
+ address: tokenAddress,
3195
+ abi: ERC20_ABI,
3196
+ functionName: "allowance",
3197
+ args: [userAddress, VAULT_ADDRESS]
3198
+ });
3199
+ if (allowance < parsedAmount) {
3200
+ const approveTx = await this.walletClient.writeContract({
3201
+ address: tokenAddress,
3202
+ abi: ERC20_ABI,
3203
+ functionName: "approve",
3204
+ args: [VAULT_ADDRESS, parsedAmount],
3205
+ chain: chainConfig.chain,
3206
+ account: this.walletClient.account
3207
+ });
3208
+ await chainConfig.publicClient.waitForTransactionReceipt({
3209
+ hash: approveTx
3210
+ });
3211
+ }
3212
+ const depositTx = await this.walletClient.writeContract({
3213
+ address: VAULT_ADDRESS,
3214
+ abi: VAULT_ABI,
3215
+ functionName: "deposit",
3216
+ args: [parsedAmount, userAddress],
3217
+ chain: chainConfig.chain,
3218
+ account: this.walletClient.account
3219
+ });
3220
+ const receipt = await chainConfig.publicClient.waitForTransactionReceipt({
3221
+ hash: depositTx
3222
+ });
3223
+ if (receipt.status !== "success") {
3224
+ throw new Error("Vault deposit transaction failed");
3225
+ }
3226
+ return {
3227
+ success: true,
3228
+ txHash: depositTx,
3229
+ amount,
3230
+ asset,
3231
+ vaultAddress: VAULT_ADDRESS
3232
+ };
3233
+ } catch (error) {
3234
+ throw new Error(`Vault deposit failed: ${error.message}`);
3235
+ }
3236
+ }
3237
+ /**
3238
+ * Request withdrawal from the Zyfai Vault
3239
+ * Withdrawals are async - use getVaultWithdrawStatus and vaultClaim after
3240
+ *
3241
+ * @param shares - Amount of shares to redeem (optional, defaults to all shares)
3242
+ * @returns Withdraw request result with withdrawKey
3243
+ *
3244
+ * @example
3245
+ * ```typescript
3246
+ * const result = await sdk.vaultWithdraw();
3247
+ * console.log("Withdraw key:", result.withdrawKey);
3248
+ * // Later, check status and claim
3249
+ * ```
3250
+ */
3251
+ async vaultWithdraw(shares, chainId = 8453) {
3252
+ if (!this.walletClient?.account) {
3253
+ throw new Error("Wallet not connected. Call connectAccount first.");
3254
+ }
3255
+ const userAddress = this.walletClient.account.address;
3256
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3257
+ try {
3258
+ let sharesToRedeem;
3259
+ if (shares) {
3260
+ sharesToRedeem = BigInt(shares);
3261
+ } else {
3262
+ const maxShares = await chainConfig.publicClient.readContract({
3263
+ address: VAULT_ADDRESS,
3264
+ abi: VAULT_ABI,
3265
+ functionName: "maxRequestRedeem",
3266
+ args: [userAddress]
3267
+ });
3268
+ if (maxShares === 0n) {
3269
+ throw new Error("No shares available to redeem or withdrawals are paused");
3270
+ }
3271
+ sharesToRedeem = maxShares;
3272
+ }
3273
+ const redeemTx = await this.walletClient.writeContract({
3274
+ address: VAULT_ADDRESS,
3275
+ abi: VAULT_ABI,
3276
+ functionName: "requestRedeem",
3277
+ args: [sharesToRedeem, userAddress, userAddress],
3278
+ chain: chainConfig.chain,
3279
+ account: this.walletClient.account
3280
+ });
3281
+ await chainConfig.publicClient.waitForTransactionReceipt({
3282
+ hash: redeemTx
3283
+ });
3284
+ const nonceResult = await chainConfig.publicClient.readContract({
3285
+ address: VAULT_ADDRESS,
3286
+ abi: VAULT_ABI,
3287
+ functionName: "nonces",
3288
+ args: [userAddress]
3289
+ });
3290
+ const nonce = BigInt(nonceResult);
3291
+ if (nonce === 0n) {
3292
+ throw new Error("Nonce is 0 after requestRedeem - unexpected state");
3293
+ }
3294
+ const withdrawKey = await chainConfig.publicClient.readContract({
3295
+ address: VAULT_ADDRESS,
3296
+ abi: VAULT_ABI,
3297
+ functionName: "getWithdrawKey",
3298
+ args: [userAddress, nonce - 1n]
3299
+ });
3300
+ const isClaimable = await chainConfig.publicClient.readContract({
3301
+ address: VAULT_ADDRESS,
3302
+ abi: VAULT_ABI,
3303
+ functionName: "isClaimable",
3304
+ args: [withdrawKey]
3305
+ });
3306
+ return {
3307
+ success: true,
3308
+ txHash: redeemTx,
3309
+ withdrawKey,
3310
+ status: isClaimable ? "claimable" : "pending"
3311
+ };
3312
+ } catch (error) {
3313
+ throw new Error(`Vault withdraw request failed: ${error.message}`);
3314
+ }
3315
+ }
3316
+ /**
3317
+ * Get the status of a pending withdrawal
3318
+ *
3319
+ * @param withdrawKey - The withdraw key to check (optional, gets latest if not provided)
3320
+ * @returns Withdraw status
3321
+ *
3322
+ * @example
3323
+ * ```typescript
3324
+ * const status = await sdk.getVaultWithdrawStatus();
3325
+ * if (status.isClaimable) {
3326
+ * await sdk.vaultClaim(status.withdrawKey);
3327
+ * }
3328
+ * ```
3329
+ */
3330
+ async getVaultWithdrawStatus(withdrawKey, chainId = 8453) {
3331
+ if (!this.walletClient?.account) {
3332
+ throw new Error("Wallet not connected. Call connectAccount first.");
3333
+ }
3334
+ const userAddress = this.walletClient.account.address;
3335
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3336
+ try {
3337
+ const nonceResult = await chainConfig.publicClient.readContract({
3338
+ address: VAULT_ADDRESS,
3339
+ abi: VAULT_ABI,
3340
+ functionName: "nonces",
3341
+ args: [userAddress]
3342
+ });
3343
+ const nonce = BigInt(nonceResult);
3344
+ if (nonce === 0n) {
3345
+ return {
3346
+ success: true,
3347
+ withdrawKey: null,
3348
+ isClaimable: false,
3349
+ isPending: false,
3350
+ nonce: 0n
3351
+ };
3352
+ }
3353
+ let keyToCheck = withdrawKey;
3354
+ if (!keyToCheck) {
3355
+ keyToCheck = await chainConfig.publicClient.readContract({
3356
+ address: VAULT_ADDRESS,
3357
+ abi: VAULT_ABI,
3358
+ functionName: "getWithdrawKey",
3359
+ args: [userAddress, nonce - 1n]
3360
+ });
3361
+ }
3362
+ const [isClaimable, isClaimed] = await Promise.all([
3363
+ chainConfig.publicClient.readContract({
3364
+ address: VAULT_ADDRESS,
3365
+ abi: VAULT_ABI,
3366
+ functionName: "isClaimable",
3367
+ args: [keyToCheck]
3368
+ }),
3369
+ chainConfig.publicClient.readContract({
3370
+ address: VAULT_ADDRESS,
3371
+ abi: VAULT_ABI,
3372
+ functionName: "isClaimed",
3373
+ args: [keyToCheck]
3374
+ })
3375
+ ]);
3376
+ if (isClaimed) {
3377
+ return {
3378
+ success: true,
3379
+ withdrawKey: null,
3380
+ isClaimable: false,
3381
+ isPending: false,
3382
+ nonce
3383
+ };
3384
+ }
3385
+ return {
3386
+ success: true,
3387
+ withdrawKey: keyToCheck,
3388
+ isClaimable,
3389
+ isPending: !isClaimable,
3390
+ nonce
3391
+ };
3392
+ } catch (error) {
3393
+ throw new Error(`Failed to get withdraw status: ${error.message}`);
3394
+ }
3395
+ }
3396
+ /**
3397
+ * Claim a completed withdrawal from the Zyfai Vault
3398
+ *
3399
+ * @param withdrawKey - The withdraw key to claim
3400
+ * @returns Claim transaction result
3401
+ *
3402
+ * @example
3403
+ * ```typescript
3404
+ * const status = await sdk.getVaultWithdrawStatus();
3405
+ * if (status.isClaimable) {
3406
+ * const claim = await sdk.vaultClaim(status.withdrawKey);
3407
+ * console.log("Claimed:", claim.txHash);
3408
+ * }
3409
+ * ```
3410
+ */
3411
+ async vaultClaim(withdrawKey, chainId = 8453) {
3412
+ if (!this.walletClient?.account) {
3413
+ throw new Error("Wallet not connected. Call connectAccount first.");
3414
+ }
3415
+ if (!withdrawKey) {
3416
+ throw new Error("Withdraw key is required");
3417
+ }
3418
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3419
+ try {
3420
+ const isClaimable = await chainConfig.publicClient.readContract({
3421
+ address: VAULT_ADDRESS,
3422
+ abi: VAULT_ABI,
3423
+ functionName: "isClaimable",
3424
+ args: [withdrawKey]
3425
+ });
3426
+ if (!isClaimable) {
3427
+ const isClaimed = await chainConfig.publicClient.readContract({
3428
+ address: VAULT_ADDRESS,
3429
+ abi: VAULT_ABI,
3430
+ functionName: "isClaimed",
3431
+ args: [withdrawKey]
3432
+ });
3433
+ if (isClaimed) {
3434
+ throw new Error("This withdrawal has already been claimed");
3435
+ }
3436
+ throw new Error("Withdrawal is not yet claimable. Please wait for processing.");
3437
+ }
3438
+ const claimTx = await this.walletClient.writeContract({
3439
+ address: VAULT_ADDRESS,
3440
+ abi: VAULT_ABI,
3441
+ functionName: "claim",
3442
+ args: [withdrawKey],
3443
+ chain: chainConfig.chain,
3444
+ account: this.walletClient.account
3445
+ });
3446
+ const receipt = await chainConfig.publicClient.waitForTransactionReceipt({
3447
+ hash: claimTx
3448
+ });
3449
+ if (receipt.status !== "success") {
3450
+ throw new Error("Vault claim transaction failed");
3451
+ }
3452
+ return {
3453
+ success: true,
3454
+ txHash: claimTx,
3455
+ claimed: true
3456
+ };
3457
+ } catch (error) {
3458
+ throw new Error(`Vault claim failed: ${error.message}`);
3459
+ }
3460
+ }
3461
+ /**
3462
+ * Get vault shares info for the connected wallet
3463
+ *
3464
+ * @param userAddress - Optional user address (defaults to connected wallet)
3465
+ * @returns Vault shares balance and token symbol
3466
+ *
3467
+ * @example
3468
+ * ```typescript
3469
+ * const { shares, symbol } = await sdk.getVaultShares();
3470
+ * console.log(`Balance: ${shares} ${symbol}`);
3471
+ * ```
3472
+ */
3473
+ async getVaultShares(userAddress, chainId = 8453) {
3474
+ const address = userAddress || this.walletClient?.account?.address;
3475
+ if (!address) {
3476
+ throw new Error("User address required. Provide address or connect wallet first.");
3477
+ }
3478
+ const chainConfig = getChainConfig(chainId, this.rpcUrls);
3479
+ const [shareBalance, tokenSymbol] = await Promise.all([
3480
+ chainConfig.publicClient.readContract({
3481
+ address: VAULT_ADDRESS,
3482
+ abi: VAULT_ABI,
3483
+ functionName: "balanceOf",
3484
+ args: [address]
3485
+ }),
3486
+ chainConfig.publicClient.readContract({
3487
+ address: VAULT_ADDRESS,
3488
+ abi: VAULT_ABI,
3489
+ functionName: "symbol"
3490
+ })
3491
+ ]);
3492
+ return {
3493
+ success: true,
3494
+ shares: shareBalance,
3495
+ symbol: tokenSymbol
3496
+ };
3497
+ }
3006
3498
  };
3007
3499
  // ============================================================================
3008
3500
  // Agent Identity Registry
@@ -3012,10 +3504,178 @@ var _ZyfaiSDK = class _ZyfaiSDK {
3012
3504
  */
3013
3505
  _ZyfaiSDK.IDENTITY_REGISTRY_CHAIN_IDS = [8453, 42161];
3014
3506
  var ZyfaiSDK = _ZyfaiSDK;
3507
+
3508
+ // src/providers/bankr.ts
3509
+ function createBankrProvider(config) {
3510
+ const {
3511
+ apiKey,
3512
+ baseUrl = "https://api.bankr.bot",
3513
+ chainId = 8453
3514
+ } = config;
3515
+ if (!apiKey) {
3516
+ throw new Error("Bankr API key is required");
3517
+ }
3518
+ let cachedWalletAddress = null;
3519
+ const fetchBankr = async (endpoint, body) => {
3520
+ const response = await fetch(`${baseUrl}${endpoint}`, {
3521
+ method: body ? "POST" : "GET",
3522
+ headers: {
3523
+ "Content-Type": "application/json",
3524
+ "X-API-Key": apiKey
3525
+ },
3526
+ body: body ? JSON.stringify(body) : void 0
3527
+ });
3528
+ if (!response.ok) {
3529
+ const errorData = await response.json().catch(() => ({}));
3530
+ throw new Error(errorData.message || errorData.error || `Bankr API error: ${response.status}`);
3531
+ }
3532
+ return response.json();
3533
+ };
3534
+ const getWalletAddress = async () => {
3535
+ if (cachedWalletAddress) {
3536
+ return cachedWalletAddress;
3537
+ }
3538
+ const data = await fetchBankr("/agent/me");
3539
+ const evmWallet = data.wallets?.find((w) => w.chain === "evm");
3540
+ if (!evmWallet?.address) {
3541
+ throw new Error("No EVM wallet found in Bankr account");
3542
+ }
3543
+ cachedWalletAddress = evmWallet.address;
3544
+ return evmWallet.address;
3545
+ };
3546
+ const provider = {
3547
+ /**
3548
+ * EIP-1193 request method
3549
+ * Routes RPC calls to appropriate Bankr API endpoints
3550
+ */
3551
+ async request({ method, params }) {
3552
+ switch (method) {
3553
+ case "eth_requestAccounts":
3554
+ case "eth_accounts": {
3555
+ const address = await getWalletAddress();
3556
+ return [address];
3557
+ }
3558
+ case "eth_chainId": {
3559
+ return `0x${chainId.toString(16)}`;
3560
+ }
3561
+ case "net_version": {
3562
+ return chainId.toString();
3563
+ }
3564
+ case "personal_sign": {
3565
+ const [messageHex, address] = params || [];
3566
+ let message = messageHex;
3567
+ if (typeof messageHex === "string" && messageHex.startsWith("0x")) {
3568
+ const isRawHash = messageHex.length === 66;
3569
+ if (!isRawHash) {
3570
+ try {
3571
+ message = Buffer.from(messageHex.slice(2), "hex").toString("utf8");
3572
+ } catch {
3573
+ message = messageHex;
3574
+ }
3575
+ }
3576
+ }
3577
+ const data = await fetchBankr("/agent/sign", {
3578
+ signatureType: "personal_sign",
3579
+ message
3580
+ });
3581
+ if (!data.success || !data.signature) {
3582
+ throw new Error(data.error || "Bankr signing failed");
3583
+ }
3584
+ return data.signature;
3585
+ }
3586
+ case "eth_signTypedData":
3587
+ case "eth_signTypedData_v4": {
3588
+ const [address, typedDataString] = params || [];
3589
+ const typedData = typeof typedDataString === "string" ? JSON.parse(typedDataString) : typedDataString;
3590
+ const data = await fetchBankr("/agent/sign", {
3591
+ signatureType: "eth_signTypedData_v4",
3592
+ typedData
3593
+ });
3594
+ if (!data.success || !data.signature) {
3595
+ throw new Error(data.error || "Bankr typed data signing failed");
3596
+ }
3597
+ return data.signature;
3598
+ }
3599
+ case "eth_sendTransaction": {
3600
+ const [tx] = params || [];
3601
+ const signData = await fetchBankr("/agent/sign", {
3602
+ signatureType: "eth_signTransaction",
3603
+ transaction: {
3604
+ to: tx.to,
3605
+ chainId: tx.chainId ? parseInt(tx.chainId, 16) : chainId,
3606
+ value: tx.value || "0",
3607
+ data: tx.data || "0x",
3608
+ gas: tx.gas,
3609
+ gasLimit: tx.gasLimit,
3610
+ maxFeePerGas: tx.maxFeePerGas,
3611
+ maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
3612
+ nonce: tx.nonce
3613
+ }
3614
+ });
3615
+ if (!signData.success || !signData.signature) {
3616
+ throw new Error(signData.error || "Bankr transaction signing failed");
3617
+ }
3618
+ const submitData = await fetchBankr("/agent/submit", {
3619
+ signedTransaction: signData.signature,
3620
+ chainId: tx.chainId ? parseInt(tx.chainId, 16) : chainId
3621
+ });
3622
+ if (!submitData.success) {
3623
+ throw new Error(submitData.error || "Bankr transaction submission failed");
3624
+ }
3625
+ return submitData.transactionHash || submitData.txHash;
3626
+ }
3627
+ case "eth_signTransaction": {
3628
+ const [tx] = params || [];
3629
+ const data = await fetchBankr("/agent/sign", {
3630
+ signatureType: "eth_signTransaction",
3631
+ transaction: {
3632
+ to: tx.to,
3633
+ chainId: tx.chainId ? parseInt(tx.chainId, 16) : chainId,
3634
+ value: tx.value || "0",
3635
+ data: tx.data || "0x",
3636
+ gas: tx.gas,
3637
+ gasLimit: tx.gasLimit,
3638
+ maxFeePerGas: tx.maxFeePerGas,
3639
+ maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
3640
+ nonce: tx.nonce
3641
+ }
3642
+ });
3643
+ if (!data.success || !data.signature) {
3644
+ throw new Error(data.error || "Bankr transaction signing failed");
3645
+ }
3646
+ return data.signature;
3647
+ }
3648
+ case "wallet_switchEthereumChain": {
3649
+ return null;
3650
+ }
3651
+ default:
3652
+ throw new Error(`Unsupported method: ${method}. Bankr provider supports: eth_requestAccounts, eth_accounts, eth_chainId, personal_sign, eth_signTypedData_v4, eth_sendTransaction, eth_signTransaction`);
3653
+ }
3654
+ },
3655
+ /**
3656
+ * Event listener stub (required by EIP-1193)
3657
+ * Bankr API doesn't support real-time events
3658
+ */
3659
+ on: (event, callback) => {
3660
+ },
3661
+ /**
3662
+ * Remove event listener stub (required by EIP-1193)
3663
+ */
3664
+ removeListener: (event, callback) => {
3665
+ },
3666
+ /**
3667
+ * Check if this is a Bankr provider
3668
+ */
3669
+ isBankr: true
3670
+ };
3671
+ return provider;
3672
+ }
3015
3673
  // Annotate the CommonJS export names for ESM import in node:
3016
3674
  0 && (module.exports = {
3017
3675
  DEFAULT_TOKEN_ADDRESSES,
3676
+ VAULT_ADDRESS,
3018
3677
  ZyfaiSDK,
3678
+ createBankrProvider,
3019
3679
  getChainConfig,
3020
3680
  getDefaultTokenAddress,
3021
3681
  getSupportedChainIds,