@owney/sdk 0.7.22-beta.4 → 0.7.22-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-T5YJVIQG.js → chunk-CWGCQLB2.js} +13 -1
- package/dist/index.cjs +44 -20
- package/dist/index.js +1 -1
- package/dist/{surfliquid.agent-ZTIK54MW.js → surfliquid.agent-2XTX6I4E.js} +32 -11
- package/dist/{surfliquid.smart-account-YV3PLZ72.js → surfliquid.smart-account-JHW6VYLJ.js} +4 -13
- package/package.json +1 -1
|
@@ -251,8 +251,20 @@ async function depositSponsored(input) {
|
|
|
251
251
|
}
|
|
252
252
|
return { txHash, vault };
|
|
253
253
|
}
|
|
254
|
+
var PROCEEDS_POLL_ATTEMPTS = 6;
|
|
255
|
+
var PROCEEDS_POLL_INTERVAL_MS = 1500;
|
|
256
|
+
var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
257
|
+
async function awaitProceeds(chain, smartAccount, sleep) {
|
|
258
|
+
for (let attempt = 0; attempt < PROCEEDS_POLL_ATTEMPTS; attempt += 1) {
|
|
259
|
+
const balance = await chain.usdcBalanceOf(smartAccount);
|
|
260
|
+
if (balance > 0n) return balance;
|
|
261
|
+
if (attempt < PROCEEDS_POLL_ATTEMPTS - 1) await sleep(PROCEEDS_POLL_INTERVAL_MS);
|
|
262
|
+
}
|
|
263
|
+
return 0n;
|
|
264
|
+
}
|
|
254
265
|
async function withdrawSponsored(input) {
|
|
255
266
|
const { api, chain, wallet, amount } = input;
|
|
267
|
+
const sleep = input.sleep ?? defaultSleep;
|
|
256
268
|
const registered = await api.getVault(wallet.smartAccountAddress);
|
|
257
269
|
if (!registered.userVaultAddress) {
|
|
258
270
|
throw new Error("SurfLiquid has no vault registered for this wallet");
|
|
@@ -272,7 +284,7 @@ async function withdrawSponsored(input) {
|
|
|
272
284
|
return { txHash: sweepHash, amount: stranded.toString() };
|
|
273
285
|
}
|
|
274
286
|
try {
|
|
275
|
-
const proceeds = await chain
|
|
287
|
+
const proceeds = await awaitProceeds(chain, wallet.smartAccountAddress, sleep);
|
|
276
288
|
if (proceeds === 0n) return { txHash: withdrawHash, amount: "0" };
|
|
277
289
|
const sweepHash = await wallet.sendCalls(
|
|
278
290
|
buildSweepCalls({ owner: wallet.ownerAddress, amount: proceeds })
|
package/dist/index.cjs
CHANGED
|
@@ -501,7 +501,7 @@ function createSurfBroker(options) {
|
|
|
501
501
|
)
|
|
502
502
|
};
|
|
503
503
|
}
|
|
504
|
-
var SURF_SESSION_HEADER, SURF_BROKER_TIMEOUT_MS, VAULT_MEMO_TTL_MS, AGENT_ID, DISCOVERY_WALLET, SurfSessionExpiredError, asRecord, unavailable;
|
|
504
|
+
var SURF_SESSION_HEADER, SURF_BROKER_TIMEOUT_MS, VAULT_MEMO_TTL_MS, AGENT_ID, DISCOVERY_WALLET, SurfSessionExpiredError, asRecord, unavailable, emptyVaultInfo;
|
|
505
505
|
var init_surfliquid_broker = __esm({
|
|
506
506
|
"src/agents/surfliquid/surfliquid.broker.ts"() {
|
|
507
507
|
"use strict";
|
|
@@ -520,6 +520,7 @@ var init_surfliquid_broker = __esm({
|
|
|
520
520
|
};
|
|
521
521
|
asRecord = (value) => value && typeof value === "object" ? value : {};
|
|
522
522
|
unavailable = (message, details) => new OwneyError("SURF_UNAVAILABLE", message, details, AGENT_ID);
|
|
523
|
+
emptyVaultInfo = () => normalizeVault(void 0);
|
|
523
524
|
}
|
|
524
525
|
});
|
|
525
526
|
|
|
@@ -562,8 +563,18 @@ function mapMessage(message) {
|
|
|
562
563
|
}
|
|
563
564
|
return [base4];
|
|
564
565
|
}
|
|
566
|
+
function dedupeMessages(messages) {
|
|
567
|
+
const seen = /* @__PURE__ */ new Set();
|
|
568
|
+
return messages.filter((message) => {
|
|
569
|
+
if (!message.txHash) return true;
|
|
570
|
+
const key2 = `${message.transactionType}:${message.txHash}`;
|
|
571
|
+
if (seen.has(key2)) return false;
|
|
572
|
+
seen.add(key2);
|
|
573
|
+
return true;
|
|
574
|
+
});
|
|
575
|
+
}
|
|
565
576
|
function mapHistory(result, _chainId) {
|
|
566
|
-
const data = result.messages.flatMap(mapMessage);
|
|
577
|
+
const data = dedupeMessages(result.messages).flatMap(mapMessage);
|
|
567
578
|
const hasMore = result.page < result.pages;
|
|
568
579
|
return {
|
|
569
580
|
data,
|
|
@@ -873,8 +884,17 @@ async function depositSponsored(input) {
|
|
|
873
884
|
}
|
|
874
885
|
return { txHash, vault };
|
|
875
886
|
}
|
|
887
|
+
async function awaitProceeds(chain, smartAccount, sleep) {
|
|
888
|
+
for (let attempt = 0; attempt < PROCEEDS_POLL_ATTEMPTS; attempt += 1) {
|
|
889
|
+
const balance = await chain.usdcBalanceOf(smartAccount);
|
|
890
|
+
if (balance > 0n) return balance;
|
|
891
|
+
if (attempt < PROCEEDS_POLL_ATTEMPTS - 1) await sleep(PROCEEDS_POLL_INTERVAL_MS);
|
|
892
|
+
}
|
|
893
|
+
return 0n;
|
|
894
|
+
}
|
|
876
895
|
async function withdrawSponsored(input) {
|
|
877
896
|
const { api, chain, wallet, amount } = input;
|
|
897
|
+
const sleep = input.sleep ?? defaultSleep;
|
|
878
898
|
const registered = await api.getVault(wallet.smartAccountAddress);
|
|
879
899
|
if (!registered.userVaultAddress) {
|
|
880
900
|
throw new Error("SurfLiquid has no vault registered for this wallet");
|
|
@@ -894,7 +914,7 @@ async function withdrawSponsored(input) {
|
|
|
894
914
|
return { txHash: sweepHash, amount: stranded.toString() };
|
|
895
915
|
}
|
|
896
916
|
try {
|
|
897
|
-
const proceeds = await chain
|
|
917
|
+
const proceeds = await awaitProceeds(chain, wallet.smartAccountAddress, sleep);
|
|
898
918
|
if (proceeds === 0n) return { txHash: withdrawHash, amount: "0" };
|
|
899
919
|
const sweepHash = await wallet.sendCalls(
|
|
900
920
|
buildSweepCalls({ owner: wallet.ownerAddress, amount: proceeds })
|
|
@@ -906,7 +926,7 @@ async function withdrawSponsored(input) {
|
|
|
906
926
|
);
|
|
907
927
|
}
|
|
908
928
|
}
|
|
909
|
-
var import_viem8, SubmittedError, VaultNotSponsorableError;
|
|
929
|
+
var import_viem8, SubmittedError, VaultNotSponsorableError, PROCEEDS_POLL_ATTEMPTS, PROCEEDS_POLL_INTERVAL_MS, defaultSleep;
|
|
910
930
|
var init_surfliquid_sponsorship = __esm({
|
|
911
931
|
"src/agents/surfliquid/surfliquid.sponsorship.ts"() {
|
|
912
932
|
"use strict";
|
|
@@ -928,6 +948,9 @@ var init_surfliquid_sponsorship = __esm({
|
|
|
928
948
|
this.name = "VaultNotSponsorableError";
|
|
929
949
|
}
|
|
930
950
|
};
|
|
951
|
+
PROCEEDS_POLL_ATTEMPTS = 6;
|
|
952
|
+
PROCEEDS_POLL_INTERVAL_MS = 1500;
|
|
953
|
+
defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
931
954
|
}
|
|
932
955
|
});
|
|
933
956
|
|
|
@@ -1114,19 +1137,10 @@ async function createSponsoredWallet(input) {
|
|
|
1114
1137
|
message: typedData.message
|
|
1115
1138
|
}),
|
|
1116
1139
|
// The smart account signs (ERC-1271), not the EOA: SurfLiquid's SIWE session must
|
|
1117
|
-
// be the vault owner, which is the smart account.
|
|
1118
|
-
//
|
|
1140
|
+
// be the vault owner, which is the smart account. While the account is still
|
|
1141
|
+
// counterfactual, Safe/permissionless wraps this as an EIP-6492 signature SurfLiquid
|
|
1142
|
+
// accepts; the first deposit's userOp deploys the account via its initCode.
|
|
1119
1143
|
signMessage: (message) => account.signMessage({ message }),
|
|
1120
|
-
// Deploy-on-connect: the account is counterfactual until its first userOp, but SIWE
|
|
1121
|
-
// (isValidSignature) needs on-chain code. A no-op self-call carries the factory
|
|
1122
|
-
// initCode and deploys it. Idempotency is the caller's (it checks isDeployed first).
|
|
1123
|
-
deployAccount: async () => {
|
|
1124
|
-
const userOpHash = await smartAccountClient.sendUserOperation({
|
|
1125
|
-
calls: [{ to: account.address, value: 0n, data: "0x" }]
|
|
1126
|
-
});
|
|
1127
|
-
const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash: userOpHash });
|
|
1128
|
-
return receipt.receipt.transactionHash;
|
|
1129
|
-
},
|
|
1130
1144
|
sendCalls: async (calls) => {
|
|
1131
1145
|
const userOpHash = await smartAccountClient.sendUserOperation({
|
|
1132
1146
|
calls: calls.map((c) => ({ to: c.to, data: c.data, value: 0n }))
|
|
@@ -1245,10 +1259,6 @@ var init_surfliquid_agent = __esm({
|
|
|
1245
1259
|
this.smartAccountAddress = smartAccountAddress;
|
|
1246
1260
|
const broker = this.brokerFor(smartAccountAddress);
|
|
1247
1261
|
if (!shouldForce && broker.hasSession()) return broker;
|
|
1248
|
-
const { createSponsoredChain: createSponsoredChain2 } = await Promise.resolve().then(() => (init_surfliquid_smart_account(), surfliquid_smart_account_exports));
|
|
1249
|
-
if (!await createSponsoredChain2(this.config.rpcUrl).isDeployed(smartAccountAddress)) {
|
|
1250
|
-
await wallet.deployAccount();
|
|
1251
|
-
}
|
|
1252
1262
|
const message = await broker.nonce();
|
|
1253
1263
|
const signature = await wallet.signMessage(message);
|
|
1254
1264
|
await broker.login(message, signature);
|
|
@@ -1296,9 +1306,21 @@ var init_surfliquid_agent = __esm({
|
|
|
1296
1306
|
this.brokerWallet = null;
|
|
1297
1307
|
this.smartAccountAddress = null;
|
|
1298
1308
|
}
|
|
1309
|
+
// One signature on connect: SIWE the counterfactual smart account (EIP-6492). The
|
|
1310
|
+
// account isn't deployed and no funds move — the first deposit's userOp deploys it.
|
|
1299
1311
|
async activateAgent(state, _chainId) {
|
|
1300
1312
|
await this.connect(state);
|
|
1301
1313
|
}
|
|
1314
|
+
/** A counterfactual account owns no vault and can't be a SIWE signer yet — reads answer empty. */
|
|
1315
|
+
async isSmartAccountDeployed(state) {
|
|
1316
|
+
if (this.broker?.hasSession()) return true;
|
|
1317
|
+
const wallet = await this.sponsoredWallet(state);
|
|
1318
|
+
this.smartAccountAddress = wallet.smartAccountAddress;
|
|
1319
|
+
const { createSponsoredChain: createSponsoredChain2 } = await Promise.resolve().then(() => (init_surfliquid_smart_account(), surfliquid_smart_account_exports));
|
|
1320
|
+
return createSponsoredChain2(this.config.rpcUrl).isDeployed(
|
|
1321
|
+
wallet.smartAccountAddress
|
|
1322
|
+
);
|
|
1323
|
+
}
|
|
1302
1324
|
// --- IAgent: funds (gasless only) ---
|
|
1303
1325
|
async deposit(state, _chainId, amount, _asset, _depositCallback) {
|
|
1304
1326
|
const broker = await this.connect(state);
|
|
@@ -1355,6 +1377,7 @@ var init_surfliquid_agent = __esm({
|
|
|
1355
1377
|
}
|
|
1356
1378
|
// --- IAgent: portfolio reads ---
|
|
1357
1379
|
async vault(state) {
|
|
1380
|
+
if (!await this.isSmartAccountDeployed(state)) return emptyVaultInfo();
|
|
1358
1381
|
const broker = await this.connect(state);
|
|
1359
1382
|
return this.withSession(state, () => broker.getVault(this.surfWallet(state)));
|
|
1360
1383
|
}
|
|
@@ -1372,6 +1395,7 @@ var init_surfliquid_agent = __esm({
|
|
|
1372
1395
|
return mapAccountApy(await this.vault(state), days);
|
|
1373
1396
|
}
|
|
1374
1397
|
async getHistory(state, chainId, options) {
|
|
1398
|
+
if (!await this.isSmartAccountDeployed(state)) return { data: [], hasMore: false };
|
|
1375
1399
|
const broker = await this.connect(state);
|
|
1376
1400
|
const page = options?.cursor ? Number(options.cursor) : 1;
|
|
1377
1401
|
const limit = options?.limit ?? HISTORY_DEFAULT_LIMIT;
|
package/dist/index.js
CHANGED
|
@@ -3036,7 +3036,7 @@ var OwneySDK = class {
|
|
|
3036
3036
|
}
|
|
3037
3037
|
if (agentId === "surfliquid") {
|
|
3038
3038
|
if (!key2) return null;
|
|
3039
|
-
const { SurfLiquidAgent } = await import("./surfliquid.agent-
|
|
3039
|
+
const { SurfLiquidAgent } = await import("./surfliquid.agent-2XTX6I4E.js");
|
|
3040
3040
|
return new SurfLiquidAgent({
|
|
3041
3041
|
apiKey: this.apiKey,
|
|
3042
3042
|
routingApiBaseUrl: this.routingApiBaseUrl
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
readStuckBalance,
|
|
14
14
|
sweepStuckBalance,
|
|
15
15
|
withdrawSponsored
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CWGCQLB2.js";
|
|
17
17
|
import "./chunk-AURO3C3R.js";
|
|
18
18
|
|
|
19
19
|
// src/agents/surfliquid/surfliquid.session-store.ts
|
|
@@ -96,6 +96,7 @@ function parseJson(text) {
|
|
|
96
96
|
return void 0;
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
+
var emptyVaultInfo = () => normalizeVault(void 0);
|
|
99
100
|
function normalizeVault(json) {
|
|
100
101
|
const root = asRecord(json);
|
|
101
102
|
const data = asRecord(root.data);
|
|
@@ -301,8 +302,18 @@ function mapMessage(message) {
|
|
|
301
302
|
}
|
|
302
303
|
return [base];
|
|
303
304
|
}
|
|
305
|
+
function dedupeMessages(messages) {
|
|
306
|
+
const seen = /* @__PURE__ */ new Set();
|
|
307
|
+
return messages.filter((message) => {
|
|
308
|
+
if (!message.txHash) return true;
|
|
309
|
+
const key = `${message.transactionType}:${message.txHash}`;
|
|
310
|
+
if (seen.has(key)) return false;
|
|
311
|
+
seen.add(key);
|
|
312
|
+
return true;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
304
315
|
function mapHistory(result, _chainId) {
|
|
305
|
-
const data = result.messages.flatMap(mapMessage);
|
|
316
|
+
const data = dedupeMessages(result.messages).flatMap(mapMessage);
|
|
306
317
|
const hasMore = result.page < result.pages;
|
|
307
318
|
return {
|
|
308
319
|
data,
|
|
@@ -532,10 +543,6 @@ var SurfLiquidAgent = class {
|
|
|
532
543
|
this.smartAccountAddress = smartAccountAddress;
|
|
533
544
|
const broker = this.brokerFor(smartAccountAddress);
|
|
534
545
|
if (!shouldForce && broker.hasSession()) return broker;
|
|
535
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-YV3PLZ72.js");
|
|
536
|
-
if (!await createSponsoredChain(this.config.rpcUrl).isDeployed(smartAccountAddress)) {
|
|
537
|
-
await wallet.deployAccount();
|
|
538
|
-
}
|
|
539
546
|
const message = await broker.nonce();
|
|
540
547
|
const signature = await wallet.signMessage(message);
|
|
541
548
|
await broker.login(message, signature);
|
|
@@ -567,7 +574,7 @@ var SurfLiquidAgent = class {
|
|
|
567
574
|
}
|
|
568
575
|
}
|
|
569
576
|
async sponsoredWallet(state) {
|
|
570
|
-
const { createSponsoredWallet } = await import("./surfliquid.smart-account-
|
|
577
|
+
const { createSponsoredWallet } = await import("./surfliquid.smart-account-JHW6VYLJ.js");
|
|
571
578
|
return createSponsoredWallet({
|
|
572
579
|
provider: state.provider,
|
|
573
580
|
ownerAddress: state.walletAddress,
|
|
@@ -583,14 +590,26 @@ var SurfLiquidAgent = class {
|
|
|
583
590
|
this.brokerWallet = null;
|
|
584
591
|
this.smartAccountAddress = null;
|
|
585
592
|
}
|
|
593
|
+
// One signature on connect: SIWE the counterfactual smart account (EIP-6492). The
|
|
594
|
+
// account isn't deployed and no funds move — the first deposit's userOp deploys it.
|
|
586
595
|
async activateAgent(state, _chainId) {
|
|
587
596
|
await this.connect(state);
|
|
588
597
|
}
|
|
598
|
+
/** A counterfactual account owns no vault and can't be a SIWE signer yet — reads answer empty. */
|
|
599
|
+
async isSmartAccountDeployed(state) {
|
|
600
|
+
if (this.broker?.hasSession()) return true;
|
|
601
|
+
const wallet = await this.sponsoredWallet(state);
|
|
602
|
+
this.smartAccountAddress = wallet.smartAccountAddress;
|
|
603
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-JHW6VYLJ.js");
|
|
604
|
+
return createSponsoredChain(this.config.rpcUrl).isDeployed(
|
|
605
|
+
wallet.smartAccountAddress
|
|
606
|
+
);
|
|
607
|
+
}
|
|
589
608
|
// --- IAgent: funds (gasless only) ---
|
|
590
609
|
async deposit(state, _chainId, amount, _asset, _depositCallback) {
|
|
591
610
|
const broker = await this.connect(state);
|
|
592
611
|
const wallet = await this.sponsoredWallet(state);
|
|
593
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
612
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-JHW6VYLJ.js");
|
|
594
613
|
try {
|
|
595
614
|
const { txHash, vault } = await this.withSession(
|
|
596
615
|
state,
|
|
@@ -605,7 +624,7 @@ var SurfLiquidAgent = class {
|
|
|
605
624
|
async withdraw(state, _chainId, _token, amount) {
|
|
606
625
|
const broker = await this.connect(state);
|
|
607
626
|
const wallet = await this.sponsoredWallet(state);
|
|
608
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
627
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-JHW6VYLJ.js");
|
|
609
628
|
try {
|
|
610
629
|
const result = await this.withSession(
|
|
611
630
|
state,
|
|
@@ -625,14 +644,14 @@ var SurfLiquidAgent = class {
|
|
|
625
644
|
/** Funds a prior withdrawal's sweep left in the smart account (never reached the EOA). No session needed — pure read. */
|
|
626
645
|
async getStuckBalance(state) {
|
|
627
646
|
const wallet = await this.sponsoredWallet(state);
|
|
628
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
647
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-JHW6VYLJ.js");
|
|
629
648
|
const amount = await readStuckBalance({ chain: createSponsoredChain(this.config.rpcUrl), wallet });
|
|
630
649
|
return { amount: amount.toString(), smartAccountAddress: wallet.smartAccountAddress };
|
|
631
650
|
}
|
|
632
651
|
/** Sweep the stranded balance to the owner's EOA — one sponsored userOp, one signature. */
|
|
633
652
|
async recoverStuckBalance(state) {
|
|
634
653
|
const wallet = await this.sponsoredWallet(state);
|
|
635
|
-
const { createSponsoredChain } = await import("./surfliquid.smart-account-
|
|
654
|
+
const { createSponsoredChain } = await import("./surfliquid.smart-account-JHW6VYLJ.js");
|
|
636
655
|
try {
|
|
637
656
|
const { txHash, amount } = await sweepStuckBalance({ chain: createSponsoredChain(this.config.rpcUrl), wallet });
|
|
638
657
|
return { txHash, type: "full", amount: amount.toString() };
|
|
@@ -642,6 +661,7 @@ var SurfLiquidAgent = class {
|
|
|
642
661
|
}
|
|
643
662
|
// --- IAgent: portfolio reads ---
|
|
644
663
|
async vault(state) {
|
|
664
|
+
if (!await this.isSmartAccountDeployed(state)) return emptyVaultInfo();
|
|
645
665
|
const broker = await this.connect(state);
|
|
646
666
|
return this.withSession(state, () => broker.getVault(this.surfWallet(state)));
|
|
647
667
|
}
|
|
@@ -659,6 +679,7 @@ var SurfLiquidAgent = class {
|
|
|
659
679
|
return mapAccountApy(await this.vault(state), days);
|
|
660
680
|
}
|
|
661
681
|
async getHistory(state, chainId, options) {
|
|
682
|
+
if (!await this.isSmartAccountDeployed(state)) return { data: [], hasMore: false };
|
|
662
683
|
const broker = await this.connect(state);
|
|
663
684
|
const page = options?.cursor ? Number(options.cursor) : 1;
|
|
664
685
|
const limit = options?.limit ?? HISTORY_DEFAULT_LIMIT;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
SURFLIQUID_VAULT_ABI,
|
|
7
7
|
SubmittedError,
|
|
8
8
|
USDC_ABI
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-CWGCQLB2.js";
|
|
10
10
|
import {
|
|
11
11
|
readTokenMeta
|
|
12
12
|
} from "./chunk-AURO3C3R.js";
|
|
@@ -114,19 +114,10 @@ async function createSponsoredWallet(input) {
|
|
|
114
114
|
message: typedData.message
|
|
115
115
|
}),
|
|
116
116
|
// The smart account signs (ERC-1271), not the EOA: SurfLiquid's SIWE session must
|
|
117
|
-
// be the vault owner, which is the smart account.
|
|
118
|
-
//
|
|
117
|
+
// be the vault owner, which is the smart account. While the account is still
|
|
118
|
+
// counterfactual, Safe/permissionless wraps this as an EIP-6492 signature SurfLiquid
|
|
119
|
+
// accepts; the first deposit's userOp deploys the account via its initCode.
|
|
119
120
|
signMessage: (message) => account.signMessage({ message }),
|
|
120
|
-
// Deploy-on-connect: the account is counterfactual until its first userOp, but SIWE
|
|
121
|
-
// (isValidSignature) needs on-chain code. A no-op self-call carries the factory
|
|
122
|
-
// initCode and deploys it. Idempotency is the caller's (it checks isDeployed first).
|
|
123
|
-
deployAccount: async () => {
|
|
124
|
-
const userOpHash = await smartAccountClient.sendUserOperation({
|
|
125
|
-
calls: [{ to: account.address, value: 0n, data: "0x" }]
|
|
126
|
-
});
|
|
127
|
-
const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash: userOpHash });
|
|
128
|
-
return receipt.receipt.transactionHash;
|
|
129
|
-
},
|
|
130
121
|
sendCalls: async (calls) => {
|
|
131
122
|
const userOpHash = await smartAccountClient.sendUserOperation({
|
|
132
123
|
calls: calls.map((c) => ({ to: c.to, data: c.data, value: 0n }))
|