@instadapp/avocado-base 0.0.0-dev.9853aa2 → 0.0.0-dev.991c44c

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 (41) hide show
  1. package/abi/multisigForwarder.json +697 -0
  2. package/app.vue +7 -0
  3. package/assets/images/icons/change-threshold.svg +4 -0
  4. package/assets/images/icons/cross-transfer.svg +7 -0
  5. package/assets/images/icons/dapp.svg +4 -0
  6. package/assets/images/icons/deploy.svg +12 -0
  7. package/assets/images/icons/gas.svg +12 -5
  8. package/assets/images/icons/hammer.svg +5 -0
  9. package/assets/images/icons/info-2.svg +12 -0
  10. package/assets/images/icons/instadapp-pro.svg +4 -0
  11. package/assets/images/icons/multi-send.svg +7 -0
  12. package/assets/images/icons/permit-sign.svg +11 -0
  13. package/assets/images/icons/plus-circle.svg +6 -0
  14. package/assets/images/icons/refresh.svg +4 -4
  15. package/assets/images/icons/reject-proposal.svg +6 -0
  16. package/assets/images/icons/transfer.svg +5 -0
  17. package/assets/images/icons/trash-2.svg +8 -0
  18. package/assets/images/icons/upgrade.svg +4 -0
  19. package/components/ActionLogo.vue +40 -0
  20. package/components/ActionMetadata.vue +27 -4
  21. package/components/AuthorityAvatar.vue +38 -0
  22. package/components/ChainLogo.vue +14 -556
  23. package/components/CopyClipboard.vue +64 -0
  24. package/components/metadata/Bridge.vue +26 -6
  25. package/components/metadata/CrossTransfer.vue +5 -1
  26. package/components/metadata/GasTopup.vue +7 -1
  27. package/components/metadata/Permit2.vue +6 -1
  28. package/components/metadata/Signers.vue +63 -0
  29. package/components/metadata/Swap.vue +9 -2
  30. package/components/metadata/Transfer.vue +6 -2
  31. package/contracts/MultisigForwarder.ts +859 -0
  32. package/contracts/factories/MultisigForwarder__factory.ts +721 -0
  33. package/contracts/factories/index.ts +1 -0
  34. package/contracts/index.ts +2 -0
  35. package/package.json +5 -3
  36. package/utils/formatter.ts +1 -1
  37. package/utils/helper.ts +8 -0
  38. package/utils/metadata.ts +229 -145
  39. package/utils/network.ts +163 -80
  40. package/utils/services.ts +8 -1
  41. package/utils/utils.d.ts +128 -127
@@ -6,9 +6,11 @@ export type { BalanceResolver } from "./BalanceResolver";
6
6
  export type { Erc20 } from "./Erc20";
7
7
  export type { Forwarder } from "./Forwarder";
8
8
  export type { GaslessWallet } from "./GaslessWallet";
9
+ export type { MultisigForwarder } from "./MultisigForwarder";
9
10
  export * as factories from "./factories";
10
11
  export { AvoFactoryProxy__factory } from "./factories/AvoFactoryProxy__factory";
11
12
  export { BalanceResolver__factory } from "./factories/BalanceResolver__factory";
12
13
  export { Erc20__factory } from "./factories/Erc20__factory";
13
14
  export { Forwarder__factory } from "./factories/Forwarder__factory";
14
15
  export { GaslessWallet__factory } from "./factories/GaslessWallet__factory";
16
+ export { MultisigForwarder__factory } from "./factories/MultisigForwarder__factory";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instadapp/avocado-base",
3
- "version": "0.0.0-dev.9853aa2",
3
+ "version": "0.0.0-dev.991c44c",
4
4
  "type": "module",
5
5
  "main": "./nuxt.config.ts",
6
6
  "types": "global.d.ts",
@@ -20,11 +20,13 @@
20
20
  "nuxt-svgo": "^3.1.0",
21
21
  "rimraf": "^3.0.2",
22
22
  "typechain": "^8.1.1",
23
- "unplugin-vue-components": "^0.25.1"
23
+ "unplugin-vue-components": "^0.25.1",
24
+ "vue-tippy": "^6.0.0"
24
25
  },
25
26
  "dependencies": {
26
27
  "@vueuse/nuxt": "^10.2.0",
27
28
  "bignumber.js": "^9.1.1",
28
- "ethers": "^5.7.2"
29
+ "ethers": "^5.7.2",
30
+ "xxhashjs": "^0.2.2"
29
31
  }
30
32
  }
@@ -72,7 +72,7 @@ export function formatDecimal(value: string | number, fractionDigits?: number) {
72
72
  let decimals;
73
73
 
74
74
  if (num.lt(1)) {
75
- decimals = 8;
75
+ decimals = 4;
76
76
  } else if (num.lt(10)) {
77
77
  decimals = 6;
78
78
  } else if (num.lt(100)) {
package/utils/helper.ts CHANGED
@@ -52,3 +52,11 @@ export function onImageError(this: HTMLImageElement) {
52
52
  parentElement.classList.add("bg-gray-300");
53
53
  }
54
54
  }
55
+
56
+ export function formatMultipleAddresses(addresses: string[], shorten = true) {
57
+ const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' })
58
+ const formattedString = formatter.format(addresses.map(i => shorten ? shortenHash(i) || '' : i))
59
+
60
+ return formattedString
61
+ }
62
+
package/utils/metadata.ts CHANGED
@@ -1,11 +1,32 @@
1
1
  import { ethers, utils } from "ethers";
2
- import { Forwarder__factory } from "../contracts";
2
+ import { Forwarder__factory, MultisigForwarder__factory } from "../contracts";
3
+ import { toBN } from "./bignumber";
4
+
5
+ export const MetadataEnums = {
6
+ transfer: "transfer",
7
+ bridge: "bridge",
8
+ swap: "swap",
9
+ "gas-topup": "gas-topup",
10
+ upgrade: "upgrade",
11
+ dapp: "dapp",
12
+ deploy: "deploy",
13
+ permit2: "permit2",
14
+ "cross-transfer": "cross-transfer",
15
+ auth: "auth",
16
+ rejection: "rejection",
17
+ "instadapp-pro": "instadapp-pro",
18
+ "add-signers": "add-signers",
19
+ "remove-signers": "remove-signers",
20
+ "change-threshold": "change-threshold",
21
+ import: "import",
22
+ "transaction-builder": "transaction-builder",
23
+ } as const;
3
24
 
4
25
  const multiMetadataTypes = ["bytes[]"];
5
26
 
6
27
  const metadataTypes = ["bytes32 type", "uint8 version", "bytes data"];
7
28
 
8
- const actionMetadataTypes = {
29
+ const actionMetadataTypes: Record<MetadataTypes, string[]> = {
9
30
  transfer: ["address token", "uint256 amount", "address receiver"],
10
31
  "cross-transfer": [
11
32
  "address fromToken",
@@ -34,8 +55,10 @@ const actionMetadataTypes = {
34
55
  "gas-topup": ["uint256 amount", "address token", "address onBehalf"],
35
56
  upgrade: ["bytes32 version", "address walletImpl"],
36
57
  dapp: ["string name", "string url"],
58
+ import: ["bytes32 protocol", "uint256 valueInUsd"],
37
59
  auth: ["address address", "uint256 chainId", "bool remove"],
38
60
  deploy: [],
61
+ "transaction-builder": [],
39
62
  permit2: [
40
63
  "address token",
41
64
  "address spender",
@@ -43,7 +66,10 @@ const actionMetadataTypes = {
43
66
  "uint48 expiration",
44
67
  ],
45
68
  "instadapp-pro": ["string castDetails"],
46
- reject: ["string reason"],
69
+ "add-signers": ["address[] signers"],
70
+ "remove-signers": ["address[] signers"],
71
+ "change-threshold": ["uint8 count"],
72
+ rejection: ["bytes32 id"],
47
73
  };
48
74
 
49
75
  const encodeMetadata = (props: MetadataProps) => {
@@ -64,7 +90,7 @@ export const encodeDappMetadata = (
64
90
  );
65
91
 
66
92
  const data = encodeMetadata({
67
- type: "dapp",
93
+ type: MetadataEnums.dapp,
68
94
  encodedData,
69
95
  });
70
96
 
@@ -81,21 +107,21 @@ export const encodeTransferMetadata = (
81
107
  );
82
108
 
83
109
  const data = encodeMetadata({
84
- type: "transfer",
110
+ type: MetadataEnums.transfer,
85
111
  encodedData,
86
112
  });
87
113
 
88
114
  return single ? encodeMultipleActions(data) : data;
89
115
  };
90
116
 
91
- export const encodeRejectMetadata = (reason: string, single = true) => {
117
+ export const encodeRejectionMetadata = (id: string, single = true) => {
92
118
  const encodedData = ethers.utils.defaultAbiCoder.encode(
93
- actionMetadataTypes.reject,
94
- [reason]
119
+ actionMetadataTypes.rejection,
120
+ [id]
95
121
  );
96
122
 
97
123
  const data = encodeMetadata({
98
- type: "reject",
124
+ type: MetadataEnums.rejection,
99
125
  encodedData,
100
126
  });
101
127
 
@@ -118,7 +144,7 @@ export const encodeCrossTransferMetadata = (
118
144
  );
119
145
 
120
146
  const data = encodeMetadata({
121
- type: "cross-transfer",
147
+ type: MetadataEnums["cross-transfer"],
122
148
  encodedData,
123
149
  });
124
150
 
@@ -135,7 +161,7 @@ export const encodeAuthMetadata = (
135
161
  );
136
162
 
137
163
  const data = encodeMetadata({
138
- type: "auth",
164
+ type: MetadataEnums.auth,
139
165
  encodedData,
140
166
  });
141
167
 
@@ -144,7 +170,16 @@ export const encodeAuthMetadata = (
144
170
 
145
171
  export const encodeDeployMetadata = (single = true) => {
146
172
  const data = encodeMetadata({
147
- type: "deploy",
173
+ type: MetadataEnums.deploy,
174
+ encodedData: "0x",
175
+ });
176
+
177
+ return single ? encodeMultipleActions(data) : data;
178
+ };
179
+
180
+ export const encodeTransactionBuilderMetadata = (single = true) => {
181
+ const data = encodeMetadata({
182
+ type: MetadataEnums["transaction-builder"],
148
183
  encodedData: "0x",
149
184
  });
150
185
 
@@ -161,7 +196,7 @@ export const encodeWCSignMetadata = (
161
196
  );
162
197
 
163
198
  const data = encodeMetadata({
164
- type: "permit2",
199
+ type: MetadataEnums.permit2,
165
200
  encodedData,
166
201
  });
167
202
 
@@ -178,7 +213,7 @@ export const encodeUpgradeMetadata = (
178
213
  );
179
214
 
180
215
  const data = encodeMetadata({
181
- type: "upgrade",
216
+ type: MetadataEnums.upgrade,
182
217
  encodedData,
183
218
  });
184
219
 
@@ -202,7 +237,7 @@ export const encodeSwapMetadata = (
202
237
  );
203
238
 
204
239
  const data = encodeMetadata({
205
- type: "swap",
240
+ type: MetadataEnums.swap,
206
241
  encodedData,
207
242
  });
208
243
 
@@ -218,10 +253,8 @@ export const encodeTopupMetadata = (
218
253
  [params.amount, params.token, params.onBehalf]
219
254
  );
220
255
 
221
- console.log(params);
222
-
223
256
  const data = encodeMetadata({
224
- type: "gas-topup",
257
+ type: MetadataEnums["gas-topup"],
225
258
  encodedData,
226
259
  });
227
260
 
@@ -246,7 +279,76 @@ export const encodeBridgeMetadata = (
246
279
  );
247
280
 
248
281
  const data = encodeMetadata({
249
- type: "bridge",
282
+ type: MetadataEnums.bridge,
283
+ encodedData,
284
+ });
285
+
286
+ return single ? encodeMultipleActions(data) : data;
287
+ };
288
+
289
+ export const encodeChangeThresholdMetadata = (
290
+ threshold: string | number,
291
+ single = true
292
+ ) => {
293
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
294
+ actionMetadataTypes["change-threshold"],
295
+ [toBN(threshold).toNumber()]
296
+ );
297
+
298
+ const data = encodeMetadata({
299
+ type: MetadataEnums["change-threshold"],
300
+ encodedData,
301
+ });
302
+
303
+ return single ? encodeMultipleActions(data) : data;
304
+ };
305
+
306
+ export const encodeRemoveSignersMetadata = (
307
+ addresses: string[],
308
+ single = true
309
+ ) => {
310
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
311
+ actionMetadataTypes["remove-signers"],
312
+ [addresses]
313
+ );
314
+
315
+ const data = encodeMetadata({
316
+ type: MetadataEnums["remove-signers"],
317
+ encodedData,
318
+ });
319
+
320
+ return single ? encodeMultipleActions(data) : data;
321
+ };
322
+
323
+ export const encodeImportMetadata = (
324
+ protocol: string,
325
+ valueInUsd: string,
326
+ single = true
327
+ ) => {
328
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
329
+ actionMetadataTypes["import"],
330
+ [protocol, valueInUsd]
331
+ );
332
+
333
+ const data = encodeMetadata({
334
+ type: MetadataEnums["import"],
335
+ encodedData,
336
+ });
337
+
338
+ return single ? encodeMultipleActions(data) : data;
339
+ };
340
+
341
+ export const encodeAddSignersMetadata = (
342
+ addresses: string[],
343
+ single = true
344
+ ) => {
345
+ const encodedData = ethers.utils.defaultAbiCoder.encode(
346
+ actionMetadataTypes["add-signers"],
347
+ [addresses]
348
+ );
349
+
350
+ const data = encodeMetadata({
351
+ type: MetadataEnums["add-signers"],
250
352
  encodedData,
251
353
  });
252
354
 
@@ -276,8 +378,10 @@ export const decodeMetadata = (metadata: string) => {
276
378
  }
277
379
  };
278
380
 
381
+ const iface = Forwarder__factory.createInterface();
382
+ const ifaceMultisig = MultisigForwarder__factory.createInterface();
383
+
279
384
  const getMetadataFromData = (data: string) => {
280
- const iface = Forwarder__factory.createInterface();
281
385
  let metadata = "0x";
282
386
 
283
387
  if (data.startsWith("0x18e7f485")) {
@@ -297,37 +401,121 @@ const getMetadataFromData = (data: string) => {
297
401
  } else {
298
402
  metadata = executeDataV2.params_.metadata;
299
403
  }
300
- } else if (data.startsWith("0x85114d53")) {
301
- const executeDataV3 = iface.decodeFunctionData("executeV3", data);
302
- if (
303
- executeDataV3.params_.metadata === "0x" ||
304
- !executeDataV3.params_.metadata
305
- ) {
306
- return null;
307
- } else {
308
- metadata = executeDataV3.params_.metadata;
309
- }
310
404
  } else {
311
- const executeDataMultisigV3 = iface.decodeFunctionData(
312
- "executeMultisigV3",
405
+ const executeDataMultisig = ifaceMultisig.decodeFunctionData(
406
+ "executeV1",
313
407
  data
314
408
  );
315
409
  if (
316
- executeDataMultisigV3.params_.metadata === "0x" ||
317
- !executeDataMultisigV3.params_.metadata
410
+ executeDataMultisig.params_.metadata === "0x" ||
411
+ !executeDataMultisig.params_.metadata
318
412
  ) {
319
413
  return null;
320
414
  } else {
321
- metadata = executeDataMultisigV3.params_.metadata;
415
+ metadata = executeDataMultisig.params_.metadata;
322
416
  }
323
417
  }
324
418
 
325
419
  return metadata;
326
420
  };
327
421
 
422
+ const typesPayload: IPayload = {
423
+ import: (data, type) => ({
424
+ type,
425
+ protocol: utils.parseBytes32String(data.protocol || ""),
426
+ valueInUsd: toBN(data.valueInUsd).toFixed(),
427
+ }),
428
+ transfer: (data, type) => ({
429
+ type,
430
+ token: data.token,
431
+ amount: toBN(data.amount).toFixed(),
432
+ receiver: data.receiver,
433
+ }),
434
+ bridge: (data, type) => ({
435
+ type,
436
+ amount: toBN(data.amount).toFixed(),
437
+ receiver: data.receiver,
438
+ toToken: data.toToken,
439
+ fromToken: data.fromToken,
440
+ toChainId: data.toChainId ? data.toChainId.toString() : null,
441
+ bridgeFee: toBN(data.bridgeFee).toFixed(),
442
+ }),
443
+ swap: (data, type) => ({
444
+ type,
445
+ buyAmount: toBN(data.buyAmount).toFixed(),
446
+ sellAmount: toBN(data.sellAmount).toFixed(),
447
+ buyToken: data.buyToken,
448
+ sellToken: data.sellToken,
449
+ receiver: data.receiver,
450
+ protocol: utils.parseBytes32String(data.protocol || ""),
451
+ }),
452
+ upgrade: (data, type) => ({
453
+ type,
454
+ version: utils.parseBytes32String(data.version || ""),
455
+ walletImpl: data.walletImpl,
456
+ }),
457
+ "gas-topup": (data, type) => ({
458
+ type,
459
+ amount: toBN(data.amount).toFixed(),
460
+ token: data.token,
461
+ onBehalf: data.onBehalf,
462
+ }),
463
+ dapp: (data, type) => ({
464
+ type,
465
+ name: data.name,
466
+ url: data.url,
467
+ }),
468
+ deploy: (data, type) => ({
469
+ type,
470
+ }),
471
+ "transaction-builder": (data, type) => ({
472
+ type,
473
+ }),
474
+ permit2: (data, type) => ({
475
+ type,
476
+ token: data.token,
477
+ spender: data.spender,
478
+ amount: toBN(data.amount).toFixed(),
479
+ expiration: data.expiration,
480
+ }),
481
+ "cross-transfer": (data, type) => ({
482
+ type,
483
+ fromToken: data.fromToken,
484
+ toToken: data.toToken,
485
+ toChainId: data.toChainId ? data.toChainId.toString() : null,
486
+ amount: toBN(data.amount).toFixed(),
487
+ receiver: data.receiver,
488
+ }),
489
+ auth: (data) => ({
490
+ type: data.remove ? "remove-authority" : "add-authority",
491
+ address: data.address,
492
+ chainId: data.chainId ? data.chainId.toString() : null,
493
+ remove: data.remove,
494
+ }),
495
+ "instadapp-pro": (data, type) => ({
496
+ type,
497
+ castDetails: data.castDetails,
498
+ }),
499
+ rejection: (data, type) => ({
500
+ type,
501
+ id: data.id,
502
+ }),
503
+ "add-signers": (data, type) => ({
504
+ type,
505
+ addresses: data.signers,
506
+ }),
507
+ "remove-signers": (data, type) => ({
508
+ type,
509
+ addresses: data.signers,
510
+ }),
511
+ "change-threshold": (data, type) => ({
512
+ type,
513
+ count: data.count,
514
+ }),
515
+ };
516
+
328
517
  const parseMetadata = (metadata: string) => {
329
518
  const metadataArr = [];
330
- let payload = {};
331
519
 
332
520
  const [decodedMultiMetadata = []] =
333
521
  (ethers.utils.defaultAbiCoder.decode(
@@ -350,116 +538,12 @@ const parseMetadata = (metadata: string) => {
350
538
  decodedMetadata.data
351
539
  );
352
540
 
353
- switch (type) {
354
- case "transfer":
355
- payload = {
356
- type,
357
- token: decodedData.token,
358
- amount: toBN(decodedData.amount).toFixed(),
359
- receiver: decodedData.receiver,
360
- };
361
- break;
362
- case "bridge":
363
- payload = {
364
- type,
365
- amount: toBN(decodedData.amount).toFixed(),
366
- receiver: decodedData.receiver,
367
- toToken: decodedData.toToken,
368
- fromToken: decodedData.fromToken,
369
- toChainId: decodedData.toChainId
370
- ? decodedData.toChainId.toString()
371
- : null,
372
- bridgeFee: toBN(decodedData.bridgeFee).toFixed(),
373
- };
374
- break;
375
- case "swap":
376
- payload = {
377
- type,
378
- buyAmount: toBN(decodedData.buyAmount).toFixed(),
379
- sellAmount: toBN(decodedData.sellAmount).toFixed(),
380
- buyToken: decodedData.buyToken,
381
- sellToken: decodedData.sellToken,
382
- receiver: decodedData.receiver,
383
- protocol: utils.parseBytes32String(decodedData?.protocol || ""),
384
- };
385
- break;
386
- case "upgrade":
387
- payload = {
388
- type,
389
- version: utils.parseBytes32String(decodedData?.version || ""),
390
- walletImpl: decodedData?.walletImpl,
391
- };
392
- break;
393
- case "gas-topup":
394
- payload = {
395
- type,
396
- amount: toBN(decodedData.amount).toFixed(),
397
- token: decodedData.token,
398
- onBehalf: decodedData.onBehalf,
399
- };
400
- break;
401
- case "dapp":
402
- payload = {
403
- type,
404
- name: decodedData?.name,
405
- url: decodedData?.url,
406
- };
407
- break;
408
- case "deploy":
409
- payload = {
410
- type,
411
- };
412
- break;
413
-
414
- case "permit2":
415
- payload = {
416
- type,
417
- token: decodedData.token,
418
- spender: decodedData.spender,
419
- amount: toBN(decodedData.amount).toFixed(),
420
- expiration: decodedData.expiration,
421
- };
422
- break;
423
-
424
- case "cross-transfer":
425
- payload = {
426
- type,
427
- fromToken: decodedData.fromToken,
428
- toToken: decodedData.toToken,
429
- toChainId: decodedData.toChainId
430
- ? decodedData.toChainId.toString()
431
- : null,
432
- amount: toBN(decodedData.amount).toFixed(),
433
- receiver: decodedData.receiver,
434
- };
435
-
436
- break;
437
- case "auth":
438
- payload = {
439
- type: decodedData.remove ? "remove-authority" : "add-authority",
440
- address: decodedData.address,
441
- chainId: decodedData.chainId ? decodedData.chainId.toString() : null,
442
- remove: decodedData.remove,
443
- };
444
-
445
- break;
446
- case "instadapp-pro":
447
- payload = {
448
- type,
449
- castDetails: decodedData.castDetails,
450
- };
451
-
452
- break;
453
-
454
- case "reject":
455
- payload = {
456
- type,
457
- reason: decodedData.reason,
458
- };
459
- break;
460
- }
541
+ const payloadFunc = typesPayload[type];
461
542
 
462
- metadataArr.push(payload);
543
+ if (payloadFunc) {
544
+ const payload = payloadFunc(decodedData, type);
545
+ metadataArr.push(payload);
546
+ }
463
547
  }
464
548
 
465
549
  return metadataArr;