@safe-global/api-kit 2.5.8 → 3.0.0-alpha.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.
Files changed (40) hide show
  1. package/dist/cjs/index.cjs +993 -0
  2. package/dist/esm/index.mjs +960 -0
  3. package/dist/src/SafeApiKit.d.ts +10 -1
  4. package/dist/src/SafeApiKit.d.ts.map +1 -0
  5. package/dist/src/index.d.ts +1 -0
  6. package/dist/src/index.d.ts.map +1 -0
  7. package/dist/src/types/safeTransactionServiceTypes.d.ts +3 -0
  8. package/dist/src/types/safeTransactionServiceTypes.d.ts.map +1 -0
  9. package/dist/src/utils/config.d.ts +1 -0
  10. package/dist/src/utils/config.d.ts.map +1 -0
  11. package/dist/src/utils/constants.d.ts +1 -0
  12. package/dist/src/utils/constants.d.ts.map +1 -0
  13. package/dist/src/utils/httpRequests.d.ts +1 -0
  14. package/dist/src/utils/httpRequests.d.ts.map +1 -0
  15. package/dist/src/utils/index.d.ts +1 -0
  16. package/dist/src/utils/index.d.ts.map +1 -0
  17. package/dist/src/utils/safeOperation.d.ts +5 -2
  18. package/dist/src/utils/safeOperation.d.ts.map +1 -0
  19. package/dist/src/utils/signDelegate.d.ts +1 -0
  20. package/dist/src/utils/signDelegate.d.ts.map +1 -0
  21. package/package.json +17 -8
  22. package/dist/src/SafeApiKit.js +0 -804
  23. package/dist/src/SafeApiKit.js.map +0 -1
  24. package/dist/src/index.js +0 -23
  25. package/dist/src/index.js.map +0 -1
  26. package/dist/src/types/safeTransactionServiceTypes.js +0 -3
  27. package/dist/src/types/safeTransactionServiceTypes.js.map +0 -1
  28. package/dist/src/utils/config.js +0 -25
  29. package/dist/src/utils/config.js.map +0 -1
  30. package/dist/src/utils/constants.js +0 -5
  31. package/dist/src/utils/constants.js.map +0 -1
  32. package/dist/src/utils/httpRequests.js +0 -59
  33. package/dist/src/utils/httpRequests.js.map +0 -1
  34. package/dist/src/utils/index.js +0 -7
  35. package/dist/src/utils/index.js.map +0 -1
  36. package/dist/src/utils/safeOperation.js +0 -19
  37. package/dist/src/utils/safeOperation.js.map +0 -1
  38. package/dist/src/utils/signDelegate.js +0 -25
  39. package/dist/src/utils/signDelegate.js.map +0 -1
  40. package/dist/tsconfig.build.tsbuildinfo +0 -1
@@ -0,0 +1,993 @@
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/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ default: () => src_default
34
+ });
35
+ module.exports = __toCommonJS(src_exports);
36
+
37
+ // src/utils/httpRequests.ts
38
+ var import_node_fetch = __toESM(require("node-fetch"));
39
+ async function sendRequest({ url, method, body }) {
40
+ const response = await (0, import_node_fetch.default)(url, {
41
+ method,
42
+ headers: {
43
+ Accept: "application/json",
44
+ "Content-Type": "application/json"
45
+ },
46
+ body: JSON.stringify(body)
47
+ });
48
+ let jsonResponse;
49
+ try {
50
+ jsonResponse = await response.json();
51
+ } catch (error) {
52
+ if (!response.ok) {
53
+ throw new Error(response.statusText);
54
+ }
55
+ }
56
+ if (response.ok) {
57
+ return jsonResponse;
58
+ }
59
+ if (jsonResponse.data) {
60
+ throw new Error(jsonResponse.data);
61
+ }
62
+ if (jsonResponse.detail) {
63
+ throw new Error(jsonResponse.detail);
64
+ }
65
+ if (jsonResponse.message) {
66
+ throw new Error(jsonResponse.message);
67
+ }
68
+ if (jsonResponse.nonFieldErrors) {
69
+ throw new Error(jsonResponse.nonFieldErrors);
70
+ }
71
+ if (jsonResponse.delegate) {
72
+ throw new Error(jsonResponse.delegate);
73
+ }
74
+ if (jsonResponse.safe) {
75
+ throw new Error(jsonResponse.safe);
76
+ }
77
+ if (jsonResponse.delegator) {
78
+ throw new Error(jsonResponse.delegator);
79
+ }
80
+ throw new Error(response.statusText);
81
+ }
82
+
83
+ // src/utils/signDelegate.ts
84
+ async function signDelegate(walletClient, delegateAddress, chainId) {
85
+ const domain = {
86
+ name: "Safe Transaction Service",
87
+ version: "1.0",
88
+ chainId: Number(chainId)
89
+ };
90
+ const types = {
91
+ Delegate: [
92
+ { name: "delegateAddress", type: "address" },
93
+ { name: "totp", type: "uint256" }
94
+ ]
95
+ };
96
+ const totp = Math.floor(Date.now() / 1e3 / 3600);
97
+ return walletClient.signTypedData({
98
+ domain,
99
+ types,
100
+ primaryType: "Delegate",
101
+ message: { delegateAddress, totp }
102
+ });
103
+ }
104
+
105
+ // src/SafeApiKit.ts
106
+ var import_protocol_kit = require("@safe-global/protocol-kit");
107
+
108
+ // src/utils/config.ts
109
+ var TRANSACTION_SERVICE_URLS = {
110
+ "1": "https://safe-transaction-mainnet.safe.global/api",
111
+ "10": "https://safe-transaction-optimism.safe.global/api",
112
+ "56": "https://safe-transaction-bsc.safe.global/api",
113
+ "100": "https://safe-transaction-gnosis-chain.safe.global/api",
114
+ "137": "https://safe-transaction-polygon.safe.global/api",
115
+ "196": "https://safe-transaction-xlayer.safe.global/api",
116
+ "324": "https://safe-transaction-zksync.safe.global/api",
117
+ "1101": "https://safe-transaction-zkevm.safe.global/api",
118
+ "5000": "https://safe-transaction-mantle.safe.global/api",
119
+ "8453": "https://safe-transaction-base.safe.global/api",
120
+ "42161": "https://safe-transaction-arbitrum.safe.global/api",
121
+ "42220": "https://safe-transaction-celo.safe.global/api",
122
+ "43114": "https://safe-transaction-avalanche.safe.global/api",
123
+ "59144": "https://safe-transaction-linea.safe.global/api",
124
+ "81457": "https://safe-transaction-blast.safe.global/api",
125
+ "84532": "https://safe-transaction-base-sepolia.safe.global/api",
126
+ "534352": "https://safe-transaction-scroll.safe.global/api",
127
+ "11155111": "https://safe-transaction-sepolia.safe.global/api",
128
+ "1313161554": "https://safe-transaction-aurora.safe.global/api"
129
+ };
130
+
131
+ // src/utils/constants.ts
132
+ var EMPTY_DATA = "0x";
133
+
134
+ // src/utils/index.ts
135
+ var isEmptyData = (input) => !input || input === EMPTY_DATA;
136
+
137
+ // src/utils/safeOperation.ts
138
+ var getAddSafeOperationProps = async (safeOperation) => {
139
+ const userOperation = safeOperation.getUserOperation();
140
+ userOperation.signature = safeOperation.encodedSignatures();
141
+ return {
142
+ entryPoint: safeOperation.options.entryPoint,
143
+ moduleAddress: safeOperation.options.moduleAddress,
144
+ safeAddress: userOperation.sender,
145
+ userOperation,
146
+ options: {
147
+ validAfter: safeOperation.options.validAfter,
148
+ validUntil: safeOperation.options.validUntil
149
+ }
150
+ };
151
+ };
152
+ var isSafeOperation = (obj) => {
153
+ return "signatures" in obj && "getUserOperation" in obj && "getHash" in obj;
154
+ };
155
+
156
+ // src/SafeApiKit.ts
157
+ var SafeApiKit = class {
158
+ #chainId;
159
+ #txServiceBaseUrl;
160
+ constructor({ chainId, txServiceUrl }) {
161
+ this.#chainId = chainId;
162
+ if (txServiceUrl) {
163
+ this.#txServiceBaseUrl = txServiceUrl;
164
+ } else {
165
+ const url = TRANSACTION_SERVICE_URLS[chainId.toString()];
166
+ if (!url) {
167
+ throw new TypeError(
168
+ `There is no transaction service available for chainId ${chainId}. Please set the txServiceUrl property to use a custom transaction service.`
169
+ );
170
+ }
171
+ this.#txServiceBaseUrl = url;
172
+ }
173
+ }
174
+ #isValidAddress(address) {
175
+ try {
176
+ (0, import_protocol_kit.validateEthereumAddress)(address);
177
+ return true;
178
+ } catch {
179
+ return false;
180
+ }
181
+ }
182
+ #getEip3770Address(fullAddress) {
183
+ return (0, import_protocol_kit.validateEip3770Address)(fullAddress, this.#chainId);
184
+ }
185
+ /**
186
+ * Returns the information and configuration of the service.
187
+ *
188
+ * @returns The information and configuration of the service
189
+ */
190
+ async getServiceInfo() {
191
+ return sendRequest({
192
+ url: `${this.#txServiceBaseUrl}/v1/about`,
193
+ method: "get" /* Get */
194
+ });
195
+ }
196
+ /**
197
+ * Returns the list of Safe singletons.
198
+ *
199
+ * @returns The list of Safe singletons
200
+ */
201
+ async getServiceSingletonsInfo() {
202
+ return sendRequest({
203
+ url: `${this.#txServiceBaseUrl}/v1/about/singletons`,
204
+ method: "get" /* Get */
205
+ });
206
+ }
207
+ /**
208
+ * Decodes the specified Safe transaction data.
209
+ *
210
+ * @param data - The Safe transaction data. '0x' prefixed hexadecimal string.
211
+ * @param to - The address of the receiving contract. If provided, the decoded data will be more accurate, as in case of an ABI collision the Safe Transaction Service would know which ABI to use
212
+ * @returns The transaction data decoded
213
+ * @throws "Invalid data"
214
+ * @throws "Not Found"
215
+ * @throws "Ensure this field has at least 1 hexadecimal chars (not counting 0x)."
216
+ */
217
+ async decodeData(data, to) {
218
+ if (data === "") {
219
+ throw new Error("Invalid data");
220
+ }
221
+ const dataDecoderRequest = { data };
222
+ if (to) {
223
+ dataDecoderRequest.to = to;
224
+ }
225
+ return sendRequest({
226
+ url: `${this.#txServiceBaseUrl}/v1/data-decoder/`,
227
+ method: "post" /* Post */,
228
+ body: dataDecoderRequest
229
+ });
230
+ }
231
+ /**
232
+ * Returns the list of Safes where the address provided is an owner.
233
+ *
234
+ * @param ownerAddress - The owner address
235
+ * @returns The list of Safes where the address provided is an owner
236
+ * @throws "Invalid owner address"
237
+ * @throws "Checksum address validation failed"
238
+ */
239
+ async getSafesByOwner(ownerAddress) {
240
+ if (ownerAddress === "") {
241
+ throw new Error("Invalid owner address");
242
+ }
243
+ const { address } = this.#getEip3770Address(ownerAddress);
244
+ return sendRequest({
245
+ url: `${this.#txServiceBaseUrl}/v1/owners/${address}/safes/`,
246
+ method: "get" /* Get */
247
+ });
248
+ }
249
+ /**
250
+ * Returns the list of Safes where the module address provided is enabled.
251
+ *
252
+ * @param moduleAddress - The Safe module address
253
+ * @returns The list of Safe addresses where the module provided is enabled
254
+ * @throws "Invalid module address"
255
+ * @throws "Module address checksum not valid"
256
+ */
257
+ async getSafesByModule(moduleAddress) {
258
+ if (moduleAddress === "") {
259
+ throw new Error("Invalid module address");
260
+ }
261
+ const { address } = this.#getEip3770Address(moduleAddress);
262
+ return sendRequest({
263
+ url: `${this.#txServiceBaseUrl}/v1/modules/${address}/safes/`,
264
+ method: "get" /* Get */
265
+ });
266
+ }
267
+ /**
268
+ * Returns all the information of a Safe transaction.
269
+ *
270
+ * @param safeTxHash - Hash of the Safe transaction
271
+ * @returns The information of a Safe transaction
272
+ * @throws "Invalid safeTxHash"
273
+ * @throws "Not found."
274
+ */
275
+ async getTransaction(safeTxHash) {
276
+ if (safeTxHash === "") {
277
+ throw new Error("Invalid safeTxHash");
278
+ }
279
+ return sendRequest({
280
+ url: `${this.#txServiceBaseUrl}/v1/multisig-transactions/${safeTxHash}/`,
281
+ method: "get" /* Get */
282
+ });
283
+ }
284
+ /**
285
+ * Returns the list of confirmations for a given a Safe transaction.
286
+ *
287
+ * @param safeTxHash - The hash of the Safe transaction
288
+ * @returns The list of confirmations
289
+ * @throws "Invalid safeTxHash"
290
+ */
291
+ async getTransactionConfirmations(safeTxHash) {
292
+ if (safeTxHash === "") {
293
+ throw new Error("Invalid safeTxHash");
294
+ }
295
+ return sendRequest({
296
+ url: `${this.#txServiceBaseUrl}/v1/multisig-transactions/${safeTxHash}/confirmations/`,
297
+ method: "get" /* Get */
298
+ });
299
+ }
300
+ /**
301
+ * Adds a confirmation for a Safe transaction.
302
+ *
303
+ * @param safeTxHash - Hash of the Safe transaction that will be confirmed
304
+ * @param signature - Signature of the transaction
305
+ * @returns
306
+ * @throws "Invalid safeTxHash"
307
+ * @throws "Invalid signature"
308
+ * @throws "Malformed data"
309
+ * @throws "Error processing data"
310
+ */
311
+ async confirmTransaction(safeTxHash, signature) {
312
+ if (safeTxHash === "") {
313
+ throw new Error("Invalid safeTxHash");
314
+ }
315
+ if (signature === "") {
316
+ throw new Error("Invalid signature");
317
+ }
318
+ return sendRequest({
319
+ url: `${this.#txServiceBaseUrl}/v1/multisig-transactions/${safeTxHash}/confirmations/`,
320
+ method: "post" /* Post */,
321
+ body: {
322
+ signature
323
+ }
324
+ });
325
+ }
326
+ /**
327
+ * Returns the information and configuration of the provided Safe address.
328
+ *
329
+ * @param safeAddress - The Safe address
330
+ * @returns The information and configuration of the provided Safe address
331
+ * @throws "Invalid Safe address"
332
+ * @throws "Checksum address validation failed"
333
+ */
334
+ async getSafeInfo(safeAddress) {
335
+ if (safeAddress === "") {
336
+ throw new Error("Invalid Safe address");
337
+ }
338
+ const { address } = this.#getEip3770Address(safeAddress);
339
+ return sendRequest({
340
+ url: `${this.#txServiceBaseUrl}/v1/safes/${address}/`,
341
+ method: "get" /* Get */
342
+ }).then((response) => {
343
+ if (!response?.singleton) {
344
+ const { masterCopy, ...rest } = response;
345
+ return { ...rest, singleton: masterCopy };
346
+ }
347
+ return response;
348
+ });
349
+ }
350
+ /**
351
+ * Returns the list of delegates.
352
+ *
353
+ * @param getSafeDelegateProps - Properties to filter the returned list of delegates
354
+ * @returns The list of delegates
355
+ * @throws "Checksum address validation failed"
356
+ */
357
+ async getSafeDelegates({
358
+ safeAddress,
359
+ delegateAddress,
360
+ delegatorAddress,
361
+ label,
362
+ limit,
363
+ offset
364
+ }) {
365
+ const url = new URL(`${this.#txServiceBaseUrl}/v2/delegates`);
366
+ if (safeAddress) {
367
+ const { address: safe } = this.#getEip3770Address(safeAddress);
368
+ url.searchParams.set("safe", safe);
369
+ }
370
+ if (delegateAddress) {
371
+ const { address: delegate } = this.#getEip3770Address(delegateAddress);
372
+ url.searchParams.set("delegate", delegate);
373
+ }
374
+ if (delegatorAddress) {
375
+ const { address: delegator } = this.#getEip3770Address(delegatorAddress);
376
+ url.searchParams.set("delegator", delegator);
377
+ }
378
+ if (label) {
379
+ url.searchParams.set("label", label);
380
+ }
381
+ if (limit != null) {
382
+ url.searchParams.set("limit", limit.toString());
383
+ }
384
+ if (offset != null) {
385
+ url.searchParams.set("offset", offset.toString());
386
+ }
387
+ return sendRequest({
388
+ url: url.toString(),
389
+ method: "get" /* Get */
390
+ });
391
+ }
392
+ /**
393
+ * Adds a new delegate for a given Safe address.
394
+ *
395
+ * @param addSafeDelegateProps - The configuration of the new delegate
396
+ * @returns
397
+ * @throws "Invalid Safe delegate address"
398
+ * @throws "Invalid Safe delegator address"
399
+ * @throws "Invalid label"
400
+ * @throws "Checksum address validation failed"
401
+ * @throws "Address <delegate_address> is not checksumed"
402
+ * @throws "Safe=<safe_address> does not exist or it's still not indexed"
403
+ * @throws "Signing owner is not an owner of the Safe"
404
+ */
405
+ async addSafeDelegate({
406
+ safeAddress,
407
+ delegateAddress,
408
+ delegatorAddress,
409
+ label,
410
+ signer
411
+ }) {
412
+ if (delegateAddress === "") {
413
+ throw new Error("Invalid Safe delegate address");
414
+ }
415
+ if (delegatorAddress === "") {
416
+ throw new Error("Invalid Safe delegator address");
417
+ }
418
+ if (label === "") {
419
+ throw new Error("Invalid label");
420
+ }
421
+ const { address: delegate } = this.#getEip3770Address(delegateAddress);
422
+ const { address: delegator } = this.#getEip3770Address(delegatorAddress);
423
+ const signature = await signDelegate(signer, delegate, this.#chainId);
424
+ const body = {
425
+ safe: safeAddress ? this.#getEip3770Address(safeAddress).address : null,
426
+ delegate,
427
+ delegator,
428
+ label,
429
+ signature
430
+ };
431
+ return sendRequest({
432
+ url: `${this.#txServiceBaseUrl}/v2/delegates/`,
433
+ method: "post" /* Post */,
434
+ body
435
+ });
436
+ }
437
+ /**
438
+ * Removes a delegate for a given Safe address.
439
+ *
440
+ * @param deleteSafeDelegateProps - The configuration for the delegate that will be removed
441
+ * @returns
442
+ * @throws "Invalid Safe delegate address"
443
+ * @throws "Invalid Safe delegator address"
444
+ * @throws "Checksum address validation failed"
445
+ * @throws "Signing owner is not an owner of the Safe"
446
+ * @throws "Not found"
447
+ */
448
+ async removeSafeDelegate({
449
+ delegateAddress,
450
+ delegatorAddress,
451
+ signer
452
+ }) {
453
+ if (delegateAddress === "") {
454
+ throw new Error("Invalid Safe delegate address");
455
+ }
456
+ if (delegatorAddress === "") {
457
+ throw new Error("Invalid Safe delegator address");
458
+ }
459
+ const { address: delegate } = this.#getEip3770Address(delegateAddress);
460
+ const { address: delegator } = this.#getEip3770Address(delegatorAddress);
461
+ const signature = await signDelegate(signer, delegate, this.#chainId);
462
+ return sendRequest({
463
+ url: `${this.#txServiceBaseUrl}/v2/delegates/${delegate}`,
464
+ method: "delete" /* Delete */,
465
+ body: {
466
+ delegator,
467
+ signature
468
+ }
469
+ });
470
+ }
471
+ /**
472
+ * Returns the creation information of a Safe.
473
+ *
474
+ * @param safeAddress - The Safe address
475
+ * @returns The creation information of a Safe
476
+ * @throws "Invalid Safe address"
477
+ * @throws "Safe creation not found"
478
+ * @throws "Checksum address validation failed"
479
+ * @throws "Problem connecting to Ethereum network"
480
+ */
481
+ async getSafeCreationInfo(safeAddress) {
482
+ if (safeAddress === "") {
483
+ throw new Error("Invalid Safe address");
484
+ }
485
+ const { address } = this.#getEip3770Address(safeAddress);
486
+ return sendRequest({
487
+ url: `${this.#txServiceBaseUrl}/v1/safes/${address}/creation/`,
488
+ method: "get" /* Get */
489
+ }).then((response) => {
490
+ if (!response?.singleton) {
491
+ const { masterCopy, ...rest } = response;
492
+ return { ...rest, singleton: masterCopy };
493
+ }
494
+ return response;
495
+ });
496
+ }
497
+ /**
498
+ * Estimates the safeTxGas for a given Safe multi-signature transaction.
499
+ *
500
+ * @param safeAddress - The Safe address
501
+ * @param safeTransaction - The Safe transaction to estimate
502
+ * @returns The safeTxGas for the given Safe transaction
503
+ * @throws "Invalid Safe address"
504
+ * @throws "Data not valid"
505
+ * @throws "Safe not found"
506
+ * @throws "Tx not valid"
507
+ */
508
+ async estimateSafeTransaction(safeAddress, safeTransaction) {
509
+ if (safeAddress === "") {
510
+ throw new Error("Invalid Safe address");
511
+ }
512
+ const { address } = this.#getEip3770Address(safeAddress);
513
+ return sendRequest({
514
+ url: `${this.#txServiceBaseUrl}/v1/safes/${address}/multisig-transactions/estimations/`,
515
+ method: "post" /* Post */,
516
+ body: safeTransaction
517
+ });
518
+ }
519
+ /**
520
+ * Creates a new multi-signature transaction with its confirmations and stores it in the Safe Transaction Service.
521
+ *
522
+ * @param proposeTransactionConfig - The configuration of the proposed transaction
523
+ * @returns The hash of the Safe transaction proposed
524
+ * @throws "Invalid Safe address"
525
+ * @throws "Invalid safeTxHash"
526
+ * @throws "Invalid data"
527
+ * @throws "Invalid ethereum address/User is not an owner/Invalid signature/Nonce already executed/Sender is not an owner"
528
+ */
529
+ async proposeTransaction({
530
+ safeAddress,
531
+ safeTransactionData,
532
+ safeTxHash,
533
+ senderAddress,
534
+ senderSignature,
535
+ origin
536
+ }) {
537
+ if (safeAddress === "") {
538
+ throw new Error("Invalid Safe address");
539
+ }
540
+ const { address: safe } = this.#getEip3770Address(safeAddress);
541
+ const { address: sender } = this.#getEip3770Address(senderAddress);
542
+ if (safeTxHash === "") {
543
+ throw new Error("Invalid safeTxHash");
544
+ }
545
+ return sendRequest({
546
+ url: `${this.#txServiceBaseUrl}/v1/safes/${safe}/multisig-transactions/`,
547
+ method: "post" /* Post */,
548
+ body: {
549
+ ...safeTransactionData,
550
+ contractTransactionHash: safeTxHash,
551
+ sender,
552
+ signature: senderSignature,
553
+ origin
554
+ }
555
+ });
556
+ }
557
+ /**
558
+ * Returns the history of incoming transactions of a Safe account.
559
+ *
560
+ * @param safeAddress - The Safe address
561
+ * @returns The history of incoming transactions
562
+ * @throws "Invalid Safe address"
563
+ * @throws "Checksum address validation failed"
564
+ */
565
+ async getIncomingTransactions(safeAddress) {
566
+ if (safeAddress === "") {
567
+ throw new Error("Invalid Safe address");
568
+ }
569
+ const { address } = this.#getEip3770Address(safeAddress);
570
+ return sendRequest({
571
+ url: `${this.#txServiceBaseUrl}/v1/safes/${address}/incoming-transfers?executed=true`,
572
+ method: "get" /* Get */
573
+ });
574
+ }
575
+ /**
576
+ * Returns the history of module transactions of a Safe account.
577
+ *
578
+ * @param safeAddress - The Safe address
579
+ * @returns The history of module transactions
580
+ * @throws "Invalid Safe address"
581
+ * @throws "Invalid data"
582
+ * @throws "Invalid ethereum address"
583
+ */
584
+ async getModuleTransactions(safeAddress) {
585
+ if (safeAddress === "") {
586
+ throw new Error("Invalid Safe address");
587
+ }
588
+ const { address } = this.#getEip3770Address(safeAddress);
589
+ return sendRequest({
590
+ url: `${this.#txServiceBaseUrl}/v1/safes/${address}/module-transactions/`,
591
+ method: "get" /* Get */
592
+ });
593
+ }
594
+ /**
595
+ * Returns the history of multi-signature transactions of a Safe account.
596
+ *
597
+ * @param safeAddress - The Safe address
598
+ * @returns The history of multi-signature transactions
599
+ * @throws "Invalid Safe address"
600
+ * @throws "Checksum address validation failed"
601
+ */
602
+ async getMultisigTransactions(safeAddress) {
603
+ if (safeAddress === "") {
604
+ throw new Error("Invalid Safe address");
605
+ }
606
+ const { address } = this.#getEip3770Address(safeAddress);
607
+ return sendRequest({
608
+ url: `${this.#txServiceBaseUrl}/v1/safes/${address}/multisig-transactions/`,
609
+ method: "get" /* Get */
610
+ });
611
+ }
612
+ async getPendingTransactions(safeAddress, propsOrCurrentNonce = {}) {
613
+ if (safeAddress === "") {
614
+ throw new Error("Invalid Safe address");
615
+ }
616
+ let currentNonce;
617
+ let hasConfirmations;
618
+ let ordering;
619
+ let limit;
620
+ let offset;
621
+ if (typeof propsOrCurrentNonce === "object") {
622
+ ;
623
+ ({ currentNonce, hasConfirmations, ordering, limit, offset } = propsOrCurrentNonce);
624
+ } else {
625
+ console.warn(
626
+ "Deprecated: Use `currentNonce` inside an object instead. See `PendingTransactionsOptions`."
627
+ );
628
+ currentNonce = propsOrCurrentNonce;
629
+ }
630
+ const { address } = this.#getEip3770Address(safeAddress);
631
+ const nonce = currentNonce ? currentNonce : (await this.getSafeInfo(address)).nonce;
632
+ const url = new URL(
633
+ `${this.#txServiceBaseUrl}/v1/safes/${address}/multisig-transactions/?executed=false&nonce__gte=${nonce}`
634
+ );
635
+ if (hasConfirmations) {
636
+ url.searchParams.set("has_confirmations", hasConfirmations.toString());
637
+ }
638
+ if (ordering) {
639
+ url.searchParams.set("ordering", ordering);
640
+ }
641
+ if (limit != null) {
642
+ url.searchParams.set("limit", limit.toString());
643
+ }
644
+ if (offset != null) {
645
+ url.searchParams.set("offset", offset.toString());
646
+ }
647
+ return sendRequest({
648
+ url: url.toString(),
649
+ method: "get" /* Get */
650
+ });
651
+ }
652
+ /**
653
+ * Returns a list of transactions for a Safe. The list has different structures depending on the transaction type
654
+ *
655
+ * @param safeAddress - The Safe address
656
+ * @returns The list of transactions waiting for the confirmation of the Safe owners
657
+ * @throws "Invalid Safe address"
658
+ * @throws "Checksum address validation failed"
659
+ */
660
+ async getAllTransactions(safeAddress, options) {
661
+ if (safeAddress === "") {
662
+ throw new Error("Invalid Safe address");
663
+ }
664
+ const { address } = this.#getEip3770Address(safeAddress);
665
+ const url = new URL(`${this.#txServiceBaseUrl}/v1/safes/${address}/all-transactions/`);
666
+ const trusted = options?.trusted?.toString() || "true";
667
+ url.searchParams.set("trusted", trusted);
668
+ const queued = options?.queued?.toString() || "true";
669
+ url.searchParams.set("queued", queued);
670
+ const executed = options?.executed?.toString() || "false";
671
+ url.searchParams.set("executed", executed);
672
+ return sendRequest({
673
+ url: url.toString(),
674
+ method: "get" /* Get */
675
+ });
676
+ }
677
+ /**
678
+ * Returns the right nonce to propose a new transaction after the last pending transaction.
679
+ *
680
+ * @param safeAddress - The Safe address
681
+ * @returns The right nonce to propose a new transaction after the last pending transaction
682
+ * @throws "Invalid Safe address"
683
+ * @throws "Invalid data"
684
+ * @throws "Invalid ethereum address"
685
+ */
686
+ async getNextNonce(safeAddress) {
687
+ if (safeAddress === "") {
688
+ throw new Error("Invalid Safe address");
689
+ }
690
+ const { address } = this.#getEip3770Address(safeAddress);
691
+ const pendingTransactions = await this.getPendingTransactions(address);
692
+ if (pendingTransactions.results.length > 0) {
693
+ const maxNonce = pendingTransactions.results.reduce((acc, tx) => {
694
+ const curr = BigInt(tx.nonce);
695
+ return curr > acc ? curr : acc;
696
+ }, 0n);
697
+ return (maxNonce + 1n).toString();
698
+ }
699
+ const safeInfo = await this.getSafeInfo(address);
700
+ return safeInfo.nonce;
701
+ }
702
+ /**
703
+ * Returns the list of all the ERC20 tokens handled by the Safe.
704
+ *
705
+ * @returns The list of all the ERC20 tokens
706
+ */
707
+ async getTokenList() {
708
+ return sendRequest({
709
+ url: `${this.#txServiceBaseUrl}/v1/tokens/`,
710
+ method: "get" /* Get */
711
+ });
712
+ }
713
+ /**
714
+ * Returns the information of a given ERC20 token.
715
+ *
716
+ * @param tokenAddress - The token address
717
+ * @returns The information of the given ERC20 token
718
+ * @throws "Invalid token address"
719
+ * @throws "Checksum address validation failed"
720
+ */
721
+ async getToken(tokenAddress) {
722
+ if (tokenAddress === "") {
723
+ throw new Error("Invalid token address");
724
+ }
725
+ const { address } = this.#getEip3770Address(tokenAddress);
726
+ return sendRequest({
727
+ url: `${this.#txServiceBaseUrl}/v1/tokens/${address}/`,
728
+ method: "get" /* Get */
729
+ });
730
+ }
731
+ /**
732
+ * Get a message by its safe message hash
733
+ * @param messageHash The Safe message hash
734
+ * @returns The message
735
+ */
736
+ async getMessage(messageHash) {
737
+ if (!messageHash) {
738
+ throw new Error("Invalid messageHash");
739
+ }
740
+ return sendRequest({
741
+ url: `${this.#txServiceBaseUrl}/v1/messages/${messageHash}/`,
742
+ method: "get" /* Get */
743
+ });
744
+ }
745
+ /**
746
+ * Get the list of messages associated to a Safe account
747
+ * @param safeAddress The safe address
748
+ * @param options The options to filter the list of messages
749
+ * @returns The paginated list of messages
750
+ */
751
+ async getMessages(safeAddress, { ordering, limit, offset } = {}) {
752
+ if (!this.#isValidAddress(safeAddress)) {
753
+ throw new Error("Invalid safeAddress");
754
+ }
755
+ const url = new URL(`${this.#txServiceBaseUrl}/v1/safes/${safeAddress}/messages/`);
756
+ if (ordering) {
757
+ url.searchParams.set("ordering", ordering);
758
+ }
759
+ if (limit != null) {
760
+ url.searchParams.set("limit", limit.toString());
761
+ }
762
+ if (offset != null) {
763
+ url.searchParams.set("offset", offset.toString());
764
+ }
765
+ return sendRequest({
766
+ url: url.toString(),
767
+ method: "get" /* Get */
768
+ });
769
+ }
770
+ /**
771
+ * Creates a new message with an initial signature
772
+ * Add more signatures from other owners using addMessageSignature()
773
+ * @param safeAddress The safe address
774
+ * @param options The raw message to add, signature and safeAppId if any
775
+ */
776
+ async addMessage(safeAddress, addMessageProps) {
777
+ if (!this.#isValidAddress(safeAddress)) {
778
+ throw new Error("Invalid safeAddress");
779
+ }
780
+ return sendRequest({
781
+ url: `${this.#txServiceBaseUrl}/v1/safes/${safeAddress}/messages/`,
782
+ method: "post" /* Post */,
783
+ body: addMessageProps
784
+ });
785
+ }
786
+ /**
787
+ * Add a signature to an existing message
788
+ * @param messageHash The safe message hash
789
+ * @param signature The signature
790
+ */
791
+ async addMessageSignature(messageHash, signature) {
792
+ if (!messageHash || !signature) {
793
+ throw new Error("Invalid messageHash or signature");
794
+ }
795
+ return sendRequest({
796
+ url: `${this.#txServiceBaseUrl}/v1/messages/${messageHash}/signatures/`,
797
+ method: "post" /* Post */,
798
+ body: {
799
+ signature
800
+ }
801
+ });
802
+ }
803
+ /**
804
+ * Get the SafeOperations that were sent from a particular address.
805
+ * @param getSafeOperationsProps - The parameters to filter the list of SafeOperations
806
+ * @throws "Safe address must not be empty"
807
+ * @throws "Invalid Ethereum address {safeAddress}"
808
+ * @returns The SafeOperations sent from the given Safe's address
809
+ */
810
+ async getSafeOperationsByAddress({
811
+ safeAddress,
812
+ executed,
813
+ hasConfirmations,
814
+ ordering,
815
+ limit,
816
+ offset
817
+ }) {
818
+ if (!safeAddress) {
819
+ throw new Error("Safe address must not be empty");
820
+ }
821
+ const { address } = this.#getEip3770Address(safeAddress);
822
+ const url = new URL(`${this.#txServiceBaseUrl}/v1/safes/${address}/safe-operations/`);
823
+ if (ordering) {
824
+ url.searchParams.set("ordering", ordering);
825
+ }
826
+ if (limit != null) {
827
+ url.searchParams.set("limit", limit.toString());
828
+ }
829
+ if (offset != null) {
830
+ url.searchParams.set("offset", offset.toString());
831
+ }
832
+ if (hasConfirmations != null) {
833
+ url.searchParams.set("has_confirmations", hasConfirmations.toString());
834
+ }
835
+ if (executed != null) {
836
+ url.searchParams.set("executed", executed.toString());
837
+ }
838
+ return sendRequest({
839
+ url: url.toString(),
840
+ method: "get" /* Get */
841
+ });
842
+ }
843
+ /**
844
+ * Get the SafeOperations that are pending to send to the bundler
845
+ * @param getSafeOperationsProps - The parameters to filter the list of SafeOperations
846
+ * @throws "Safe address must not be empty"
847
+ * @throws "Invalid Ethereum address {safeAddress}"
848
+ * @returns The pending SafeOperations
849
+ */
850
+ async getPendingSafeOperations(props) {
851
+ return this.getSafeOperationsByAddress({
852
+ ...props,
853
+ executed: false
854
+ });
855
+ }
856
+ /**
857
+ * Get a SafeOperation by its hash.
858
+ * @param safeOperationHash The SafeOperation hash
859
+ * @throws "SafeOperation hash must not be empty"
860
+ * @throws "Not found."
861
+ * @returns The SafeOperation
862
+ */
863
+ async getSafeOperation(safeOperationHash) {
864
+ if (!safeOperationHash) {
865
+ throw new Error("SafeOperation hash must not be empty");
866
+ }
867
+ return sendRequest({
868
+ url: `${this.#txServiceBaseUrl}/v1/safe-operations/${safeOperationHash}/`,
869
+ method: "get" /* Get */
870
+ });
871
+ }
872
+ /**
873
+ * Create a new 4337 SafeOperation for a Safe.
874
+ * @param addSafeOperationProps - The configuration of the SafeOperation
875
+ * @throws "Safe address must not be empty"
876
+ * @throws "Invalid Safe address {safeAddress}"
877
+ * @throws "Module address must not be empty"
878
+ * @throws "Invalid module address {moduleAddress}"
879
+ * @throws "Signature must not be empty"
880
+ */
881
+ async addSafeOperation(safeOperation) {
882
+ let safeAddress, moduleAddress;
883
+ let addSafeOperationProps;
884
+ if (isSafeOperation(safeOperation)) {
885
+ addSafeOperationProps = await getAddSafeOperationProps(safeOperation);
886
+ } else {
887
+ addSafeOperationProps = safeOperation;
888
+ }
889
+ const {
890
+ entryPoint,
891
+ moduleAddress: moduleAddressProp,
892
+ options,
893
+ safeAddress: safeAddressProp,
894
+ userOperation
895
+ } = addSafeOperationProps;
896
+ if (!safeAddressProp) {
897
+ throw new Error("Safe address must not be empty");
898
+ }
899
+ try {
900
+ safeAddress = this.#getEip3770Address(safeAddressProp).address;
901
+ } catch (err) {
902
+ throw new Error(`Invalid Safe address ${safeAddressProp}`);
903
+ }
904
+ if (!moduleAddressProp) {
905
+ throw new Error("Module address must not be empty");
906
+ }
907
+ try {
908
+ moduleAddress = this.#getEip3770Address(moduleAddressProp).address;
909
+ } catch (err) {
910
+ throw new Error(`Invalid module address ${moduleAddressProp}`);
911
+ }
912
+ if (isEmptyData(userOperation.signature)) {
913
+ throw new Error("Signature must not be empty");
914
+ }
915
+ const getISOString = (date) => !date ? null : new Date(date * 1e3).toISOString();
916
+ const userOperationV06 = userOperation;
917
+ return sendRequest({
918
+ url: `${this.#txServiceBaseUrl}/v1/safes/${safeAddress}/safe-operations/`,
919
+ method: "post" /* Post */,
920
+ body: {
921
+ initCode: isEmptyData(userOperationV06.initCode) ? null : userOperationV06.initCode,
922
+ nonce: userOperation.nonce,
923
+ callData: userOperation.callData,
924
+ callGasLimit: userOperation.callGasLimit.toString(),
925
+ verificationGasLimit: userOperation.verificationGasLimit.toString(),
926
+ preVerificationGas: userOperation.preVerificationGas.toString(),
927
+ maxFeePerGas: userOperation.maxFeePerGas.toString(),
928
+ maxPriorityFeePerGas: userOperation.maxPriorityFeePerGas.toString(),
929
+ paymasterAndData: isEmptyData(userOperationV06.paymasterAndData) ? null : userOperationV06.paymasterAndData,
930
+ entryPoint,
931
+ validAfter: getISOString(options?.validAfter),
932
+ validUntil: getISOString(options?.validUntil),
933
+ signature: userOperation.signature,
934
+ moduleAddress
935
+ }
936
+ });
937
+ }
938
+ /**
939
+ * Returns the list of confirmations for a given a SafeOperation.
940
+ *
941
+ * @param safeOperationHash - The hash of the SafeOperation to get confirmations for
942
+ * @param getSafeOperationConfirmationsOptions - Additional options for fetching the list of confirmations
943
+ * @returns The list of confirmations
944
+ * @throws "Invalid SafeOperation hash"
945
+ * @throws "Invalid data"
946
+ */
947
+ async getSafeOperationConfirmations(safeOperationHash, { limit, offset } = {}) {
948
+ if (!safeOperationHash) {
949
+ throw new Error("Invalid SafeOperation hash");
950
+ }
951
+ const url = new URL(
952
+ `${this.#txServiceBaseUrl}/v1/safe-operations/${safeOperationHash}/confirmations/`
953
+ );
954
+ if (limit != null) {
955
+ url.searchParams.set("limit", limit.toString());
956
+ }
957
+ if (offset != null) {
958
+ url.searchParams.set("offset", offset.toString());
959
+ }
960
+ return sendRequest({
961
+ url: url.toString(),
962
+ method: "get" /* Get */
963
+ });
964
+ }
965
+ /**
966
+ * Adds a confirmation for a SafeOperation.
967
+ *
968
+ * @param safeOperationHash The SafeOperation hash
969
+ * @param signature - Signature of the SafeOperation
970
+ * @returns
971
+ * @throws "Invalid SafeOperation hash"
972
+ * @throws "Invalid signature"
973
+ * @throws "Malformed data"
974
+ * @throws "Error processing data"
975
+ */
976
+ async confirmSafeOperation(safeOperationHash, signature) {
977
+ if (!safeOperationHash) {
978
+ throw new Error("Invalid SafeOperation hash");
979
+ }
980
+ if (!signature) {
981
+ throw new Error("Invalid signature");
982
+ }
983
+ return sendRequest({
984
+ url: `${this.#txServiceBaseUrl}/v1/safe-operations/${safeOperationHash}/confirmations/`,
985
+ method: "post" /* Post */,
986
+ body: { signature }
987
+ });
988
+ }
989
+ };
990
+ var SafeApiKit_default = SafeApiKit;
991
+
992
+ // src/index.ts
993
+ var src_default = SafeApiKit_default;