@polyester/sdk 0.25.1 → 0.26.1
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/CHANGELOG.md +34 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -2
- package/dist/server-client.d.ts +12 -1
- package/dist/server-client.d.ts.map +1 -1
- package/dist/server-client.js +8 -3
- package/dist/server-client.js.map +1 -1
- package/dist/server-session.d.ts +3 -2
- package/dist/server-session.js +2 -1
- package/dist/services/auth/account-signer-auth.d.ts.map +1 -1
- package/dist/services/auth/account-signer-auth.js +78 -44
- package/dist/services/auth/account-signer-auth.js.map +1 -1
- package/dist/services/auth/cookie-constants.d.ts +14 -1
- package/dist/services/auth/cookie-constants.d.ts.map +1 -1
- package/dist/services/auth/cookie-constants.js +13 -1
- package/dist/services/auth/cookie-constants.js.map +1 -1
- package/dist/services/auth/session.d.ts +10 -2
- package/dist/services/auth/session.d.ts.map +1 -1
- package/dist/services/auth/session.js +9 -11
- package/dist/services/auth/session.js.map +1 -1
- package/dist/services/auth/token-storage.js +5 -5
- package/dist/services/auth/token-storage.js.map +1 -1
- package/dist/services/candles/candles.schemas.d.ts +10 -10
- package/dist/services/heatmap/heatmap.schemas.d.ts +13 -13
- package/dist/services/market-overview/market-overview.schemas.d.ts +3 -3
- package/dist/services/orderbook/orderbook.schemas.d.ts +1 -1
- package/dist/services/orders/orders-output.schemas.d.ts +6 -6
- package/dist/services/subaccounts/subaccounts.schemas.d.ts +5 -5
- package/dist/services/trades/trades.schemas.d.ts +1 -1
- package/dist/services/triggers/trigger-input.schemas.d.ts +2 -2
- package/dist/services/triggers/triggers-output.schemas.d.ts +18 -18
- package/dist/smart-account/index.d.ts +2 -2
- package/dist/smart-account/index.js +2 -2
- package/dist/smart-account/smart-account.d.ts +3095 -7
- package/dist/smart-account/smart-account.d.ts.map +1 -1
- package/dist/smart-account/smart-account.js +169 -45
- package/dist/smart-account/smart-account.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smart-account.d.ts","names":[],"sources":["../../src/smart-account/smart-account.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"smart-account.d.ts","names":[],"sources":["../../src/smart-account/smart-account.ts"],"mappings":";;;;KAWY,2BAA2B,QAAQ,kBAAkB;KACrD,8BAA8B,kBAAkB;UAqB3C;EACb,aAAa;EACb,OAAO;EACP;EACA,eAAe;;UAGF;EACb,aAAa;EACb,cAAc;EACd;;iBAGY,sCACZ,aACA,cACA,aACD,4CAA4C;;;;iBAuBzB,8BAClB,aACA,OACA,WACA,gBACD,2BAA2B,QAAQ;UAuBrB;;EAEb;;EAEA;;;;;;;iBAQY,kCACZ,SAAS,0BACT;EACI,aAAa;EACb,UAAU;6BACb,kCAAA,gDAAA;;;;;;;;;;;IA3F0B,kBAAA,kCAAA,sCAAA,0CAAA,sCAAA,0BAAA,oBAAA,WAAA,iBAAA,WAAA,gBAAA,aAAA,aAAA;MAAuB,aAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4D8B,UAAC;IAGvD,6BAAC;;EAOP,aAAA;IAAgB;;EAO+B,mBAAA,4BAAA,qCAAA,uBAAA;;;;;;;;;;IA4C9D;;;IAMF,gBAAD,8BAAA,yBAAA,uBAAA,4BAAA;;;;;;;;;;;;;;;;;;;IA/HwB,kBAAA,kCAAA,sCAAA,0CAAA,sCAAA,0BAAA,oBAAA,WAAA,iBAAA,WAAA,gBAAA,aAAA,aAAA;MAAuB,aAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import { predictSafeAddress } from "../account-signer/predict-safe-address.js";
|
|
2
|
-
import { createPublicClient, http } from "viem";
|
|
2
|
+
import { createPublicClient, http, withTimeout } from "viem";
|
|
3
3
|
import { estimateUserOperationGas, prepareUserOperation } from "viem/account-abstraction";
|
|
4
4
|
import { createSmartAccountClient } from "permissionless";
|
|
5
|
+
import { getUserOperationStatus } from "permissionless/actions/pimlico";
|
|
5
6
|
import { toSafeSmartAccount } from "permissionless/accounts";
|
|
6
7
|
import { createPimlicoClient } from "permissionless/clients/pimlico";
|
|
7
8
|
//#region src/smart-account/smart-account.ts
|
|
8
9
|
const smartAccountEnvironmentFingerprints = /* @__PURE__ */ new WeakMap();
|
|
9
|
-
const
|
|
10
|
+
const smartAccountClientPrimers = /* @__PURE__ */ new WeakMap();
|
|
11
|
+
const smartAccountClientCacheResets = /* @__PURE__ */ new WeakMap();
|
|
12
|
+
const smartAccountClients = /* @__PURE__ */ new WeakMap();
|
|
13
|
+
const USER_OPERATION_GAS_PRICE_TTL_MS = 6e4;
|
|
10
14
|
const USER_OPERATION_GAS_BUFFER_BPS = 2000n;
|
|
11
15
|
const USER_OPERATION_MIN_GAS_BUFFER = 50000n;
|
|
12
|
-
const
|
|
13
|
-
|
|
16
|
+
const USER_OPERATION_RECEIPT_POLLING_INTERVAL_MS = 250;
|
|
17
|
+
/**
|
|
18
|
+
* While the bundler reports `not_found`, the chain is checked for a receipt
|
|
19
|
+
* on every Nth poll (once per second at the default interval). `not_found` is
|
|
20
|
+
* not definitive — a bundler restart forgets ops whose bundle is still
|
|
21
|
+
* pending — so polling continues until the deadline.
|
|
22
|
+
*/
|
|
23
|
+
const NOT_FOUND_RECEIPT_CHECK_EVERY = 4;
|
|
14
24
|
function predictPolyesterSmartAccountAddress({ environment, ownerAddress, saltNonce = 0n }) {
|
|
15
25
|
const { safeProxyFactoryAddress, safeSingletonAddress, safeModuleSetupAddress, safe4337ModuleAddress, multiSendAddress } = environment.accountAbstraction.safe;
|
|
16
26
|
return predictSafeAddress({
|
|
@@ -43,37 +53,44 @@ async function createPolyesterSmartAccount({ environment, owner, saltNonce, publ
|
|
|
43
53
|
return account;
|
|
44
54
|
}
|
|
45
55
|
/**
|
|
46
|
-
* Creates a viem client bound to a Polyester smart account.
|
|
56
|
+
* Creates a viem client bound to a Polyester smart account. Memoized per
|
|
57
|
+
* (account, environment, options): repeat calls return the same client, so
|
|
58
|
+
* the gas price cache and warmed connections survive across submissions.
|
|
47
59
|
*/
|
|
48
60
|
function createPolyesterSmartAccountClient(account, params) {
|
|
49
61
|
const { environment, options } = params;
|
|
50
|
-
const { gasPriceCacheTtlMs = USER_OPERATION_GAS_PRICE_TTL_MS, pollingIntervalMs = USER_OPERATION_RECEIPT_POLLING_INTERVAL_MS } = options ?? {};
|
|
51
62
|
const accountEnvironmentFingerprint = smartAccountEnvironmentFingerprints.get(account);
|
|
52
63
|
if (accountEnvironmentFingerprint && accountEnvironmentFingerprint !== environment.fingerprint) throw new Error("Smart account environment does not match client environment.");
|
|
64
|
+
let clients = smartAccountClients.get(account);
|
|
65
|
+
if (!clients) smartAccountClients.set(account, clients = /* @__PURE__ */ new Map());
|
|
66
|
+
const key = JSON.stringify([
|
|
67
|
+
environment.fingerprint,
|
|
68
|
+
options?.gasPriceCacheTtlMs ?? USER_OPERATION_GAS_PRICE_TTL_MS,
|
|
69
|
+
options?.pollingIntervalMs ?? USER_OPERATION_RECEIPT_POLLING_INTERVAL_MS
|
|
70
|
+
]);
|
|
71
|
+
let client = clients.get(key);
|
|
72
|
+
if (!client) {
|
|
73
|
+
client = buildPolyesterSmartAccountClient(account, environment, options);
|
|
74
|
+
clients.set(key, client);
|
|
75
|
+
}
|
|
76
|
+
return client;
|
|
77
|
+
}
|
|
78
|
+
function buildPolyesterSmartAccountClient(account, environment, options) {
|
|
79
|
+
const { gasPriceCacheTtlMs = USER_OPERATION_GAS_PRICE_TTL_MS, pollingIntervalMs = USER_OPERATION_RECEIPT_POLLING_INTERVAL_MS } = options ?? {};
|
|
53
80
|
const paymaster = createPimlicoClient({
|
|
54
81
|
chain: environment.chain,
|
|
55
82
|
transport: http(environment.accountAbstraction.paymasterUrl),
|
|
56
83
|
entryPoint: environment.accountAbstraction.entryPoint
|
|
57
84
|
});
|
|
58
|
-
|
|
59
|
-
const getGasPrice =
|
|
60
|
-
if (!cachedGasPrice || Date.now() - cachedGasPrice.fetchedAt >= gasPriceCacheTtlMs) {
|
|
61
|
-
const result = paymaster.getUserOperationGasPrice();
|
|
62
|
-
const entry = {
|
|
63
|
-
fetchedAt: Date.now(),
|
|
64
|
-
result
|
|
65
|
-
};
|
|
66
|
-
cachedGasPrice = entry;
|
|
67
|
-
result.catch(() => {
|
|
68
|
-
if (cachedGasPrice === entry) cachedGasPrice = void 0;
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
return cachedGasPrice.result;
|
|
72
|
-
};
|
|
85
|
+
const gasPrice = cachedForTtl(() => paymaster.getUserOperationGasPrice(), gasPriceCacheTtlMs);
|
|
86
|
+
const getGasPrice = gasPrice.get;
|
|
73
87
|
const client = createSmartAccountClient({
|
|
74
88
|
account,
|
|
75
89
|
chain: environment.chain,
|
|
76
|
-
paymaster
|
|
90
|
+
paymaster: {
|
|
91
|
+
getPaymasterStubData: (parameters) => paymaster.getPaymasterStubData(parameters),
|
|
92
|
+
getPaymasterData: (parameters) => paymaster.getPaymasterData(parameters)
|
|
93
|
+
},
|
|
77
94
|
bundlerTransport: http(environment.accountAbstraction.bundlerUrl),
|
|
78
95
|
pollingInterval: pollingIntervalMs,
|
|
79
96
|
userOperation: {
|
|
@@ -87,25 +104,41 @@ function createPolyesterSmartAccountClient(account, params) {
|
|
|
87
104
|
}
|
|
88
105
|
}
|
|
89
106
|
});
|
|
90
|
-
|
|
107
|
+
smartAccountClientPrimers.set(client, () => Promise.allSettled([getGasPrice()]));
|
|
108
|
+
smartAccountClientCacheResets.set(client, () => {
|
|
109
|
+
gasPrice.clear();
|
|
110
|
+
});
|
|
91
111
|
return client;
|
|
92
112
|
}
|
|
93
|
-
/**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
113
|
+
/** Memoizes a promise-returning fetch for `ttlMs`; a rejected fetch is not cached. */
|
|
114
|
+
function cachedForTtl(fetch, ttlMs) {
|
|
115
|
+
let cached;
|
|
116
|
+
return {
|
|
117
|
+
get: () => {
|
|
118
|
+
if (!cached || Date.now() - cached.fetchedAt >= ttlMs) {
|
|
119
|
+
const entry = {
|
|
120
|
+
fetchedAt: Date.now(),
|
|
121
|
+
result: fetch()
|
|
122
|
+
};
|
|
123
|
+
cached = entry;
|
|
124
|
+
entry.result.catch(() => {
|
|
125
|
+
if (cached === entry) cached = void 0;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return cached.result;
|
|
129
|
+
},
|
|
130
|
+
clear: () => {
|
|
131
|
+
cached = void 0;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
104
134
|
}
|
|
105
135
|
function addUserOperationGasBuffer(gas) {
|
|
106
136
|
const percentBuffer = gas * USER_OPERATION_GAS_BUFFER_BPS / 10000n;
|
|
107
137
|
return gas + (percentBuffer > USER_OPERATION_MIN_GAS_BUFFER ? percentBuffer : USER_OPERATION_MIN_GAS_BUFFER);
|
|
108
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Pads account and paymaster gas limits (+20%, 50k floor) before getPaymasterData.
|
|
141
|
+
*/
|
|
109
142
|
function bufferPolyesterUserOperationGas(gas) {
|
|
110
143
|
return {
|
|
111
144
|
...gas,
|
|
@@ -116,22 +149,113 @@ function bufferPolyesterUserOperationGas(gas) {
|
|
|
116
149
|
...typeof gas.paymasterVerificationGasLimit === "bigint" ? { paymasterVerificationGasLimit: addUserOperationGasBuffer(gas.paymasterVerificationGasLimit) } : {}
|
|
117
150
|
};
|
|
118
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Warms the network path for an upcoming submission: primes the gas-price
|
|
154
|
+
* cache and opens connections to the RPC endpoint. Never
|
|
155
|
+
* throws; the nonce is intentionally not cached — fetching it here is
|
|
156
|
+
* connection warm-up only.
|
|
157
|
+
*/
|
|
158
|
+
async function warmPolyesterSmartAccountClient(client) {
|
|
159
|
+
await Promise.allSettled([
|
|
160
|
+
smartAccountClientPrimers.get(client)?.(),
|
|
161
|
+
client.account.getNonce(),
|
|
162
|
+
client.account.isDeployed()
|
|
163
|
+
]);
|
|
164
|
+
}
|
|
119
165
|
async function sendPolyesterUserOperation(client, parameters, options = {}) {
|
|
120
|
-
const { onWalletSignatureRequested } = options;
|
|
121
|
-
if (!onWalletSignatureRequested) return client.sendUserOperation(parameters);
|
|
166
|
+
const { onWalletSignatureRequested, onPhase } = options;
|
|
122
167
|
const account = parameters.account ?? client.account;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
168
|
+
let phaseStartedAt = Date.now();
|
|
169
|
+
const endPhase = (phase) => {
|
|
170
|
+
const now = Date.now();
|
|
171
|
+
reportPhase(onPhase, phase, now - phaseStartedAt);
|
|
172
|
+
phaseStartedAt = now;
|
|
173
|
+
};
|
|
174
|
+
let signed = false;
|
|
175
|
+
try {
|
|
176
|
+
const hash = await client.sendUserOperation({
|
|
177
|
+
...parameters,
|
|
178
|
+
account: {
|
|
179
|
+
...account,
|
|
180
|
+
signUserOperation: async (userOperation) => {
|
|
181
|
+
endPhase("prepare");
|
|
182
|
+
onWalletSignatureRequested?.();
|
|
183
|
+
const signature = await account.signUserOperation(userOperation);
|
|
184
|
+
signed = true;
|
|
185
|
+
endPhase("sign");
|
|
186
|
+
return signature;
|
|
187
|
+
}
|
|
130
188
|
}
|
|
189
|
+
});
|
|
190
|
+
endPhase("send");
|
|
191
|
+
return hash;
|
|
192
|
+
} catch (error) {
|
|
193
|
+
if (signed) smartAccountClientCacheResets.get(client)?.();
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** Observers must never affect the result: a throwing `onPhase` is swallowed. */
|
|
198
|
+
function reportPhase(onPhase, phase, ms) {
|
|
199
|
+
try {
|
|
200
|
+
onPhase?.(phase, ms);
|
|
201
|
+
} catch {}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Waits for a UserOperation to land. Polls the bundler's cheap
|
|
205
|
+
* `pimlico_getUserOperationStatus` at the client's polling interval, checking
|
|
206
|
+
* immediately, and only fetches the receipt once the bundler reports it has
|
|
207
|
+
* been mined. Status lives in bundler memory, so `not_found` (e.g. after a
|
|
208
|
+
* bundler restart) also checks the chain for a receipt until the deadline.
|
|
209
|
+
* `timeoutMs` bounds every request, not just the gaps between them.
|
|
210
|
+
*/
|
|
211
|
+
async function waitForPolyesterUserOperationReceipt(client, hash, options = {}) {
|
|
212
|
+
const { timeoutMs = 12e4, onPhase } = options;
|
|
213
|
+
const startedAt = Date.now();
|
|
214
|
+
const deadline = startedAt + timeoutMs;
|
|
215
|
+
const timedOut = () => /* @__PURE__ */ new Error(`Timed out waiting for UserOperation ${hash}.`);
|
|
216
|
+
const untilDeadline = (fn) => {
|
|
217
|
+
const timeout = deadline - Date.now();
|
|
218
|
+
if (timeout <= 0) return Promise.reject(timedOut());
|
|
219
|
+
return withTimeout(fn, {
|
|
220
|
+
timeout,
|
|
221
|
+
errorInstance: timedOut()
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
const statusClient = client;
|
|
225
|
+
let consecutiveNotFound = 0;
|
|
226
|
+
for (;;) {
|
|
227
|
+
const { status } = await untilDeadline(() => getUserOperationStatus(statusClient, { hash }));
|
|
228
|
+
if (status === "included" || status === "reverted") {
|
|
229
|
+
const receipt = await untilDeadline(() => client.waitForUserOperationReceipt({
|
|
230
|
+
hash,
|
|
231
|
+
timeout: deadline - Date.now()
|
|
232
|
+
}));
|
|
233
|
+
reportPhase(onPhase, "receipt", Date.now() - startedAt);
|
|
234
|
+
return receipt;
|
|
131
235
|
}
|
|
132
|
-
|
|
236
|
+
if (status === "failed") throw new Error(`UserOperation ${hash} was bundled but the bundle transaction reverted; it was not executed.`);
|
|
237
|
+
if (status === "rejected") {
|
|
238
|
+
smartAccountClientCacheResets.get(client)?.();
|
|
239
|
+
throw new Error(`UserOperation ${hash} was rejected by the bundler.`);
|
|
240
|
+
}
|
|
241
|
+
if (status === "not_found") {
|
|
242
|
+
if (consecutiveNotFound++ % NOT_FOUND_RECEIPT_CHECK_EVERY === 0) {
|
|
243
|
+
const receipt = await untilDeadline(() => client.getUserOperationReceipt({ hash })).catch((error) => {
|
|
244
|
+
if (error.name === "UserOperationReceiptNotFoundError") return void 0;
|
|
245
|
+
throw error;
|
|
246
|
+
});
|
|
247
|
+
if (receipt) {
|
|
248
|
+
reportPhase(onPhase, "receipt", Date.now() - startedAt);
|
|
249
|
+
return receipt;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
} else consecutiveNotFound = 0;
|
|
253
|
+
const remaining = deadline - Date.now();
|
|
254
|
+
if (remaining <= 0) throw timedOut();
|
|
255
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(client.pollingInterval, remaining)));
|
|
256
|
+
}
|
|
133
257
|
}
|
|
134
258
|
//#endregion
|
|
135
|
-
export { createPolyesterSmartAccount, createPolyesterSmartAccountClient, predictPolyesterSmartAccountAddress, sendPolyesterUserOperation, warmPolyesterSmartAccountClient };
|
|
259
|
+
export { createPolyesterSmartAccount, createPolyesterSmartAccountClient, predictPolyesterSmartAccountAddress, sendPolyesterUserOperation, waitForPolyesterUserOperationReceipt, warmPolyesterSmartAccountClient };
|
|
136
260
|
|
|
137
261
|
//# sourceMappingURL=smart-account.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smart-account.js","names":[],"sources":["../../src/smart-account/smart-account.ts"],"sourcesContent":["import type { Address, LocalAccount, PublicClient } from \"viem\";\nimport { createPublicClient, http } from \"viem\";\nimport type { EstimateUserOperationGasParameters } from \"viem/account-abstraction\";\nimport { estimateUserOperationGas, prepareUserOperation } from \"viem/account-abstraction\";\nimport { createSmartAccountClient } from \"permissionless\";\nimport { toSafeSmartAccount } from \"permissionless/accounts\";\nimport { createPimlicoClient } from \"permissionless/clients/pimlico\";\nimport type { PolyesterEnvironment } from \"../environment.js\";\nimport { predictSafeAddress } from \"../account-signer/predict-safe-address.js\";\n\nexport type SafeSmartAccountInstance = Awaited<ReturnType<typeof toSafeSmartAccount>>;\nexport type PolyesterSmartAccountClient = ReturnType<typeof createPolyesterSmartAccountClient>;\n\nconst smartAccountEnvironmentFingerprints = new WeakMap<SafeSmartAccountInstance, string>();\nconst smartAccountClientGasPricePrimers = new WeakMap<object, () => Promise<unknown>>();\nconst USER_OPERATION_GAS_BUFFER_BPS = 2_000n;\nconst USER_OPERATION_MIN_GAS_BUFFER = 50_000n;\nconst USER_OPERATION_GAS_PRICE_TTL_MS = 10_000;\nconst USER_OPERATION_RECEIPT_POLLING_INTERVAL_MS = 1_000;\n\ntype PolyesterUserOperationGas = {\n callGasLimit?: bigint;\n preVerificationGas?: bigint;\n verificationGasLimit?: bigint;\n paymasterPostOpGasLimit?: bigint;\n paymasterVerificationGasLimit?: bigint;\n};\n\nexport interface CreateSmartAccountParams {\n environment: PolyesterEnvironment;\n owner: LocalAccount;\n saltNonce?: bigint;\n publicClient?: PublicClient;\n}\n\nexport interface PredictPolyesterSmartAccountAddressParams {\n environment: PolyesterEnvironment;\n ownerAddress: Address;\n saltNonce?: bigint;\n}\n\nexport function predictPolyesterSmartAccountAddress({\n environment,\n ownerAddress,\n saltNonce = 0n,\n}: PredictPolyesterSmartAccountAddressParams): Address {\n const {\n safeProxyFactoryAddress,\n safeSingletonAddress,\n safeModuleSetupAddress,\n safe4337ModuleAddress,\n multiSendAddress,\n } = environment.accountAbstraction.safe;\n\n return predictSafeAddress({\n owners: [ownerAddress],\n saltNonce,\n safeProxyFactoryAddress,\n safeSingletonAddress,\n safeModuleSetupAddress,\n safe4337ModuleAddress,\n multiSendAddress,\n });\n}\n\n/**\n * Creates a Polyester smart account instance.\n */\nexport async function createPolyesterSmartAccount({\n environment,\n owner,\n saltNonce,\n publicClient,\n}: CreateSmartAccountParams): Promise<SafeSmartAccountInstance> {\n const client =\n publicClient ??\n createPublicClient({\n chain: environment.chain,\n transport: http(environment.rpcUrl),\n });\n\n if (client.chain?.id && client.chain.id !== environment.chain.id) {\n throw new Error(\"Smart account public client chain does not match environment.\");\n }\n\n const account = await toSafeSmartAccount({\n client,\n owners: [owner],\n saltNonce,\n entryPoint: environment.accountAbstraction.entryPoint,\n ...environment.accountAbstraction.safe,\n });\n smartAccountEnvironmentFingerprints.set(account, environment.fingerprint);\n return account;\n}\n\nexport interface PolyesterSmartAccountClientOptions {\n /** How long a fetched gas price is reused, in milliseconds. Defaults to 10s. */\n gasPriceCacheTtlMs?: number;\n /** How often to poll for UserOperation receipts, in milliseconds. Defaults to 1s. */\n pollingIntervalMs?: number;\n}\n\n/**\n * Creates a viem client bound to a Polyester smart account.\n */\nexport function createPolyesterSmartAccountClient(\n account: SafeSmartAccountInstance,\n params: {\n environment: PolyesterEnvironment;\n options?: PolyesterSmartAccountClientOptions;\n },\n) {\n const { environment, options } = params;\n const {\n gasPriceCacheTtlMs = USER_OPERATION_GAS_PRICE_TTL_MS,\n pollingIntervalMs = USER_OPERATION_RECEIPT_POLLING_INTERVAL_MS,\n } = options ?? {};\n const accountEnvironmentFingerprint = smartAccountEnvironmentFingerprints.get(account);\n if (\n accountEnvironmentFingerprint &&\n accountEnvironmentFingerprint !== environment.fingerprint\n ) {\n throw new Error(\"Smart account environment does not match client environment.\");\n }\n\n const paymaster = createPimlicoClient({\n chain: environment.chain,\n transport: http(environment.accountAbstraction.paymasterUrl),\n entryPoint: environment.accountAbstraction.entryPoint,\n });\n\n let cachedGasPrice:\n | { fetchedAt: number; result: ReturnType<typeof paymaster.getUserOperationGasPrice> }\n | undefined;\n const getGasPrice = () => {\n if (!cachedGasPrice || Date.now() - cachedGasPrice.fetchedAt >= gasPriceCacheTtlMs) {\n const result = paymaster.getUserOperationGasPrice();\n const entry = { fetchedAt: Date.now(), result };\n cachedGasPrice = entry;\n result.catch(() => {\n if (cachedGasPrice === entry) cachedGasPrice = undefined;\n });\n }\n return cachedGasPrice.result;\n };\n\n const client = createSmartAccountClient({\n account,\n chain: environment.chain,\n paymaster,\n bundlerTransport: http(environment.accountAbstraction.bundlerUrl),\n pollingInterval: pollingIntervalMs,\n userOperation: {\n estimateFeesPerGas: async () => (await getGasPrice()).fast,\n // Single prepare pass: viem resolves gas estimation via\n // `getAction(client, estimateUserOperationGas, ...)`, so handing\n // `prepareUserOperation` a client whose estimate action buffers the\n // result makes the buffered limits flow into `pm_getPaymasterData`\n // before signing — the sponsorship signature commits to them.\n prepareUserOperation: (prepareClient, prepareParameters) => {\n const bufferingClient = {\n ...prepareClient,\n estimateUserOperationGas: async (\n estimateParameters: EstimateUserOperationGasParameters,\n ) =>\n bufferPolyesterUserOperationGas(\n await estimateUserOperationGas(prepareClient, estimateParameters),\n ),\n };\n return prepareUserOperation(\n bufferingClient as typeof prepareClient,\n prepareParameters as Parameters<typeof prepareUserOperation>[1],\n );\n },\n },\n });\n smartAccountClientGasPricePrimers.set(client, getGasPrice);\n return client;\n}\n\n/**\n * Warms the network path for an upcoming submission: primes the gas-price\n * cache and opens connections to the RPC endpoint. Never throws; the nonce is\n * intentionally not cached — fetching it here is connection warm-up only.\n */\nexport async function warmPolyesterSmartAccountClient(\n client: PolyesterSmartAccountClient,\n): Promise<void> {\n await Promise.allSettled([\n smartAccountClientGasPricePrimers.get(client)?.(),\n client.account.getNonce(),\n client.account.isDeployed(),\n ]);\n}\n\nfunction addUserOperationGasBuffer(gas: bigint): bigint {\n const percentBuffer = (gas * USER_OPERATION_GAS_BUFFER_BPS) / 10_000n;\n return (\n gas +\n (percentBuffer > USER_OPERATION_MIN_GAS_BUFFER\n ? percentBuffer\n : USER_OPERATION_MIN_GAS_BUFFER)\n );\n}\n\nfunction bufferPolyesterUserOperationGas<T extends PolyesterUserOperationGas>(gas: T): T {\n return {\n ...gas,\n ...(typeof gas.callGasLimit === \"bigint\"\n ? { callGasLimit: addUserOperationGasBuffer(gas.callGasLimit) }\n : {}),\n ...(typeof gas.preVerificationGas === \"bigint\"\n ? { preVerificationGas: addUserOperationGasBuffer(gas.preVerificationGas) }\n : {}),\n ...(typeof gas.verificationGasLimit === \"bigint\"\n ? { verificationGasLimit: addUserOperationGasBuffer(gas.verificationGasLimit) }\n : {}),\n ...(typeof gas.paymasterPostOpGasLimit === \"bigint\"\n ? { paymasterPostOpGasLimit: addUserOperationGasBuffer(gas.paymasterPostOpGasLimit) }\n : {}),\n ...(typeof gas.paymasterVerificationGasLimit === \"bigint\"\n ? {\n paymasterVerificationGasLimit: addUserOperationGasBuffer(\n gas.paymasterVerificationGasLimit,\n ),\n }\n : {}),\n };\n}\n\nexport interface SendPolyesterUserOperationOptions {\n /**\n * Fires once per submission, immediately before the wallet is asked to\n * sign the fully prepared operation — the prepare→sign boundary.\n */\n onWalletSignatureRequested?: () => void;\n}\n\nexport async function sendPolyesterUserOperation(\n client: PolyesterSmartAccountClient,\n parameters: Parameters<PolyesterSmartAccountClient[\"sendUserOperation\"]>[0],\n options: SendPolyesterUserOperationOptions = {},\n): Promise<Awaited<ReturnType<PolyesterSmartAccountClient[\"sendUserOperation\"]>>> {\n const { onWalletSignatureRequested } = options;\n if (!onWalletSignatureRequested) return client.sendUserOperation(parameters);\n\n const account =\n (parameters as { account?: SafeSmartAccountInstance }).account ?? client.account;\n return client.sendUserOperation({\n ...parameters,\n account: {\n ...account,\n signUserOperation: (\n userOperation: Parameters<SafeSmartAccountInstance[\"signUserOperation\"]>[0],\n ) => {\n onWalletSignatureRequested();\n return account.signUserOperation(userOperation);\n },\n },\n } as Parameters<PolyesterSmartAccountClient[\"sendUserOperation\"]>[0]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"smart-account.js","names":[],"sources":["../../src/smart-account/smart-account.ts"],"sourcesContent":["import type { Address, LocalAccount, PublicClient } from \"viem\";\nimport { createPublicClient, http, withTimeout } from \"viem\";\nimport type { EstimateUserOperationGasParameters } from \"viem/account-abstraction\";\nimport { estimateUserOperationGas, prepareUserOperation } from \"viem/account-abstraction\";\nimport { createSmartAccountClient } from \"permissionless\";\nimport { getUserOperationStatus } from \"permissionless/actions/pimlico\";\nimport { toSafeSmartAccount } from \"permissionless/accounts\";\nimport { createPimlicoClient } from \"permissionless/clients/pimlico\";\nimport type { PolyesterEnvironment } from \"../environment.js\";\nimport { predictSafeAddress } from \"../account-signer/predict-safe-address.js\";\n\nexport type SafeSmartAccountInstance = Awaited<ReturnType<typeof toSafeSmartAccount>>;\nexport type PolyesterSmartAccountClient = ReturnType<typeof buildPolyesterSmartAccountClient>;\n\nconst smartAccountEnvironmentFingerprints = new WeakMap<SafeSmartAccountInstance, string>();\nconst smartAccountClientPrimers = new WeakMap<object, () => Promise<unknown>>();\nconst smartAccountClientCacheResets = new WeakMap<object, () => void>();\nconst smartAccountClients = new WeakMap<\n SafeSmartAccountInstance,\n Map<string, PolyesterSmartAccountClient>\n>();\nconst USER_OPERATION_GAS_PRICE_TTL_MS = 60_000;\nconst USER_OPERATION_GAS_BUFFER_BPS = 2_000n;\nconst USER_OPERATION_MIN_GAS_BUFFER = 50_000n;\nconst USER_OPERATION_RECEIPT_POLLING_INTERVAL_MS = 250;\n/**\n * While the bundler reports `not_found`, the chain is checked for a receipt\n * on every Nth poll (once per second at the default interval). `not_found` is\n * not definitive — a bundler restart forgets ops whose bundle is still\n * pending — so polling continues until the deadline.\n */\nconst NOT_FOUND_RECEIPT_CHECK_EVERY = 4;\n\nexport interface CreateSmartAccountParams {\n environment: PolyesterEnvironment;\n owner: LocalAccount;\n saltNonce?: bigint;\n publicClient?: PublicClient;\n}\n\nexport interface PredictPolyesterSmartAccountAddressParams {\n environment: PolyesterEnvironment;\n ownerAddress: Address;\n saltNonce?: bigint;\n}\n\nexport function predictPolyesterSmartAccountAddress({\n environment,\n ownerAddress,\n saltNonce = 0n,\n}: PredictPolyesterSmartAccountAddressParams): Address {\n const {\n safeProxyFactoryAddress,\n safeSingletonAddress,\n safeModuleSetupAddress,\n safe4337ModuleAddress,\n multiSendAddress,\n } = environment.accountAbstraction.safe;\n\n return predictSafeAddress({\n owners: [ownerAddress],\n saltNonce,\n safeProxyFactoryAddress,\n safeSingletonAddress,\n safeModuleSetupAddress,\n safe4337ModuleAddress,\n multiSendAddress,\n });\n}\n\n/**\n * Creates a Polyester smart account instance.\n */\nexport async function createPolyesterSmartAccount({\n environment,\n owner,\n saltNonce,\n publicClient,\n}: CreateSmartAccountParams): Promise<SafeSmartAccountInstance> {\n const client =\n publicClient ??\n createPublicClient({\n chain: environment.chain,\n transport: http(environment.rpcUrl),\n });\n\n if (client.chain?.id && client.chain.id !== environment.chain.id) {\n throw new Error(\"Smart account public client chain does not match environment.\");\n }\n\n const account = await toSafeSmartAccount({\n client,\n owners: [owner],\n saltNonce,\n entryPoint: environment.accountAbstraction.entryPoint,\n ...environment.accountAbstraction.safe,\n });\n smartAccountEnvironmentFingerprints.set(account, environment.fingerprint);\n return account;\n}\n\nexport interface PolyesterSmartAccountClientOptions {\n /** How long a fetched gas price is reused, in milliseconds. Defaults to 60s. */\n gasPriceCacheTtlMs?: number;\n /** How often to poll for UserOperation inclusion, in milliseconds. Defaults to 250ms. */\n pollingIntervalMs?: number;\n}\n\n/**\n * Creates a viem client bound to a Polyester smart account. Memoized per\n * (account, environment, options): repeat calls return the same client, so\n * the gas price cache and warmed connections survive across submissions.\n */\nexport function createPolyesterSmartAccountClient(\n account: SafeSmartAccountInstance,\n params: {\n environment: PolyesterEnvironment;\n options?: PolyesterSmartAccountClientOptions;\n },\n) {\n const { environment, options } = params;\n const accountEnvironmentFingerprint = smartAccountEnvironmentFingerprints.get(account);\n if (\n accountEnvironmentFingerprint &&\n accountEnvironmentFingerprint !== environment.fingerprint\n ) {\n throw new Error(\"Smart account environment does not match client environment.\");\n }\n let clients = smartAccountClients.get(account);\n if (!clients) smartAccountClients.set(account, (clients = new Map()));\n const key = JSON.stringify([\n environment.fingerprint,\n options?.gasPriceCacheTtlMs ?? USER_OPERATION_GAS_PRICE_TTL_MS,\n options?.pollingIntervalMs ?? USER_OPERATION_RECEIPT_POLLING_INTERVAL_MS,\n ]);\n let client = clients.get(key);\n if (!client) {\n client = buildPolyesterSmartAccountClient(account, environment, options);\n clients.set(key, client);\n }\n return client;\n}\n\nfunction buildPolyesterSmartAccountClient(\n account: SafeSmartAccountInstance,\n environment: PolyesterEnvironment,\n options: PolyesterSmartAccountClientOptions | undefined,\n) {\n const {\n gasPriceCacheTtlMs = USER_OPERATION_GAS_PRICE_TTL_MS,\n pollingIntervalMs = USER_OPERATION_RECEIPT_POLLING_INTERVAL_MS,\n } = options ?? {};\n\n const paymaster = createPimlicoClient({\n chain: environment.chain,\n transport: http(environment.accountAbstraction.paymasterUrl),\n entryPoint: environment.accountAbstraction.entryPoint,\n });\n\n const gasPrice = cachedForTtl(() => paymaster.getUserOperationGasPrice(), gasPriceCacheTtlMs);\n const getGasPrice = gasPrice.get;\n\n const client = createSmartAccountClient({\n account,\n chain: environment.chain,\n paymaster: {\n getPaymasterStubData: (parameters) => paymaster.getPaymasterStubData(parameters),\n getPaymasterData: (parameters) => paymaster.getPaymasterData(parameters),\n },\n bundlerTransport: http(environment.accountAbstraction.bundlerUrl),\n pollingInterval: pollingIntervalMs,\n userOperation: {\n estimateFeesPerGas: async () => (await getGasPrice()).fast,\n // Single prepare pass: viem resolves gas estimation via\n // `getAction(client, estimateUserOperationGas, ...)`, so handing\n // `prepareUserOperation` a client whose estimate action buffers the\n // result makes the buffered limits flow into getPaymasterData\n // before signing — the sponsorship signature commits to them.\n prepareUserOperation: (prepareClient, prepareParameters) => {\n const bufferingClient = {\n ...prepareClient,\n estimateUserOperationGas: async (\n estimateParameters: EstimateUserOperationGasParameters,\n ) =>\n bufferPolyesterUserOperationGas(\n await estimateUserOperationGas(prepareClient, estimateParameters),\n ),\n };\n return prepareUserOperation(\n bufferingClient as typeof prepareClient,\n prepareParameters as Parameters<typeof prepareUserOperation>[1],\n );\n },\n },\n });\n smartAccountClientPrimers.set(client, () => Promise.allSettled([getGasPrice()]));\n smartAccountClientCacheResets.set(client, () => {\n gasPrice.clear();\n });\n return client;\n}\n\n/** Memoizes a promise-returning fetch for `ttlMs`; a rejected fetch is not cached. */\nfunction cachedForTtl<T>(\n fetch: () => Promise<T>,\n ttlMs: number,\n): { get: () => Promise<T>; clear: () => void } {\n let cached: { fetchedAt: number; result: Promise<T> } | undefined;\n return {\n get: () => {\n if (!cached || Date.now() - cached.fetchedAt >= ttlMs) {\n const entry = { fetchedAt: Date.now(), result: fetch() };\n cached = entry;\n entry.result.catch(() => {\n if (cached === entry) cached = undefined;\n });\n }\n return cached.result;\n },\n clear: () => {\n cached = undefined;\n },\n };\n}\n\nfunction addUserOperationGasBuffer(gas: bigint): bigint {\n const percentBuffer = (gas * USER_OPERATION_GAS_BUFFER_BPS) / 10_000n;\n return (\n gas +\n (percentBuffer > USER_OPERATION_MIN_GAS_BUFFER\n ? percentBuffer\n : USER_OPERATION_MIN_GAS_BUFFER)\n );\n}\n\n/**\n * Pads account and paymaster gas limits (+20%, 50k floor) before getPaymasterData.\n */\nfunction bufferPolyesterUserOperationGas<\n T extends {\n callGasLimit?: bigint;\n preVerificationGas?: bigint;\n verificationGasLimit?: bigint;\n paymasterPostOpGasLimit?: bigint;\n paymasterVerificationGasLimit?: bigint;\n },\n>(gas: T): T {\n return {\n ...gas,\n ...(typeof gas.callGasLimit === \"bigint\"\n ? { callGasLimit: addUserOperationGasBuffer(gas.callGasLimit) }\n : {}),\n ...(typeof gas.preVerificationGas === \"bigint\"\n ? { preVerificationGas: addUserOperationGasBuffer(gas.preVerificationGas) }\n : {}),\n ...(typeof gas.verificationGasLimit === \"bigint\"\n ? { verificationGasLimit: addUserOperationGasBuffer(gas.verificationGasLimit) }\n : {}),\n ...(typeof gas.paymasterPostOpGasLimit === \"bigint\"\n ? { paymasterPostOpGasLimit: addUserOperationGasBuffer(gas.paymasterPostOpGasLimit) }\n : {}),\n ...(typeof gas.paymasterVerificationGasLimit === \"bigint\"\n ? {\n paymasterVerificationGasLimit: addUserOperationGasBuffer(\n gas.paymasterVerificationGasLimit,\n ),\n }\n : {}),\n };\n}\n\n/**\n * Warms the network path for an upcoming submission: primes the gas-price\n * cache and opens connections to the RPC endpoint. Never\n * throws; the nonce is intentionally not cached — fetching it here is\n * connection warm-up only.\n */\nexport async function warmPolyesterSmartAccountClient(\n client: PolyesterSmartAccountClient,\n): Promise<void> {\n await Promise.allSettled([\n smartAccountClientPrimers.get(client)?.(),\n client.account.getNonce(),\n client.account.isDeployed(),\n ]);\n}\n\nexport type PolyesterUserOperationPhase = \"prepare\" | \"sign\" | \"send\" | \"receipt\";\n\nexport interface SendPolyesterUserOperationOptions {\n /**\n * Fires once per submission, immediately before the wallet is asked to\n * sign the fully prepared operation — the prepare→sign boundary.\n */\n onWalletSignatureRequested?: () => void;\n /**\n * Reports how long each submission phase took. `prepare` covers nonce,\n * fees and sponsorship; `sign` the wallet signature; `send`\n * `eth_sendUserOperation`. Pass the same callback to\n * {@link waitForPolyesterUserOperationReceipt} to get `receipt`.\n */\n onPhase?: (phase: PolyesterUserOperationPhase, ms: number) => void;\n}\n\nexport async function sendPolyesterUserOperation(\n client: PolyesterSmartAccountClient,\n parameters: Parameters<PolyesterSmartAccountClient[\"sendUserOperation\"]>[0],\n options: SendPolyesterUserOperationOptions = {},\n): Promise<Awaited<ReturnType<PolyesterSmartAccountClient[\"sendUserOperation\"]>>> {\n const { onWalletSignatureRequested, onPhase } = options;\n const account =\n (parameters as { account?: SafeSmartAccountInstance }).account ?? client.account;\n let phaseStartedAt = Date.now();\n const endPhase = (phase: PolyesterUserOperationPhase) => {\n const now = Date.now();\n reportPhase(onPhase, phase, now - phaseStartedAt);\n phaseStartedAt = now;\n };\n let signed = false;\n try {\n const hash = await client.sendUserOperation({\n ...parameters,\n account: {\n ...account,\n signUserOperation: async (\n userOperation: Parameters<SafeSmartAccountInstance[\"signUserOperation\"]>[0],\n ) => {\n endPhase(\"prepare\");\n onWalletSignatureRequested?.();\n const signature = await account.signUserOperation(userOperation);\n signed = true;\n endPhase(\"sign\");\n return signature;\n },\n },\n } as Parameters<PolyesterSmartAccountClient[\"sendUserOperation\"]>[0]);\n endPhase(\"send\");\n return hash;\n } catch (error) {\n // Only a failure after signing (i.e. from `eth_sendUserOperation`) can\n // mean the bundler rejected the cached gas price. Earlier\n // failures — a cancelled wallet prompt above all — keep the cache so\n // the retry stays cheap.\n if (signed) smartAccountClientCacheResets.get(client)?.();\n throw error;\n }\n}\n\n/** Observers must never affect the result: a throwing `onPhase` is swallowed. */\nfunction reportPhase(\n onPhase: SendPolyesterUserOperationOptions[\"onPhase\"],\n phase: PolyesterUserOperationPhase,\n ms: number,\n): void {\n try {\n onPhase?.(phase, ms);\n } catch {\n // ignore\n }\n}\n\nexport interface WaitForPolyesterUserOperationReceiptOptions {\n /** Overall deadline in milliseconds. Defaults to viem's 120s. */\n timeoutMs?: number;\n /** Receives `(\"receipt\", ms)` once the receipt is available. */\n onPhase?: SendPolyesterUserOperationOptions[\"onPhase\"];\n}\n\n/**\n * Waits for a UserOperation to land. Polls the bundler's cheap\n * `pimlico_getUserOperationStatus` at the client's polling interval, checking\n * immediately, and only fetches the receipt once the bundler reports it has\n * been mined. Status lives in bundler memory, so `not_found` (e.g. after a\n * bundler restart) also checks the chain for a receipt until the deadline.\n * `timeoutMs` bounds every request, not just the gaps between them.\n */\nexport async function waitForPolyesterUserOperationReceipt(\n client: PolyesterSmartAccountClient,\n hash: `0x${string}`,\n options: WaitForPolyesterUserOperationReceiptOptions = {},\n): Promise<Awaited<ReturnType<PolyesterSmartAccountClient[\"waitForUserOperationReceipt\"]>>> {\n const { timeoutMs = 120_000, onPhase } = options;\n const startedAt = Date.now();\n const deadline = startedAt + timeoutMs;\n const timedOut = () => new Error(`Timed out waiting for UserOperation ${hash}.`);\n const untilDeadline = <T>(fn: () => Promise<T>): Promise<T> => {\n const timeout = deadline - Date.now();\n if (timeout <= 0) return Promise.reject(timedOut());\n return withTimeout(fn, { timeout, errorInstance: timedOut() });\n };\n const statusClient = client as unknown as Parameters<typeof getUserOperationStatus>[0];\n\n let consecutiveNotFound = 0;\n for (;;) {\n const { status } = await untilDeadline(() =>\n getUserOperationStatus(statusClient, { hash }),\n );\n if (status === \"included\" || status === \"reverted\") {\n const receipt = await untilDeadline(() =>\n client.waitForUserOperationReceipt({ hash, timeout: deadline - Date.now() }),\n );\n reportPhase(onPhase, \"receipt\", Date.now() - startedAt);\n return receipt;\n }\n if (status === \"failed\") {\n throw new Error(\n `UserOperation ${hash} was bundled but the bundle transaction reverted; it was not executed.`,\n );\n }\n if (status === \"rejected\") {\n // Re-simulation failures are often fee-too-low: drop cached prices.\n smartAccountClientCacheResets.get(client)?.();\n throw new Error(`UserOperation ${hash} was rejected by the bundler.`);\n }\n if (status === \"not_found\") {\n if (consecutiveNotFound++ % NOT_FOUND_RECEIPT_CHECK_EVERY === 0) {\n const receipt = await untilDeadline(() =>\n client.getUserOperationReceipt({ hash }),\n ).catch((error: Error) => {\n if (error.name === \"UserOperationReceiptNotFoundError\") return undefined;\n throw error;\n });\n if (receipt) {\n reportPhase(onPhase, \"receipt\", Date.now() - startedAt);\n return receipt;\n }\n }\n } else {\n consecutiveNotFound = 0;\n }\n const remaining = deadline - Date.now();\n if (remaining <= 0) throw timedOut();\n await new Promise((resolve) =>\n setTimeout(resolve, Math.min(client.pollingInterval, remaining)),\n );\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED