@zyfai/sdk 0.1.26 → 0.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -26
- package/dist/index.d.mts +0 -4
- package/dist/index.d.ts +0 -4
- package/dist/index.js +45 -220
- package/dist/index.mjs +50 -233
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,8 +28,6 @@ pnpm add @zyfai/sdk viem
|
|
|
28
28
|
## Prerequisites
|
|
29
29
|
|
|
30
30
|
1. **API Key**: Single API key for both Execution API (Safe deployment, transactions, session keys) and Data API (earnings, opportunities, analytics)
|
|
31
|
-
2. **Bundler API Key**: Required for Safe deployment. Get it from:
|
|
32
|
-
- [Pimlico](https://www.pimlico.io/) (Recommended)
|
|
33
31
|
|
|
34
32
|
**Get your API key from [ZyFAI Dashboard](https://sdk.zyf.ai)**
|
|
35
33
|
|
|
@@ -44,8 +42,7 @@ import { ZyfaiSDK } from "@zyfai/sdk";
|
|
|
44
42
|
|
|
45
43
|
// Option 1: Full configuration object
|
|
46
44
|
const sdk = new ZyfaiSDK({
|
|
47
|
-
apiKey: "your-api-key",
|
|
48
|
-
bundlerApiKey: "your-bundler-api-key", // Required for Safe deployment
|
|
45
|
+
apiKey: "your-api-key",
|
|
49
46
|
environment: "production", // or 'staging' (default: 'production')
|
|
50
47
|
});
|
|
51
48
|
|
|
@@ -55,11 +52,10 @@ const sdk = new ZyfaiSDK("your-api-key");
|
|
|
55
52
|
|
|
56
53
|
**Configuration Options:**
|
|
57
54
|
|
|
58
|
-
| Option
|
|
59
|
-
|
|
|
60
|
-
| `apiKey`
|
|
61
|
-
| `
|
|
62
|
-
| `environment` | No | `"production"` or `"staging"` (default: `"production"`) |
|
|
55
|
+
| Option | Required | Description |
|
|
56
|
+
| ------------- | -------- | ---------------------------------------------------------------------------------------------------- |
|
|
57
|
+
| `apiKey` | Yes | API key for both Execution API and Data API (Safe deployment, transactions, session keys, analytics) |
|
|
58
|
+
| `environment` | No | `"production"` or `"staging"` (default: `"production"`) |
|
|
63
59
|
|
|
64
60
|
### Connect Account
|
|
65
61
|
|
|
@@ -124,16 +120,11 @@ const result = await sdk.deploySafe(userAddress, 8453);
|
|
|
124
120
|
if (result.success) {
|
|
125
121
|
console.log("Safe Address:", result.safeAddress);
|
|
126
122
|
console.log("Status:", result.status); // 'deployed' | 'failed'
|
|
127
|
-
|
|
128
|
-
if (result.alreadyDeployed) {
|
|
129
|
-
console.log("Safe was already deployed - no action needed");
|
|
130
|
-
} else {
|
|
131
|
-
console.log("Transaction Hash:", result.txHash);
|
|
132
|
-
}
|
|
123
|
+
console.log("Transaction Hash:", result.txHash);
|
|
133
124
|
}
|
|
134
125
|
```
|
|
135
126
|
|
|
136
|
-
**Note:** The SDK proactively checks if the Safe is already deployed before attempting deployment. If it exists, it returns
|
|
127
|
+
**Note:** The SDK proactively checks if the Safe is already deployed before attempting deployment. If it exists, it returns early without making any transactions.
|
|
137
128
|
|
|
138
129
|
### 2. Multi-Chain Support
|
|
139
130
|
|
|
@@ -178,8 +169,7 @@ new ZyfaiSDK(config: SDKConfig | string)
|
|
|
178
169
|
- If an object is provided:
|
|
179
170
|
- `apiKey` (string): Your ZyFAI API key (required)
|
|
180
171
|
- `environment` ('production' | 'staging', optional): API environment (default: 'production')
|
|
181
|
-
- `
|
|
182
|
-
- `rpcUrls` (object, optional): Custom RPC URLs per chain to avoid rate limiting
|
|
172
|
+
- `rpcUrls` (object, optional): Custom RPC URLs per chain to avoid rate limiting (optional, only needed for local operations like `getSmartWalletAddress`)
|
|
183
173
|
- `8453` (string, optional): Base Mainnet RPC URL
|
|
184
174
|
- `42161` (string, optional): Arbitrum One RPC URL
|
|
185
175
|
- `9745` (string, optional): Plasma Mainnet RPC URL
|
|
@@ -193,14 +183,12 @@ const sdk = new ZyfaiSDK("your-api-key");
|
|
|
193
183
|
// Option 2: Object initialization (full configuration)
|
|
194
184
|
const sdk = new ZyfaiSDK({
|
|
195
185
|
apiKey: "your-api-key",
|
|
196
|
-
bundlerApiKey: "your-bundler-api-key",
|
|
197
186
|
environment: "production",
|
|
198
187
|
});
|
|
199
188
|
|
|
200
189
|
// Option 3: With custom RPC URLs (recommended to avoid rate limiting)
|
|
201
190
|
const sdk = new ZyfaiSDK({
|
|
202
191
|
apiKey: "your-api-key",
|
|
203
|
-
bundlerApiKey: "your-bundler-api-key",
|
|
204
192
|
environment: "production",
|
|
205
193
|
rpcUrls: {
|
|
206
194
|
8453: "https://base-mainnet.g.alchemy.com/v2/YOUR_API_KEY", // Base
|
|
@@ -283,7 +271,7 @@ Get the Smart Wallet (Safe) address for a user.
|
|
|
283
271
|
|
|
284
272
|
##### `deploySafe(userAddress: string, chainId: SupportedChainId): Promise<DeploySafeResponse>`
|
|
285
273
|
|
|
286
|
-
Deploy a Safe smart wallet for a user.
|
|
274
|
+
Deploy a Safe smart wallet for a user. **Deployment is handled by the backend API**, which manages all RPC calls and bundler interactions. This avoids rate limiting issues.
|
|
287
275
|
|
|
288
276
|
**Parameters:**
|
|
289
277
|
|
|
@@ -298,10 +286,14 @@ Deploy a Safe smart wallet for a user.
|
|
|
298
286
|
safeAddress: Address;
|
|
299
287
|
txHash: string;
|
|
300
288
|
status: "deployed" | "failed";
|
|
301
|
-
alreadyDeployed?: boolean; // True if the Safe was already deployed (no new deployment needed)
|
|
302
289
|
}
|
|
303
290
|
```
|
|
304
291
|
|
|
292
|
+
**Note:**
|
|
293
|
+
|
|
294
|
+
- User must be authenticated (automatically done via `connectAccount()`)
|
|
295
|
+
- Backend handles all RPC calls, avoiding rate limiting
|
|
296
|
+
|
|
305
297
|
##### `addWalletToSdk(walletAddress: string): Promise<AddWalletToSdkResponse>`
|
|
306
298
|
|
|
307
299
|
Add a wallet address to the SDK API key's allowedWallets list. This endpoint requires SDK API key authentication (API key starting with "zyfai\_").
|
|
@@ -710,7 +702,6 @@ import { ZyfaiSDK } from "@zyfai/sdk";
|
|
|
710
702
|
async function main() {
|
|
711
703
|
const sdk = new ZyfaiSDK({
|
|
712
704
|
apiKey: process.env.ZYFAI_API_KEY!,
|
|
713
|
-
bundlerApiKey: process.env.BUNDLER_API_KEY!,
|
|
714
705
|
});
|
|
715
706
|
|
|
716
707
|
// Connect account (automatically authenticates via SIWE)
|
|
@@ -865,9 +856,6 @@ For running the examples, set up the following environment variables:
|
|
|
865
856
|
# Required: API key (used for both Execution API and Data API)
|
|
866
857
|
ZYFAI_API_KEY=your-api-key
|
|
867
858
|
|
|
868
|
-
# Required for Safe deployment: Bundler API key (e.g., Pimlico)
|
|
869
|
-
BUNDLER_API_KEY=your-pimlico-api-key
|
|
870
|
-
|
|
871
859
|
# Required for examples: Private key for signing transactions
|
|
872
860
|
# WARNING: Never commit your private key to version control!
|
|
873
861
|
PRIVATE_KEY=0x...
|
package/dist/index.d.mts
CHANGED
|
@@ -14,7 +14,6 @@ interface RpcUrlsConfig {
|
|
|
14
14
|
interface SDKConfig {
|
|
15
15
|
apiKey: string;
|
|
16
16
|
environment?: Environment;
|
|
17
|
-
bundlerApiKey?: string;
|
|
18
17
|
rpcUrls?: RpcUrlsConfig;
|
|
19
18
|
}
|
|
20
19
|
interface DeploySafeResponse {
|
|
@@ -22,8 +21,6 @@ interface DeploySafeResponse {
|
|
|
22
21
|
safeAddress: Address;
|
|
23
22
|
txHash: string;
|
|
24
23
|
status: "deployed" | "failed";
|
|
25
|
-
/** True if the Safe was already deployed (no new deployment needed) */
|
|
26
|
-
alreadyDeployed?: boolean;
|
|
27
24
|
}
|
|
28
25
|
/** @internal */
|
|
29
26
|
interface UpdateUserProfileRequest {
|
|
@@ -414,7 +411,6 @@ declare class ZyfaiSDK {
|
|
|
414
411
|
private httpClient;
|
|
415
412
|
private signer;
|
|
416
413
|
private walletClient;
|
|
417
|
-
private bundlerApiKey?;
|
|
418
414
|
private authenticatedUserId;
|
|
419
415
|
private hasActiveSessionKey;
|
|
420
416
|
private environment;
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ interface RpcUrlsConfig {
|
|
|
14
14
|
interface SDKConfig {
|
|
15
15
|
apiKey: string;
|
|
16
16
|
environment?: Environment;
|
|
17
|
-
bundlerApiKey?: string;
|
|
18
17
|
rpcUrls?: RpcUrlsConfig;
|
|
19
18
|
}
|
|
20
19
|
interface DeploySafeResponse {
|
|
@@ -22,8 +21,6 @@ interface DeploySafeResponse {
|
|
|
22
21
|
safeAddress: Address;
|
|
23
22
|
txHash: string;
|
|
24
23
|
status: "deployed" | "failed";
|
|
25
|
-
/** True if the Safe was already deployed (no new deployment needed) */
|
|
26
|
-
alreadyDeployed?: boolean;
|
|
27
24
|
}
|
|
28
25
|
/** @internal */
|
|
29
26
|
interface UpdateUserProfileRequest {
|
|
@@ -414,7 +411,6 @@ declare class ZyfaiSDK {
|
|
|
414
411
|
private httpClient;
|
|
415
412
|
private signer;
|
|
416
413
|
private walletClient;
|
|
417
|
-
private bundlerApiKey?;
|
|
418
414
|
private authenticatedUserId;
|
|
419
415
|
private hasActiveSessionKey;
|
|
420
416
|
private environment;
|
package/dist/index.js
CHANGED
|
@@ -61,6 +61,8 @@ var ENDPOINTS = {
|
|
|
61
61
|
USER_ME: "/users/me",
|
|
62
62
|
USER_WITHDRAW: "/users/withdraw",
|
|
63
63
|
PARTIAL_WITHDRAW: "/users/partial-withdraw",
|
|
64
|
+
// Safe Deployment (single endpoint)
|
|
65
|
+
SAFE_DEPLOY: "/users/safe-deploy",
|
|
64
66
|
// Session Keys
|
|
65
67
|
SESSION_KEYS_CONFIG: "/session-keys/config",
|
|
66
68
|
SESSION_KEYS_ADD: "/session-keys/add",
|
|
@@ -433,120 +435,18 @@ var isSupportedChain = (chainId) => {
|
|
|
433
435
|
var getSupportedChainIds = () => {
|
|
434
436
|
return Object.keys(CHAINS).map(Number);
|
|
435
437
|
};
|
|
436
|
-
var getBundlerUrl = (chainId, bundlerApiKey, bundlerProvider = "pimlico") => {
|
|
437
|
-
if (!bundlerApiKey) {
|
|
438
|
-
throw new Error("Bundler API key is required for Safe deployment");
|
|
439
|
-
}
|
|
440
|
-
switch (bundlerProvider) {
|
|
441
|
-
case "pimlico":
|
|
442
|
-
return `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${bundlerApiKey}`;
|
|
443
|
-
case "custom":
|
|
444
|
-
return bundlerApiKey;
|
|
445
|
-
default:
|
|
446
|
-
throw new Error(`Unsupported bundler provider: ${bundlerProvider}`);
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
438
|
|
|
450
439
|
// src/utils/safe-account.ts
|
|
451
440
|
var import_module_sdk = require("@rhinestone/module-sdk");
|
|
452
|
-
var import_permissionless = require("permissionless");
|
|
453
|
-
var import_erc7579 = require("permissionless/actions/erc7579");
|
|
454
|
-
var import_pimlico = require("permissionless/clients/pimlico");
|
|
455
441
|
var import_accounts = require("permissionless/accounts");
|
|
456
442
|
var import_viem3 = require("viem");
|
|
457
443
|
var import_account_abstraction = require("viem/account-abstraction");
|
|
458
|
-
var import_actions = require("permissionless/actions");
|
|
459
|
-
var import_account_abstraction2 = require("viem/account-abstraction");
|
|
460
444
|
var SAFE_7579_ADDRESS = "0x7579EE8307284F293B1927136486880611F20002";
|
|
461
445
|
var ERC7579_LAUNCHPAD_ADDRESS = "0x7579011aB74c46090561ea277Ba79D510c6C00ff";
|
|
462
446
|
var ACCOUNT_SALTS = {
|
|
463
447
|
staging: "zyfai-staging",
|
|
464
448
|
production: "zyfai"
|
|
465
449
|
};
|
|
466
|
-
var MODULE_TYPE_IDS = {
|
|
467
|
-
validator: 1n,
|
|
468
|
-
executor: 2n,
|
|
469
|
-
fallback: 3n,
|
|
470
|
-
hook: 4n
|
|
471
|
-
};
|
|
472
|
-
var SMART_SESSIONS_FALLBACK = {
|
|
473
|
-
module: "0x12cae64c42f362e7d5a847c2d33388373f629177",
|
|
474
|
-
address: "0x12cae64c42f362e7d5a847c2d33388373f629177",
|
|
475
|
-
type: "fallback",
|
|
476
|
-
selector: (0, import_viem3.encodeAbiParameters)(
|
|
477
|
-
[{ name: "functionSignature", type: "bytes4" }],
|
|
478
|
-
["0x84b0196e"]
|
|
479
|
-
),
|
|
480
|
-
initData: "0x84b0196e00000000000000000000000000000000000000000000000000000000fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"
|
|
481
|
-
};
|
|
482
|
-
var INTENT_EXECUTOR = {
|
|
483
|
-
address: "0x00000000005aD9ce1f5035FD62CA96CEf16AdAAF",
|
|
484
|
-
type: "executor",
|
|
485
|
-
initData: "0x"
|
|
486
|
-
};
|
|
487
|
-
var PROXY_EXECUTOR = {
|
|
488
|
-
address: "0xF659d30D4EB88B06A909F20839D8959Bd77d8790",
|
|
489
|
-
type: "executor",
|
|
490
|
-
initData: "0x"
|
|
491
|
-
};
|
|
492
|
-
var getModulesToInstall = (chainId) => {
|
|
493
|
-
const smartSessions = (0, import_module_sdk.getSmartSessionsValidator)({});
|
|
494
|
-
const accountLockerHook = (0, import_module_sdk.getAccountLockerHook)({ isOmniMode: true });
|
|
495
|
-
const accountLockerSourceExecutor = (0, import_module_sdk.getAccountLockerSourceExecutor)();
|
|
496
|
-
const accountLockerTargetExecutor = (0, import_module_sdk.getAccountLockerTargetExecutor)();
|
|
497
|
-
if (chainId === 9745) {
|
|
498
|
-
return [
|
|
499
|
-
smartSessions,
|
|
500
|
-
SMART_SESSIONS_FALLBACK,
|
|
501
|
-
INTENT_EXECUTOR,
|
|
502
|
-
PROXY_EXECUTOR
|
|
503
|
-
];
|
|
504
|
-
}
|
|
505
|
-
return [
|
|
506
|
-
smartSessions,
|
|
507
|
-
{
|
|
508
|
-
...accountLockerHook,
|
|
509
|
-
type: "executor"
|
|
510
|
-
},
|
|
511
|
-
accountLockerSourceExecutor,
|
|
512
|
-
accountLockerTargetExecutor,
|
|
513
|
-
SMART_SESSIONS_FALLBACK,
|
|
514
|
-
INTENT_EXECUTOR,
|
|
515
|
-
PROXY_EXECUTOR
|
|
516
|
-
];
|
|
517
|
-
};
|
|
518
|
-
var getInstallModuleCallData = (module2) => {
|
|
519
|
-
return (0, import_viem3.encodeFunctionData)({
|
|
520
|
-
abi: [
|
|
521
|
-
{
|
|
522
|
-
type: "function",
|
|
523
|
-
name: "installModule",
|
|
524
|
-
inputs: [
|
|
525
|
-
{
|
|
526
|
-
type: "uint256",
|
|
527
|
-
name: "moduleTypeId"
|
|
528
|
-
},
|
|
529
|
-
{
|
|
530
|
-
type: "address",
|
|
531
|
-
name: "module"
|
|
532
|
-
},
|
|
533
|
-
{
|
|
534
|
-
type: "bytes",
|
|
535
|
-
name: "initData"
|
|
536
|
-
}
|
|
537
|
-
],
|
|
538
|
-
outputs: [],
|
|
539
|
-
stateMutability: "nonpayable"
|
|
540
|
-
}
|
|
541
|
-
],
|
|
542
|
-
functionName: "installModule",
|
|
543
|
-
args: [
|
|
544
|
-
MODULE_TYPE_IDS[module2.type],
|
|
545
|
-
module2.address,
|
|
546
|
-
module2.initData || "0x"
|
|
547
|
-
]
|
|
548
|
-
});
|
|
549
|
-
};
|
|
550
450
|
var getSafeAccount = async (config) => {
|
|
551
451
|
const {
|
|
552
452
|
owner,
|
|
@@ -579,10 +479,13 @@ var getSafeAccount = async (config) => {
|
|
|
579
479
|
threshold: 1
|
|
580
480
|
});
|
|
581
481
|
const saltHex = (0, import_viem3.fromHex)((0, import_viem3.toHex)(effectiveSalt), "bigint");
|
|
482
|
+
const tempOwner = {
|
|
483
|
+
address: formattedEffectiveAddress,
|
|
484
|
+
type: "json-rpc"
|
|
485
|
+
};
|
|
582
486
|
const safeAccount = await (0, import_accounts.toSafeSmartAccount)({
|
|
583
487
|
client: publicClient,
|
|
584
|
-
owners: [
|
|
585
|
-
// Pass the owner object with address and signMessage capability
|
|
488
|
+
owners: [tempOwner],
|
|
586
489
|
version: "1.4.1",
|
|
587
490
|
entryPoint: {
|
|
588
491
|
address: import_account_abstraction.entryPoint07Address,
|
|
@@ -652,100 +555,41 @@ var getAccountType = async (address, publicClient) => {
|
|
|
652
555
|
return "Unknown";
|
|
653
556
|
}
|
|
654
557
|
};
|
|
655
|
-
var getSmartAccountClient = async (config) => {
|
|
656
|
-
const { chain, bundlerUrl } = config;
|
|
657
|
-
const safeAccount = await getSafeAccount(config);
|
|
658
|
-
const bundlerClient = (0, import_pimlico.createPimlicoClient)({
|
|
659
|
-
transport: (0, import_viem3.http)(bundlerUrl),
|
|
660
|
-
entryPoint: {
|
|
661
|
-
address: import_account_abstraction.entryPoint07Address,
|
|
662
|
-
version: "0.7"
|
|
663
|
-
}
|
|
664
|
-
});
|
|
665
|
-
const smartAccountClient = (0, import_permissionless.createSmartAccountClient)({
|
|
666
|
-
account: safeAccount,
|
|
667
|
-
chain,
|
|
668
|
-
bundlerTransport: (0, import_viem3.http)(bundlerUrl),
|
|
669
|
-
paymaster: bundlerClient,
|
|
670
|
-
userOperation: {
|
|
671
|
-
estimateFeesPerGas: async () => {
|
|
672
|
-
return (await bundlerClient.getUserOperationGasPrice()).fast;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
}).extend((0, import_erc7579.erc7579Actions)());
|
|
676
|
-
return smartAccountClient;
|
|
677
|
-
};
|
|
678
558
|
var deploySafeAccount = async (config) => {
|
|
679
559
|
try {
|
|
680
|
-
const { owner,
|
|
560
|
+
const { owner, httpClient, chainId } = config;
|
|
681
561
|
if (!owner || !owner.account) {
|
|
682
562
|
throw new Error(
|
|
683
563
|
"Wallet not connected. Please connect your wallet first."
|
|
684
564
|
);
|
|
685
565
|
}
|
|
686
|
-
const
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
}
|
|
694
|
-
const modulesToInstall = getModulesToInstall(chainId);
|
|
695
|
-
const installCalls = modulesToInstall.map((module2) => ({
|
|
696
|
-
to: safeAddress,
|
|
697
|
-
data: getInstallModuleCallData(module2)
|
|
698
|
-
}));
|
|
699
|
-
const smartAccountClient = await getSmartAccountClient(config);
|
|
700
|
-
const safeAccount = await getSafeAccount(config);
|
|
701
|
-
const ownableValidator = (0, import_module_sdk.getOwnableValidator)({
|
|
702
|
-
owners: [owner.account.address],
|
|
703
|
-
threshold: 1
|
|
704
|
-
});
|
|
705
|
-
const nonce = await (0, import_actions.getAccountNonce)(publicClient, {
|
|
706
|
-
address: safeAddress,
|
|
707
|
-
entryPointAddress: import_account_abstraction.entryPoint07Address,
|
|
708
|
-
key: BigInt(
|
|
709
|
-
(0, import_viem3.pad)(ownableValidator.address, {
|
|
710
|
-
dir: "right",
|
|
711
|
-
size: 24
|
|
712
|
-
}) || 0
|
|
713
|
-
)
|
|
714
|
-
});
|
|
715
|
-
const userOperation = await smartAccountClient.prepareUserOperation({
|
|
716
|
-
account: safeAccount,
|
|
717
|
-
calls: installCalls,
|
|
718
|
-
nonce
|
|
719
|
-
});
|
|
720
|
-
const userOpHashToSign = (0, import_account_abstraction2.getUserOperationHash)({
|
|
721
|
-
chainId,
|
|
722
|
-
entryPointAddress: import_account_abstraction.entryPoint07Address,
|
|
723
|
-
entryPointVersion: "0.7",
|
|
724
|
-
userOperation
|
|
725
|
-
});
|
|
726
|
-
if (!owner.account) {
|
|
727
|
-
throw new Error("Owner account is required for signing");
|
|
566
|
+
const prepareResponse = await httpClient.post(
|
|
567
|
+
`${ENDPOINTS.SAFE_DEPLOY}?chainId=${chainId}`
|
|
568
|
+
);
|
|
569
|
+
if (!prepareResponse.userOpHashToSign) {
|
|
570
|
+
throw new Error(
|
|
571
|
+
"Backend did not return userOpHashToSign. Response: " + JSON.stringify(prepareResponse)
|
|
572
|
+
);
|
|
728
573
|
}
|
|
729
|
-
|
|
574
|
+
const userOpHashToSign = prepareResponse.userOpHashToSign;
|
|
575
|
+
const userOpSignature = await owner.signMessage({
|
|
730
576
|
account: owner.account,
|
|
731
577
|
message: { raw: userOpHashToSign }
|
|
732
578
|
});
|
|
733
|
-
const
|
|
734
|
-
|
|
579
|
+
const deployResponse = await httpClient.post(
|
|
580
|
+
`${ENDPOINTS.SAFE_DEPLOY}?chainId=${chainId}`,
|
|
581
|
+
{ userOpSignature }
|
|
735
582
|
);
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
return {
|
|
741
|
-
safeAddress,
|
|
742
|
-
txHash: transaction.receipt.transactionHash,
|
|
743
|
-
isDeployed: true
|
|
744
|
-
};
|
|
745
|
-
} catch (error) {
|
|
746
|
-
console.error("Transaction failed:", error);
|
|
747
|
-
throw new Error("Failed to execute transaction");
|
|
583
|
+
if (!deployResponse.success) {
|
|
584
|
+
throw new Error(
|
|
585
|
+
`Safe deployment failed: ${JSON.stringify(deployResponse)}`
|
|
586
|
+
);
|
|
748
587
|
}
|
|
588
|
+
return {
|
|
589
|
+
safeAddress: deployResponse.safeAddress || "0x",
|
|
590
|
+
txHash: deployResponse.txHash,
|
|
591
|
+
isDeployed: true
|
|
592
|
+
};
|
|
749
593
|
} catch (error) {
|
|
750
594
|
throw new Error(
|
|
751
595
|
`Failed to deploy Safe account: ${error.message}`
|
|
@@ -799,24 +643,20 @@ var signSessionKey = async (config, sessions, allPublicClients, signingParams) =
|
|
|
799
643
|
// src/core/ZyfaiSDK.ts
|
|
800
644
|
var import_siwe = require("siwe");
|
|
801
645
|
var ZyfaiSDK = class {
|
|
802
|
-
// Optional custom RPC URLs per chain
|
|
803
646
|
constructor(config) {
|
|
804
647
|
this.signer = null;
|
|
805
648
|
this.walletClient = null;
|
|
806
649
|
this.authenticatedUserId = null;
|
|
807
|
-
// If non-null, user is authenticated
|
|
808
650
|
this.hasActiveSessionKey = false;
|
|
809
651
|
this.currentProvider = null;
|
|
810
|
-
// Store reference to current provider for event handling
|
|
811
652
|
this.currentChainId = null;
|
|
812
653
|
const sdkConfig = typeof config === "string" ? { apiKey: config } : config;
|
|
813
|
-
const { apiKey, environment,
|
|
654
|
+
const { apiKey, environment, rpcUrls } = sdkConfig;
|
|
814
655
|
if (!apiKey) {
|
|
815
656
|
throw new Error("API key is required");
|
|
816
657
|
}
|
|
817
658
|
this.environment = environment || "production";
|
|
818
659
|
this.httpClient = new HttpClient(apiKey, this.environment);
|
|
819
|
-
this.bundlerApiKey = bundlerApiKey;
|
|
820
660
|
this.rpcUrls = rpcUrls;
|
|
821
661
|
}
|
|
822
662
|
/**
|
|
@@ -1193,11 +1033,7 @@ var ZyfaiSDK = class {
|
|
|
1193
1033
|
if (!isSupportedChain(chainId)) {
|
|
1194
1034
|
throw new Error(`Unsupported chain ID: ${chainId}`);
|
|
1195
1035
|
}
|
|
1196
|
-
|
|
1197
|
-
throw new Error(
|
|
1198
|
-
"Bundler API key is required for Safe deployment. Please provide bundlerApiKey in SDK configuration."
|
|
1199
|
-
);
|
|
1200
|
-
}
|
|
1036
|
+
await this.authenticateUser();
|
|
1201
1037
|
const walletClient = this.getWalletClient(chainId);
|
|
1202
1038
|
const chainConfig = getChainConfig(chainId, this.rpcUrls);
|
|
1203
1039
|
const safeAddress = await getDeterministicSafeAddress({
|
|
@@ -1211,45 +1047,34 @@ var ZyfaiSDK = class {
|
|
|
1211
1047
|
safeAddress,
|
|
1212
1048
|
chainConfig.publicClient
|
|
1213
1049
|
);
|
|
1050
|
+
if (!alreadyDeployed) {
|
|
1051
|
+
const accountType = await getAccountType(
|
|
1052
|
+
userAddress,
|
|
1053
|
+
chainConfig.publicClient
|
|
1054
|
+
);
|
|
1055
|
+
if (accountType !== "EOA") {
|
|
1056
|
+
throw new Error(
|
|
1057
|
+
`Address ${userAddress} is not an EOA. Only EOA addresses can deploy Safe smart wallets.`
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1214
1061
|
if (alreadyDeployed) {
|
|
1215
1062
|
return {
|
|
1216
1063
|
success: true,
|
|
1217
1064
|
safeAddress,
|
|
1218
1065
|
txHash: "0x0",
|
|
1219
|
-
status: "deployed"
|
|
1220
|
-
alreadyDeployed: true
|
|
1066
|
+
status: "deployed"
|
|
1221
1067
|
};
|
|
1222
1068
|
}
|
|
1223
|
-
const accountType = await getAccountType(
|
|
1224
|
-
userAddress,
|
|
1225
|
-
chainConfig.publicClient
|
|
1226
|
-
);
|
|
1227
|
-
if (accountType !== "EOA") {
|
|
1228
|
-
throw new Error(
|
|
1229
|
-
`Address ${userAddress} is not an EOA. Only EOA addresses can deploy Safe smart wallets.`
|
|
1230
|
-
);
|
|
1231
|
-
}
|
|
1232
|
-
const bundlerUrl = getBundlerUrl(chainId, this.bundlerApiKey);
|
|
1233
1069
|
const deploymentResult = await deploySafeAccount({
|
|
1234
1070
|
owner: walletClient,
|
|
1235
1071
|
safeOwnerAddress: userAddress,
|
|
1236
1072
|
chain: chainConfig.chain,
|
|
1237
1073
|
publicClient: chainConfig.publicClient,
|
|
1238
|
-
bundlerUrl,
|
|
1239
1074
|
environment: this.environment,
|
|
1240
|
-
chainId
|
|
1075
|
+
chainId,
|
|
1076
|
+
httpClient: this.httpClient
|
|
1241
1077
|
});
|
|
1242
|
-
try {
|
|
1243
|
-
await this.updateUserProfile({
|
|
1244
|
-
smartWallet: deploymentResult.safeAddress,
|
|
1245
|
-
chains: [chainId]
|
|
1246
|
-
});
|
|
1247
|
-
} catch (updateError) {
|
|
1248
|
-
console.warn(
|
|
1249
|
-
"Failed to update user profile after Safe deployment:",
|
|
1250
|
-
updateError.message
|
|
1251
|
-
);
|
|
1252
|
-
}
|
|
1253
1078
|
try {
|
|
1254
1079
|
await this.initializeUser(deploymentResult.safeAddress, chainId);
|
|
1255
1080
|
} catch (initError) {
|
package/dist/index.mjs
CHANGED
|
@@ -20,6 +20,8 @@ var ENDPOINTS = {
|
|
|
20
20
|
USER_ME: "/users/me",
|
|
21
21
|
USER_WITHDRAW: "/users/withdraw",
|
|
22
22
|
PARTIAL_WITHDRAW: "/users/partial-withdraw",
|
|
23
|
+
// Safe Deployment (single endpoint)
|
|
24
|
+
SAFE_DEPLOY: "/users/safe-deploy",
|
|
23
25
|
// Session Keys
|
|
24
26
|
SESSION_KEYS_CONFIG: "/session-keys/config",
|
|
25
27
|
SESSION_KEYS_ADD: "/session-keys/add",
|
|
@@ -320,7 +322,7 @@ import { privateKeyToAccount } from "viem/accounts";
|
|
|
320
322
|
import {
|
|
321
323
|
createWalletClient,
|
|
322
324
|
custom,
|
|
323
|
-
http as
|
|
325
|
+
http as http2,
|
|
324
326
|
getAddress as getAddress2
|
|
325
327
|
} from "viem";
|
|
326
328
|
|
|
@@ -397,19 +399,6 @@ var isSupportedChain = (chainId) => {
|
|
|
397
399
|
var getSupportedChainIds = () => {
|
|
398
400
|
return Object.keys(CHAINS).map(Number);
|
|
399
401
|
};
|
|
400
|
-
var getBundlerUrl = (chainId, bundlerApiKey, bundlerProvider = "pimlico") => {
|
|
401
|
-
if (!bundlerApiKey) {
|
|
402
|
-
throw new Error("Bundler API key is required for Safe deployment");
|
|
403
|
-
}
|
|
404
|
-
switch (bundlerProvider) {
|
|
405
|
-
case "pimlico":
|
|
406
|
-
return `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${bundlerApiKey}`;
|
|
407
|
-
case "custom":
|
|
408
|
-
return bundlerApiKey;
|
|
409
|
-
default:
|
|
410
|
-
throw new Error(`Unsupported bundler provider: ${bundlerProvider}`);
|
|
411
|
-
}
|
|
412
|
-
};
|
|
413
402
|
|
|
414
403
|
// src/utils/safe-account.ts
|
|
415
404
|
import {
|
|
@@ -418,120 +407,23 @@ import {
|
|
|
418
407
|
getAccount,
|
|
419
408
|
getEnableSessionDetails,
|
|
420
409
|
getPermissionId,
|
|
421
|
-
getSessionNonce
|
|
422
|
-
getSmartSessionsValidator,
|
|
423
|
-
getAccountLockerHook,
|
|
424
|
-
getAccountLockerSourceExecutor,
|
|
425
|
-
getAccountLockerTargetExecutor
|
|
410
|
+
getSessionNonce
|
|
426
411
|
} from "@rhinestone/module-sdk";
|
|
427
|
-
import { createSmartAccountClient } from "permissionless";
|
|
428
|
-
import { erc7579Actions } from "permissionless/actions/erc7579";
|
|
429
|
-
import { createPimlicoClient } from "permissionless/clients/pimlico";
|
|
430
412
|
import { toSafeSmartAccount } from "permissionless/accounts";
|
|
431
413
|
import {
|
|
432
|
-
http as http2,
|
|
433
414
|
getAddress,
|
|
434
|
-
encodeFunctionData,
|
|
435
415
|
fromHex,
|
|
436
|
-
toHex
|
|
437
|
-
encodeAbiParameters,
|
|
438
|
-
pad
|
|
416
|
+
toHex
|
|
439
417
|
} from "viem";
|
|
440
418
|
import {
|
|
441
419
|
entryPoint07Address
|
|
442
420
|
} from "viem/account-abstraction";
|
|
443
|
-
import { getAccountNonce } from "permissionless/actions";
|
|
444
|
-
import { getUserOperationHash } from "viem/account-abstraction";
|
|
445
421
|
var SAFE_7579_ADDRESS = "0x7579EE8307284F293B1927136486880611F20002";
|
|
446
422
|
var ERC7579_LAUNCHPAD_ADDRESS = "0x7579011aB74c46090561ea277Ba79D510c6C00ff";
|
|
447
423
|
var ACCOUNT_SALTS = {
|
|
448
424
|
staging: "zyfai-staging",
|
|
449
425
|
production: "zyfai"
|
|
450
426
|
};
|
|
451
|
-
var MODULE_TYPE_IDS = {
|
|
452
|
-
validator: 1n,
|
|
453
|
-
executor: 2n,
|
|
454
|
-
fallback: 3n,
|
|
455
|
-
hook: 4n
|
|
456
|
-
};
|
|
457
|
-
var SMART_SESSIONS_FALLBACK = {
|
|
458
|
-
module: "0x12cae64c42f362e7d5a847c2d33388373f629177",
|
|
459
|
-
address: "0x12cae64c42f362e7d5a847c2d33388373f629177",
|
|
460
|
-
type: "fallback",
|
|
461
|
-
selector: encodeAbiParameters(
|
|
462
|
-
[{ name: "functionSignature", type: "bytes4" }],
|
|
463
|
-
["0x84b0196e"]
|
|
464
|
-
),
|
|
465
|
-
initData: "0x84b0196e00000000000000000000000000000000000000000000000000000000fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"
|
|
466
|
-
};
|
|
467
|
-
var INTENT_EXECUTOR = {
|
|
468
|
-
address: "0x00000000005aD9ce1f5035FD62CA96CEf16AdAAF",
|
|
469
|
-
type: "executor",
|
|
470
|
-
initData: "0x"
|
|
471
|
-
};
|
|
472
|
-
var PROXY_EXECUTOR = {
|
|
473
|
-
address: "0xF659d30D4EB88B06A909F20839D8959Bd77d8790",
|
|
474
|
-
type: "executor",
|
|
475
|
-
initData: "0x"
|
|
476
|
-
};
|
|
477
|
-
var getModulesToInstall = (chainId) => {
|
|
478
|
-
const smartSessions = getSmartSessionsValidator({});
|
|
479
|
-
const accountLockerHook = getAccountLockerHook({ isOmniMode: true });
|
|
480
|
-
const accountLockerSourceExecutor = getAccountLockerSourceExecutor();
|
|
481
|
-
const accountLockerTargetExecutor = getAccountLockerTargetExecutor();
|
|
482
|
-
if (chainId === 9745) {
|
|
483
|
-
return [
|
|
484
|
-
smartSessions,
|
|
485
|
-
SMART_SESSIONS_FALLBACK,
|
|
486
|
-
INTENT_EXECUTOR,
|
|
487
|
-
PROXY_EXECUTOR
|
|
488
|
-
];
|
|
489
|
-
}
|
|
490
|
-
return [
|
|
491
|
-
smartSessions,
|
|
492
|
-
{
|
|
493
|
-
...accountLockerHook,
|
|
494
|
-
type: "executor"
|
|
495
|
-
},
|
|
496
|
-
accountLockerSourceExecutor,
|
|
497
|
-
accountLockerTargetExecutor,
|
|
498
|
-
SMART_SESSIONS_FALLBACK,
|
|
499
|
-
INTENT_EXECUTOR,
|
|
500
|
-
PROXY_EXECUTOR
|
|
501
|
-
];
|
|
502
|
-
};
|
|
503
|
-
var getInstallModuleCallData = (module) => {
|
|
504
|
-
return encodeFunctionData({
|
|
505
|
-
abi: [
|
|
506
|
-
{
|
|
507
|
-
type: "function",
|
|
508
|
-
name: "installModule",
|
|
509
|
-
inputs: [
|
|
510
|
-
{
|
|
511
|
-
type: "uint256",
|
|
512
|
-
name: "moduleTypeId"
|
|
513
|
-
},
|
|
514
|
-
{
|
|
515
|
-
type: "address",
|
|
516
|
-
name: "module"
|
|
517
|
-
},
|
|
518
|
-
{
|
|
519
|
-
type: "bytes",
|
|
520
|
-
name: "initData"
|
|
521
|
-
}
|
|
522
|
-
],
|
|
523
|
-
outputs: [],
|
|
524
|
-
stateMutability: "nonpayable"
|
|
525
|
-
}
|
|
526
|
-
],
|
|
527
|
-
functionName: "installModule",
|
|
528
|
-
args: [
|
|
529
|
-
MODULE_TYPE_IDS[module.type],
|
|
530
|
-
module.address,
|
|
531
|
-
module.initData || "0x"
|
|
532
|
-
]
|
|
533
|
-
});
|
|
534
|
-
};
|
|
535
427
|
var getSafeAccount = async (config) => {
|
|
536
428
|
const {
|
|
537
429
|
owner,
|
|
@@ -564,10 +456,13 @@ var getSafeAccount = async (config) => {
|
|
|
564
456
|
threshold: 1
|
|
565
457
|
});
|
|
566
458
|
const saltHex = fromHex(toHex(effectiveSalt), "bigint");
|
|
459
|
+
const tempOwner = {
|
|
460
|
+
address: formattedEffectiveAddress,
|
|
461
|
+
type: "json-rpc"
|
|
462
|
+
};
|
|
567
463
|
const safeAccount = await toSafeSmartAccount({
|
|
568
464
|
client: publicClient,
|
|
569
|
-
owners: [
|
|
570
|
-
// Pass the owner object with address and signMessage capability
|
|
465
|
+
owners: [tempOwner],
|
|
571
466
|
version: "1.4.1",
|
|
572
467
|
entryPoint: {
|
|
573
468
|
address: entryPoint07Address,
|
|
@@ -637,100 +532,41 @@ var getAccountType = async (address, publicClient) => {
|
|
|
637
532
|
return "Unknown";
|
|
638
533
|
}
|
|
639
534
|
};
|
|
640
|
-
var getSmartAccountClient = async (config) => {
|
|
641
|
-
const { chain, bundlerUrl } = config;
|
|
642
|
-
const safeAccount = await getSafeAccount(config);
|
|
643
|
-
const bundlerClient = createPimlicoClient({
|
|
644
|
-
transport: http2(bundlerUrl),
|
|
645
|
-
entryPoint: {
|
|
646
|
-
address: entryPoint07Address,
|
|
647
|
-
version: "0.7"
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
const smartAccountClient = createSmartAccountClient({
|
|
651
|
-
account: safeAccount,
|
|
652
|
-
chain,
|
|
653
|
-
bundlerTransport: http2(bundlerUrl),
|
|
654
|
-
paymaster: bundlerClient,
|
|
655
|
-
userOperation: {
|
|
656
|
-
estimateFeesPerGas: async () => {
|
|
657
|
-
return (await bundlerClient.getUserOperationGasPrice()).fast;
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
}).extend(erc7579Actions());
|
|
661
|
-
return smartAccountClient;
|
|
662
|
-
};
|
|
663
535
|
var deploySafeAccount = async (config) => {
|
|
664
536
|
try {
|
|
665
|
-
const { owner,
|
|
537
|
+
const { owner, httpClient, chainId } = config;
|
|
666
538
|
if (!owner || !owner.account) {
|
|
667
539
|
throw new Error(
|
|
668
540
|
"Wallet not connected. Please connect your wallet first."
|
|
669
541
|
);
|
|
670
542
|
}
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
}
|
|
679
|
-
const modulesToInstall = getModulesToInstall(chainId);
|
|
680
|
-
const installCalls = modulesToInstall.map((module) => ({
|
|
681
|
-
to: safeAddress,
|
|
682
|
-
data: getInstallModuleCallData(module)
|
|
683
|
-
}));
|
|
684
|
-
const smartAccountClient = await getSmartAccountClient(config);
|
|
685
|
-
const safeAccount = await getSafeAccount(config);
|
|
686
|
-
const ownableValidator = getOwnableValidator({
|
|
687
|
-
owners: [owner.account.address],
|
|
688
|
-
threshold: 1
|
|
689
|
-
});
|
|
690
|
-
const nonce = await getAccountNonce(publicClient, {
|
|
691
|
-
address: safeAddress,
|
|
692
|
-
entryPointAddress: entryPoint07Address,
|
|
693
|
-
key: BigInt(
|
|
694
|
-
pad(ownableValidator.address, {
|
|
695
|
-
dir: "right",
|
|
696
|
-
size: 24
|
|
697
|
-
}) || 0
|
|
698
|
-
)
|
|
699
|
-
});
|
|
700
|
-
const userOperation = await smartAccountClient.prepareUserOperation({
|
|
701
|
-
account: safeAccount,
|
|
702
|
-
calls: installCalls,
|
|
703
|
-
nonce
|
|
704
|
-
});
|
|
705
|
-
const userOpHashToSign = getUserOperationHash({
|
|
706
|
-
chainId,
|
|
707
|
-
entryPointAddress: entryPoint07Address,
|
|
708
|
-
entryPointVersion: "0.7",
|
|
709
|
-
userOperation
|
|
710
|
-
});
|
|
711
|
-
if (!owner.account) {
|
|
712
|
-
throw new Error("Owner account is required for signing");
|
|
543
|
+
const prepareResponse = await httpClient.post(
|
|
544
|
+
`${ENDPOINTS.SAFE_DEPLOY}?chainId=${chainId}`
|
|
545
|
+
);
|
|
546
|
+
if (!prepareResponse.userOpHashToSign) {
|
|
547
|
+
throw new Error(
|
|
548
|
+
"Backend did not return userOpHashToSign. Response: " + JSON.stringify(prepareResponse)
|
|
549
|
+
);
|
|
713
550
|
}
|
|
714
|
-
|
|
551
|
+
const userOpHashToSign = prepareResponse.userOpHashToSign;
|
|
552
|
+
const userOpSignature = await owner.signMessage({
|
|
715
553
|
account: owner.account,
|
|
716
554
|
message: { raw: userOpHashToSign }
|
|
717
555
|
});
|
|
718
|
-
const
|
|
719
|
-
|
|
556
|
+
const deployResponse = await httpClient.post(
|
|
557
|
+
`${ENDPOINTS.SAFE_DEPLOY}?chainId=${chainId}`,
|
|
558
|
+
{ userOpSignature }
|
|
720
559
|
);
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
return {
|
|
726
|
-
safeAddress,
|
|
727
|
-
txHash: transaction.receipt.transactionHash,
|
|
728
|
-
isDeployed: true
|
|
729
|
-
};
|
|
730
|
-
} catch (error) {
|
|
731
|
-
console.error("Transaction failed:", error);
|
|
732
|
-
throw new Error("Failed to execute transaction");
|
|
560
|
+
if (!deployResponse.success) {
|
|
561
|
+
throw new Error(
|
|
562
|
+
`Safe deployment failed: ${JSON.stringify(deployResponse)}`
|
|
563
|
+
);
|
|
733
564
|
}
|
|
565
|
+
return {
|
|
566
|
+
safeAddress: deployResponse.safeAddress || "0x",
|
|
567
|
+
txHash: deployResponse.txHash,
|
|
568
|
+
isDeployed: true
|
|
569
|
+
};
|
|
734
570
|
} catch (error) {
|
|
735
571
|
throw new Error(
|
|
736
572
|
`Failed to deploy Safe account: ${error.message}`
|
|
@@ -784,24 +620,20 @@ var signSessionKey = async (config, sessions, allPublicClients, signingParams) =
|
|
|
784
620
|
// src/core/ZyfaiSDK.ts
|
|
785
621
|
import { SiweMessage } from "siwe";
|
|
786
622
|
var ZyfaiSDK = class {
|
|
787
|
-
// Optional custom RPC URLs per chain
|
|
788
623
|
constructor(config) {
|
|
789
624
|
this.signer = null;
|
|
790
625
|
this.walletClient = null;
|
|
791
626
|
this.authenticatedUserId = null;
|
|
792
|
-
// If non-null, user is authenticated
|
|
793
627
|
this.hasActiveSessionKey = false;
|
|
794
628
|
this.currentProvider = null;
|
|
795
|
-
// Store reference to current provider for event handling
|
|
796
629
|
this.currentChainId = null;
|
|
797
630
|
const sdkConfig = typeof config === "string" ? { apiKey: config } : config;
|
|
798
|
-
const { apiKey, environment,
|
|
631
|
+
const { apiKey, environment, rpcUrls } = sdkConfig;
|
|
799
632
|
if (!apiKey) {
|
|
800
633
|
throw new Error("API key is required");
|
|
801
634
|
}
|
|
802
635
|
this.environment = environment || "production";
|
|
803
636
|
this.httpClient = new HttpClient(apiKey, this.environment);
|
|
804
|
-
this.bundlerApiKey = bundlerApiKey;
|
|
805
637
|
this.rpcUrls = rpcUrls;
|
|
806
638
|
}
|
|
807
639
|
/**
|
|
@@ -1021,7 +853,7 @@ var ZyfaiSDK = class {
|
|
|
1021
853
|
this.walletClient = createWalletClient({
|
|
1022
854
|
account: this.signer,
|
|
1023
855
|
chain: chainConfig.chain,
|
|
1024
|
-
transport:
|
|
856
|
+
transport: http2(chainConfig.rpcUrl)
|
|
1025
857
|
});
|
|
1026
858
|
connectedAddress = this.signer.address;
|
|
1027
859
|
this.currentProvider = null;
|
|
@@ -1107,7 +939,7 @@ var ZyfaiSDK = class {
|
|
|
1107
939
|
return createWalletClient({
|
|
1108
940
|
account: this.signer,
|
|
1109
941
|
chain: targetChainConfig.chain,
|
|
1110
|
-
transport:
|
|
942
|
+
transport: http2(targetChainConfig.rpcUrl)
|
|
1111
943
|
});
|
|
1112
944
|
} else {
|
|
1113
945
|
if (!this.walletClient) {
|
|
@@ -1178,11 +1010,7 @@ var ZyfaiSDK = class {
|
|
|
1178
1010
|
if (!isSupportedChain(chainId)) {
|
|
1179
1011
|
throw new Error(`Unsupported chain ID: ${chainId}`);
|
|
1180
1012
|
}
|
|
1181
|
-
|
|
1182
|
-
throw new Error(
|
|
1183
|
-
"Bundler API key is required for Safe deployment. Please provide bundlerApiKey in SDK configuration."
|
|
1184
|
-
);
|
|
1185
|
-
}
|
|
1013
|
+
await this.authenticateUser();
|
|
1186
1014
|
const walletClient = this.getWalletClient(chainId);
|
|
1187
1015
|
const chainConfig = getChainConfig(chainId, this.rpcUrls);
|
|
1188
1016
|
const safeAddress = await getDeterministicSafeAddress({
|
|
@@ -1196,45 +1024,34 @@ var ZyfaiSDK = class {
|
|
|
1196
1024
|
safeAddress,
|
|
1197
1025
|
chainConfig.publicClient
|
|
1198
1026
|
);
|
|
1027
|
+
if (!alreadyDeployed) {
|
|
1028
|
+
const accountType = await getAccountType(
|
|
1029
|
+
userAddress,
|
|
1030
|
+
chainConfig.publicClient
|
|
1031
|
+
);
|
|
1032
|
+
if (accountType !== "EOA") {
|
|
1033
|
+
throw new Error(
|
|
1034
|
+
`Address ${userAddress} is not an EOA. Only EOA addresses can deploy Safe smart wallets.`
|
|
1035
|
+
);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1199
1038
|
if (alreadyDeployed) {
|
|
1200
1039
|
return {
|
|
1201
1040
|
success: true,
|
|
1202
1041
|
safeAddress,
|
|
1203
1042
|
txHash: "0x0",
|
|
1204
|
-
status: "deployed"
|
|
1205
|
-
alreadyDeployed: true
|
|
1043
|
+
status: "deployed"
|
|
1206
1044
|
};
|
|
1207
1045
|
}
|
|
1208
|
-
const accountType = await getAccountType(
|
|
1209
|
-
userAddress,
|
|
1210
|
-
chainConfig.publicClient
|
|
1211
|
-
);
|
|
1212
|
-
if (accountType !== "EOA") {
|
|
1213
|
-
throw new Error(
|
|
1214
|
-
`Address ${userAddress} is not an EOA. Only EOA addresses can deploy Safe smart wallets.`
|
|
1215
|
-
);
|
|
1216
|
-
}
|
|
1217
|
-
const bundlerUrl = getBundlerUrl(chainId, this.bundlerApiKey);
|
|
1218
1046
|
const deploymentResult = await deploySafeAccount({
|
|
1219
1047
|
owner: walletClient,
|
|
1220
1048
|
safeOwnerAddress: userAddress,
|
|
1221
1049
|
chain: chainConfig.chain,
|
|
1222
1050
|
publicClient: chainConfig.publicClient,
|
|
1223
|
-
bundlerUrl,
|
|
1224
1051
|
environment: this.environment,
|
|
1225
|
-
chainId
|
|
1052
|
+
chainId,
|
|
1053
|
+
httpClient: this.httpClient
|
|
1226
1054
|
});
|
|
1227
|
-
try {
|
|
1228
|
-
await this.updateUserProfile({
|
|
1229
|
-
smartWallet: deploymentResult.safeAddress,
|
|
1230
|
-
chains: [chainId]
|
|
1231
|
-
});
|
|
1232
|
-
} catch (updateError) {
|
|
1233
|
-
console.warn(
|
|
1234
|
-
"Failed to update user profile after Safe deployment:",
|
|
1235
|
-
updateError.message
|
|
1236
|
-
);
|
|
1237
|
-
}
|
|
1238
1055
|
try {
|
|
1239
1056
|
await this.initializeUser(deploymentResult.safeAddress, chainId);
|
|
1240
1057
|
} catch (initError) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zyfai/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
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",
|