dequanto 0.2.55 → 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 (98) 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/safe/GnosisSafeHandler.js.map +1 -1
  6. package/lib/cjs/services/TimelockService/ITimelockService.js.map +1 -1
  7. package/lib/cjs/services/TimelockService/TimelockService.js +1 -1
  8. package/lib/cjs/services/TimelockService/TimelockService.js.map +1 -1
  9. package/lib/cjs/solidity/utils/$types.js +26 -0
  10. package/lib/cjs/solidity/utils/$types.js.map +1 -1
  11. package/lib/cjs/txs/TxWriter.js +6 -4
  12. package/lib/cjs/txs/TxWriter.js.map +1 -1
  13. package/lib/cjs/txs/agents/BatchAgent.js +32 -7
  14. package/lib/cjs/txs/agents/BatchAgent.js.map +1 -1
  15. package/lib/cjs/txs/agents/TxWriterAccountAgents.js +2 -0
  16. package/lib/cjs/txs/agents/TxWriterAccountAgents.js.map +1 -1
  17. package/lib/cjs/txs/agents/ZodiacAgent.js +20 -0
  18. package/lib/cjs/txs/agents/ZodiacAgent.js.map +1 -0
  19. package/lib/cjs/utils/$account.js +5 -1
  20. package/lib/cjs/utils/$account.js.map +1 -1
  21. package/lib/cjs/zodiac/ZodiacTx.js +83 -0
  22. package/lib/cjs/zodiac/ZodiacTx.js.map +1 -0
  23. package/lib/esm/abi/$abi.js.map +1 -1
  24. package/lib/esm/abi/$abi.mjs +36 -1
  25. package/lib/esm/contracts/ContractReader.js.map +1 -1
  26. package/lib/esm/contracts/ContractReader.mjs +2 -2
  27. package/lib/esm/safe/GnosisSafeHandler.js.map +1 -1
  28. package/lib/esm/services/TimelockService/ITimelockService.js.map +1 -1
  29. package/lib/esm/services/TimelockService/TimelockService.js.map +1 -1
  30. package/lib/esm/services/TimelockService/TimelockService.mjs +1 -1
  31. package/lib/esm/solidity/utils/$types.js.map +1 -1
  32. package/lib/esm/solidity/utils/$types.mjs +26 -0
  33. package/lib/esm/txs/TxWriter.js.map +1 -1
  34. package/lib/esm/txs/TxWriter.mjs +6 -4
  35. package/lib/esm/txs/agents/BatchAgent.js.map +1 -1
  36. package/lib/esm/txs/agents/BatchAgent.mjs +32 -7
  37. package/lib/esm/txs/agents/TxWriterAccountAgents.js.map +1 -1
  38. package/lib/esm/txs/agents/TxWriterAccountAgents.mjs +2 -0
  39. package/lib/esm/txs/agents/ZodiacAgent.js.map +1 -0
  40. package/lib/esm/txs/agents/ZodiacAgent.mjs +16 -0
  41. package/lib/esm/utils/$account.js.map +1 -1
  42. package/lib/esm/utils/$account.mjs +5 -1
  43. package/lib/esm/zodiac/ZodiacTx.js.map +1 -0
  44. package/lib/esm/zodiac/ZodiacTx.mjs +79 -0
  45. package/lib/types/contracts/ContractReader.d.ts +1 -1
  46. package/lib/types/models/TAccount.d.ts +11 -2
  47. package/lib/types/models/TEth.d.ts +4 -1
  48. package/lib/types/services/TimelockService/ITimelockService.d.ts +1 -0
  49. package/lib/types/solidity/utils/$types.d.ts +8 -0
  50. package/lib/types/txs/agents/BatchAgent.d.ts +2 -1
  51. package/lib/types/txs/agents/ZodiacAgent.d.ts +7 -0
  52. package/lib/types/utils/$account.d.ts +2 -1
  53. package/lib/types/zodiac/ZodiacTx.d.ts +30 -0
  54. package/package.json +1 -1
  55. package/skills/dequanto/INDEX.md +1 -1
  56. package/skills/dequanto/SKILL.md +4 -3
  57. package/skills/dequanto/examples/browser-wallet.spec.ts +2 -1
  58. package/skills/dequanto/examples/config.spec.ts +2 -1
  59. package/skills/dequanto/examples/contract-read.spec.ts +2 -1
  60. package/skills/dequanto/examples/contract-write.spec.ts +2 -1
  61. package/skills/dequanto/examples/deploy-contract.spec.ts +2 -1
  62. package/skills/dequanto/examples/erc4337-userop.spec.ts +2 -1
  63. package/skills/dequanto/examples/explorer-abi.spec.ts +2 -1
  64. package/skills/dequanto/examples/generate-contract-class.spec.ts +2 -1
  65. package/skills/dequanto/examples/hardhat-debug.spec.ts +2 -1
  66. package/skills/dequanto/examples/hardhat-fork.spec.ts +2 -1
  67. package/skills/dequanto/examples/index-events.spec.ts +2 -1
  68. package/skills/dequanto/examples/live-events.spec.ts +2 -1
  69. package/skills/dequanto/examples/revert-error.spec.ts +2 -1
  70. package/skills/dequanto/examples/rpc-read.spec.ts +19 -5
  71. package/skills/dequanto/examples/safe-batch.spec.ts +92 -3
  72. package/skills/dequanto/examples/send-transaction.spec.ts +2 -1
  73. package/skills/dequanto/examples/storage.spec.ts +2 -1
  74. package/skills/dequanto/examples/token-transfer.spec.ts +2 -1
  75. package/skills/dequanto/examples/utils.spec.ts +2 -1
  76. package/skills/dequanto/references/safe-erc4337.md +50 -3
  77. package/skills/dequanto/references/tokens-accounts.md +1 -0
  78. package/skills/dequanto/references/transactions.md +2 -1
  79. package/src/abi/$abi.ts +36 -0
  80. package/src/contracts/ContractReader.ts +2 -2
  81. package/src/models/TAccount.ts +17 -2
  82. package/src/models/TEth.ts +4 -1
  83. package/src/safe/GnosisSafeHandler.ts +12 -12
  84. package/src/services/TimelockService/ITimelockService.ts +2 -0
  85. package/src/services/TimelockService/TimelockService.ts +1 -1
  86. package/src/solidity/utils/$types.ts +27 -0
  87. package/src/txs/TxWriter.ts +6 -4
  88. package/src/txs/agents/BatchAgent.ts +33 -7
  89. package/src/txs/agents/TxWriterAccountAgents.ts +2 -0
  90. package/src/txs/agents/ZodiacAgent.ts +19 -0
  91. package/src/utils/$account.ts +6 -2
  92. package/src/zodiac/ZodiacTx.ts +99 -0
  93. package/typings/index.d.ts +1 -4
  94. package/typings/globals/atma-utest/index.d.ts +0 -53
  95. package/typings/globals/atma-utest/typings.json +0 -10
  96. package/typings/globals/axios/index.d.ts +0 -6
  97. package/typings/globals/mask/index.d.ts +0 -6
  98. package/typings/globals/mask/typings.json +0 -9
@@ -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
- }