dequanto 0.2.53 → 0.2.56

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 (110) hide show
  1. package/lib/cjs/abi/$abi.js +39 -1
  2. package/lib/cjs/abi/$abi.js.map +1 -1
  3. package/lib/cjs/contracts/ContractReader.js +2 -2
  4. package/lib/cjs/contracts/ContractReader.js.map +1 -1
  5. package/lib/cjs/gen/Generator.js +1 -0
  6. package/lib/cjs/gen/Generator.js.map +1 -1
  7. package/lib/cjs/gen/GeneratorFromAbi.js +38 -9
  8. package/lib/cjs/gen/GeneratorFromAbi.js.map +1 -1
  9. package/lib/cjs/safe/GnosisSafeHandler.js.map +1 -1
  10. package/lib/cjs/services/TimelockService/ITimelockService.js.map +1 -1
  11. package/lib/cjs/services/TimelockService/TimelockService.js +1 -1
  12. package/lib/cjs/services/TimelockService/TimelockService.js.map +1 -1
  13. package/lib/cjs/solidity/utils/$types.js +26 -0
  14. package/lib/cjs/solidity/utils/$types.js.map +1 -1
  15. package/lib/cjs/txs/TxWriter.js +6 -4
  16. package/lib/cjs/txs/TxWriter.js.map +1 -1
  17. package/lib/cjs/txs/agents/BatchAgent.js +32 -7
  18. package/lib/cjs/txs/agents/BatchAgent.js.map +1 -1
  19. package/lib/cjs/txs/agents/TxWriterAccountAgents.js +2 -0
  20. package/lib/cjs/txs/agents/TxWriterAccountAgents.js.map +1 -1
  21. package/lib/cjs/txs/agents/ZodiacAgent.js +20 -0
  22. package/lib/cjs/txs/agents/ZodiacAgent.js.map +1 -0
  23. package/lib/cjs/utils/$account.js +5 -1
  24. package/lib/cjs/utils/$account.js.map +1 -1
  25. package/lib/cjs/zodiac/ZodiacTx.js +83 -0
  26. package/lib/cjs/zodiac/ZodiacTx.js.map +1 -0
  27. package/lib/esm/abi/$abi.js.map +1 -1
  28. package/lib/esm/abi/$abi.mjs +36 -1
  29. package/lib/esm/contracts/ContractReader.js.map +1 -1
  30. package/lib/esm/contracts/ContractReader.mjs +2 -2
  31. package/lib/esm/gen/Generator.js.map +1 -1
  32. package/lib/esm/gen/Generator.mjs +1 -0
  33. package/lib/esm/gen/GeneratorFromAbi.js.map +1 -1
  34. package/lib/esm/gen/GeneratorFromAbi.mjs +38 -9
  35. package/lib/esm/safe/GnosisSafeHandler.js.map +1 -1
  36. package/lib/esm/services/TimelockService/ITimelockService.js.map +1 -1
  37. package/lib/esm/services/TimelockService/TimelockService.js.map +1 -1
  38. package/lib/esm/services/TimelockService/TimelockService.mjs +1 -1
  39. package/lib/esm/solidity/utils/$types.js.map +1 -1
  40. package/lib/esm/solidity/utils/$types.mjs +26 -0
  41. package/lib/esm/txs/TxWriter.js.map +1 -1
  42. package/lib/esm/txs/TxWriter.mjs +6 -4
  43. package/lib/esm/txs/agents/BatchAgent.js.map +1 -1
  44. package/lib/esm/txs/agents/BatchAgent.mjs +32 -7
  45. package/lib/esm/txs/agents/TxWriterAccountAgents.js.map +1 -1
  46. package/lib/esm/txs/agents/TxWriterAccountAgents.mjs +2 -0
  47. package/lib/esm/txs/agents/ZodiacAgent.js.map +1 -0
  48. package/lib/esm/txs/agents/ZodiacAgent.mjs +16 -0
  49. package/lib/esm/utils/$account.js.map +1 -1
  50. package/lib/esm/utils/$account.mjs +5 -1
  51. package/lib/esm/zodiac/ZodiacTx.js.map +1 -0
  52. package/lib/esm/zodiac/ZodiacTx.mjs +79 -0
  53. package/lib/types/contracts/ContractReader.d.ts +1 -1
  54. package/lib/types/gen/Generator.d.ts +17 -0
  55. package/lib/types/gen/GeneratorFromAbi.d.ts +7 -0
  56. package/lib/types/models/TAccount.d.ts +11 -2
  57. package/lib/types/models/TEth.d.ts +4 -1
  58. package/lib/types/services/TimelockService/ITimelockService.d.ts +1 -0
  59. package/lib/types/solidity/utils/$types.d.ts +8 -0
  60. package/lib/types/txs/agents/BatchAgent.d.ts +2 -1
  61. package/lib/types/txs/agents/ZodiacAgent.d.ts +7 -0
  62. package/lib/types/utils/$account.d.ts +2 -1
  63. package/lib/types/zodiac/ZodiacTx.d.ts +30 -0
  64. package/package.json +1 -1
  65. package/skills/dequanto/INDEX.md +1 -1
  66. package/skills/dequanto/SKILL.md +4 -3
  67. package/skills/dequanto/examples/browser-wallet.spec.ts +2 -1
  68. package/skills/dequanto/examples/config.spec.ts +2 -1
  69. package/skills/dequanto/examples/contract-read.spec.ts +2 -1
  70. package/skills/dequanto/examples/contract-write.spec.ts +2 -1
  71. package/skills/dequanto/examples/deploy-contract.spec.ts +2 -1
  72. package/skills/dequanto/examples/erc4337-userop.spec.ts +2 -1
  73. package/skills/dequanto/examples/explorer-abi.spec.ts +2 -1
  74. package/skills/dequanto/examples/generate-contract-class.spec.ts +2 -1
  75. package/skills/dequanto/examples/hardhat-debug.spec.ts +2 -1
  76. package/skills/dequanto/examples/hardhat-fork.spec.ts +2 -1
  77. package/skills/dequanto/examples/index-events.spec.ts +2 -1
  78. package/skills/dequanto/examples/live-events.spec.ts +2 -1
  79. package/skills/dequanto/examples/revert-error.spec.ts +2 -1
  80. package/skills/dequanto/examples/rpc-read.spec.ts +19 -5
  81. package/skills/dequanto/examples/safe-batch.spec.ts +92 -3
  82. package/skills/dequanto/examples/send-transaction.spec.ts +2 -1
  83. package/skills/dequanto/examples/storage.spec.ts +2 -1
  84. package/skills/dequanto/examples/token-transfer.spec.ts +2 -1
  85. package/skills/dequanto/examples/utils.spec.ts +2 -1
  86. package/skills/dequanto/references/safe-erc4337.md +50 -3
  87. package/skills/dequanto/references/tokens-accounts.md +1 -0
  88. package/skills/dequanto/references/transactions.md +2 -1
  89. package/src/abi/$abi.ts +36 -0
  90. package/src/contracts/ContractReader.ts +2 -2
  91. package/src/gen/Generator.ts +4 -0
  92. package/src/gen/GeneratorFromAbi.ts +40 -10
  93. package/src/models/TAccount.ts +17 -2
  94. package/src/models/TEth.ts +4 -1
  95. package/src/safe/GnosisSafeHandler.ts +12 -12
  96. package/src/services/TimelockService/ITimelockService.ts +2 -0
  97. package/src/services/TimelockService/TimelockService.ts +1 -1
  98. package/src/solidity/utils/$types.ts +27 -0
  99. package/src/txs/TxWriter.ts +6 -4
  100. package/src/txs/agents/BatchAgent.ts +33 -7
  101. package/src/txs/agents/TxWriterAccountAgents.ts +2 -0
  102. package/src/txs/agents/ZodiacAgent.ts +19 -0
  103. package/src/utils/$account.ts +6 -2
  104. package/src/zodiac/ZodiacTx.ts +99 -0
  105. package/typings/index.d.ts +1 -4
  106. package/typings/globals/atma-utest/index.d.ts +0 -53
  107. package/typings/globals/atma-utest/typings.json +0 -10
  108. package/typings/globals/axios/index.d.ts +0 -6
  109. package/typings/globals/mask/index.d.ts +0 -6
  110. package/typings/globals/mask/typings.json +0 -9
@@ -45,10 +45,10 @@ export class GnosisSafeHandler {
45
45
  this.client = config.client ?? di.resolve(EthWeb3Client);
46
46
  this.transport = config.transport ?? (
47
47
  config.owners.length > 1
48
- // when multiple owners are provided assume the transport is InMemory
49
- ? new InMemoryServiceTransport(this.client, this.owners[0])
50
- // otherwise use the default Safe Transaction Service
51
- : new SafeServiceTransport(this.client, this.owners)
48
+ // when multiple owners are provided assume the transport is InMemory
49
+ ? new InMemoryServiceTransport(this.client, this.owners[0])
50
+ // otherwise use the default Safe Transaction Service
51
+ : new SafeServiceTransport(this.client, this.owners)
52
52
  )
53
53
 
54
54
  $require.Address(this.safeAddress, `Safe address ${this.safeAddress} is not valid`);
@@ -147,7 +147,7 @@ export class GnosisSafeHandler {
147
147
  return tx;
148
148
  }
149
149
 
150
- async executeTxData (txData: TEth.TxLike, owner: EoAccount, safeTxParams?: {
150
+ async executeTxData(txData: TEth.TxLike, owner: EoAccount, safeTxParams?: {
151
151
  // 0 - Call (default)
152
152
  // 1 - DelegateCall
153
153
  operation?: 0 | 1
@@ -158,7 +158,7 @@ export class GnosisSafeHandler {
158
158
  return tx;
159
159
  }
160
160
 
161
- async createTxHash (builder: TxDataBuilder, value?: bigint, safeTxParams?: {
161
+ async createTxHash(builder: TxDataBuilder, value?: bigint, safeTxParams?: {
162
162
  operation?: 0 | 1
163
163
  }) {
164
164
  let txData = builder.getTxData(this.client);
@@ -234,7 +234,7 @@ export class GnosisSafeHandler {
234
234
  let txProps: SafeServiceTypes.ProposeTransactionProps = {
235
235
  safeAddress: $address.toChecksum(this.safeAddress),
236
236
  senderAddress: $address.toChecksum(owner.address),
237
- safeTransaction: <SafeServiceTypes.SafeTransaction> {
237
+ safeTransaction: <SafeServiceTypes.SafeTransaction>{
238
238
  data: safeTxData,
239
239
  signatures: signatures,
240
240
  },
@@ -286,11 +286,11 @@ export class GnosisSafeHandler {
286
286
  })
287
287
  }
288
288
 
289
- static parseSafeTx(buffer: TEth.Hex, value?): { name, args: any[]} {
290
- return $abiUtils.parseMethodCallData([ SafeAbi.execTransaction ], { input: buffer, value });
289
+ static parseSafeTx(buffer: TEth.Hex, value?): { name, args: any[] } {
290
+ return $abiUtils.parseMethodCallData([SafeAbi.execTransaction], { input: buffer, value });
291
291
  }
292
292
 
293
- static async getInstance (senderMix: string | EoAccount, safeAccount: SafeAccount, client: Web3Client, options: {
293
+ static async getInstance(senderMix: string | EoAccount, safeAccount: SafeAccount, client: Web3Client, options: {
294
294
  transport?: ISafeServiceTransport
295
295
  contracts?: typeof config.safe.contracts
296
296
  }): Promise<GnosisSafeHandler> {
@@ -298,7 +298,7 @@ export class GnosisSafeHandler {
298
298
  ? await ChainAccountService.get(senderMix) as EoAccount
299
299
  : senderMix;
300
300
 
301
- let owners = [ sender ];
301
+ let owners = [sender];
302
302
 
303
303
  if (safeAccount.owners) {
304
304
  let others = await alot(safeAccount.owners)
@@ -408,7 +408,7 @@ const SafeAbi = {
408
408
  }
409
409
  ]
410
410
  },
411
- getTransactionHash: <TAbiItem> {
411
+ getTransactionHash: <TAbiItem>{
412
412
  "type": "function",
413
413
  "stateMutability": "view",
414
414
  "outputs": [
@@ -67,6 +67,8 @@ export interface ITimelockService {
67
67
  }
68
68
 
69
69
  export interface ITimelockTx {
70
+ timelock?: TEth.Address
71
+
70
72
  // operation hash, unique as includes random salt
71
73
  id: TEth.Hex
72
74
  // operation key, should be unique only within pending operations
@@ -86,10 +86,10 @@ export class TimelockService implements ITimelockService {
86
86
  let [ callSalt ] = callSaltArr;
87
87
 
88
88
  let [ callScheduleFirst ] = callScheduled;
89
- callScheduleFirst.params.delay
90
89
 
91
90
  let schedule = {
92
91
  sender: null,
92
+ timelock: callScheduleFirst.address,
93
93
  key: callSalt.params.id,
94
94
  id: callSalt.params.id,
95
95
  salt: callSalt.params.salt,
@@ -2,6 +2,7 @@ import { $abiParser } from 'dequanto/utils/$abiParser';
2
2
  import { $abiType } from 'dequanto/utils/$abiType';
3
3
  import { $abiUtils } from 'dequanto/utils/$abiUtils';
4
4
  import alot from 'alot';
5
+ import { type TAbiInput } from 'dequanto/types/TAbi';
5
6
 
6
7
  export namespace $types {
7
8
  export function isFixedArray (type: string) {
@@ -23,6 +24,11 @@ export namespace $types {
23
24
  }
24
25
 
25
26
 
27
+ /**
28
+ * Returns the type size in bits, excluding ABI padding.
29
+ * Sums element sizes for fixed arrays and tuple declarations.
30
+ * Returns Infinity for dynamic or unknown types.
31
+ */
26
32
  export function sizeOf(type: string) {
27
33
  if (type === 'address') {
28
34
  // 20bytes
@@ -58,4 +64,25 @@ export namespace $types {
58
64
  }
59
65
  return Infinity;
60
66
  }
67
+
68
+ /** Number of 32-byte ABI words; Infinity for dynamic or unknown types. */
69
+ export function wordSizeOf(type: string | TAbiInput): number {
70
+ let input = typeof type === 'string' ? { type } : type;
71
+ let name = input.type.trim();
72
+ if (isFixedArray(name)) {
73
+ let baseType = $abiType.array.getBaseType(name);
74
+ let words = wordSizeOf({ ...input, type: baseType });
75
+ return Number.isFinite(words) ? words * $abiType.array.getLength(name) : Infinity;
76
+ }
77
+ if (isDynamicArray(name)) {
78
+ return Infinity;
79
+ }
80
+ if (name === 'tuple') {
81
+ return input.components == null ? Infinity : alot(input.components).sum(x => wordSizeOf(x));
82
+ }
83
+ if (isStruct(name) || name === '()') {
84
+ return alot($abiParser.parseArguments(name)).sum(x => wordSizeOf(x));
85
+ }
86
+ return Math.ceil(sizeOf(name) / 256);
87
+ }
61
88
  }
@@ -673,10 +673,12 @@ export class TxWriter extends class_EventEmitter<ITxWriterEvents> implements ITx
673
673
  let account = await TxWriter.prepareAccount(accountMix);
674
674
  let txBuilder = new TxDataBuilder(client, account, data);
675
675
 
676
- await Promise.all([
677
- txBuilder.ensureGas(),
678
- txBuilder.ensureNonce(),
679
- ]);
676
+ if (await TxWriter.hasAgent(account) === false) {
677
+ await Promise.all([
678
+ txBuilder.ensureGas(),
679
+ txBuilder.ensureNonce(),
680
+ ]);
681
+ }
680
682
 
681
683
  let w = new TxWriter(client, txBuilder, account);
682
684
  w.send(options);
@@ -12,6 +12,7 @@ import { $date } from 'dequanto/utils/$date';
12
12
  import { $address } from 'dequanto/utils/$address';
13
13
  import { $logger } from 'dequanto/utils/$logger';
14
14
  import { SafeTx } from 'dequanto/safe/SafeTx';
15
+ import { ZodiacTx } from 'dequanto/zodiac/ZodiacTx';
15
16
  import { TimelockController } from 'dequanto/prebuilt/openzeppelin/TimelockController';
16
17
  import { TimelockService } from 'dequanto/services/TimelockService/TimelockService';
17
18
  import { TxDataBuilder } from '../TxDataBuilder';
@@ -86,7 +87,7 @@ export class BatchAgent implements ITxWriterAgent {
86
87
  /**
87
88
  * Executes the queued transactions.
88
89
  *
89
- * By default, duplicate transactions are skipped. If the account is Safe or Timelock,
90
+ * By default, duplicate transactions are skipped. If the account is Safe, Zodiac, or Timelock,
90
91
  * prepares the corresponding calldata and submits it as a batch transaction.
91
92
  *
92
93
  * @param options.includeDuplicates Include duplicate transactions in the execution batch.
@@ -100,10 +101,10 @@ export class BatchAgent implements ITxWriterAgent {
100
101
  if (options?.includeDuplicates !== true) {
101
102
  txs = alot(txs).distinctBy(x => {
102
103
  const data = x.outerWriter.builder.data;
103
- const acc = x.account ?? x.sender;
104
- // remove duplicates by [from,to,data]
104
+ // Remove duplicates by account, value, target, and calldata.
105
105
  return [
106
- acc.address.toLowerCase(),
106
+ this.getAccountKey(x),
107
+ String(data.value ?? 0),
107
108
  data.to?.toLowerCase() ?? '',
108
109
  data.data ?? ''
109
110
  ].join('');
@@ -117,10 +118,10 @@ export class BatchAgent implements ITxWriterAgent {
117
118
  ? txs[i + 1]
118
119
  : null;
119
120
 
120
- let acc0 = tx.account?.address ?? tx.sender?.address;
121
- let acc1 = next?.account?.address ?? next?.sender?.address;
121
+ let acc0 = this.getAccountKey(tx);
122
+ let acc1 = next == null ? null : this.getAccountKey(next);
122
123
 
123
- if (next == null || $address.eq(acc0, acc1) === false) {
124
+ if (next == null || acc0 !== acc1) {
124
125
  let arr = await this.executeGroup(txs.slice(groupStart, i + 1));
125
126
  writers.push(...arr);
126
127
  groupStart = i + 1;
@@ -175,9 +176,34 @@ export class BatchAgent implements ITxWriterAgent {
175
176
  return lines.join('\n');
176
177
  }
177
178
 
179
+ private getAccountKey (tx: MockTxWriter): string {
180
+ let account = tx.account ?? tx.sender;
181
+ let address = (account.address ?? tx.sender?.address)?.toLowerCase();
182
+ if ($account.isZodiac(account)) {
183
+ let roleKey = account.roleKey?.toLowerCase() ?? '';
184
+ return `${address}-${roleKey}`;
185
+ }
186
+ return address;
187
+ }
188
+
178
189
  private async executeGroup (txs: MockTxWriter[]) {
179
190
  let { account, sender } = txs[0];
180
191
  let acc = account ?? sender;
192
+ if ($account.isZodiac(acc)) {
193
+ let first = txs[0].outerWriter;
194
+ let { client, builder, options } = first;
195
+ let zodiac = new ZodiacTx({
196
+ ...acc,
197
+ operator: sender ?? acc.operator
198
+ }, client, {
199
+ builder: builder.config,
200
+ writer: options,
201
+ });
202
+ let calls = txs.map(x => x.outerWriter.builder.getTxData());
203
+ let writer = await zodiac.executeBatch(...calls);
204
+ await writer.wait();
205
+ return [writer];
206
+ }
181
207
  if ($account.isSafe(acc)) {
182
208
  let tx = await this.executeBatchSafe(acc, txs);
183
209
  return [ tx ];
@@ -3,6 +3,7 @@ import type { ITxWriterEmitter, TxWriter } from '../TxWriter';
3
3
  import { SafeAgent } from './SafeAgent';
4
4
  import { Erc4337Agent } from './Erc4337Agent';
5
5
  import { TimelockAgent } from './TimelockAgent';
6
+ import { ZodiacAgent } from './ZodiacAgent';
6
7
 
7
8
 
8
9
  export interface ITxWriterAgent {
@@ -17,6 +18,7 @@ export namespace TxWriterAccountAgents {
17
18
 
18
19
  const agents: ITxWriterAccountAgent[] = [
19
20
  new SafeAgent(),
21
+ new ZodiacAgent(),
20
22
  new Erc4337Agent(),
21
23
  new TimelockAgent(),
22
24
  ];
@@ -0,0 +1,19 @@
1
+ import { EoAccount, TAccount, ZodiacAccount } from 'dequanto/models/TAccount';
2
+ import { $account } from 'dequanto/utils/$account';
3
+ import { ZodiacTx } from 'dequanto/zodiac/ZodiacTx';
4
+ import { TxWriter } from '../TxWriter';
5
+ import { ITxWriterAccountAgent } from './TxWriterAccountAgents';
6
+
7
+ export class ZodiacAgent implements ITxWriterAccountAgent {
8
+ supports (account: TAccount) {
9
+ return $account.isZodiac(account);
10
+ }
11
+
12
+ async process (sender: EoAccount, account: ZodiacAccount, outerWriter: TxWriter) {
13
+ let zodiac = new ZodiacTx({ ...account, operator: sender }, outerWriter.client, {
14
+ builder: outerWriter.builder.config,
15
+ writer: outerWriter.options,
16
+ });
17
+ return zodiac.execute(outerWriter.builder.getTxData());
18
+ }
19
+ }
@@ -1,4 +1,4 @@
1
- import { EoAccount, Erc4337Account, SafeAccount, TAccount, TimelockAccount } from "dequanto/models/TAccount";
1
+ import { EoAccount, Erc4337Account, SafeAccount, TAccount, TimelockAccount, ZodiacAccount } from "dequanto/models/TAccount";
2
2
  import { $address } from './$address';
3
3
  import { $require } from './$require';
4
4
  import { $sig } from './$sig';
@@ -13,7 +13,7 @@ export namespace $account {
13
13
  return { name: account };
14
14
  }
15
15
 
16
- let acc = isSafe(account) || isErc4337 (account) || isTimelock(account)
16
+ let acc = isSafe(account) || isErc4337 (account) || isTimelock(account) || isZodiac(account)
17
17
  ? account.operator
18
18
  : account;
19
19
 
@@ -21,6 +21,10 @@ export namespace $account {
21
21
  return acc as EoAccount;
22
22
  }
23
23
 
24
+ export function isZodiac (account: TAccount): account is ZodiacAccount {
25
+ return account != null && typeof account === 'object' && account.type === 'zodiac';
26
+ }
27
+
24
28
  export function isSafe (account:TAccount): account is SafeAccount {
25
29
  if (account == null) {
26
30
  return false;
@@ -0,0 +1,99 @@
1
+ import { Web3Client } from 'dequanto/clients/Web3Client';
2
+ import { ZodiacAccount } from 'dequanto/models/TAccount';
3
+ import { TEth } from 'dequanto/models/TEth';
4
+ import { config } from 'dequanto/config/Config';
5
+ import { ITxBuilderOptions } from 'dequanto/txs/ITxBuilderOptions';
6
+ import { TxDataBuilder } from 'dequanto/txs/TxDataBuilder';
7
+ import { ITxWriterOptions, TxWriter } from 'dequanto/txs/TxWriter';
8
+ import { $abi } from 'dequanto/abi/$abi';
9
+ import { $abiUtils } from 'dequanto/utils/$abiUtils';
10
+ import { $hex } from 'dequanto/utils/$hex';
11
+ import { $require } from 'dequanto/utils/$require';
12
+
13
+ type TCall = Pick<TEth.TxLike, 'to' | 'data' | 'value'>;
14
+
15
+ /** Roles v2 execution. Inner values are paid by the avatar, not the operator. */
16
+ export class ZodiacTx {
17
+ constructor (
18
+ public account: ZodiacAccount,
19
+ public client: Web3Client,
20
+ public options?: {
21
+ contracts?: typeof config.safe.contracts
22
+ builder?: ITxBuilderOptions
23
+ writer?: ITxWriterOptions
24
+ }
25
+ ) {}
26
+
27
+ /** Encode a transaction to the Roles Modifier without submitting it. */
28
+ getTxData (call: TCall, operation: 0 | 1 = 0): TEth.TxLike {
29
+ $require.Address(this.account.address, 'Zodiac Roles Modifier address');
30
+ $require.Hex(this.account.roleKey, 'Zodiac roleKey must be hex');
31
+ $require.Address(call.to, 'Zodiac transaction target');
32
+ return {
33
+ to: this.account.address,
34
+ value: 0n,
35
+ data: $abi.encodeCall('execTransactionWithRole(address to,uint256 value,bytes data,uint8 operation,bytes32 roleKey,bool shouldRevert)', [
36
+ call.to,
37
+ call.value ?? 0n,
38
+ call.data ?? '0x',
39
+ operation,
40
+ $hex.padBytes(this.account.roleKey ?? '0x0', 32),
41
+ true
42
+ ])
43
+ };
44
+ }
45
+
46
+ /** The Roles Modifier must have an unwrapper registered for this MultiSend deployment. */
47
+ getBatchTxData (...calls: TCall[]): TEth.TxLike {
48
+ $require.gt(calls.length, 0, 'Zodiac batch must not be empty');
49
+ let getAddress = (key: 'MultiSend' | 'MultiSendCallOnly') => {
50
+ return this.options?.contracts?.[this.client.network]?.[key]
51
+ ?? config.safe?.contracts?.[this.client.network]?.[key];
52
+ };
53
+ let multiSendAddress = getAddress('MultiSendCallOnly') ?? getAddress('MultiSend');
54
+ $require.Address(multiSendAddress, 'Zodiac MultiSend contract');
55
+ let transactions = calls.map(call => {
56
+ $require.Address(call.to, 'Zodiac batch transaction target');
57
+ let data = call.data ?? '0x';
58
+ return $abiUtils.encodePacked(
59
+ ['uint8', 0],
60
+ ['address', call.to],
61
+ ['uint256', call.value ?? 0n],
62
+ ['uint256', $hex.getBytesLength(data)],
63
+ ['bytes', data]
64
+ );
65
+ });
66
+ return this.getTxData({
67
+ to: multiSendAddress,
68
+ value: 0n,
69
+ data: $abi.encodeCall('multiSend(bytes transactions)', [$hex.concat(transactions)])
70
+ }, 1);
71
+ }
72
+
73
+ async execute (call: TCall) {
74
+ return this.send(this.getTxData(call));
75
+ }
76
+
77
+ async executeBatch (...calls: TCall[]) {
78
+ return this.send(this.getBatchTxData(...calls));
79
+ }
80
+
81
+ private async send (data: TEth.TxLike) {
82
+ $require.notNull(this.account.operator, 'Zodiac operator is required');
83
+ let sender = await TxWriter.prepareAccount(this.account.operator);
84
+ let builder = new TxDataBuilder(this.client, sender, data, this.options?.builder);
85
+ let config = this.options?.builder;
86
+ await builder.setGas({
87
+ price: config?.gasPrice,
88
+ priceRatio: config?.gasPriceRatio,
89
+ gasLimit: config?.gasLimit,
90
+ gasLimitRatio: config?.gasLimitRatio,
91
+ gasEstimation: config?.gasEstimation,
92
+ from: config?.from ?? sender.address,
93
+ type: config?.type,
94
+ });
95
+ return TxWriter
96
+ .create(this.client, builder, sender)
97
+ .send(this.options?.writer);
98
+ }
99
+ }
@@ -1,5 +1,2 @@
1
1
  /// <reference path="globals/assertion/index.d.ts" />
2
- /// <reference path="globals/atma-utest/index.d.ts" />
3
- /// <reference path="globals/mask/index.d.ts" />
4
- /// <reference path="globals/axios/index.d.ts" />
5
-
2
+ /// <reference path="globals/mocha/index.d.ts" />
@@ -1,53 +0,0 @@
1
- // Generated by typings
2
- // Source: https://raw.githubusercontent.com/atmajs/utest/master/types/index.d.ts
3
- declare module "atma-utest-global" {
4
- export = UTest;
5
- }
6
-
7
- declare var UTest: IUtest;
8
-
9
- declare interface IUtest {
10
- (definition: IUTestDefinition): void
11
-
12
- domtest: IDomTest
13
- request (url, method, headers, data, callback)
14
- server: {
15
- render (template: string, ...args)
16
- }
17
-
18
- benchmark (model: IUTestDefinition)
19
- benchmarkVersions (model: IUTestDefinition)
20
-
21
- }
22
-
23
- interface IDomTest {
24
- (subject: HTMLElement | JQuery | any, testMarkup: string | any): PromiseLike<any>
25
- use (astName: string): IDomTest
26
- process (subject: HTMLElement | JQuery | any, testMarkup: string | any): PromiseLike<any>
27
- }
28
-
29
- interface IUTestDefinition {
30
- $config?: {
31
- timeout?: number
32
- errorableCallbacks?: boolean
33
- breakOnError?: boolean
34
-
35
- 'http.config'?: any
36
- 'http.eval'?: string
37
- 'http.include'?: any
38
- 'http.service'?: any
39
- 'http.process'?: any
40
- 'util.process'?: any
41
- }
42
- $before?: (done?: Function) => void | PromiseLike<any>
43
- $after?: (done?: Function) => void | PromiseLike<any>
44
- $teardown?: (done?: Function) => void | PromiseLike<any>
45
-
46
-
47
-
48
- [key: string]: ITestCase | IUTestDefinition | any
49
- }
50
-
51
- interface ITestCase {
52
- (done?: Function, ...args: any[]): void | PromiseLike<any> | any
53
- }
@@ -1,10 +0,0 @@
1
- {
2
- "resolution": "main",
3
- "tree": {
4
- "src": "https://raw.githubusercontent.com/atmajs/utest/master/typings.json",
5
- "raw": "github:atmajs/utest",
6
- "main": "types/index.d.ts",
7
- "global": true,
8
- "name": "atma-utest-global"
9
- }
10
- }
@@ -1,6 +0,0 @@
1
- ///<reference path="../../../node_modules/axios/index.d.ts"/>
2
- import { AxiosInstance } from 'axios';
3
-
4
- declare global {
5
- const axios: AxiosInstance
6
- }
@@ -1,6 +0,0 @@
1
- ///<reference path="../../../node_modules/maskjs/lib/mask.d.ts"/>
2
- import { Mask } from 'mask';
3
-
4
- declare global {
5
- const mask: typeof Mask
6
- }
@@ -1,9 +0,0 @@
1
- {
2
- "resolution": "main",
3
- "tree": {
4
- "src": "https://raw.githubusercontent.com/atmajs/maskjs/master/typings.json",
5
- "raw": "github:atmajs/maskjs/typings.json",
6
- "main": "types/index.d.ts",
7
- "name": "mask"
8
- }
9
- }