@zyfai/sdk 0.2.37 → 0.2.39
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/README.md +24 -17
- package/dist/index.d.mts +156 -10
- package/dist/index.d.ts +156 -10
- package/dist/index.js +224 -66
- package/dist/index.mjs +210 -52
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -47,6 +47,7 @@ var import_axios = __toESM(require("axios"));
|
|
|
47
47
|
// src/config/endpoints.ts
|
|
48
48
|
var API_ENDPOINT = "https://api.zyf.ai";
|
|
49
49
|
var DATA_API_ENDPOINT = "https://defiapi.zyf.ai";
|
|
50
|
+
var WS_ENDPOINT = "wss://defiapi.zyf.ai/ws/events";
|
|
50
51
|
var API_VERSION = "/api/v1";
|
|
51
52
|
var DATA_API_VERSION = "/api/v2";
|
|
52
53
|
var ENDPOINTS = {
|
|
@@ -80,6 +81,21 @@ var ENDPOINTS = {
|
|
|
80
81
|
SDK_TVL: "/data/sdk-tvl",
|
|
81
82
|
// Agent Identity Registry
|
|
82
83
|
AGENT_TOKEN_URI: "/users/me/agent-token-uri",
|
|
84
|
+
// Simulation
|
|
85
|
+
SIMULATE_BEST_POSITIONS: (params) => {
|
|
86
|
+
const networks = Array.isArray(params.networks) ? params.networks.join(",") : params.networks;
|
|
87
|
+
const query = [
|
|
88
|
+
`amount=${params.amount}`,
|
|
89
|
+
`token=${params.token}`,
|
|
90
|
+
`networks=${networks}`,
|
|
91
|
+
`strategy=${params.strategy}`
|
|
92
|
+
];
|
|
93
|
+
if (params.minSplit !== void 0) query.push(`minSplit=${params.minSplit}`);
|
|
94
|
+
if (params.protocols?.length) query.push(`protocols=${params.protocols.join(",")}`);
|
|
95
|
+
if (params.pools?.length) query.push(`pools=${params.pools.join(",")}`);
|
|
96
|
+
if (params.userPositions?.length) query.push(`userPositions=${encodeURIComponent(JSON.stringify(params.userPositions))}`);
|
|
97
|
+
return `/simulate/best-positions?${query.join("&")}`;
|
|
98
|
+
},
|
|
83
99
|
// Customization
|
|
84
100
|
CUSTOMIZE_BATCH: "/customization/customize-batch",
|
|
85
101
|
CUSTOMIZATION_POOLS: (protocolId, strategy) => `/customization/pools?protocolId=${protocolId}${strategy ? `&strategy=${strategy}` : ""}`,
|
|
@@ -476,41 +492,34 @@ var VAULT_ABI = [
|
|
|
476
492
|
];
|
|
477
493
|
var VAULT_ADDRESS = "0xD580071c47d4a667858B5FafAb85BC9C609beC5D";
|
|
478
494
|
|
|
495
|
+
// src/config/constants.ts
|
|
496
|
+
var MIN_PORTFOLIO_BALANCE = {
|
|
497
|
+
1: {
|
|
498
|
+
USDC: 10000n * 10n ** 6n,
|
|
499
|
+
// 10,000 USDC (6 decimals)
|
|
500
|
+
WETH: 5n * 10n ** 18n
|
|
501
|
+
// 5 WETH (18 decimals)
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
var formatMinPortfolioLabel = (raw, decimals, symbol) => {
|
|
505
|
+
const whole = raw / 10n ** BigInt(decimals);
|
|
506
|
+
return `${whole.toString()} ${symbol}`;
|
|
507
|
+
};
|
|
508
|
+
|
|
479
509
|
// src/core/ZyfaiSDK.ts
|
|
480
510
|
var import_accounts2 = require("viem/accounts");
|
|
481
|
-
var
|
|
511
|
+
var import_viem4 = require("viem");
|
|
482
512
|
|
|
483
513
|
// src/config/chains.ts
|
|
484
514
|
var import_viem2 = require("viem");
|
|
485
515
|
var import_chains = require("viem/chains");
|
|
486
|
-
var import_viem3 = require("viem");
|
|
487
|
-
var plasma = (0, import_viem3.defineChain)({
|
|
488
|
-
id: 9745,
|
|
489
|
-
name: "Plasma",
|
|
490
|
-
nativeCurrency: {
|
|
491
|
-
decimals: 18,
|
|
492
|
-
name: "Plasma",
|
|
493
|
-
symbol: "PLSM"
|
|
494
|
-
},
|
|
495
|
-
rpcUrls: {
|
|
496
|
-
default: {
|
|
497
|
-
http: ["https://rpc.plasma.to"]
|
|
498
|
-
}
|
|
499
|
-
},
|
|
500
|
-
blockExplorers: {
|
|
501
|
-
default: {
|
|
502
|
-
name: "Plasma Explorer",
|
|
503
|
-
url: "https://explorer.plasma.io"
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
});
|
|
507
516
|
var DEFAULT_TOKEN_ADDRESSES = {
|
|
517
|
+
1: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
518
|
+
// USDC on Ethereum Mainnet
|
|
508
519
|
8453: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
509
520
|
// USDC on Base
|
|
510
|
-
42161: "0xaf88d065e77c8cc2239327c5edb3a432268e5831"
|
|
521
|
+
42161: "0xaf88d065e77c8cc2239327c5edb3a432268e5831"
|
|
511
522
|
// USDC on Arbitrum
|
|
512
|
-
9745: "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"
|
|
513
|
-
// USDT on Plasma
|
|
514
523
|
};
|
|
515
524
|
var ASSET_CONFIGS = {
|
|
516
525
|
USDC: {
|
|
@@ -521,25 +530,23 @@ var ASSET_CONFIGS = {
|
|
|
521
530
|
decimals: 6,
|
|
522
531
|
tokenSymbols: ["USDC", "USDC.e", "USDT", "USDT0"],
|
|
523
532
|
tokenSymbolsByChainId: {
|
|
533
|
+
1: "USDC",
|
|
524
534
|
8453: "USDC",
|
|
525
535
|
42161: "USDC",
|
|
526
|
-
9745: "USDT0",
|
|
527
536
|
146: "USDC.e",
|
|
528
|
-
|
|
537
|
+
59144: "USDC"
|
|
529
538
|
},
|
|
530
539
|
addresses: {
|
|
540
|
+
1: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
541
|
+
// Ethereum
|
|
531
542
|
8453: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
532
543
|
// Base
|
|
533
544
|
42161: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
534
545
|
// Arbitrum
|
|
535
|
-
9745: "0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb",
|
|
536
|
-
// Plasma
|
|
537
546
|
146: "0x29219dd400f2bf60e5a23d13be72b486d4038894",
|
|
538
547
|
// Sonic
|
|
539
|
-
59144: "0x176211869ca2b568f2a7d4ee941e073a821ee1ff"
|
|
548
|
+
59144: "0x176211869ca2b568f2a7d4ee941e073a821ee1ff"
|
|
540
549
|
// Linea
|
|
541
|
-
1: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
|
542
|
-
// Ethereum
|
|
543
550
|
},
|
|
544
551
|
enabled: true
|
|
545
552
|
},
|
|
@@ -551,26 +558,23 @@ var ASSET_CONFIGS = {
|
|
|
551
558
|
decimals: 18,
|
|
552
559
|
tokenSymbols: ["WETH", "ETH"],
|
|
553
560
|
tokenSymbolsByChainId: {
|
|
561
|
+
1: "WETH",
|
|
554
562
|
8453: "WETH",
|
|
555
563
|
42161: "WETH",
|
|
556
|
-
9745: "WETH",
|
|
557
564
|
146: "WETH",
|
|
558
|
-
59144: "WETH"
|
|
559
|
-
1: "WETH"
|
|
565
|
+
59144: "WETH"
|
|
560
566
|
},
|
|
561
567
|
addresses: {
|
|
568
|
+
1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
569
|
+
// Ethereum
|
|
562
570
|
8453: "0x4200000000000000000000000000000000000006",
|
|
563
571
|
// Base
|
|
564
572
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
565
573
|
// Arbitrum
|
|
566
|
-
9745: "0x4200000000000000000000000000000000000006",
|
|
567
|
-
// Plasma
|
|
568
574
|
146: "0x039e64f90d4199560e7533692f69448878db85c7",
|
|
569
575
|
// Sonic
|
|
570
|
-
59144: "0xe5d7c2a44ffddf6b295a15c148167daaaf5cf34f"
|
|
576
|
+
59144: "0xe5d7c2a44ffddf6b295a15c148167daaaf5cf34f"
|
|
571
577
|
// Linea
|
|
572
|
-
1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
|
573
|
-
// Ethereum
|
|
574
578
|
},
|
|
575
579
|
enabled: true
|
|
576
580
|
}
|
|
@@ -585,14 +589,14 @@ var getDefaultTokenAddress = (chainId, asset) => {
|
|
|
585
589
|
return address;
|
|
586
590
|
};
|
|
587
591
|
var DEFAULT_RPC_URLS = {
|
|
592
|
+
1: "https://mainnet.infura.io/v3/8e6cdd06e30d40ac9990bf61bed3a3d0",
|
|
588
593
|
8453: "https://mainnet.base.org",
|
|
589
|
-
42161: "https://arb1.arbitrum.io/rpc"
|
|
590
|
-
9745: "https://rpc.plasma.to"
|
|
594
|
+
42161: "https://arb1.arbitrum.io/rpc"
|
|
591
595
|
};
|
|
592
596
|
var CHAINS = {
|
|
597
|
+
1: import_chains.mainnet,
|
|
593
598
|
8453: import_chains.base,
|
|
594
|
-
42161: import_chains.arbitrum
|
|
595
|
-
9745: plasma
|
|
599
|
+
42161: import_chains.arbitrum
|
|
596
600
|
};
|
|
597
601
|
var getChainConfig = (chainId, rpcUrls) => {
|
|
598
602
|
const chain = CHAINS[chainId];
|
|
@@ -620,7 +624,7 @@ var getSupportedChainIds = () => {
|
|
|
620
624
|
// src/utils/safe-account.ts
|
|
621
625
|
var import_module_sdk = require("@rhinestone/module-sdk");
|
|
622
626
|
var import_accounts = require("permissionless/accounts");
|
|
623
|
-
var
|
|
627
|
+
var import_viem3 = require("viem");
|
|
624
628
|
var import_account_abstraction = require("viem/account-abstraction");
|
|
625
629
|
var SAFE_7579_ADDRESS = "0x7579EE8307284F293B1927136486880611F20002";
|
|
626
630
|
var ERC7579_LAUNCHPAD_ADDRESS = "0x7579011aB74c46090561ea277Ba79D510c6C00ff";
|
|
@@ -630,12 +634,12 @@ var getSafeAccount = async (config) => {
|
|
|
630
634
|
if (!safeOwnerAddress) {
|
|
631
635
|
throw new Error("Safe owner address is required");
|
|
632
636
|
}
|
|
633
|
-
const formattedOwnerAddress = (0,
|
|
637
|
+
const formattedOwnerAddress = (0, import_viem3.getAddress)(safeOwnerAddress);
|
|
634
638
|
const ownableValidator = (0, import_module_sdk.getOwnableValidator)({
|
|
635
639
|
owners: [formattedOwnerAddress],
|
|
636
640
|
threshold: 1
|
|
637
641
|
});
|
|
638
|
-
const saltHex = (0,
|
|
642
|
+
const saltHex = (0, import_viem3.fromHex)((0, import_viem3.toHex)(ACCOUNT_SALT), "bigint");
|
|
639
643
|
const tempOwner = {
|
|
640
644
|
address: formattedOwnerAddress,
|
|
641
645
|
type: "json-rpc"
|
|
@@ -939,7 +943,7 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
939
943
|
return;
|
|
940
944
|
}
|
|
941
945
|
const walletClient = this.getWalletClient();
|
|
942
|
-
const userAddress = (0,
|
|
946
|
+
const userAddress = (0, import_viem4.getAddress)(walletClient.account.address);
|
|
943
947
|
const chainId = this.currentChainId || walletClient.chain?.id || 8453;
|
|
944
948
|
const challengeResponse = await this.httpClient.post(ENDPOINTS.AUTH_CHALLENGE, {});
|
|
945
949
|
let uri;
|
|
@@ -1293,10 +1297,10 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
1293
1297
|
this.walletClient.chain?.id || 8453,
|
|
1294
1298
|
this.rpcUrls
|
|
1295
1299
|
);
|
|
1296
|
-
this.walletClient = (0,
|
|
1300
|
+
this.walletClient = (0, import_viem4.createWalletClient)({
|
|
1297
1301
|
account: newAddress,
|
|
1298
1302
|
chain: chainConfig.chain,
|
|
1299
|
-
transport: (0,
|
|
1303
|
+
transport: (0, import_viem4.custom)(this.currentProvider)
|
|
1300
1304
|
});
|
|
1301
1305
|
this.currentChainId = this.walletClient.chain?.id || null;
|
|
1302
1306
|
try {
|
|
@@ -1348,10 +1352,10 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
1348
1352
|
}
|
|
1349
1353
|
this.signer = (0, import_accounts2.privateKeyToAccount)(privateKey);
|
|
1350
1354
|
this.currentChainId = chainId;
|
|
1351
|
-
this.walletClient = (0,
|
|
1355
|
+
this.walletClient = (0, import_viem4.createWalletClient)({
|
|
1352
1356
|
account: this.signer,
|
|
1353
1357
|
chain: chainConfig.chain,
|
|
1354
|
-
transport: (0,
|
|
1358
|
+
transport: (0, import_viem4.http)(chainConfig.rpcUrl)
|
|
1355
1359
|
});
|
|
1356
1360
|
connectedAddress = this.signer.address;
|
|
1357
1361
|
this.currentProvider = null;
|
|
@@ -1369,10 +1373,10 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
1369
1373
|
if (!accounts || accounts.length === 0) {
|
|
1370
1374
|
throw new Error("No accounts found in wallet provider");
|
|
1371
1375
|
}
|
|
1372
|
-
this.walletClient = (0,
|
|
1376
|
+
this.walletClient = (0, import_viem4.createWalletClient)({
|
|
1373
1377
|
account: accounts[0],
|
|
1374
1378
|
chain: chainConfig.chain,
|
|
1375
|
-
transport: (0,
|
|
1379
|
+
transport: (0, import_viem4.custom)(provider)
|
|
1376
1380
|
});
|
|
1377
1381
|
connectedAddress = accounts[0];
|
|
1378
1382
|
this.currentProvider = provider;
|
|
@@ -1381,7 +1385,7 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
1381
1385
|
provider.on("accountsChanged", this.handleAccountsChanged.bind(this));
|
|
1382
1386
|
}
|
|
1383
1387
|
} else if (provider.account && provider.transport) {
|
|
1384
|
-
this.walletClient = (0,
|
|
1388
|
+
this.walletClient = (0, import_viem4.createWalletClient)({
|
|
1385
1389
|
account: provider.account,
|
|
1386
1390
|
chain: chainConfig.chain,
|
|
1387
1391
|
transport: provider.transport
|
|
@@ -1434,10 +1438,10 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
1434
1438
|
targetChainId,
|
|
1435
1439
|
this.rpcUrls
|
|
1436
1440
|
);
|
|
1437
|
-
return (0,
|
|
1441
|
+
return (0, import_viem4.createWalletClient)({
|
|
1438
1442
|
account: this.signer,
|
|
1439
1443
|
chain: targetChainConfig.chain,
|
|
1440
|
-
transport: (0,
|
|
1444
|
+
transport: (0, import_viem4.http)(targetChainConfig.rpcUrl)
|
|
1441
1445
|
});
|
|
1442
1446
|
} else {
|
|
1443
1447
|
if (!this.walletClient) {
|
|
@@ -1800,22 +1804,30 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
1800
1804
|
* Deposit funds from EOA to Safe smart wallet
|
|
1801
1805
|
* Transfers tokens from the connected wallet to the user's Safe and logs the deposit
|
|
1802
1806
|
*
|
|
1803
|
-
* Token is automatically selected based on chain:
|
|
1804
|
-
* - Base (8453)
|
|
1805
|
-
*
|
|
1807
|
+
* Token is automatically selected based on chain (USDC by default):
|
|
1808
|
+
* - Ethereum Mainnet (1), Base (8453), Arbitrum (42161)
|
|
1809
|
+
*
|
|
1810
|
+
* Minimum portfolio balance enforced (Safe balance + deposit amount),
|
|
1811
|
+
* configured per-chain in `MIN_PORTFOLIO_BALANCE`:
|
|
1812
|
+
* - Ethereum Mainnet (1): 5 USDC (test threshold)
|
|
1813
|
+
* - Base (8453) & Arbitrum (42161): no minimum
|
|
1814
|
+
*
|
|
1815
|
+
* If no minimum is configured for a given (chainId, asset) pair,
|
|
1816
|
+
* the check is skipped.
|
|
1806
1817
|
*
|
|
1807
1818
|
* @param userAddress - User's address (owner of the Safe)
|
|
1808
1819
|
* @param chainId - Target chain ID
|
|
1809
1820
|
* @param amount - Amount in least decimal units (e.g., "100000000" for 100 USDC with 6 decimals)
|
|
1821
|
+
* @param asset - Optional asset symbol ("USDC" or "WETH"). Defaults to "USDC".
|
|
1810
1822
|
* @returns Deposit response with transaction hash
|
|
1811
1823
|
*
|
|
1812
1824
|
* @example
|
|
1813
1825
|
* ```typescript
|
|
1814
|
-
* // Deposit
|
|
1826
|
+
* // Deposit 10,000 USDC (6 decimals) to Safe on Base
|
|
1815
1827
|
* const result = await sdk.depositFunds(
|
|
1816
1828
|
* "0xUser...",
|
|
1817
1829
|
* 8453,
|
|
1818
|
-
* "
|
|
1830
|
+
* "10000000000" // 10,000 USDC = 10_000 * 10^6
|
|
1819
1831
|
* );
|
|
1820
1832
|
* ```
|
|
1821
1833
|
*/
|
|
@@ -1830,7 +1842,15 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
1830
1842
|
if (!amount || isNaN(Number(amount)) || Number(amount) <= 0) {
|
|
1831
1843
|
throw new Error("Valid amount is required");
|
|
1832
1844
|
}
|
|
1833
|
-
const
|
|
1845
|
+
const assetSymbol = (asset || "USDC").toUpperCase();
|
|
1846
|
+
const assetConfig = ASSET_CONFIGS[assetSymbol];
|
|
1847
|
+
if (!assetConfig) {
|
|
1848
|
+
throw new Error(
|
|
1849
|
+
`Unsupported asset: ${assetSymbol}. Supported: USDC, WETH.`
|
|
1850
|
+
);
|
|
1851
|
+
}
|
|
1852
|
+
const minRequired = MIN_PORTFOLIO_BALANCE[chainId]?.[assetSymbol];
|
|
1853
|
+
const token = getDefaultTokenAddress(chainId, assetSymbol);
|
|
1834
1854
|
const walletClient = this.getWalletClient();
|
|
1835
1855
|
const chainConfig = getChainConfig(chainId, this.rpcUrls);
|
|
1836
1856
|
const safeAddress = await getDeterministicSafeAddress({
|
|
@@ -1848,6 +1868,25 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
1848
1868
|
);
|
|
1849
1869
|
}
|
|
1850
1870
|
const amountBigInt = BigInt(amount);
|
|
1871
|
+
if (minRequired !== void 0) {
|
|
1872
|
+
const currentSafeBalance = await chainConfig.publicClient.readContract({
|
|
1873
|
+
address: token,
|
|
1874
|
+
abi: ERC20_ABI,
|
|
1875
|
+
functionName: "balanceOf",
|
|
1876
|
+
args: [safeAddress]
|
|
1877
|
+
});
|
|
1878
|
+
const totalAfterDeposit = currentSafeBalance + amountBigInt;
|
|
1879
|
+
if (totalAfterDeposit < minRequired) {
|
|
1880
|
+
const minLabel = formatMinPortfolioLabel(
|
|
1881
|
+
minRequired,
|
|
1882
|
+
assetConfig.decimals,
|
|
1883
|
+
assetSymbol
|
|
1884
|
+
);
|
|
1885
|
+
throw new Error(
|
|
1886
|
+
`Minimum portfolio balance not met on chain ${chainId}. Total portfolio must be at least ${minLabel}. Current Safe balance: ${currentSafeBalance.toString()}, deposit amount: ${amountBigInt.toString()}, total after deposit: ${totalAfterDeposit.toString()} (raw units, ${assetConfig.decimals} decimals).`
|
|
1887
|
+
);
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1851
1890
|
const txHash = await walletClient.writeContract({
|
|
1852
1891
|
address: token,
|
|
1853
1892
|
abi: ERC20_ABI,
|
|
@@ -1895,8 +1934,7 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
1895
1934
|
* - Need more control over transaction execution
|
|
1896
1935
|
*
|
|
1897
1936
|
* Token is automatically selected based on chain if not provided:
|
|
1898
|
-
* - Base (8453)
|
|
1899
|
-
* - Plasma (9745): USDT
|
|
1937
|
+
* - Ethereum Mainnet (1), Base (8453), Arbitrum (42161): USDC by default
|
|
1900
1938
|
*
|
|
1901
1939
|
* @param chainId - Chain ID where the deposit was made
|
|
1902
1940
|
* @param txHash - Transaction hash of the deposit
|
|
@@ -3073,6 +3111,54 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
3073
3111
|
);
|
|
3074
3112
|
}
|
|
3075
3113
|
}
|
|
3114
|
+
// ============================================================================
|
|
3115
|
+
// Simulation
|
|
3116
|
+
// ============================================================================
|
|
3117
|
+
/**
|
|
3118
|
+
* Simulate the best yield positions for a given amount, splitting it across
|
|
3119
|
+
* the top-ranked pools (up to minSplit positions) for the requested chains/strategy.
|
|
3120
|
+
*
|
|
3121
|
+
* Returns ready-to-execute calldata (approve + deposit) per position. The deposit
|
|
3122
|
+
* calldata contains a "<RECEIVER>" placeholder that must be replaced with the
|
|
3123
|
+
* actual receiving address (e.g. the user's Safe) before sending the transaction.
|
|
3124
|
+
*
|
|
3125
|
+
* @param params - Simulation parameters
|
|
3126
|
+
* @returns Chain-keyed map of simulated positions with calldata
|
|
3127
|
+
*
|
|
3128
|
+
* @example
|
|
3129
|
+
* ```typescript
|
|
3130
|
+
* const result = await sdk.simulateBestPositions({
|
|
3131
|
+
* amount: 3000,
|
|
3132
|
+
* token: "USDC",
|
|
3133
|
+
* networks: 8453,
|
|
3134
|
+
* strategy: "conservative",
|
|
3135
|
+
* minSplit: 3,
|
|
3136
|
+
* protocols: ["aave", "compound", "morpho"],
|
|
3137
|
+
* });
|
|
3138
|
+
* console.log(result.data["8453"]);
|
|
3139
|
+
* ```
|
|
3140
|
+
*/
|
|
3141
|
+
async simulateBestPositions(params) {
|
|
3142
|
+
try {
|
|
3143
|
+
if (!isValidPublicStrategy(params.strategy)) {
|
|
3144
|
+
throw new Error(
|
|
3145
|
+
`Invalid strategy: ${params.strategy}. Must be "conservative" or "aggressive".`
|
|
3146
|
+
);
|
|
3147
|
+
}
|
|
3148
|
+
const internalStrategy = toInternalStrategy(params.strategy);
|
|
3149
|
+
const response = await this.httpClient.get(
|
|
3150
|
+
ENDPOINTS.SIMULATE_BEST_POSITIONS({
|
|
3151
|
+
...params,
|
|
3152
|
+
strategy: internalStrategy
|
|
3153
|
+
})
|
|
3154
|
+
);
|
|
3155
|
+
return response;
|
|
3156
|
+
} catch (error) {
|
|
3157
|
+
throw new Error(
|
|
3158
|
+
`Failed to simulate best positions: ${error.message}`
|
|
3159
|
+
);
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3076
3162
|
/**
|
|
3077
3163
|
* Get currently selected pools for a protocol on a specific chain.
|
|
3078
3164
|
*
|
|
@@ -3149,7 +3235,7 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
3149
3235
|
if (!tokenUriResponse.tokenUri) {
|
|
3150
3236
|
throw new Error("API did not return a tokenUri");
|
|
3151
3237
|
}
|
|
3152
|
-
const callData = (0,
|
|
3238
|
+
const callData = (0, import_viem4.encodeFunctionData)({
|
|
3153
3239
|
abi: IDENTITY_REGISTRY_ABI,
|
|
3154
3240
|
functionName: "register",
|
|
3155
3241
|
args: [tokenUriResponse.tokenUri]
|
|
@@ -3515,6 +3601,78 @@ var _ZyfaiSDK = class _ZyfaiSDK {
|
|
|
3515
3601
|
symbol: tokenSymbol
|
|
3516
3602
|
};
|
|
3517
3603
|
}
|
|
3604
|
+
// ============================================================================
|
|
3605
|
+
// WebSocket Event Stream
|
|
3606
|
+
// ============================================================================
|
|
3607
|
+
/**
|
|
3608
|
+
* Subscribe to real-time Zyfai risk and liquidity events via WebSocket.
|
|
3609
|
+
*
|
|
3610
|
+
* Events: depeg, liquidity_trap, liquidity_restored, pool_status_change,
|
|
3611
|
+
* new_collateral_detected, liquidity_drop.
|
|
3612
|
+
*
|
|
3613
|
+
* @param handlers - Callback per event type, plus onError
|
|
3614
|
+
* @param filters - Optional protocol/pool filter sent to the server on subscribe
|
|
3615
|
+
* @returns Cleanup function — call it to close the connection
|
|
3616
|
+
*
|
|
3617
|
+
* @example
|
|
3618
|
+
* ```typescript
|
|
3619
|
+
* const unsubscribe = sdk.subscribeToEvents(
|
|
3620
|
+
* {
|
|
3621
|
+
* onDepeg: (data) => console.log("Depeg detected:", data.token, data.severity),
|
|
3622
|
+
* onLiquidityDrop: (data) => console.log("Liquidity drop:", data.pool, data.dropPercent),
|
|
3623
|
+
* },
|
|
3624
|
+
* { protocols: ["morpho"], pools: ["gauntlet usdc core"] }
|
|
3625
|
+
* );
|
|
3626
|
+
*
|
|
3627
|
+
* // Later, close the connection:
|
|
3628
|
+
* unsubscribe();
|
|
3629
|
+
* ```
|
|
3630
|
+
*/
|
|
3631
|
+
subscribeToEvents(handlers, filters) {
|
|
3632
|
+
let ws = null;
|
|
3633
|
+
let closed = false;
|
|
3634
|
+
const connect = () => {
|
|
3635
|
+
ws = new globalThis.WebSocket(WS_ENDPOINT);
|
|
3636
|
+
ws.onopen = () => {
|
|
3637
|
+
const msg = { type: "subscribe" };
|
|
3638
|
+
if (filters && (filters.chains?.length || filters.protocols?.length || filters.pools?.length)) {
|
|
3639
|
+
msg.filters = filters;
|
|
3640
|
+
}
|
|
3641
|
+
ws.send(JSON.stringify(msg));
|
|
3642
|
+
};
|
|
3643
|
+
ws.onmessage = (event) => {
|
|
3644
|
+
try {
|
|
3645
|
+
const msg = JSON.parse(event.data);
|
|
3646
|
+
if (msg.type !== "event") return;
|
|
3647
|
+
switch (msg.eventType) {
|
|
3648
|
+
case "depeg":
|
|
3649
|
+
handlers.onDepeg?.(msg.data);
|
|
3650
|
+
break;
|
|
3651
|
+
case "new_collateral_detected":
|
|
3652
|
+
handlers.onNewCollateralDetected?.(msg.data);
|
|
3653
|
+
break;
|
|
3654
|
+
case "liquidity_drop":
|
|
3655
|
+
handlers.onLiquidityDrop?.(msg.data);
|
|
3656
|
+
break;
|
|
3657
|
+
}
|
|
3658
|
+
} catch {
|
|
3659
|
+
}
|
|
3660
|
+
};
|
|
3661
|
+
ws.onerror = (error) => {
|
|
3662
|
+
handlers.onError?.(error);
|
|
3663
|
+
};
|
|
3664
|
+
ws.onclose = () => {
|
|
3665
|
+
if (!closed) {
|
|
3666
|
+
setTimeout(connect, 3e3);
|
|
3667
|
+
}
|
|
3668
|
+
};
|
|
3669
|
+
};
|
|
3670
|
+
connect();
|
|
3671
|
+
return () => {
|
|
3672
|
+
closed = true;
|
|
3673
|
+
ws?.close();
|
|
3674
|
+
};
|
|
3675
|
+
}
|
|
3518
3676
|
};
|
|
3519
3677
|
// ============================================================================
|
|
3520
3678
|
// Agent Identity Registry
|