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.
- package/lib/cjs/abi/$abi.js +39 -1
- package/lib/cjs/abi/$abi.js.map +1 -1
- package/lib/cjs/contracts/ContractReader.js +2 -2
- package/lib/cjs/contracts/ContractReader.js.map +1 -1
- package/lib/cjs/safe/GnosisSafeHandler.js.map +1 -1
- package/lib/cjs/services/TimelockService/ITimelockService.js.map +1 -1
- package/lib/cjs/services/TimelockService/TimelockService.js +1 -1
- package/lib/cjs/services/TimelockService/TimelockService.js.map +1 -1
- package/lib/cjs/solidity/utils/$types.js +26 -0
- package/lib/cjs/solidity/utils/$types.js.map +1 -1
- package/lib/cjs/txs/TxWriter.js +6 -4
- package/lib/cjs/txs/TxWriter.js.map +1 -1
- package/lib/cjs/txs/agents/BatchAgent.js +32 -7
- package/lib/cjs/txs/agents/BatchAgent.js.map +1 -1
- package/lib/cjs/txs/agents/TxWriterAccountAgents.js +2 -0
- package/lib/cjs/txs/agents/TxWriterAccountAgents.js.map +1 -1
- package/lib/cjs/txs/agents/ZodiacAgent.js +20 -0
- package/lib/cjs/txs/agents/ZodiacAgent.js.map +1 -0
- package/lib/cjs/utils/$account.js +5 -1
- package/lib/cjs/utils/$account.js.map +1 -1
- package/lib/cjs/zodiac/ZodiacTx.js +83 -0
- package/lib/cjs/zodiac/ZodiacTx.js.map +1 -0
- package/lib/esm/abi/$abi.js.map +1 -1
- package/lib/esm/abi/$abi.mjs +36 -1
- package/lib/esm/contracts/ContractReader.js.map +1 -1
- package/lib/esm/contracts/ContractReader.mjs +2 -2
- package/lib/esm/safe/GnosisSafeHandler.js.map +1 -1
- package/lib/esm/services/TimelockService/ITimelockService.js.map +1 -1
- package/lib/esm/services/TimelockService/TimelockService.js.map +1 -1
- package/lib/esm/services/TimelockService/TimelockService.mjs +1 -1
- package/lib/esm/solidity/utils/$types.js.map +1 -1
- package/lib/esm/solidity/utils/$types.mjs +26 -0
- package/lib/esm/txs/TxWriter.js.map +1 -1
- package/lib/esm/txs/TxWriter.mjs +6 -4
- package/lib/esm/txs/agents/BatchAgent.js.map +1 -1
- package/lib/esm/txs/agents/BatchAgent.mjs +32 -7
- package/lib/esm/txs/agents/TxWriterAccountAgents.js.map +1 -1
- package/lib/esm/txs/agents/TxWriterAccountAgents.mjs +2 -0
- package/lib/esm/txs/agents/ZodiacAgent.js.map +1 -0
- package/lib/esm/txs/agents/ZodiacAgent.mjs +16 -0
- package/lib/esm/utils/$account.js.map +1 -1
- package/lib/esm/utils/$account.mjs +5 -1
- package/lib/esm/zodiac/ZodiacTx.js.map +1 -0
- package/lib/esm/zodiac/ZodiacTx.mjs +79 -0
- package/lib/types/contracts/ContractReader.d.ts +1 -1
- package/lib/types/models/TAccount.d.ts +11 -2
- package/lib/types/models/TEth.d.ts +4 -1
- package/lib/types/services/TimelockService/ITimelockService.d.ts +1 -0
- package/lib/types/solidity/utils/$types.d.ts +8 -0
- package/lib/types/txs/agents/BatchAgent.d.ts +2 -1
- package/lib/types/txs/agents/ZodiacAgent.d.ts +7 -0
- package/lib/types/utils/$account.d.ts +2 -1
- package/lib/types/zodiac/ZodiacTx.d.ts +30 -0
- package/package.json +1 -1
- package/skills/dequanto/INDEX.md +1 -1
- package/skills/dequanto/SKILL.md +4 -3
- package/skills/dequanto/examples/browser-wallet.spec.ts +2 -1
- package/skills/dequanto/examples/config.spec.ts +2 -1
- package/skills/dequanto/examples/contract-read.spec.ts +2 -1
- package/skills/dequanto/examples/contract-write.spec.ts +2 -1
- package/skills/dequanto/examples/deploy-contract.spec.ts +2 -1
- package/skills/dequanto/examples/erc4337-userop.spec.ts +2 -1
- package/skills/dequanto/examples/explorer-abi.spec.ts +2 -1
- package/skills/dequanto/examples/generate-contract-class.spec.ts +2 -1
- package/skills/dequanto/examples/hardhat-debug.spec.ts +2 -1
- package/skills/dequanto/examples/hardhat-fork.spec.ts +2 -1
- package/skills/dequanto/examples/index-events.spec.ts +2 -1
- package/skills/dequanto/examples/live-events.spec.ts +2 -1
- package/skills/dequanto/examples/revert-error.spec.ts +2 -1
- package/skills/dequanto/examples/rpc-read.spec.ts +19 -5
- package/skills/dequanto/examples/safe-batch.spec.ts +92 -3
- package/skills/dequanto/examples/send-transaction.spec.ts +2 -1
- package/skills/dequanto/examples/storage.spec.ts +2 -1
- package/skills/dequanto/examples/token-transfer.spec.ts +2 -1
- package/skills/dequanto/examples/utils.spec.ts +2 -1
- package/skills/dequanto/references/safe-erc4337.md +50 -3
- package/skills/dequanto/references/tokens-accounts.md +1 -0
- package/skills/dequanto/references/transactions.md +2 -1
- package/src/abi/$abi.ts +36 -0
- package/src/contracts/ContractReader.ts +2 -2
- package/src/models/TAccount.ts +17 -2
- package/src/models/TEth.ts +4 -1
- package/src/safe/GnosisSafeHandler.ts +12 -12
- package/src/services/TimelockService/ITimelockService.ts +2 -0
- package/src/services/TimelockService/TimelockService.ts +1 -1
- package/src/solidity/utils/$types.ts +27 -0
- package/src/txs/TxWriter.ts +6 -4
- package/src/txs/agents/BatchAgent.ts +33 -7
- package/src/txs/agents/TxWriterAccountAgents.ts +2 -0
- package/src/txs/agents/ZodiacAgent.ts +19 -0
- package/src/utils/$account.ts +6 -2
- package/src/zodiac/ZodiacTx.ts +99 -0
- package/typings/index.d.ts +1 -4
- package/typings/globals/atma-utest/index.d.ts +0 -53
- package/typings/globals/atma-utest/typings.json +0 -10
- package/typings/globals/axios/index.d.ts +0 -6
- package/typings/globals/mask/index.d.ts +0 -6
- 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
|
-
|
|
104
|
-
// remove duplicates by [from,to,data]
|
|
104
|
+
// Remove duplicates by account, value, target, and calldata.
|
|
105
105
|
return [
|
|
106
|
-
|
|
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 =
|
|
121
|
-
let acc1 = next
|
|
121
|
+
let acc0 = this.getAccountKey(tx);
|
|
122
|
+
let acc1 = next == null ? null : this.getAccountKey(next);
|
|
122
123
|
|
|
123
|
-
if (next == null ||
|
|
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
|
+
}
|
package/src/utils/$account.ts
CHANGED
|
@@ -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
|
+
}
|
package/typings/index.d.ts
CHANGED
|
@@ -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
|
-
}
|