@zyfai/sdk 0.1.2 → 0.1.4
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 +39 -8
- package/dist/index.d.mts +20 -4
- package/dist/index.d.ts +20 -4
- package/dist/index.js +107 -47
- package/dist/index.mjs +110 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,16 +100,23 @@ const walletInfo = await sdk.getSmartWalletAddress(userAddress, 42161);
|
|
|
100
100
|
console.log("Safe Address:", walletInfo.address);
|
|
101
101
|
console.log("Is Deployed:", walletInfo.isDeployed);
|
|
102
102
|
|
|
103
|
-
// Deploy the Safe
|
|
103
|
+
// Deploy the Safe (automatically checks if already deployed)
|
|
104
104
|
const result = await sdk.deploySafe(userAddress, 42161);
|
|
105
105
|
|
|
106
106
|
if (result.success) {
|
|
107
107
|
console.log("Safe Address:", result.safeAddress);
|
|
108
108
|
console.log("Status:", result.status); // 'deployed' | 'failed'
|
|
109
|
-
|
|
109
|
+
|
|
110
|
+
if (result.alreadyDeployed) {
|
|
111
|
+
console.log("Safe was already deployed - no action needed");
|
|
112
|
+
} else {
|
|
113
|
+
console.log("Transaction Hash:", result.txHash);
|
|
114
|
+
}
|
|
110
115
|
}
|
|
111
116
|
```
|
|
112
117
|
|
|
118
|
+
**Note:** The SDK proactively checks if the Safe is already deployed before attempting deployment. If it exists, it returns `alreadyDeployed: true` without making any transactions.
|
|
119
|
+
|
|
113
120
|
### 2. Multi-Chain Support
|
|
114
121
|
|
|
115
122
|
The SDK supports the following chains:
|
|
@@ -229,25 +236,31 @@ The SDK automatically fetches optimal session configuration from ZyFAI API:
|
|
|
229
236
|
```typescript
|
|
230
237
|
// SDK automatically:
|
|
231
238
|
// 1. Authenticates via SIWE (creates user record if needed)
|
|
232
|
-
// 2.
|
|
233
|
-
// 3.
|
|
239
|
+
// 2. Checks if user already has an active session key (returns early if so)
|
|
240
|
+
// 3. Calculates the deterministic Safe address
|
|
234
241
|
// 4. Retrieves personalized config via /session-keys/config
|
|
235
242
|
// 5. Signs the session key
|
|
236
243
|
// 6. Calls /session-keys/add so the session becomes active immediately
|
|
237
244
|
|
|
238
245
|
const result = await sdk.createSessionKey(userAddress, 42161);
|
|
239
246
|
|
|
240
|
-
|
|
241
|
-
|
|
247
|
+
// Check if session key already existed
|
|
248
|
+
if (result.alreadyActive) {
|
|
249
|
+
console.log("Session key already active:", result.message);
|
|
250
|
+
} else {
|
|
251
|
+
console.log("Session created:", result.signature);
|
|
252
|
+
console.log("Safe address:", result.sessionKeyAddress);
|
|
253
|
+
console.log("Activation ID:", result.sessionActivation?.id);
|
|
254
|
+
}
|
|
242
255
|
console.log("User ID:", result.userId);
|
|
243
|
-
console.log("Activation ID:", result.sessionActivation?.id);
|
|
244
256
|
```
|
|
245
257
|
|
|
246
258
|
**Important**:
|
|
247
259
|
|
|
248
260
|
- `createSessionKey` requires SIWE authentication (prompts wallet signature on first call)
|
|
261
|
+
- The SDK proactively checks if the user already has an active session key (from login response) and returns early without requiring any signature if one exists
|
|
249
262
|
- The user record must have `smartWallet` and `chainId` set (automatically handled after calling `deploySafe` or `updateUserProfile`)
|
|
250
|
-
-
|
|
263
|
+
- When `alreadyActive` is `true`, `sessionKeyAddress` and `signature` are not available in the response
|
|
251
264
|
|
|
252
265
|
### 4. Deposit Funds
|
|
253
266
|
|
|
@@ -713,6 +726,24 @@ Make sure to call `connectAccount()` before calling other methods that require s
|
|
|
713
726
|
|
|
714
727
|
Check that the chain ID is in the supported chains list: Arbitrum (42161), Base (8453), or Plasma (9745).
|
|
715
728
|
|
|
729
|
+
### SIWE Authentication Issues in Browser
|
|
730
|
+
|
|
731
|
+
The SDK automatically detects browser vs Node.js environments for SIWE authentication:
|
|
732
|
+
- **Browser**: Uses `window.location.origin` for the SIWE message domain/uri to match the browser's automatic `Origin` header
|
|
733
|
+
- **Node.js**: Uses the API endpoint URL
|
|
734
|
+
|
|
735
|
+
If you encounter SIWE authentication failures in a browser, ensure:
|
|
736
|
+
1. Your frontend origin is allowed by the API's CORS configuration
|
|
737
|
+
2. You're using the correct `environment` setting (`staging` or `production`)
|
|
738
|
+
|
|
739
|
+
### Session Key Already Exists
|
|
740
|
+
|
|
741
|
+
If `createSessionKey` returns `{ alreadyActive: true }`, the user already has an active session key. This is not an error - the SDK proactively checks before attempting to create a new one.
|
|
742
|
+
|
|
743
|
+
### Data API CORS Errors
|
|
744
|
+
|
|
745
|
+
Some Data API endpoints may require server-side CORS configuration. If you see CORS errors for endpoints like `onchain-earnings`, `calculate-onchain-earnings`, or `opportunities`, contact ZyFAI support to ensure your origin is whitelisted.
|
|
746
|
+
|
|
716
747
|
## Contributing
|
|
717
748
|
|
|
718
749
|
Contributions are welcome! Please open an issue or submit a pull request.
|
package/dist/index.d.mts
CHANGED
|
@@ -21,6 +21,8 @@ interface DeploySafeResponse {
|
|
|
21
21
|
safeAddress: Address;
|
|
22
22
|
txHash: string;
|
|
23
23
|
status: "deployed" | "failed";
|
|
24
|
+
/** True if the Safe was already deployed (no new deployment needed) */
|
|
25
|
+
alreadyDeployed?: boolean;
|
|
24
26
|
}
|
|
25
27
|
/** @internal */
|
|
26
28
|
interface UpdateUserProfileRequest {
|
|
@@ -52,11 +54,17 @@ interface AddSessionKeyResponse {
|
|
|
52
54
|
}
|
|
53
55
|
interface SessionKeyResponse {
|
|
54
56
|
success: boolean;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
/** Session key address (not available when alreadyActive is true) */
|
|
58
|
+
sessionKeyAddress?: Address;
|
|
59
|
+
/** Signature (not available when alreadyActive is true) */
|
|
60
|
+
signature?: Hex;
|
|
57
61
|
sessionNonces?: bigint[];
|
|
58
62
|
userId?: string;
|
|
59
63
|
sessionActivation?: AddSessionKeyResponse;
|
|
64
|
+
/** Message when session key already exists */
|
|
65
|
+
message?: string;
|
|
66
|
+
/** True if a session key was already active for this user */
|
|
67
|
+
alreadyActive?: boolean;
|
|
60
68
|
}
|
|
61
69
|
interface SmartWalletResponse {
|
|
62
70
|
address: Address;
|
|
@@ -117,7 +125,6 @@ interface PositionSlot {
|
|
|
117
125
|
interface PositionsResponse {
|
|
118
126
|
success: boolean;
|
|
119
127
|
userAddress: string;
|
|
120
|
-
totalValueUsd: number;
|
|
121
128
|
positions: Position[];
|
|
122
129
|
}
|
|
123
130
|
interface UserDetails {
|
|
@@ -142,10 +149,18 @@ interface UserDetailsResponse {
|
|
|
142
149
|
success: boolean;
|
|
143
150
|
user: UserDetails;
|
|
144
151
|
}
|
|
152
|
+
interface TVLBreakdown {
|
|
153
|
+
chain_id: number;
|
|
154
|
+
protocol_id: string | null;
|
|
155
|
+
protocol_name: string | null;
|
|
156
|
+
pool: string | null;
|
|
157
|
+
total_balance: number;
|
|
158
|
+
}
|
|
145
159
|
interface TVLResponse {
|
|
146
160
|
success: boolean;
|
|
147
161
|
totalTvl: number;
|
|
148
|
-
byChain?: Record<
|
|
162
|
+
byChain?: Record<number, number>;
|
|
163
|
+
breakdown?: TVLBreakdown[];
|
|
149
164
|
}
|
|
150
165
|
interface VolumeResponse {
|
|
151
166
|
success: boolean;
|
|
@@ -397,6 +412,7 @@ declare class ZyfaiSDK {
|
|
|
397
412
|
private bundlerApiKey?;
|
|
398
413
|
private isAuthenticated;
|
|
399
414
|
private authenticatedUserId;
|
|
415
|
+
private hasActiveSessionKey;
|
|
400
416
|
private environment;
|
|
401
417
|
constructor(config: SDKConfig | string);
|
|
402
418
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ interface DeploySafeResponse {
|
|
|
21
21
|
safeAddress: Address;
|
|
22
22
|
txHash: string;
|
|
23
23
|
status: "deployed" | "failed";
|
|
24
|
+
/** True if the Safe was already deployed (no new deployment needed) */
|
|
25
|
+
alreadyDeployed?: boolean;
|
|
24
26
|
}
|
|
25
27
|
/** @internal */
|
|
26
28
|
interface UpdateUserProfileRequest {
|
|
@@ -52,11 +54,17 @@ interface AddSessionKeyResponse {
|
|
|
52
54
|
}
|
|
53
55
|
interface SessionKeyResponse {
|
|
54
56
|
success: boolean;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
/** Session key address (not available when alreadyActive is true) */
|
|
58
|
+
sessionKeyAddress?: Address;
|
|
59
|
+
/** Signature (not available when alreadyActive is true) */
|
|
60
|
+
signature?: Hex;
|
|
57
61
|
sessionNonces?: bigint[];
|
|
58
62
|
userId?: string;
|
|
59
63
|
sessionActivation?: AddSessionKeyResponse;
|
|
64
|
+
/** Message when session key already exists */
|
|
65
|
+
message?: string;
|
|
66
|
+
/** True if a session key was already active for this user */
|
|
67
|
+
alreadyActive?: boolean;
|
|
60
68
|
}
|
|
61
69
|
interface SmartWalletResponse {
|
|
62
70
|
address: Address;
|
|
@@ -117,7 +125,6 @@ interface PositionSlot {
|
|
|
117
125
|
interface PositionsResponse {
|
|
118
126
|
success: boolean;
|
|
119
127
|
userAddress: string;
|
|
120
|
-
totalValueUsd: number;
|
|
121
128
|
positions: Position[];
|
|
122
129
|
}
|
|
123
130
|
interface UserDetails {
|
|
@@ -142,10 +149,18 @@ interface UserDetailsResponse {
|
|
|
142
149
|
success: boolean;
|
|
143
150
|
user: UserDetails;
|
|
144
151
|
}
|
|
152
|
+
interface TVLBreakdown {
|
|
153
|
+
chain_id: number;
|
|
154
|
+
protocol_id: string | null;
|
|
155
|
+
protocol_name: string | null;
|
|
156
|
+
pool: string | null;
|
|
157
|
+
total_balance: number;
|
|
158
|
+
}
|
|
145
159
|
interface TVLResponse {
|
|
146
160
|
success: boolean;
|
|
147
161
|
totalTvl: number;
|
|
148
|
-
byChain?: Record<
|
|
162
|
+
byChain?: Record<number, number>;
|
|
163
|
+
breakdown?: TVLBreakdown[];
|
|
149
164
|
}
|
|
150
165
|
interface VolumeResponse {
|
|
151
166
|
success: boolean;
|
|
@@ -397,6 +412,7 @@ declare class ZyfaiSDK {
|
|
|
397
412
|
private bundlerApiKey?;
|
|
398
413
|
private isAuthenticated;
|
|
399
414
|
private authenticatedUserId;
|
|
415
|
+
private hasActiveSessionKey;
|
|
400
416
|
private environment;
|
|
401
417
|
constructor(config: SDKConfig | string);
|
|
402
418
|
/**
|
package/dist/index.js
CHANGED
|
@@ -87,7 +87,7 @@ var DATA_ENDPOINTS = {
|
|
|
87
87
|
// Portfolio
|
|
88
88
|
DEBANK_PORTFOLIO_MULTICHAIN: (address) => `/debank/portfolio/multichain/${address}`,
|
|
89
89
|
// Opportunities
|
|
90
|
-
OPPORTUNITIES_SAFE: (chainId) => chainId ? `/opportunities/
|
|
90
|
+
OPPORTUNITIES_SAFE: (chainId) => chainId ? `/opportunities/safe?chainId=${chainId}` : "/opportunities/safe",
|
|
91
91
|
OPPORTUNITIES_DEGEN: (chainId) => chainId ? `/opportunities/degen-strategies?chainId=${chainId}` : "/opportunities/degen-strategies",
|
|
92
92
|
// APY History
|
|
93
93
|
DAILY_APY_HISTORY_WEIGHTED: (walletAddress, days) => `/daily-apy-history/weighted/${walletAddress}${days ? `?days=${days}` : ""}`,
|
|
@@ -116,8 +116,7 @@ var HttpClient = class {
|
|
|
116
116
|
baseURL: `${endpoint}${API_VERSION}`,
|
|
117
117
|
headers: {
|
|
118
118
|
"Content-Type": "application/json",
|
|
119
|
-
"X-API-Key": this.apiKey
|
|
120
|
-
Origin: this.origin
|
|
119
|
+
"X-API-Key": this.apiKey
|
|
121
120
|
},
|
|
122
121
|
timeout: 3e4
|
|
123
122
|
});
|
|
@@ -149,7 +148,6 @@ var HttpClient = class {
|
|
|
149
148
|
this.client.interceptors.request.use(
|
|
150
149
|
(config) => {
|
|
151
150
|
config.headers["X-API-Key"] = this.apiKey;
|
|
152
|
-
config.headers["Origin"] = this.origin;
|
|
153
151
|
if (this.authToken) {
|
|
154
152
|
config.headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
155
153
|
}
|
|
@@ -218,6 +216,9 @@ var HttpClient = class {
|
|
|
218
216
|
this.dataClient.interceptors.request.use(
|
|
219
217
|
(config) => {
|
|
220
218
|
config.headers["X-API-Key"] = this.dataApiKey;
|
|
219
|
+
if (this.authToken) {
|
|
220
|
+
config.headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
221
|
+
}
|
|
221
222
|
return config;
|
|
222
223
|
},
|
|
223
224
|
(error) => Promise.reject(error)
|
|
@@ -404,7 +405,6 @@ var getBundlerUrl = (chainId, bundlerApiKey, bundlerProvider = "pimlico") => {
|
|
|
404
405
|
// src/utils/safe-account.ts
|
|
405
406
|
var import_module_sdk = require("@rhinestone/module-sdk");
|
|
406
407
|
var import_permissionless = require("permissionless");
|
|
407
|
-
var import_actions = require("permissionless/actions");
|
|
408
408
|
var import_erc7579 = require("permissionless/actions/erc7579");
|
|
409
409
|
var import_pimlico = require("permissionless/clients/pimlico");
|
|
410
410
|
var import_accounts = require("permissionless/accounts");
|
|
@@ -412,27 +412,36 @@ var import_viem3 = require("viem");
|
|
|
412
412
|
var import_account_abstraction = require("viem/account-abstraction");
|
|
413
413
|
var SAFE_7579_ADDRESS = "0x7579EE8307284F293B1927136486880611F20002";
|
|
414
414
|
var ERC7579_LAUNCHPAD_ADDRESS = "0x7579011aB74c46090561ea277Ba79D510c6C00ff";
|
|
415
|
-
var
|
|
415
|
+
var ACCOUNT_SALTS = {
|
|
416
|
+
staging: "zyfai-staging",
|
|
417
|
+
production: "zyfai-production"
|
|
418
|
+
};
|
|
416
419
|
var getSafeAccount = async (config) => {
|
|
417
420
|
const {
|
|
418
421
|
owner,
|
|
419
422
|
safeOwnerAddress,
|
|
420
423
|
publicClient,
|
|
421
|
-
|
|
424
|
+
environment = "production"
|
|
422
425
|
} = config;
|
|
426
|
+
const effectiveSalt = ACCOUNT_SALTS[environment];
|
|
423
427
|
if (!owner || !owner.account) {
|
|
424
428
|
throw new Error("Wallet not connected. Please connect your wallet first.");
|
|
425
429
|
}
|
|
426
|
-
const
|
|
430
|
+
const signerAddress = owner.account.address;
|
|
431
|
+
if (safeOwnerAddress && safeOwnerAddress.toLowerCase() !== signerAddress.toLowerCase()) {
|
|
432
|
+
throw new Error(
|
|
433
|
+
`Connected wallet address (${signerAddress}) must match the Safe owner address (${safeOwnerAddress}). Please connect with the correct wallet.`
|
|
434
|
+
);
|
|
435
|
+
}
|
|
427
436
|
const ownableValidator = (0, import_module_sdk.getOwnableValidator)({
|
|
428
|
-
owners: [
|
|
437
|
+
owners: [signerAddress],
|
|
429
438
|
threshold: 1
|
|
430
439
|
});
|
|
431
|
-
const saltHex = (0, import_viem3.fromHex)((0, import_viem3.toHex)(
|
|
440
|
+
const saltHex = (0, import_viem3.fromHex)((0, import_viem3.toHex)(effectiveSalt), "bigint");
|
|
432
441
|
const safeAccount = await (0, import_accounts.toSafeSmartAccount)({
|
|
433
442
|
client: publicClient,
|
|
434
443
|
owners: [owner.account],
|
|
435
|
-
//
|
|
444
|
+
// Pass the account object with address and signMessage capability
|
|
436
445
|
version: "1.4.1",
|
|
437
446
|
entryPoint: {
|
|
438
447
|
address: import_account_abstraction.entryPoint07Address,
|
|
@@ -565,8 +574,8 @@ var deploySafeAccount = async (config) => {
|
|
|
565
574
|
);
|
|
566
575
|
}
|
|
567
576
|
};
|
|
568
|
-
var signSessionKey = async (config, sessions) => {
|
|
569
|
-
const { owner, publicClient
|
|
577
|
+
var signSessionKey = async (config, sessions, allPublicClients) => {
|
|
578
|
+
const { owner, publicClient } = config;
|
|
570
579
|
if (!owner || !owner.account) {
|
|
571
580
|
throw new Error("Wallet not connected. Please connect your wallet first.");
|
|
572
581
|
}
|
|
@@ -575,21 +584,24 @@ var signSessionKey = async (config, sessions) => {
|
|
|
575
584
|
address: safeAccount.address,
|
|
576
585
|
type: "safe"
|
|
577
586
|
});
|
|
587
|
+
const clients = allPublicClients || [publicClient];
|
|
578
588
|
const sessionNonces = await Promise.all(
|
|
579
|
-
sessions.map(
|
|
580
|
-
|
|
581
|
-
|
|
589
|
+
sessions.map((session) => {
|
|
590
|
+
const sessionChainId = Number(session.chainId);
|
|
591
|
+
const client = clients.find((c) => c.chain?.id === sessionChainId) || publicClient;
|
|
592
|
+
return (0, import_module_sdk.getSessionNonce)({
|
|
593
|
+
client,
|
|
582
594
|
account,
|
|
583
595
|
permissionId: (0, import_module_sdk.getPermissionId)({
|
|
584
596
|
session
|
|
585
597
|
})
|
|
586
|
-
})
|
|
587
|
-
)
|
|
598
|
+
});
|
|
599
|
+
})
|
|
588
600
|
);
|
|
589
601
|
const sessionDetails = await (0, import_module_sdk.getEnableSessionDetails)({
|
|
590
602
|
sessions,
|
|
591
603
|
account,
|
|
592
|
-
clients
|
|
604
|
+
clients,
|
|
593
605
|
permitGenericPolicy: true,
|
|
594
606
|
sessionNonces
|
|
595
607
|
});
|
|
@@ -614,6 +626,8 @@ var ZyfaiSDK = class {
|
|
|
614
626
|
this.walletClient = null;
|
|
615
627
|
this.isAuthenticated = false;
|
|
616
628
|
this.authenticatedUserId = null;
|
|
629
|
+
// Stored from login response
|
|
630
|
+
this.hasActiveSessionKey = false;
|
|
617
631
|
const sdkConfig = typeof config === "string" ? { apiKey: config } : config;
|
|
618
632
|
const { apiKey, dataApiKey, environment, bundlerApiKey } = sdkConfig;
|
|
619
633
|
if (!apiKey) {
|
|
@@ -636,11 +650,19 @@ var ZyfaiSDK = class {
|
|
|
636
650
|
return;
|
|
637
651
|
}
|
|
638
652
|
const walletClient = this.getWalletClient();
|
|
639
|
-
const userAddress = walletClient.account.address;
|
|
653
|
+
const userAddress = (0, import_viem4.getAddress)(walletClient.account.address);
|
|
640
654
|
const chainId = walletClient.chain?.id || 8453;
|
|
641
655
|
const challengeResponse = await this.httpClient.post(ENDPOINTS.AUTH_CHALLENGE, {});
|
|
642
|
-
|
|
643
|
-
|
|
656
|
+
let uri;
|
|
657
|
+
let domain;
|
|
658
|
+
const globalWindow = typeof globalThis !== "undefined" ? globalThis.window : void 0;
|
|
659
|
+
if (globalWindow?.location?.origin) {
|
|
660
|
+
uri = globalWindow.location.origin;
|
|
661
|
+
domain = globalWindow.location.host;
|
|
662
|
+
} else {
|
|
663
|
+
uri = API_ENDPOINTS[this.environment];
|
|
664
|
+
domain = API_ENDPOINTS[this.environment].split("//")[1];
|
|
665
|
+
}
|
|
644
666
|
const messageObj = new import_siwe.SiweMessage({
|
|
645
667
|
address: userAddress,
|
|
646
668
|
chainId,
|
|
@@ -661,11 +683,6 @@ var ZyfaiSDK = class {
|
|
|
661
683
|
{
|
|
662
684
|
message: messageObj,
|
|
663
685
|
signature
|
|
664
|
-
},
|
|
665
|
-
{
|
|
666
|
-
headers: {
|
|
667
|
-
Origin: uri
|
|
668
|
-
}
|
|
669
686
|
}
|
|
670
687
|
);
|
|
671
688
|
const authToken = loginResponse.accessToken || loginResponse.token;
|
|
@@ -674,6 +691,7 @@ var ZyfaiSDK = class {
|
|
|
674
691
|
}
|
|
675
692
|
this.httpClient.setAuthToken(authToken);
|
|
676
693
|
this.authenticatedUserId = loginResponse.userId || null;
|
|
694
|
+
this.hasActiveSessionKey = loginResponse.hasActiveSessionKey || false;
|
|
677
695
|
this.isAuthenticated = true;
|
|
678
696
|
} catch (error) {
|
|
679
697
|
throw new Error(
|
|
@@ -823,7 +841,8 @@ var ZyfaiSDK = class {
|
|
|
823
841
|
owner: walletClient,
|
|
824
842
|
safeOwnerAddress: userAddress,
|
|
825
843
|
chain: chainConfig.chain,
|
|
826
|
-
publicClient: chainConfig.publicClient
|
|
844
|
+
publicClient: chainConfig.publicClient,
|
|
845
|
+
environment: this.environment
|
|
827
846
|
});
|
|
828
847
|
const isDeployed = await isSafeDeployed(
|
|
829
848
|
safeAddress,
|
|
@@ -856,6 +875,26 @@ var ZyfaiSDK = class {
|
|
|
856
875
|
}
|
|
857
876
|
const walletClient = this.getWalletClient(chainId);
|
|
858
877
|
const chainConfig = getChainConfig(chainId);
|
|
878
|
+
const safeAddress = await getDeterministicSafeAddress({
|
|
879
|
+
owner: walletClient,
|
|
880
|
+
safeOwnerAddress: userAddress,
|
|
881
|
+
chain: chainConfig.chain,
|
|
882
|
+
publicClient: chainConfig.publicClient,
|
|
883
|
+
environment: this.environment
|
|
884
|
+
});
|
|
885
|
+
const alreadyDeployed = await isSafeDeployed(
|
|
886
|
+
safeAddress,
|
|
887
|
+
chainConfig.publicClient
|
|
888
|
+
);
|
|
889
|
+
if (alreadyDeployed) {
|
|
890
|
+
return {
|
|
891
|
+
success: true,
|
|
892
|
+
safeAddress,
|
|
893
|
+
txHash: "0x0",
|
|
894
|
+
status: "deployed",
|
|
895
|
+
alreadyDeployed: true
|
|
896
|
+
};
|
|
897
|
+
}
|
|
859
898
|
const accountType = await getAccountType(
|
|
860
899
|
userAddress,
|
|
861
900
|
chainConfig.publicClient
|
|
@@ -871,7 +910,8 @@ var ZyfaiSDK = class {
|
|
|
871
910
|
safeOwnerAddress: userAddress,
|
|
872
911
|
chain: chainConfig.chain,
|
|
873
912
|
publicClient: chainConfig.publicClient,
|
|
874
|
-
bundlerUrl
|
|
913
|
+
bundlerUrl,
|
|
914
|
+
environment: this.environment
|
|
875
915
|
});
|
|
876
916
|
try {
|
|
877
917
|
await this.updateUserProfile({
|
|
@@ -918,14 +958,14 @@ var ZyfaiSDK = class {
|
|
|
918
958
|
"User ID not available. Please ensure authentication completed successfully."
|
|
919
959
|
);
|
|
920
960
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
}
|
|
961
|
+
if (this.hasActiveSessionKey) {
|
|
962
|
+
return {
|
|
963
|
+
success: true,
|
|
964
|
+
userId: this.authenticatedUserId,
|
|
965
|
+
message: "Session key already exists and is active",
|
|
966
|
+
alreadyActive: true
|
|
967
|
+
};
|
|
968
|
+
}
|
|
929
969
|
const sessionConfig = await this.httpClient.get(
|
|
930
970
|
ENDPOINTS.SESSION_KEYS_CONFIG
|
|
931
971
|
);
|
|
@@ -941,10 +981,14 @@ var ZyfaiSDK = class {
|
|
|
941
981
|
chainId,
|
|
942
982
|
sessions
|
|
943
983
|
);
|
|
984
|
+
if (!signatureResult.signature) {
|
|
985
|
+
throw new Error("Failed to obtain session key signature");
|
|
986
|
+
}
|
|
944
987
|
const activation = await this.activateSessionKey(
|
|
945
988
|
signatureResult.signature,
|
|
946
989
|
signatureResult.sessionNonces
|
|
947
990
|
);
|
|
991
|
+
this.hasActiveSessionKey = true;
|
|
948
992
|
return {
|
|
949
993
|
...signatureResult,
|
|
950
994
|
userId: this.authenticatedUserId,
|
|
@@ -982,20 +1026,27 @@ var ZyfaiSDK = class {
|
|
|
982
1026
|
`Invalid account type for ${userAddress}. Must be an EOA.`
|
|
983
1027
|
);
|
|
984
1028
|
}
|
|
1029
|
+
const sessionChainIds = [
|
|
1030
|
+
...new Set(sessions.map((s) => Number(s.chainId)))
|
|
1031
|
+
];
|
|
1032
|
+
const allPublicClients = sessionChainIds.filter(isSupportedChain).map((id) => getChainConfig(id).publicClient);
|
|
985
1033
|
const { signature, sessionNonces } = await signSessionKey(
|
|
986
1034
|
{
|
|
987
1035
|
owner: walletClient,
|
|
988
1036
|
safeOwnerAddress: userAddress,
|
|
989
1037
|
chain: chainConfig.chain,
|
|
990
|
-
publicClient: chainConfig.publicClient
|
|
1038
|
+
publicClient: chainConfig.publicClient,
|
|
1039
|
+
environment: this.environment
|
|
991
1040
|
},
|
|
992
|
-
sessions
|
|
1041
|
+
sessions,
|
|
1042
|
+
allPublicClients
|
|
993
1043
|
);
|
|
994
1044
|
const safeAddress = await getDeterministicSafeAddress({
|
|
995
1045
|
owner: walletClient,
|
|
996
1046
|
safeOwnerAddress: userAddress,
|
|
997
1047
|
chain: chainConfig.chain,
|
|
998
|
-
publicClient: chainConfig.publicClient
|
|
1048
|
+
publicClient: chainConfig.publicClient,
|
|
1049
|
+
environment: this.environment
|
|
999
1050
|
});
|
|
1000
1051
|
return {
|
|
1001
1052
|
success: true,
|
|
@@ -1081,7 +1132,8 @@ var ZyfaiSDK = class {
|
|
|
1081
1132
|
owner: walletClient,
|
|
1082
1133
|
safeOwnerAddress: userAddress,
|
|
1083
1134
|
chain: chainConfig.chain,
|
|
1084
|
-
publicClient: chainConfig.publicClient
|
|
1135
|
+
publicClient: chainConfig.publicClient,
|
|
1136
|
+
environment: this.environment
|
|
1085
1137
|
});
|
|
1086
1138
|
const isDeployed = await isSafeDeployed(
|
|
1087
1139
|
safeAddress,
|
|
@@ -1156,7 +1208,8 @@ var ZyfaiSDK = class {
|
|
|
1156
1208
|
owner: walletClient,
|
|
1157
1209
|
safeOwnerAddress: userAddress,
|
|
1158
1210
|
chain: chainConfig.chain,
|
|
1159
|
-
publicClient: chainConfig.publicClient
|
|
1211
|
+
publicClient: chainConfig.publicClient,
|
|
1212
|
+
environment: this.environment
|
|
1160
1213
|
});
|
|
1161
1214
|
const isDeployed = await isSafeDeployed(
|
|
1162
1215
|
safeAddress,
|
|
@@ -1256,7 +1309,8 @@ var ZyfaiSDK = class {
|
|
|
1256
1309
|
owner: walletClient,
|
|
1257
1310
|
safeOwnerAddress: userAddress,
|
|
1258
1311
|
chain: chainConfig.chain,
|
|
1259
|
-
publicClient: chainConfig.publicClient
|
|
1312
|
+
publicClient: chainConfig.publicClient,
|
|
1313
|
+
environment: this.environment
|
|
1260
1314
|
});
|
|
1261
1315
|
const response = await this.httpClient.get(
|
|
1262
1316
|
ENDPOINTS.DATA_POSITION(safeAddress)
|
|
@@ -1264,8 +1318,6 @@ var ZyfaiSDK = class {
|
|
|
1264
1318
|
return {
|
|
1265
1319
|
success: true,
|
|
1266
1320
|
userAddress,
|
|
1267
|
-
totalValueUsd: 0,
|
|
1268
|
-
// API doesn't return this yet
|
|
1269
1321
|
positions: response ? [response] : []
|
|
1270
1322
|
};
|
|
1271
1323
|
} catch (error) {
|
|
@@ -1337,10 +1389,18 @@ var ZyfaiSDK = class {
|
|
|
1337
1389
|
async getTVL() {
|
|
1338
1390
|
try {
|
|
1339
1391
|
const response = await this.httpClient.get(ENDPOINTS.DATA_TVL);
|
|
1392
|
+
const byChain = {};
|
|
1393
|
+
for (const key of Object.keys(response)) {
|
|
1394
|
+
const numKey = parseInt(key, 10);
|
|
1395
|
+
if (!isNaN(numKey) && typeof response[key] === "number") {
|
|
1396
|
+
byChain[numKey] = response[key];
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1340
1399
|
return {
|
|
1341
1400
|
success: true,
|
|
1342
|
-
totalTvl: response.totalTvl || response.tvl || 0,
|
|
1343
|
-
byChain
|
|
1401
|
+
totalTvl: response.total || response.totalTvl || response.tvl || 0,
|
|
1402
|
+
byChain,
|
|
1403
|
+
breakdown: response.breakdown
|
|
1344
1404
|
};
|
|
1345
1405
|
} catch (error) {
|
|
1346
1406
|
throw new Error(`Failed to get TVL: ${error.message}`);
|
package/dist/index.mjs
CHANGED
|
@@ -48,7 +48,7 @@ var DATA_ENDPOINTS = {
|
|
|
48
48
|
// Portfolio
|
|
49
49
|
DEBANK_PORTFOLIO_MULTICHAIN: (address) => `/debank/portfolio/multichain/${address}`,
|
|
50
50
|
// Opportunities
|
|
51
|
-
OPPORTUNITIES_SAFE: (chainId) => chainId ? `/opportunities/
|
|
51
|
+
OPPORTUNITIES_SAFE: (chainId) => chainId ? `/opportunities/safe?chainId=${chainId}` : "/opportunities/safe",
|
|
52
52
|
OPPORTUNITIES_DEGEN: (chainId) => chainId ? `/opportunities/degen-strategies?chainId=${chainId}` : "/opportunities/degen-strategies",
|
|
53
53
|
// APY History
|
|
54
54
|
DAILY_APY_HISTORY_WEIGHTED: (walletAddress, days) => `/daily-apy-history/weighted/${walletAddress}${days ? `?days=${days}` : ""}`,
|
|
@@ -77,8 +77,7 @@ var HttpClient = class {
|
|
|
77
77
|
baseURL: `${endpoint}${API_VERSION}`,
|
|
78
78
|
headers: {
|
|
79
79
|
"Content-Type": "application/json",
|
|
80
|
-
"X-API-Key": this.apiKey
|
|
81
|
-
Origin: this.origin
|
|
80
|
+
"X-API-Key": this.apiKey
|
|
82
81
|
},
|
|
83
82
|
timeout: 3e4
|
|
84
83
|
});
|
|
@@ -110,7 +109,6 @@ var HttpClient = class {
|
|
|
110
109
|
this.client.interceptors.request.use(
|
|
111
110
|
(config) => {
|
|
112
111
|
config.headers["X-API-Key"] = this.apiKey;
|
|
113
|
-
config.headers["Origin"] = this.origin;
|
|
114
112
|
if (this.authToken) {
|
|
115
113
|
config.headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
116
114
|
}
|
|
@@ -179,6 +177,9 @@ var HttpClient = class {
|
|
|
179
177
|
this.dataClient.interceptors.request.use(
|
|
180
178
|
(config) => {
|
|
181
179
|
config.headers["X-API-Key"] = this.dataApiKey;
|
|
180
|
+
if (this.authToken) {
|
|
181
|
+
config.headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
182
|
+
}
|
|
182
183
|
return config;
|
|
183
184
|
},
|
|
184
185
|
(error) => Promise.reject(error)
|
|
@@ -293,7 +294,8 @@ import { privateKeyToAccount } from "viem/accounts";
|
|
|
293
294
|
import {
|
|
294
295
|
createWalletClient,
|
|
295
296
|
custom,
|
|
296
|
-
http as http3
|
|
297
|
+
http as http3,
|
|
298
|
+
getAddress
|
|
297
299
|
} from "viem";
|
|
298
300
|
|
|
299
301
|
// src/config/chains.ts
|
|
@@ -376,43 +378,49 @@ import {
|
|
|
376
378
|
getSessionNonce
|
|
377
379
|
} from "@rhinestone/module-sdk";
|
|
378
380
|
import { createSmartAccountClient } from "permissionless";
|
|
379
|
-
import { getAccountNonce } from "permissionless/actions";
|
|
380
381
|
import { erc7579Actions } from "permissionless/actions/erc7579";
|
|
381
382
|
import { createPimlicoClient } from "permissionless/clients/pimlico";
|
|
382
383
|
import { toSafeSmartAccount } from "permissionless/accounts";
|
|
383
384
|
import {
|
|
384
385
|
http as http2,
|
|
385
386
|
fromHex,
|
|
386
|
-
pad,
|
|
387
387
|
toHex
|
|
388
388
|
} from "viem";
|
|
389
389
|
import {
|
|
390
|
-
entryPoint07Address
|
|
391
|
-
getUserOperationHash
|
|
390
|
+
entryPoint07Address
|
|
392
391
|
} from "viem/account-abstraction";
|
|
393
392
|
var SAFE_7579_ADDRESS = "0x7579EE8307284F293B1927136486880611F20002";
|
|
394
393
|
var ERC7579_LAUNCHPAD_ADDRESS = "0x7579011aB74c46090561ea277Ba79D510c6C00ff";
|
|
395
|
-
var
|
|
394
|
+
var ACCOUNT_SALTS = {
|
|
395
|
+
staging: "zyfai-staging",
|
|
396
|
+
production: "zyfai-production"
|
|
397
|
+
};
|
|
396
398
|
var getSafeAccount = async (config) => {
|
|
397
399
|
const {
|
|
398
400
|
owner,
|
|
399
401
|
safeOwnerAddress,
|
|
400
402
|
publicClient,
|
|
401
|
-
|
|
403
|
+
environment = "production"
|
|
402
404
|
} = config;
|
|
405
|
+
const effectiveSalt = ACCOUNT_SALTS[environment];
|
|
403
406
|
if (!owner || !owner.account) {
|
|
404
407
|
throw new Error("Wallet not connected. Please connect your wallet first.");
|
|
405
408
|
}
|
|
406
|
-
const
|
|
409
|
+
const signerAddress = owner.account.address;
|
|
410
|
+
if (safeOwnerAddress && safeOwnerAddress.toLowerCase() !== signerAddress.toLowerCase()) {
|
|
411
|
+
throw new Error(
|
|
412
|
+
`Connected wallet address (${signerAddress}) must match the Safe owner address (${safeOwnerAddress}). Please connect with the correct wallet.`
|
|
413
|
+
);
|
|
414
|
+
}
|
|
407
415
|
const ownableValidator = getOwnableValidator({
|
|
408
|
-
owners: [
|
|
416
|
+
owners: [signerAddress],
|
|
409
417
|
threshold: 1
|
|
410
418
|
});
|
|
411
|
-
const saltHex = fromHex(toHex(
|
|
419
|
+
const saltHex = fromHex(toHex(effectiveSalt), "bigint");
|
|
412
420
|
const safeAccount = await toSafeSmartAccount({
|
|
413
421
|
client: publicClient,
|
|
414
422
|
owners: [owner.account],
|
|
415
|
-
//
|
|
423
|
+
// Pass the account object with address and signMessage capability
|
|
416
424
|
version: "1.4.1",
|
|
417
425
|
entryPoint: {
|
|
418
426
|
address: entryPoint07Address,
|
|
@@ -545,8 +553,8 @@ var deploySafeAccount = async (config) => {
|
|
|
545
553
|
);
|
|
546
554
|
}
|
|
547
555
|
};
|
|
548
|
-
var signSessionKey = async (config, sessions) => {
|
|
549
|
-
const { owner, publicClient
|
|
556
|
+
var signSessionKey = async (config, sessions, allPublicClients) => {
|
|
557
|
+
const { owner, publicClient } = config;
|
|
550
558
|
if (!owner || !owner.account) {
|
|
551
559
|
throw new Error("Wallet not connected. Please connect your wallet first.");
|
|
552
560
|
}
|
|
@@ -555,21 +563,24 @@ var signSessionKey = async (config, sessions) => {
|
|
|
555
563
|
address: safeAccount.address,
|
|
556
564
|
type: "safe"
|
|
557
565
|
});
|
|
566
|
+
const clients = allPublicClients || [publicClient];
|
|
558
567
|
const sessionNonces = await Promise.all(
|
|
559
|
-
sessions.map(
|
|
560
|
-
(session)
|
|
561
|
-
|
|
568
|
+
sessions.map((session) => {
|
|
569
|
+
const sessionChainId = Number(session.chainId);
|
|
570
|
+
const client = clients.find((c) => c.chain?.id === sessionChainId) || publicClient;
|
|
571
|
+
return getSessionNonce({
|
|
572
|
+
client,
|
|
562
573
|
account,
|
|
563
574
|
permissionId: getPermissionId({
|
|
564
575
|
session
|
|
565
576
|
})
|
|
566
|
-
})
|
|
567
|
-
)
|
|
577
|
+
});
|
|
578
|
+
})
|
|
568
579
|
);
|
|
569
580
|
const sessionDetails = await getEnableSessionDetails({
|
|
570
581
|
sessions,
|
|
571
582
|
account,
|
|
572
|
-
clients
|
|
583
|
+
clients,
|
|
573
584
|
permitGenericPolicy: true,
|
|
574
585
|
sessionNonces
|
|
575
586
|
});
|
|
@@ -594,6 +605,8 @@ var ZyfaiSDK = class {
|
|
|
594
605
|
this.walletClient = null;
|
|
595
606
|
this.isAuthenticated = false;
|
|
596
607
|
this.authenticatedUserId = null;
|
|
608
|
+
// Stored from login response
|
|
609
|
+
this.hasActiveSessionKey = false;
|
|
597
610
|
const sdkConfig = typeof config === "string" ? { apiKey: config } : config;
|
|
598
611
|
const { apiKey, dataApiKey, environment, bundlerApiKey } = sdkConfig;
|
|
599
612
|
if (!apiKey) {
|
|
@@ -616,11 +629,19 @@ var ZyfaiSDK = class {
|
|
|
616
629
|
return;
|
|
617
630
|
}
|
|
618
631
|
const walletClient = this.getWalletClient();
|
|
619
|
-
const userAddress = walletClient.account.address;
|
|
632
|
+
const userAddress = getAddress(walletClient.account.address);
|
|
620
633
|
const chainId = walletClient.chain?.id || 8453;
|
|
621
634
|
const challengeResponse = await this.httpClient.post(ENDPOINTS.AUTH_CHALLENGE, {});
|
|
622
|
-
|
|
623
|
-
|
|
635
|
+
let uri;
|
|
636
|
+
let domain;
|
|
637
|
+
const globalWindow = typeof globalThis !== "undefined" ? globalThis.window : void 0;
|
|
638
|
+
if (globalWindow?.location?.origin) {
|
|
639
|
+
uri = globalWindow.location.origin;
|
|
640
|
+
domain = globalWindow.location.host;
|
|
641
|
+
} else {
|
|
642
|
+
uri = API_ENDPOINTS[this.environment];
|
|
643
|
+
domain = API_ENDPOINTS[this.environment].split("//")[1];
|
|
644
|
+
}
|
|
624
645
|
const messageObj = new SiweMessage({
|
|
625
646
|
address: userAddress,
|
|
626
647
|
chainId,
|
|
@@ -641,11 +662,6 @@ var ZyfaiSDK = class {
|
|
|
641
662
|
{
|
|
642
663
|
message: messageObj,
|
|
643
664
|
signature
|
|
644
|
-
},
|
|
645
|
-
{
|
|
646
|
-
headers: {
|
|
647
|
-
Origin: uri
|
|
648
|
-
}
|
|
649
665
|
}
|
|
650
666
|
);
|
|
651
667
|
const authToken = loginResponse.accessToken || loginResponse.token;
|
|
@@ -654,6 +670,7 @@ var ZyfaiSDK = class {
|
|
|
654
670
|
}
|
|
655
671
|
this.httpClient.setAuthToken(authToken);
|
|
656
672
|
this.authenticatedUserId = loginResponse.userId || null;
|
|
673
|
+
this.hasActiveSessionKey = loginResponse.hasActiveSessionKey || false;
|
|
657
674
|
this.isAuthenticated = true;
|
|
658
675
|
} catch (error) {
|
|
659
676
|
throw new Error(
|
|
@@ -803,7 +820,8 @@ var ZyfaiSDK = class {
|
|
|
803
820
|
owner: walletClient,
|
|
804
821
|
safeOwnerAddress: userAddress,
|
|
805
822
|
chain: chainConfig.chain,
|
|
806
|
-
publicClient: chainConfig.publicClient
|
|
823
|
+
publicClient: chainConfig.publicClient,
|
|
824
|
+
environment: this.environment
|
|
807
825
|
});
|
|
808
826
|
const isDeployed = await isSafeDeployed(
|
|
809
827
|
safeAddress,
|
|
@@ -836,6 +854,26 @@ var ZyfaiSDK = class {
|
|
|
836
854
|
}
|
|
837
855
|
const walletClient = this.getWalletClient(chainId);
|
|
838
856
|
const chainConfig = getChainConfig(chainId);
|
|
857
|
+
const safeAddress = await getDeterministicSafeAddress({
|
|
858
|
+
owner: walletClient,
|
|
859
|
+
safeOwnerAddress: userAddress,
|
|
860
|
+
chain: chainConfig.chain,
|
|
861
|
+
publicClient: chainConfig.publicClient,
|
|
862
|
+
environment: this.environment
|
|
863
|
+
});
|
|
864
|
+
const alreadyDeployed = await isSafeDeployed(
|
|
865
|
+
safeAddress,
|
|
866
|
+
chainConfig.publicClient
|
|
867
|
+
);
|
|
868
|
+
if (alreadyDeployed) {
|
|
869
|
+
return {
|
|
870
|
+
success: true,
|
|
871
|
+
safeAddress,
|
|
872
|
+
txHash: "0x0",
|
|
873
|
+
status: "deployed",
|
|
874
|
+
alreadyDeployed: true
|
|
875
|
+
};
|
|
876
|
+
}
|
|
839
877
|
const accountType = await getAccountType(
|
|
840
878
|
userAddress,
|
|
841
879
|
chainConfig.publicClient
|
|
@@ -851,7 +889,8 @@ var ZyfaiSDK = class {
|
|
|
851
889
|
safeOwnerAddress: userAddress,
|
|
852
890
|
chain: chainConfig.chain,
|
|
853
891
|
publicClient: chainConfig.publicClient,
|
|
854
|
-
bundlerUrl
|
|
892
|
+
bundlerUrl,
|
|
893
|
+
environment: this.environment
|
|
855
894
|
});
|
|
856
895
|
try {
|
|
857
896
|
await this.updateUserProfile({
|
|
@@ -898,14 +937,14 @@ var ZyfaiSDK = class {
|
|
|
898
937
|
"User ID not available. Please ensure authentication completed successfully."
|
|
899
938
|
);
|
|
900
939
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
}
|
|
940
|
+
if (this.hasActiveSessionKey) {
|
|
941
|
+
return {
|
|
942
|
+
success: true,
|
|
943
|
+
userId: this.authenticatedUserId,
|
|
944
|
+
message: "Session key already exists and is active",
|
|
945
|
+
alreadyActive: true
|
|
946
|
+
};
|
|
947
|
+
}
|
|
909
948
|
const sessionConfig = await this.httpClient.get(
|
|
910
949
|
ENDPOINTS.SESSION_KEYS_CONFIG
|
|
911
950
|
);
|
|
@@ -921,10 +960,14 @@ var ZyfaiSDK = class {
|
|
|
921
960
|
chainId,
|
|
922
961
|
sessions
|
|
923
962
|
);
|
|
963
|
+
if (!signatureResult.signature) {
|
|
964
|
+
throw new Error("Failed to obtain session key signature");
|
|
965
|
+
}
|
|
924
966
|
const activation = await this.activateSessionKey(
|
|
925
967
|
signatureResult.signature,
|
|
926
968
|
signatureResult.sessionNonces
|
|
927
969
|
);
|
|
970
|
+
this.hasActiveSessionKey = true;
|
|
928
971
|
return {
|
|
929
972
|
...signatureResult,
|
|
930
973
|
userId: this.authenticatedUserId,
|
|
@@ -962,20 +1005,27 @@ var ZyfaiSDK = class {
|
|
|
962
1005
|
`Invalid account type for ${userAddress}. Must be an EOA.`
|
|
963
1006
|
);
|
|
964
1007
|
}
|
|
1008
|
+
const sessionChainIds = [
|
|
1009
|
+
...new Set(sessions.map((s) => Number(s.chainId)))
|
|
1010
|
+
];
|
|
1011
|
+
const allPublicClients = sessionChainIds.filter(isSupportedChain).map((id) => getChainConfig(id).publicClient);
|
|
965
1012
|
const { signature, sessionNonces } = await signSessionKey(
|
|
966
1013
|
{
|
|
967
1014
|
owner: walletClient,
|
|
968
1015
|
safeOwnerAddress: userAddress,
|
|
969
1016
|
chain: chainConfig.chain,
|
|
970
|
-
publicClient: chainConfig.publicClient
|
|
1017
|
+
publicClient: chainConfig.publicClient,
|
|
1018
|
+
environment: this.environment
|
|
971
1019
|
},
|
|
972
|
-
sessions
|
|
1020
|
+
sessions,
|
|
1021
|
+
allPublicClients
|
|
973
1022
|
);
|
|
974
1023
|
const safeAddress = await getDeterministicSafeAddress({
|
|
975
1024
|
owner: walletClient,
|
|
976
1025
|
safeOwnerAddress: userAddress,
|
|
977
1026
|
chain: chainConfig.chain,
|
|
978
|
-
publicClient: chainConfig.publicClient
|
|
1027
|
+
publicClient: chainConfig.publicClient,
|
|
1028
|
+
environment: this.environment
|
|
979
1029
|
});
|
|
980
1030
|
return {
|
|
981
1031
|
success: true,
|
|
@@ -1061,7 +1111,8 @@ var ZyfaiSDK = class {
|
|
|
1061
1111
|
owner: walletClient,
|
|
1062
1112
|
safeOwnerAddress: userAddress,
|
|
1063
1113
|
chain: chainConfig.chain,
|
|
1064
|
-
publicClient: chainConfig.publicClient
|
|
1114
|
+
publicClient: chainConfig.publicClient,
|
|
1115
|
+
environment: this.environment
|
|
1065
1116
|
});
|
|
1066
1117
|
const isDeployed = await isSafeDeployed(
|
|
1067
1118
|
safeAddress,
|
|
@@ -1136,7 +1187,8 @@ var ZyfaiSDK = class {
|
|
|
1136
1187
|
owner: walletClient,
|
|
1137
1188
|
safeOwnerAddress: userAddress,
|
|
1138
1189
|
chain: chainConfig.chain,
|
|
1139
|
-
publicClient: chainConfig.publicClient
|
|
1190
|
+
publicClient: chainConfig.publicClient,
|
|
1191
|
+
environment: this.environment
|
|
1140
1192
|
});
|
|
1141
1193
|
const isDeployed = await isSafeDeployed(
|
|
1142
1194
|
safeAddress,
|
|
@@ -1236,7 +1288,8 @@ var ZyfaiSDK = class {
|
|
|
1236
1288
|
owner: walletClient,
|
|
1237
1289
|
safeOwnerAddress: userAddress,
|
|
1238
1290
|
chain: chainConfig.chain,
|
|
1239
|
-
publicClient: chainConfig.publicClient
|
|
1291
|
+
publicClient: chainConfig.publicClient,
|
|
1292
|
+
environment: this.environment
|
|
1240
1293
|
});
|
|
1241
1294
|
const response = await this.httpClient.get(
|
|
1242
1295
|
ENDPOINTS.DATA_POSITION(safeAddress)
|
|
@@ -1244,8 +1297,6 @@ var ZyfaiSDK = class {
|
|
|
1244
1297
|
return {
|
|
1245
1298
|
success: true,
|
|
1246
1299
|
userAddress,
|
|
1247
|
-
totalValueUsd: 0,
|
|
1248
|
-
// API doesn't return this yet
|
|
1249
1300
|
positions: response ? [response] : []
|
|
1250
1301
|
};
|
|
1251
1302
|
} catch (error) {
|
|
@@ -1317,10 +1368,18 @@ var ZyfaiSDK = class {
|
|
|
1317
1368
|
async getTVL() {
|
|
1318
1369
|
try {
|
|
1319
1370
|
const response = await this.httpClient.get(ENDPOINTS.DATA_TVL);
|
|
1371
|
+
const byChain = {};
|
|
1372
|
+
for (const key of Object.keys(response)) {
|
|
1373
|
+
const numKey = parseInt(key, 10);
|
|
1374
|
+
if (!isNaN(numKey) && typeof response[key] === "number") {
|
|
1375
|
+
byChain[numKey] = response[key];
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1320
1378
|
return {
|
|
1321
1379
|
success: true,
|
|
1322
|
-
totalTvl: response.totalTvl || response.tvl || 0,
|
|
1323
|
-
byChain
|
|
1380
|
+
totalTvl: response.total || response.totalTvl || response.tvl || 0,
|
|
1381
|
+
byChain,
|
|
1382
|
+
breakdown: response.breakdown
|
|
1324
1383
|
};
|
|
1325
1384
|
} catch (error) {
|
|
1326
1385
|
throw new Error(`Failed to get TVL: ${error.message}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zyfai/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "TypeScript SDK for ZyFAI Yield Optimization Engine - Deploy Safe smart wallets, manage session keys, and interact with DeFi protocols",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|