@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.d.mts +205 -12
- package/dist/index.d.ts +205 -12
- package/dist/index.js +678 -11
- package/dist/index.mjs +676 -11
- package/package.json +1 -1
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:
|
|
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,
|