smart-multisig-engine 0.1.0
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 +409 -0
- package/dist/chunk-YQE6NIEB.js +210 -0
- package/dist/chunk-YQE6NIEB.js.map +1 -0
- package/dist/index.cjs +247 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +85 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/react.cjs +324 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +43 -0
- package/dist/react.d.ts +43 -0
- package/dist/react.js +106 -0
- package/dist/react.js.map +1 -0
- package/dist/types-BJD1jdcY.d.cts +64 -0
- package/dist/types-BJD1jdcY.d.ts +64 -0
- package/package.json +70 -0
package/dist/react.cjs
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/react/index.ts
|
|
31
|
+
var react_exports = {};
|
|
32
|
+
__export(react_exports, {
|
|
33
|
+
useFetchPendingTxs: () => useFetchPendingTxs,
|
|
34
|
+
useSimulate: () => useSimulate,
|
|
35
|
+
useSubmitTx: () => useSubmitTx,
|
|
36
|
+
useWaitForExecution: () => useWaitForExecution,
|
|
37
|
+
useWrite: () => useWrite
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(react_exports);
|
|
40
|
+
|
|
41
|
+
// src/react/use-submit-tx.ts
|
|
42
|
+
var import_react_query = require("@tanstack/react-query");
|
|
43
|
+
|
|
44
|
+
// src/adapters/safe/simulate-contract-call.ts
|
|
45
|
+
var import_core = require("@wagmi/core");
|
|
46
|
+
async function simulateContractCall(config, params) {
|
|
47
|
+
return (0, import_core.simulateContract)(config, {
|
|
48
|
+
address: params.address,
|
|
49
|
+
abi: params.abi,
|
|
50
|
+
functionName: params.functionName,
|
|
51
|
+
args: params.args,
|
|
52
|
+
value: params.value,
|
|
53
|
+
chainId: params.chainId,
|
|
54
|
+
account: params.account
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/adapters/safe/write-contract-call.ts
|
|
59
|
+
var import_core2 = require("@wagmi/core");
|
|
60
|
+
async function writeContractCall(config, request) {
|
|
61
|
+
return (0, import_core2.writeContract)(config, request);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/adapters/safe/fetch-pending-transactions.ts
|
|
65
|
+
var import_api_kit = __toESM(require("@safe-global/api-kit"), 1);
|
|
66
|
+
async function fetchPendingTransactions(params) {
|
|
67
|
+
const apiKit = new import_api_kit.default({
|
|
68
|
+
chainId: params.chainId,
|
|
69
|
+
...params.txServiceUrl && { txServiceUrl: params.txServiceUrl },
|
|
70
|
+
apiKey: params.apiKey
|
|
71
|
+
});
|
|
72
|
+
const response = await apiKit.getPendingTransactions(params.safeAddress);
|
|
73
|
+
return response.results;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/core/extract-call-data.ts
|
|
77
|
+
var import_viem = require("viem");
|
|
78
|
+
function extractCallData(params) {
|
|
79
|
+
const data = (0, import_viem.encodeFunctionData)({
|
|
80
|
+
abi: params.abi,
|
|
81
|
+
functionName: params.functionName,
|
|
82
|
+
args: params.args
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
to: params.address,
|
|
86
|
+
data,
|
|
87
|
+
value: params.value ?? 0n
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/core/match-pending-tx.ts
|
|
92
|
+
function matchPendingTransaction(pendingTxs, criteria) {
|
|
93
|
+
return pendingTxs.find(
|
|
94
|
+
(tx) => tx.to.toLowerCase() === criteria.to.toLowerCase() && tx.value === String(criteria.value) && tx.data?.toLowerCase() === criteria.data.toLowerCase()
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/adapters/safe/submit-and-find-safe-tx.ts
|
|
99
|
+
function delay(ms) {
|
|
100
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
101
|
+
}
|
|
102
|
+
async function submitAndFindSafeTx(options) {
|
|
103
|
+
const {
|
|
104
|
+
config,
|
|
105
|
+
safeAddress,
|
|
106
|
+
txServiceUrl,
|
|
107
|
+
apiKey,
|
|
108
|
+
pollingInterval = 3e3,
|
|
109
|
+
maxAttempts = 20,
|
|
110
|
+
...callParams
|
|
111
|
+
} = options;
|
|
112
|
+
const callData = extractCallData(callParams);
|
|
113
|
+
const simulation = await simulateContractCall(config, callParams);
|
|
114
|
+
await writeContractCall(config, simulation.request);
|
|
115
|
+
const chainId = BigInt(callParams.chainId ?? await getChainId(config));
|
|
116
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
117
|
+
await delay(pollingInterval);
|
|
118
|
+
const pendingTxs = await fetchPendingTransactions({
|
|
119
|
+
chainId,
|
|
120
|
+
safeAddress,
|
|
121
|
+
txServiceUrl,
|
|
122
|
+
apiKey
|
|
123
|
+
});
|
|
124
|
+
const match = matchPendingTransaction(pendingTxs, callData);
|
|
125
|
+
if (match) {
|
|
126
|
+
return {
|
|
127
|
+
safeTxHash: match.safeTxHash
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
throw new Error(
|
|
132
|
+
`Could not find matching Safe transaction after ${maxAttempts} attempts`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
async function getChainId(config) {
|
|
136
|
+
const { getChainId: wagmiGetChainId } = await import("@wagmi/core");
|
|
137
|
+
return wagmiGetChainId(config);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/adapters/safe/wait-for-execution.ts
|
|
141
|
+
var import_api_kit2 = __toESM(require("@safe-global/api-kit"), 1);
|
|
142
|
+
function delay2(ms) {
|
|
143
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
144
|
+
}
|
|
145
|
+
async function waitForExecution(options) {
|
|
146
|
+
const {
|
|
147
|
+
safeTxHash,
|
|
148
|
+
chainId,
|
|
149
|
+
txServiceUrl,
|
|
150
|
+
apiKey,
|
|
151
|
+
pollingInterval = 5e3,
|
|
152
|
+
maxAttempts = 60
|
|
153
|
+
} = options;
|
|
154
|
+
const apiKit = new import_api_kit2.default({
|
|
155
|
+
chainId,
|
|
156
|
+
...txServiceUrl && { txServiceUrl },
|
|
157
|
+
apiKey
|
|
158
|
+
});
|
|
159
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
160
|
+
const tx = await apiKit.getTransaction(safeTxHash);
|
|
161
|
+
if (tx.isExecuted && tx.transactionHash) {
|
|
162
|
+
return {
|
|
163
|
+
transactionHash: tx.transactionHash
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
await delay2(pollingInterval);
|
|
167
|
+
}
|
|
168
|
+
throw new Error(
|
|
169
|
+
`Safe transaction ${safeTxHash} was not executed after ${maxAttempts} attempts`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// src/adapters/registry.ts
|
|
174
|
+
var adapters = {
|
|
175
|
+
safe: {
|
|
176
|
+
submitTx: submitAndFindSafeTx,
|
|
177
|
+
waitForExecution,
|
|
178
|
+
fetchPending: fetchPendingTransactions,
|
|
179
|
+
simulate: simulateContractCall,
|
|
180
|
+
write: writeContractCall
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// src/adapters/index.ts
|
|
185
|
+
async function submitTx(options) {
|
|
186
|
+
const { adapter, walletAddress, ...rest } = options;
|
|
187
|
+
assertAdapter(adapter);
|
|
188
|
+
const result = await adapters[adapter].submitTx({
|
|
189
|
+
safeAddress: walletAddress,
|
|
190
|
+
...rest
|
|
191
|
+
});
|
|
192
|
+
return { txHash: result.safeTxHash };
|
|
193
|
+
}
|
|
194
|
+
async function waitForExecution2(options) {
|
|
195
|
+
const { adapter, txHash, ...rest } = options;
|
|
196
|
+
assertAdapter(adapter);
|
|
197
|
+
const result = await adapters[adapter].waitForExecution({
|
|
198
|
+
safeTxHash: txHash,
|
|
199
|
+
...rest
|
|
200
|
+
});
|
|
201
|
+
return { transactionHash: result.transactionHash };
|
|
202
|
+
}
|
|
203
|
+
async function fetchPendingTxs(options) {
|
|
204
|
+
const { adapter, walletAddress, ...rest } = options;
|
|
205
|
+
assertAdapter(adapter);
|
|
206
|
+
return adapters[adapter].fetchPending({
|
|
207
|
+
safeAddress: walletAddress,
|
|
208
|
+
...rest
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
async function simulate(options) {
|
|
212
|
+
const { adapter, config, ...params } = options;
|
|
213
|
+
assertAdapter(adapter);
|
|
214
|
+
return adapters[adapter].simulate(config, params);
|
|
215
|
+
}
|
|
216
|
+
async function write(options) {
|
|
217
|
+
const { adapter, config, request } = options;
|
|
218
|
+
assertAdapter(adapter);
|
|
219
|
+
return adapters[adapter].write(config, request);
|
|
220
|
+
}
|
|
221
|
+
function assertAdapter(adapter) {
|
|
222
|
+
if (!(adapter in adapters)) {
|
|
223
|
+
throw new Error(`Unknown adapter: ${adapter}. Available: ${Object.keys(adapters).join(", ")}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// src/react/use-submit-tx.ts
|
|
228
|
+
function useSubmitTx() {
|
|
229
|
+
return (0, import_react_query.useMutation)({
|
|
230
|
+
mutationFn: (options) => submitTx(options)
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/react/use-wait-for-execution.ts
|
|
235
|
+
var import_react_query2 = require("@tanstack/react-query");
|
|
236
|
+
function useWaitForExecution(options) {
|
|
237
|
+
const {
|
|
238
|
+
enabled = true,
|
|
239
|
+
pollingInterval = 5e3,
|
|
240
|
+
timeout = 12e4,
|
|
241
|
+
...waitOptions
|
|
242
|
+
} = options;
|
|
243
|
+
const maxAttempts = Math.ceil(timeout / pollingInterval);
|
|
244
|
+
return (0, import_react_query2.useQuery)({
|
|
245
|
+
queryKey: [
|
|
246
|
+
"adapter",
|
|
247
|
+
options.adapter,
|
|
248
|
+
"waitForExecution",
|
|
249
|
+
options.txHash,
|
|
250
|
+
options.chainId.toString()
|
|
251
|
+
],
|
|
252
|
+
queryFn: () => waitForExecution2({
|
|
253
|
+
...waitOptions,
|
|
254
|
+
pollingInterval,
|
|
255
|
+
maxAttempts
|
|
256
|
+
}),
|
|
257
|
+
enabled: enabled && !!options.txHash,
|
|
258
|
+
// Don't refetch - the query handles polling internally
|
|
259
|
+
refetchInterval: false,
|
|
260
|
+
refetchOnWindowFocus: false,
|
|
261
|
+
refetchOnMount: false,
|
|
262
|
+
refetchOnReconnect: false,
|
|
263
|
+
// Don't retry on error - timeout is intentional
|
|
264
|
+
retry: false,
|
|
265
|
+
// Keep data fresh
|
|
266
|
+
staleTime: Infinity,
|
|
267
|
+
// Cache result for this specific txHash
|
|
268
|
+
gcTime: 1e3 * 60 * 5
|
|
269
|
+
// 5 minutes
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// src/react/use-fetch-pending-txs.ts
|
|
274
|
+
var import_react_query3 = require("@tanstack/react-query");
|
|
275
|
+
function useFetchPendingTxs(options) {
|
|
276
|
+
const { enabled = true, refetchInterval = false, ...fetchOptions } = options;
|
|
277
|
+
return (0, import_react_query3.useQuery)({
|
|
278
|
+
queryKey: [
|
|
279
|
+
"adapter",
|
|
280
|
+
options.adapter,
|
|
281
|
+
"pendingTxs",
|
|
282
|
+
options.walletAddress,
|
|
283
|
+
options.chainId.toString()
|
|
284
|
+
],
|
|
285
|
+
queryFn: () => fetchPendingTxs(fetchOptions),
|
|
286
|
+
enabled: enabled && !!options.walletAddress,
|
|
287
|
+
refetchInterval
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// src/react/use-simulate.ts
|
|
292
|
+
var import_react_query4 = require("@tanstack/react-query");
|
|
293
|
+
function useSimulate(options) {
|
|
294
|
+
const { enabled = true, ...simulateOptions } = options;
|
|
295
|
+
return (0, import_react_query4.useQuery)({
|
|
296
|
+
queryKey: [
|
|
297
|
+
"adapter",
|
|
298
|
+
options.adapter,
|
|
299
|
+
"simulate",
|
|
300
|
+
options.address,
|
|
301
|
+
options.functionName,
|
|
302
|
+
JSON.stringify(options.args)
|
|
303
|
+
],
|
|
304
|
+
queryFn: () => simulate(simulateOptions),
|
|
305
|
+
enabled
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/react/use-write.ts
|
|
310
|
+
var import_react_query5 = require("@tanstack/react-query");
|
|
311
|
+
function useWrite() {
|
|
312
|
+
return (0, import_react_query5.useMutation)({
|
|
313
|
+
mutationFn: (options) => write(options)
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
317
|
+
0 && (module.exports = {
|
|
318
|
+
useFetchPendingTxs,
|
|
319
|
+
useSimulate,
|
|
320
|
+
useSubmitTx,
|
|
321
|
+
useWaitForExecution,
|
|
322
|
+
useWrite
|
|
323
|
+
});
|
|
324
|
+
//# sourceMappingURL=react.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/index.ts","../src/react/use-submit-tx.ts","../src/adapters/safe/simulate-contract-call.ts","../src/adapters/safe/write-contract-call.ts","../src/adapters/safe/fetch-pending-transactions.ts","../src/core/extract-call-data.ts","../src/core/match-pending-tx.ts","../src/adapters/safe/submit-and-find-safe-tx.ts","../src/adapters/safe/wait-for-execution.ts","../src/adapters/registry.ts","../src/adapters/index.ts","../src/react/use-wait-for-execution.ts","../src/react/use-fetch-pending-txs.ts","../src/react/use-simulate.ts","../src/react/use-write.ts"],"sourcesContent":["export * from \"./use-submit-tx.js\";\nexport * from \"./use-wait-for-execution.js\";\nexport * from \"./use-fetch-pending-txs.js\";\nexport * from \"./use-simulate.js\";\nexport * from \"./use-write.js\";\n","import { useMutation } from \"@tanstack/react-query\";\nimport { submitTx } from \"../adapters/index.js\";\nimport type { SubmitTxOptions, SubmitTxResult } from \"../adapters/types.js\";\n\nexport type UseSubmitTxOptions = Omit<SubmitTxOptions, \"config\"> & {\n config: SubmitTxOptions[\"config\"];\n};\n\nexport function useSubmitTx() {\n return useMutation<SubmitTxResult, Error, UseSubmitTxOptions>({\n mutationFn: (options) => submitTx(options),\n });\n}\n","import { simulateContract, type Config } from \"@wagmi/core\";\nimport type { ContractCallParams } from \"../../core/types.js\";\n\nexport async function simulateContractCall(\n config: Config,\n params: ContractCallParams,\n) {\n return simulateContract(config, {\n address: params.address,\n abi: params.abi,\n functionName: params.functionName,\n args: params.args as unknown[],\n value: params.value,\n chainId: params.chainId,\n account: params.account,\n });\n}\n","import { writeContract, type Config } from \"@wagmi/core\";\nimport type { Hex } from \"viem\";\n\nexport async function writeContractCall(\n config: Config,\n request: Parameters<typeof writeContract>[1],\n): Promise<Hex> {\n return writeContract(config, request);\n}\n","import SafeApiKit from \"@safe-global/api-kit\";\nimport type { SafeMultisigTransactionResponse } from \"@safe-global/types-kit\";\n\nexport interface FetchPendingTransactionsParams {\n chainId: bigint;\n safeAddress: string;\n txServiceUrl?: string;\n apiKey?: string;\n}\n\nexport async function fetchPendingTransactions(\n params: FetchPendingTransactionsParams,\n): Promise<SafeMultisigTransactionResponse[]> {\n const apiKit = new SafeApiKit({\n chainId: params.chainId,\n ...(params.txServiceUrl && { txServiceUrl: params.txServiceUrl }),\n apiKey: params.apiKey,\n });\n\n const response = await apiKit.getPendingTransactions(params.safeAddress);\n return response.results;\n}\n","import type { Abi, Address } from \"viem\";\nimport { encodeFunctionData } from \"viem\";\nimport type { EncodedCallData } from \"./types.js\";\n\nexport function extractCallData(params: {\n abi: Abi;\n functionName: string;\n args?: readonly unknown[];\n address: Address;\n value?: bigint;\n}): EncodedCallData {\n const data = encodeFunctionData({\n abi: params.abi,\n functionName: params.functionName,\n args: params.args as unknown[],\n });\n\n return {\n to: params.address,\n data,\n value: params.value ?? 0n,\n };\n}\n","import type { SafeMultisigTransactionResponse } from \"@safe-global/types-kit\";\nimport type { TxMatchCriteria } from \"./types.js\";\n\nexport function matchPendingTransaction(\n pendingTxs: SafeMultisigTransactionResponse[],\n criteria: TxMatchCriteria,\n): SafeMultisigTransactionResponse | undefined {\n return pendingTxs.find(\n (tx) =>\n tx.to.toLowerCase() === criteria.to.toLowerCase() &&\n tx.value === String(criteria.value) &&\n tx.data?.toLowerCase() === criteria.data.toLowerCase(),\n );\n}\n","import { extractCallData } from \"../../core/extract-call-data.js\";\nimport { matchPendingTransaction } from \"../../core/match-pending-tx.js\";\nimport { fetchPendingTransactions } from \"./fetch-pending-transactions.js\";\nimport { simulateContractCall } from \"./simulate-contract-call.js\";\nimport { writeContractCall } from \"./write-contract-call.js\";\nimport type {\n SubmitAndFindSafeTxOptions,\n SubmitAndFindSafeTxResult,\n} from \"./types.js\";\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function submitAndFindSafeTx(\n options: SubmitAndFindSafeTxOptions,\n): Promise<SubmitAndFindSafeTxResult> {\n const {\n config,\n safeAddress,\n txServiceUrl,\n apiKey,\n pollingInterval = 3000,\n maxAttempts = 20,\n ...callParams\n } = options;\n\n const callData = extractCallData(callParams);\n\n const simulation = await simulateContractCall(config, callParams);\n\n await writeContractCall(config, simulation.request as Parameters<typeof writeContractCall>[1]);\n\n const chainId = BigInt(callParams.chainId ?? (await getChainId(config)));\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n await delay(pollingInterval);\n\n const pendingTxs = await fetchPendingTransactions({\n chainId,\n safeAddress,\n txServiceUrl,\n apiKey,\n });\n const match = matchPendingTransaction(pendingTxs, callData);\n\n if (match) {\n return {\n safeTxHash: match.safeTxHash,\n };\n }\n }\n\n throw new Error(\n `Could not find matching Safe transaction after ${maxAttempts} attempts`,\n );\n}\n\nasync function getChainId(config: Parameters<typeof simulateContractCall>[0]): Promise<number> {\n const { getChainId: wagmiGetChainId } = await import(\"@wagmi/core\");\n return wagmiGetChainId(config);\n}\n","import SafeApiKit from \"@safe-global/api-kit\";\nimport type {\n WaitForExecutionOptions,\n WaitForExecutionResult,\n} from \"./types.js\";\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function waitForExecution(\n options: WaitForExecutionOptions,\n): Promise<WaitForExecutionResult> {\n const {\n safeTxHash,\n chainId,\n txServiceUrl,\n apiKey,\n pollingInterval = 5000,\n maxAttempts = 60,\n } = options;\n\n const apiKit = new SafeApiKit({\n chainId,\n ...(txServiceUrl && { txServiceUrl }),\n apiKey,\n });\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const tx = await apiKit.getTransaction(safeTxHash);\n\n if (tx.isExecuted && tx.transactionHash) {\n return {\n transactionHash: tx.transactionHash,\n };\n }\n\n await delay(pollingInterval);\n }\n\n throw new Error(\n `Safe transaction ${safeTxHash} was not executed after ${maxAttempts} attempts`,\n );\n}\n","import * as safe from \"./safe/index.js\";\n\nexport const adapters = {\n safe: {\n submitTx: safe.submitAndFindSafeTx,\n waitForExecution: safe.waitForExecution,\n fetchPending: safe.fetchPendingTransactions,\n simulate: safe.simulateContractCall,\n write: safe.writeContractCall,\n },\n} as const;\n\nexport type AdapterRegistry = typeof adapters;\n","import { adapters } from \"./registry.js\";\nimport type {\n AdapterType,\n SubmitTxOptions,\n SubmitTxResult,\n WaitForExecutionOptions,\n WaitForExecutionResult,\n FetchPendingOptions,\n SimulateOptions,\n WriteOptions,\n} from \"./types.js\";\n\n// Re-export types\nexport * from \"./types.js\";\n\n// Re-export Safe adapter for direct access\nexport * as safe from \"./safe/index.js\";\n\n// Generic entry functions\n\nexport async function submitTx(\n options: SubmitTxOptions,\n): Promise<SubmitTxResult> {\n const { adapter, walletAddress, ...rest } = options;\n assertAdapter(adapter);\n\n const result = await adapters[adapter].submitTx({\n safeAddress: walletAddress,\n ...rest,\n });\n\n return { txHash: result.safeTxHash };\n}\n\nexport async function waitForExecution(\n options: WaitForExecutionOptions,\n): Promise<WaitForExecutionResult> {\n const { adapter, txHash, ...rest } = options;\n assertAdapter(adapter);\n\n const result = await adapters[adapter].waitForExecution({\n safeTxHash: txHash,\n ...rest,\n });\n\n return { transactionHash: result.transactionHash };\n}\n\nexport async function fetchPendingTxs(\n options: FetchPendingOptions,\n): Promise<unknown[]> {\n const { adapter, walletAddress, ...rest } = options;\n assertAdapter(adapter);\n\n return adapters[adapter].fetchPending({\n safeAddress: walletAddress,\n ...rest,\n });\n}\n\nexport async function simulate(\n options: SimulateOptions,\n): Promise<unknown> {\n const { adapter, config, ...params } = options;\n assertAdapter(adapter);\n\n return adapters[adapter].simulate(config, params);\n}\n\nexport async function write(\n options: WriteOptions,\n): Promise<string> {\n const { adapter, config, request } = options;\n assertAdapter(adapter);\n\n return adapters[adapter].write(config, request as Parameters<typeof adapters.safe.write>[1]);\n}\n\nfunction assertAdapter(adapter: AdapterType): asserts adapter is keyof typeof adapters {\n if (!(adapter in adapters)) {\n throw new Error(`Unknown adapter: ${adapter}. Available: ${Object.keys(adapters).join(\", \")}`);\n }\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { waitForExecution } from \"../adapters/index.js\";\nimport type { WaitForExecutionOptions, WaitForExecutionResult } from \"../adapters/types.js\";\n\nexport interface UseWaitForExecutionOptions extends Omit<WaitForExecutionOptions, \"maxAttempts\"> {\n /** Enable/disable the query. Defaults to true. */\n enabled?: boolean;\n /** Polling interval in ms. Defaults to 5000. */\n pollingInterval?: number;\n /** Timeout in ms. After this duration, the query will fail. Defaults to 120000 (2 min). */\n timeout?: number;\n}\n\n/**\n * Hook to wait for a Safe transaction to be executed on-chain.\n *\n * Unlike standard polling queries, this hook maintains a stable loading state\n * throughout the polling process (similar to wagmi's useWaitForTransactionReceipt):\n * - `isLoading` = true while waiting for execution\n * - `isSuccess` = true once transaction is executed\n * - `isError` = true if timeout is reached\n */\nexport function useWaitForExecution(options: UseWaitForExecutionOptions) {\n const {\n enabled = true,\n pollingInterval = 5000,\n timeout = 120000,\n ...waitOptions\n } = options;\n\n // Calculate max attempts from timeout and polling interval\n const maxAttempts = Math.ceil(timeout / pollingInterval);\n\n return useQuery<WaitForExecutionResult, Error>({\n queryKey: [\n \"adapter\",\n options.adapter,\n \"waitForExecution\",\n options.txHash,\n options.chainId.toString(),\n ],\n queryFn: () =>\n waitForExecution({\n ...waitOptions,\n pollingInterval,\n maxAttempts,\n }),\n enabled: enabled && !!options.txHash,\n // Don't refetch - the query handles polling internally\n refetchInterval: false,\n refetchOnWindowFocus: false,\n refetchOnMount: false,\n refetchOnReconnect: false,\n // Don't retry on error - timeout is intentional\n retry: false,\n // Keep data fresh\n staleTime: Infinity,\n // Cache result for this specific txHash\n gcTime: 1000 * 60 * 5, // 5 minutes\n });\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { fetchPendingTxs } from \"../adapters/index.js\";\nimport type { FetchPendingOptions } from \"../adapters/types.js\";\n\nexport interface UseFetchPendingTxsOptions extends FetchPendingOptions {\n enabled?: boolean;\n refetchInterval?: number | false;\n}\n\nexport function useFetchPendingTxs(options: UseFetchPendingTxsOptions) {\n const { enabled = true, refetchInterval = false, ...fetchOptions } = options;\n\n return useQuery<unknown[], Error>({\n queryKey: [\n \"adapter\",\n options.adapter,\n \"pendingTxs\",\n options.walletAddress,\n options.chainId.toString(),\n ],\n queryFn: () => fetchPendingTxs(fetchOptions),\n enabled: enabled && !!options.walletAddress,\n refetchInterval,\n });\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { simulate } from \"../adapters/index.js\";\nimport type { SimulateOptions } from \"../adapters/types.js\";\n\nexport interface UseSimulateOptions extends SimulateOptions {\n enabled?: boolean;\n}\n\nexport function useSimulate(options: UseSimulateOptions) {\n const { enabled = true, ...simulateOptions } = options;\n\n return useQuery<unknown, Error>({\n queryKey: [\n \"adapter\",\n options.adapter,\n \"simulate\",\n options.address,\n options.functionName,\n JSON.stringify(options.args),\n ],\n queryFn: () => simulate(simulateOptions),\n enabled,\n });\n}\n","import { useMutation } from \"@tanstack/react-query\";\nimport { write } from \"../adapters/index.js\";\nimport type { WriteOptions } from \"../adapters/types.js\";\n\nexport function useWrite() {\n return useMutation<string, Error, WriteOptions>({\n mutationFn: (options) => write(options),\n });\n}\n"],"mappings":"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","names":["import_core","SafeApiKit","import_api_kit","delay","SafeApiKit","waitForExecution","import_react_query","waitForExecution","import_react_query","import_react_query","import_react_query"]}
|
package/dist/react.d.cts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
+
import { a as SubmitTxOptions, b as SubmitTxResult, W as WaitForExecutionOptions, c as WaitForExecutionResult, F as FetchPendingOptions, S as SimulateOptions, d as WriteOptions } from './types-BJD1jdcY.cjs';
|
|
3
|
+
import '@wagmi/core';
|
|
4
|
+
import 'viem';
|
|
5
|
+
|
|
6
|
+
type UseSubmitTxOptions = Omit<SubmitTxOptions, "config"> & {
|
|
7
|
+
config: SubmitTxOptions["config"];
|
|
8
|
+
};
|
|
9
|
+
declare function useSubmitTx(): _tanstack_react_query.UseMutationResult<SubmitTxResult, Error, UseSubmitTxOptions, unknown>;
|
|
10
|
+
|
|
11
|
+
interface UseWaitForExecutionOptions extends Omit<WaitForExecutionOptions, "maxAttempts"> {
|
|
12
|
+
/** Enable/disable the query. Defaults to true. */
|
|
13
|
+
enabled?: boolean;
|
|
14
|
+
/** Polling interval in ms. Defaults to 5000. */
|
|
15
|
+
pollingInterval?: number;
|
|
16
|
+
/** Timeout in ms. After this duration, the query will fail. Defaults to 120000 (2 min). */
|
|
17
|
+
timeout?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Hook to wait for a Safe transaction to be executed on-chain.
|
|
21
|
+
*
|
|
22
|
+
* Unlike standard polling queries, this hook maintains a stable loading state
|
|
23
|
+
* throughout the polling process (similar to wagmi's useWaitForTransactionReceipt):
|
|
24
|
+
* - `isLoading` = true while waiting for execution
|
|
25
|
+
* - `isSuccess` = true once transaction is executed
|
|
26
|
+
* - `isError` = true if timeout is reached
|
|
27
|
+
*/
|
|
28
|
+
declare function useWaitForExecution(options: UseWaitForExecutionOptions): _tanstack_react_query.UseQueryResult<WaitForExecutionResult, Error>;
|
|
29
|
+
|
|
30
|
+
interface UseFetchPendingTxsOptions extends FetchPendingOptions {
|
|
31
|
+
enabled?: boolean;
|
|
32
|
+
refetchInterval?: number | false;
|
|
33
|
+
}
|
|
34
|
+
declare function useFetchPendingTxs(options: UseFetchPendingTxsOptions): _tanstack_react_query.UseQueryResult<unknown[], Error>;
|
|
35
|
+
|
|
36
|
+
interface UseSimulateOptions extends SimulateOptions {
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
}
|
|
39
|
+
declare function useSimulate(options: UseSimulateOptions): _tanstack_react_query.UseQueryResult<unknown, Error>;
|
|
40
|
+
|
|
41
|
+
declare function useWrite(): _tanstack_react_query.UseMutationResult<string, Error, WriteOptions, unknown>;
|
|
42
|
+
|
|
43
|
+
export { type UseFetchPendingTxsOptions, type UseSimulateOptions, type UseSubmitTxOptions, type UseWaitForExecutionOptions, useFetchPendingTxs, useSimulate, useSubmitTx, useWaitForExecution, useWrite };
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
+
import { a as SubmitTxOptions, b as SubmitTxResult, W as WaitForExecutionOptions, c as WaitForExecutionResult, F as FetchPendingOptions, S as SimulateOptions, d as WriteOptions } from './types-BJD1jdcY.js';
|
|
3
|
+
import '@wagmi/core';
|
|
4
|
+
import 'viem';
|
|
5
|
+
|
|
6
|
+
type UseSubmitTxOptions = Omit<SubmitTxOptions, "config"> & {
|
|
7
|
+
config: SubmitTxOptions["config"];
|
|
8
|
+
};
|
|
9
|
+
declare function useSubmitTx(): _tanstack_react_query.UseMutationResult<SubmitTxResult, Error, UseSubmitTxOptions, unknown>;
|
|
10
|
+
|
|
11
|
+
interface UseWaitForExecutionOptions extends Omit<WaitForExecutionOptions, "maxAttempts"> {
|
|
12
|
+
/** Enable/disable the query. Defaults to true. */
|
|
13
|
+
enabled?: boolean;
|
|
14
|
+
/** Polling interval in ms. Defaults to 5000. */
|
|
15
|
+
pollingInterval?: number;
|
|
16
|
+
/** Timeout in ms. After this duration, the query will fail. Defaults to 120000 (2 min). */
|
|
17
|
+
timeout?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Hook to wait for a Safe transaction to be executed on-chain.
|
|
21
|
+
*
|
|
22
|
+
* Unlike standard polling queries, this hook maintains a stable loading state
|
|
23
|
+
* throughout the polling process (similar to wagmi's useWaitForTransactionReceipt):
|
|
24
|
+
* - `isLoading` = true while waiting for execution
|
|
25
|
+
* - `isSuccess` = true once transaction is executed
|
|
26
|
+
* - `isError` = true if timeout is reached
|
|
27
|
+
*/
|
|
28
|
+
declare function useWaitForExecution(options: UseWaitForExecutionOptions): _tanstack_react_query.UseQueryResult<WaitForExecutionResult, Error>;
|
|
29
|
+
|
|
30
|
+
interface UseFetchPendingTxsOptions extends FetchPendingOptions {
|
|
31
|
+
enabled?: boolean;
|
|
32
|
+
refetchInterval?: number | false;
|
|
33
|
+
}
|
|
34
|
+
declare function useFetchPendingTxs(options: UseFetchPendingTxsOptions): _tanstack_react_query.UseQueryResult<unknown[], Error>;
|
|
35
|
+
|
|
36
|
+
interface UseSimulateOptions extends SimulateOptions {
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
}
|
|
39
|
+
declare function useSimulate(options: UseSimulateOptions): _tanstack_react_query.UseQueryResult<unknown, Error>;
|
|
40
|
+
|
|
41
|
+
declare function useWrite(): _tanstack_react_query.UseMutationResult<string, Error, WriteOptions, unknown>;
|
|
42
|
+
|
|
43
|
+
export { type UseFetchPendingTxsOptions, type UseSimulateOptions, type UseSubmitTxOptions, type UseWaitForExecutionOptions, useFetchPendingTxs, useSimulate, useSubmitTx, useWaitForExecution, useWrite };
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
fetchPendingTxs,
|
|
3
|
+
simulate,
|
|
4
|
+
submitTx,
|
|
5
|
+
waitForExecution,
|
|
6
|
+
write
|
|
7
|
+
} from "./chunk-YQE6NIEB.js";
|
|
8
|
+
|
|
9
|
+
// src/react/use-submit-tx.ts
|
|
10
|
+
import { useMutation } from "@tanstack/react-query";
|
|
11
|
+
function useSubmitTx() {
|
|
12
|
+
return useMutation({
|
|
13
|
+
mutationFn: (options) => submitTx(options)
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/react/use-wait-for-execution.ts
|
|
18
|
+
import { useQuery } from "@tanstack/react-query";
|
|
19
|
+
function useWaitForExecution(options) {
|
|
20
|
+
const {
|
|
21
|
+
enabled = true,
|
|
22
|
+
pollingInterval = 5e3,
|
|
23
|
+
timeout = 12e4,
|
|
24
|
+
...waitOptions
|
|
25
|
+
} = options;
|
|
26
|
+
const maxAttempts = Math.ceil(timeout / pollingInterval);
|
|
27
|
+
return useQuery({
|
|
28
|
+
queryKey: [
|
|
29
|
+
"adapter",
|
|
30
|
+
options.adapter,
|
|
31
|
+
"waitForExecution",
|
|
32
|
+
options.txHash,
|
|
33
|
+
options.chainId.toString()
|
|
34
|
+
],
|
|
35
|
+
queryFn: () => waitForExecution({
|
|
36
|
+
...waitOptions,
|
|
37
|
+
pollingInterval,
|
|
38
|
+
maxAttempts
|
|
39
|
+
}),
|
|
40
|
+
enabled: enabled && !!options.txHash,
|
|
41
|
+
// Don't refetch - the query handles polling internally
|
|
42
|
+
refetchInterval: false,
|
|
43
|
+
refetchOnWindowFocus: false,
|
|
44
|
+
refetchOnMount: false,
|
|
45
|
+
refetchOnReconnect: false,
|
|
46
|
+
// Don't retry on error - timeout is intentional
|
|
47
|
+
retry: false,
|
|
48
|
+
// Keep data fresh
|
|
49
|
+
staleTime: Infinity,
|
|
50
|
+
// Cache result for this specific txHash
|
|
51
|
+
gcTime: 1e3 * 60 * 5
|
|
52
|
+
// 5 minutes
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/react/use-fetch-pending-txs.ts
|
|
57
|
+
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
|
58
|
+
function useFetchPendingTxs(options) {
|
|
59
|
+
const { enabled = true, refetchInterval = false, ...fetchOptions } = options;
|
|
60
|
+
return useQuery2({
|
|
61
|
+
queryKey: [
|
|
62
|
+
"adapter",
|
|
63
|
+
options.adapter,
|
|
64
|
+
"pendingTxs",
|
|
65
|
+
options.walletAddress,
|
|
66
|
+
options.chainId.toString()
|
|
67
|
+
],
|
|
68
|
+
queryFn: () => fetchPendingTxs(fetchOptions),
|
|
69
|
+
enabled: enabled && !!options.walletAddress,
|
|
70
|
+
refetchInterval
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/react/use-simulate.ts
|
|
75
|
+
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
76
|
+
function useSimulate(options) {
|
|
77
|
+
const { enabled = true, ...simulateOptions } = options;
|
|
78
|
+
return useQuery3({
|
|
79
|
+
queryKey: [
|
|
80
|
+
"adapter",
|
|
81
|
+
options.adapter,
|
|
82
|
+
"simulate",
|
|
83
|
+
options.address,
|
|
84
|
+
options.functionName,
|
|
85
|
+
JSON.stringify(options.args)
|
|
86
|
+
],
|
|
87
|
+
queryFn: () => simulate(simulateOptions),
|
|
88
|
+
enabled
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/react/use-write.ts
|
|
93
|
+
import { useMutation as useMutation2 } from "@tanstack/react-query";
|
|
94
|
+
function useWrite() {
|
|
95
|
+
return useMutation2({
|
|
96
|
+
mutationFn: (options) => write(options)
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export {
|
|
100
|
+
useFetchPendingTxs,
|
|
101
|
+
useSimulate,
|
|
102
|
+
useSubmitTx,
|
|
103
|
+
useWaitForExecution,
|
|
104
|
+
useWrite
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/use-submit-tx.ts","../src/react/use-wait-for-execution.ts","../src/react/use-fetch-pending-txs.ts","../src/react/use-simulate.ts","../src/react/use-write.ts"],"sourcesContent":["import { useMutation } from \"@tanstack/react-query\";\nimport { submitTx } from \"../adapters/index.js\";\nimport type { SubmitTxOptions, SubmitTxResult } from \"../adapters/types.js\";\n\nexport type UseSubmitTxOptions = Omit<SubmitTxOptions, \"config\"> & {\n config: SubmitTxOptions[\"config\"];\n};\n\nexport function useSubmitTx() {\n return useMutation<SubmitTxResult, Error, UseSubmitTxOptions>({\n mutationFn: (options) => submitTx(options),\n });\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { waitForExecution } from \"../adapters/index.js\";\nimport type { WaitForExecutionOptions, WaitForExecutionResult } from \"../adapters/types.js\";\n\nexport interface UseWaitForExecutionOptions extends Omit<WaitForExecutionOptions, \"maxAttempts\"> {\n /** Enable/disable the query. Defaults to true. */\n enabled?: boolean;\n /** Polling interval in ms. Defaults to 5000. */\n pollingInterval?: number;\n /** Timeout in ms. After this duration, the query will fail. Defaults to 120000 (2 min). */\n timeout?: number;\n}\n\n/**\n * Hook to wait for a Safe transaction to be executed on-chain.\n *\n * Unlike standard polling queries, this hook maintains a stable loading state\n * throughout the polling process (similar to wagmi's useWaitForTransactionReceipt):\n * - `isLoading` = true while waiting for execution\n * - `isSuccess` = true once transaction is executed\n * - `isError` = true if timeout is reached\n */\nexport function useWaitForExecution(options: UseWaitForExecutionOptions) {\n const {\n enabled = true,\n pollingInterval = 5000,\n timeout = 120000,\n ...waitOptions\n } = options;\n\n // Calculate max attempts from timeout and polling interval\n const maxAttempts = Math.ceil(timeout / pollingInterval);\n\n return useQuery<WaitForExecutionResult, Error>({\n queryKey: [\n \"adapter\",\n options.adapter,\n \"waitForExecution\",\n options.txHash,\n options.chainId.toString(),\n ],\n queryFn: () =>\n waitForExecution({\n ...waitOptions,\n pollingInterval,\n maxAttempts,\n }),\n enabled: enabled && !!options.txHash,\n // Don't refetch - the query handles polling internally\n refetchInterval: false,\n refetchOnWindowFocus: false,\n refetchOnMount: false,\n refetchOnReconnect: false,\n // Don't retry on error - timeout is intentional\n retry: false,\n // Keep data fresh\n staleTime: Infinity,\n // Cache result for this specific txHash\n gcTime: 1000 * 60 * 5, // 5 minutes\n });\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { fetchPendingTxs } from \"../adapters/index.js\";\nimport type { FetchPendingOptions } from \"../adapters/types.js\";\n\nexport interface UseFetchPendingTxsOptions extends FetchPendingOptions {\n enabled?: boolean;\n refetchInterval?: number | false;\n}\n\nexport function useFetchPendingTxs(options: UseFetchPendingTxsOptions) {\n const { enabled = true, refetchInterval = false, ...fetchOptions } = options;\n\n return useQuery<unknown[], Error>({\n queryKey: [\n \"adapter\",\n options.adapter,\n \"pendingTxs\",\n options.walletAddress,\n options.chainId.toString(),\n ],\n queryFn: () => fetchPendingTxs(fetchOptions),\n enabled: enabled && !!options.walletAddress,\n refetchInterval,\n });\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { simulate } from \"../adapters/index.js\";\nimport type { SimulateOptions } from \"../adapters/types.js\";\n\nexport interface UseSimulateOptions extends SimulateOptions {\n enabled?: boolean;\n}\n\nexport function useSimulate(options: UseSimulateOptions) {\n const { enabled = true, ...simulateOptions } = options;\n\n return useQuery<unknown, Error>({\n queryKey: [\n \"adapter\",\n options.adapter,\n \"simulate\",\n options.address,\n options.functionName,\n JSON.stringify(options.args),\n ],\n queryFn: () => simulate(simulateOptions),\n enabled,\n });\n}\n","import { useMutation } from \"@tanstack/react-query\";\nimport { write } from \"../adapters/index.js\";\nimport type { WriteOptions } from \"../adapters/types.js\";\n\nexport function useWrite() {\n return useMutation<string, Error, WriteOptions>({\n mutationFn: (options) => write(options),\n });\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,mBAAmB;AAQrB,SAAS,cAAc;AAC5B,SAAO,YAAuD;AAAA,IAC5D,YAAY,CAAC,YAAY,SAAS,OAAO;AAAA,EAC3C,CAAC;AACH;;;ACZA,SAAS,gBAAgB;AAsBlB,SAAS,oBAAoB,SAAqC;AACvE,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,UAAU;AAAA,IACV,GAAG;AAAA,EACL,IAAI;AAGJ,QAAM,cAAc,KAAK,KAAK,UAAU,eAAe;AAEvD,SAAO,SAAwC;AAAA,IAC7C,UAAU;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ,QAAQ,SAAS;AAAA,IAC3B;AAAA,IACA,SAAS,MACP,iBAAiB;AAAA,MACf,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH,SAAS,WAAW,CAAC,CAAC,QAAQ;AAAA;AAAA,IAE9B,iBAAiB;AAAA,IACjB,sBAAsB;AAAA,IACtB,gBAAgB;AAAA,IAChB,oBAAoB;AAAA;AAAA,IAEpB,OAAO;AAAA;AAAA,IAEP,WAAW;AAAA;AAAA,IAEX,QAAQ,MAAO,KAAK;AAAA;AAAA,EACtB,CAAC;AACH;;;AC5DA,SAAS,YAAAA,iBAAgB;AASlB,SAAS,mBAAmB,SAAoC;AACrE,QAAM,EAAE,UAAU,MAAM,kBAAkB,OAAO,GAAG,aAAa,IAAI;AAErE,SAAOC,UAA2B;AAAA,IAChC,UAAU;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ,QAAQ,SAAS;AAAA,IAC3B;AAAA,IACA,SAAS,MAAM,gBAAgB,YAAY;AAAA,IAC3C,SAAS,WAAW,CAAC,CAAC,QAAQ;AAAA,IAC9B;AAAA,EACF,CAAC;AACH;;;ACxBA,SAAS,YAAAC,iBAAgB;AAQlB,SAAS,YAAY,SAA6B;AACvD,QAAM,EAAE,UAAU,MAAM,GAAG,gBAAgB,IAAI;AAE/C,SAAOC,UAAyB;AAAA,IAC9B,UAAU;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,KAAK,UAAU,QAAQ,IAAI;AAAA,IAC7B;AAAA,IACA,SAAS,MAAM,SAAS,eAAe;AAAA,IACvC;AAAA,EACF,CAAC;AACH;;;ACvBA,SAAS,eAAAC,oBAAmB;AAIrB,SAAS,WAAW;AACzB,SAAOC,aAAyC;AAAA,IAC9C,YAAY,CAAC,YAAY,MAAM,OAAO;AAAA,EACxC,CAAC;AACH;","names":["useQuery","useQuery","useQuery","useQuery","useMutation","useMutation"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Config } from '@wagmi/core';
|
|
2
|
+
import { Address, Abi, Hex } from 'viem';
|
|
3
|
+
|
|
4
|
+
interface ContractCallParams {
|
|
5
|
+
address: Address;
|
|
6
|
+
abi: Abi;
|
|
7
|
+
functionName: string;
|
|
8
|
+
args?: readonly unknown[];
|
|
9
|
+
value?: bigint;
|
|
10
|
+
chainId?: number;
|
|
11
|
+
account?: Address;
|
|
12
|
+
}
|
|
13
|
+
interface EncodedCallData {
|
|
14
|
+
to: Address;
|
|
15
|
+
data: Hex;
|
|
16
|
+
value: bigint;
|
|
17
|
+
}
|
|
18
|
+
interface TxMatchCriteria {
|
|
19
|
+
to: Address;
|
|
20
|
+
value: bigint;
|
|
21
|
+
data: Hex;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type AdapterType = "safe";
|
|
25
|
+
interface AdapterServiceOptions {
|
|
26
|
+
txServiceUrl?: string;
|
|
27
|
+
apiKey?: string;
|
|
28
|
+
}
|
|
29
|
+
interface SubmitTxOptions extends ContractCallParams, AdapterServiceOptions {
|
|
30
|
+
adapter: AdapterType;
|
|
31
|
+
walletAddress: Address;
|
|
32
|
+
config: Config;
|
|
33
|
+
pollingInterval?: number;
|
|
34
|
+
maxAttempts?: number;
|
|
35
|
+
}
|
|
36
|
+
interface SubmitTxResult {
|
|
37
|
+
txHash: string;
|
|
38
|
+
}
|
|
39
|
+
interface WaitForExecutionOptions extends AdapterServiceOptions {
|
|
40
|
+
adapter: AdapterType;
|
|
41
|
+
txHash: string;
|
|
42
|
+
chainId: bigint;
|
|
43
|
+
pollingInterval?: number;
|
|
44
|
+
maxAttempts?: number;
|
|
45
|
+
}
|
|
46
|
+
interface WaitForExecutionResult {
|
|
47
|
+
transactionHash: string;
|
|
48
|
+
}
|
|
49
|
+
interface FetchPendingOptions extends AdapterServiceOptions {
|
|
50
|
+
adapter: AdapterType;
|
|
51
|
+
walletAddress: string;
|
|
52
|
+
chainId: bigint;
|
|
53
|
+
}
|
|
54
|
+
interface SimulateOptions extends ContractCallParams {
|
|
55
|
+
adapter: AdapterType;
|
|
56
|
+
config: Config;
|
|
57
|
+
}
|
|
58
|
+
interface WriteOptions {
|
|
59
|
+
adapter: AdapterType;
|
|
60
|
+
config: Config;
|
|
61
|
+
request: unknown;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export type { AdapterServiceOptions as A, ContractCallParams as C, EncodedCallData as E, FetchPendingOptions as F, SimulateOptions as S, TxMatchCriteria as T, WaitForExecutionOptions as W, SubmitTxOptions as a, SubmitTxResult as b, WaitForExecutionResult as c, WriteOptions as d, AdapterType as e };
|