dequanto 0.1.81 → 0.1.85
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/blocks/BlockDateResolver.js +59 -23
- package/lib/cjs/blocks/BlockDateResolver.js.map +1 -1
- package/lib/cjs/contracts/deploy/proxy/$proxyDeploy.js +5 -1
- package/lib/cjs/contracts/deploy/proxy/$proxyDeploy.js.map +1 -1
- package/lib/cjs/erc4337/Erc4337Factory.js +0 -1
- package/lib/cjs/erc4337/Erc4337Factory.js.map +1 -1
- package/lib/cjs/prebuilt-factories/TimelockControllerFactory.js +251 -0
- package/lib/cjs/prebuilt-factories/TimelockControllerFactory.js.map +1 -0
- package/lib/cjs/services/TimelockService/TimelockService.js +24 -4
- package/lib/cjs/services/TimelockService/TimelockService.js.map +1 -1
- package/lib/cjs/txs/TxWriter.js +1 -1
- package/lib/cjs/txs/TxWriter.js.map +1 -1
- package/lib/cjs/txs/agents/TimelockAgent.js +90 -0
- package/lib/cjs/txs/agents/TimelockAgent.js.map +1 -0
- package/lib/cjs/txs/agents/TxWriterAccountAgents.js +2 -0
- package/lib/cjs/txs/agents/TxWriterAccountAgents.js.map +1 -1
- package/lib/cjs/utils/$account.js +17 -1
- package/lib/cjs/utils/$account.js.map +1 -1
- package/lib/cjs/utils/$date.js +11 -0
- package/lib/cjs/utils/$date.js.map +1 -1
- package/lib/esm/blocks/BlockDateResolver.js.map +1 -1
- package/lib/esm/blocks/BlockDateResolver.mjs +59 -23
- package/lib/esm/contracts/deploy/proxy/$proxyDeploy.js.map +1 -1
- package/lib/esm/contracts/deploy/proxy/$proxyDeploy.mjs +5 -1
- package/lib/esm/erc4337/Erc4337Factory.js.map +1 -1
- package/lib/esm/erc4337/Erc4337Factory.mjs +0 -1
- package/lib/esm/prebuilt-factories/TimelockControllerFactory.js.map +1 -0
- package/lib/esm/prebuilt-factories/TimelockControllerFactory.mjs +244 -0
- package/lib/esm/services/TimelockService/TimelockService.js.map +1 -1
- package/lib/esm/services/TimelockService/TimelockService.mjs +24 -4
- package/lib/esm/txs/TxWriter.js.map +1 -1
- package/lib/esm/txs/TxWriter.mjs +1 -1
- package/lib/esm/txs/agents/TimelockAgent.js.map +1 -0
- package/lib/esm/txs/agents/TimelockAgent.mjs +85 -0
- package/lib/esm/txs/agents/TxWriterAccountAgents.js.map +1 -1
- package/lib/esm/txs/agents/TxWriterAccountAgents.mjs +2 -0
- package/lib/esm/utils/$account.js.map +1 -1
- package/lib/esm/utils/$account.mjs +17 -1
- package/lib/esm/utils/$date.js.map +1 -1
- package/lib/esm/utils/$date.mjs +11 -0
- package/lib/types/blocks/BlockDateResolver.d.ts +7 -5
- package/lib/types/models/TAccount.d.ts +7 -1
- package/lib/types/prebuilt-factories/TimelockControllerFactory.d.ts +188 -0
- package/lib/types/services/TimelockService/TimelockService.d.ts +14 -3
- package/lib/types/txs/TxWriter.d.ts +20 -13
- package/lib/types/txs/agents/TimelockAgent.d.ts +26 -0
- package/lib/types/txs/agents/TxWriterAccountAgents.d.ts +2 -2
- package/lib/types/utils/$account.d.ts +2 -1
- package/lib/types/utils/$date.d.ts +1 -0
- package/package.json +1 -1
- package/src/blocks/BlockDateResolver.ts +61 -28
- package/src/contracts/deploy/proxy/$proxyDeploy.ts +5 -1
- package/src/erc4337/Erc4337Factory.ts +0 -2
- package/src/models/TAccount.ts +11 -1
- package/src/prebuilt-factories/TimelockControllerFactory.ts +582 -0
- package/src/services/TimelockService/TimelockService.ts +48 -8
- package/src/txs/TxWriter.ts +29 -17
- package/src/txs/agents/TimelockAgent.ts +116 -0
- package/src/txs/agents/TxWriterAccountAgents.ts +4 -2
- package/src/utils/$account.ts +18 -2
- package/src/utils/$date.ts +11 -1
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import memd from 'memd';
|
|
2
|
-
import { TimelockController } from '@dequanto/prebuilt/openzeppelin/TimelockController';
|
|
3
|
-
import { ContractBase } from '@dequanto/contracts/ContractBase';
|
|
4
2
|
import { JsonArrayStore } from '@dequanto/json/JsonArrayStore';
|
|
5
3
|
import { IAccount } from '@dequanto/models/TAccount';
|
|
6
4
|
import { TAddress } from '@dequanto/models/TAddress';
|
|
@@ -19,10 +17,25 @@ import { File } from 'atma-io';
|
|
|
19
17
|
import { ITimelockTx, ITimelockTxParamsNormalized, ITimelockTxParams, ITimelockService, ETimelockTxStatus } from './ITimelockService';
|
|
20
18
|
import { TTxWriteMethodKeys } from '@dequanto/utils/types';
|
|
21
19
|
|
|
20
|
+
import type { TimelockController } from '@dequanto/prebuilt/openzeppelin/TimelockController';
|
|
21
|
+
import type { ContractBase } from '@dequanto/contracts/ContractBase';
|
|
22
|
+
|
|
23
|
+
import { TxDataBuilder } from '@dequanto/txs/TxDataBuilder';
|
|
24
|
+
|
|
25
|
+
const CONFIG = {
|
|
26
|
+
dir: `0x/data`
|
|
27
|
+
};
|
|
22
28
|
|
|
23
29
|
|
|
24
30
|
type TTimelockController = ContractBase & Pick<TimelockController,
|
|
25
|
-
'schedule'
|
|
31
|
+
'schedule'
|
|
32
|
+
| 'scheduleBatch'
|
|
33
|
+
| 'execute'
|
|
34
|
+
| 'executeBatch'
|
|
35
|
+
| 'getMinDelay'
|
|
36
|
+
| 'cancel'
|
|
37
|
+
| 'extractLogsCallScheduled'
|
|
38
|
+
| 'extractLogsCallSalt'
|
|
26
39
|
>;
|
|
27
40
|
|
|
28
41
|
export class TimelockService implements ITimelockService {
|
|
@@ -37,7 +50,7 @@ export class TimelockService implements ITimelockService {
|
|
|
37
50
|
// Only for hardhat client. Default: false
|
|
38
51
|
execute?: boolean
|
|
39
52
|
|
|
40
|
-
// Directory to store the submitted schedules, default: `./0x/data
|
|
53
|
+
// Directory to store the submitted schedules, default: `./0x/data/`, or use `TimelockService.config` to override it globally
|
|
41
54
|
dir?: string
|
|
42
55
|
}
|
|
43
56
|
) {
|
|
@@ -64,7 +77,7 @@ export class TimelockService implements ITimelockService {
|
|
|
64
77
|
let receipt = await this.timelock.client.getTransactionReceipt(txHash);
|
|
65
78
|
$require.notNull(receipt, `Tx ${txHash} not found`);
|
|
66
79
|
let block = await this.timelock.client.getBlock(receipt.blockNumber);
|
|
67
|
-
let contract =
|
|
80
|
+
let contract = this.timelock;
|
|
68
81
|
let callScheduled = contract.extractLogsCallScheduled(receipt);
|
|
69
82
|
$require.gte(callScheduled.length, 1, `Expected at least 1 CallScheduled log`);
|
|
70
83
|
|
|
@@ -139,11 +152,32 @@ export class TimelockService implements ITimelockService {
|
|
|
139
152
|
schedule: ITimelockTx
|
|
140
153
|
tx?: TEth.Hex
|
|
141
154
|
}> {
|
|
142
|
-
|
|
143
155
|
let txParams = await this.getTxParamsNormalizedFromContract(uniqueTaskName, sender, contract, method, ...params);
|
|
144
156
|
return await this.processTxParams(txParams);
|
|
145
157
|
}
|
|
146
158
|
|
|
159
|
+
async processData (
|
|
160
|
+
sender: IAccount,
|
|
161
|
+
builder: TxDataBuilder
|
|
162
|
+
): Promise<{
|
|
163
|
+
prevStatus: ETimelockTxStatus
|
|
164
|
+
status: ETimelockTxStatus
|
|
165
|
+
schedule: ITimelockTx
|
|
166
|
+
tx?: TEth.Hex
|
|
167
|
+
}> {
|
|
168
|
+
let { to, data, value } = builder.data;
|
|
169
|
+
let titleKey = `${to}${data}`;
|
|
170
|
+
let params = <ITimelockTxParams> {
|
|
171
|
+
title: $contract.keccak256(titleKey, 'hex'),
|
|
172
|
+
sender: sender,
|
|
173
|
+
to: to,
|
|
174
|
+
data: data,
|
|
175
|
+
value: value
|
|
176
|
+
};
|
|
177
|
+
let txParams = await this.getTxParamsNormalized (params);
|
|
178
|
+
return await this.processTxParams(txParams);
|
|
179
|
+
}
|
|
180
|
+
|
|
147
181
|
/** Schedules-Wait-Execute a task distinguished by the unique task name
|
|
148
182
|
*
|
|
149
183
|
* 1. if schedule doesn't exist, create it
|
|
@@ -521,7 +555,7 @@ export class TimelockService implements ITimelockService {
|
|
|
521
555
|
private async getUniqueByKey (key: TEth.Hex): Promise<ITimelockTx> {
|
|
522
556
|
let store = await this.getStore();
|
|
523
557
|
let all = await store.getAll();
|
|
524
|
-
let arr = all.filter(x => x.key === key);
|
|
558
|
+
let arr = all.filter(x => x.key === key && x.status === 'pending');
|
|
525
559
|
$require.lt(arr.length, 2, `Timelock service expects ${key} to be unique. Found ${arr.length}`);
|
|
526
560
|
return arr.length === 1 ? arr[0] : null;
|
|
527
561
|
}
|
|
@@ -613,7 +647,7 @@ export class TimelockService implements ITimelockService {
|
|
|
613
647
|
@memd.deco.memoize({ perInstance: true })
|
|
614
648
|
private async getStore () {
|
|
615
649
|
let { platform, network } = this.timelock.client;
|
|
616
|
-
let dir = this.options?.dir ??
|
|
650
|
+
let dir = this.options?.dir ?? CONFIG.dir;
|
|
617
651
|
|
|
618
652
|
let path = getPath(platform, dir);
|
|
619
653
|
if (platform === 'hardhat' && network !== platform) {
|
|
@@ -631,6 +665,12 @@ export class TimelockService implements ITimelockService {
|
|
|
631
665
|
key: x => x.id
|
|
632
666
|
});
|
|
633
667
|
}
|
|
668
|
+
|
|
669
|
+
static config (config: Partial<typeof CONFIG>) {
|
|
670
|
+
if (config.dir) {
|
|
671
|
+
CONFIG.dir = CONFIG.dir;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
634
674
|
}
|
|
635
675
|
|
|
636
676
|
namespace util {
|
package/src/txs/TxWriter.ts
CHANGED
|
@@ -26,15 +26,17 @@ import { TxLogParser } from './receipt/TxLogParser';
|
|
|
26
26
|
|
|
27
27
|
import { ISafeServiceTransport } from '@dequanto/safe/transport/ISafeServiceTransport';
|
|
28
28
|
import { SigFileTransport } from './sig-transports/SigFileTransport';
|
|
29
|
-
import { TxWriterAccountAgents } from './agents/TxWriterAccountAgents';
|
|
30
29
|
import { PromiseEvent } from '@dequanto/class/PromiseEvent';
|
|
31
30
|
import { $sig } from '@dequanto/utils/$sig';
|
|
32
31
|
import { TEth } from '@dequanto/models/TEth';
|
|
33
32
|
import { SafeServiceTypes } from '@dequanto/safe/types/SafeServiceTypes';
|
|
34
33
|
import { ChainAccountService } from '@dequanto/ChainAccountService';
|
|
35
34
|
import { $is } from '@dequanto/utils/$is';
|
|
35
|
+
import { TxWriterAccountAgents } from './agents/TxWriterAccountAgents';
|
|
36
|
+
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
|
|
39
|
+
export interface ITxWriterEvents {
|
|
38
40
|
transactionHash (hash: TEth.Hex)
|
|
39
41
|
receipt (receipt: TEth.TxReceipt)
|
|
40
42
|
confirmation (confNumber: number, receipt: TEth.TxReceipt)
|
|
@@ -43,6 +45,25 @@ interface ITxWriterEvents {
|
|
|
43
45
|
log (message: string)
|
|
44
46
|
safeTxProposed (safeTx: SafeServiceTypes.ProposeTransactionProps)
|
|
45
47
|
}
|
|
48
|
+
export interface ITxWriterEmitter {
|
|
49
|
+
onSent: PromiseLike<string | TEth.Hex>
|
|
50
|
+
onCompleted: PromiseLike<TEth.TxReceipt>
|
|
51
|
+
|
|
52
|
+
tx: ITxWriterTransaction
|
|
53
|
+
receipt: TEth.TxReceipt
|
|
54
|
+
|
|
55
|
+
on (event: keyof ITxWriterEvents, callback: Function): any | this
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ITxWriterTransaction {
|
|
59
|
+
timestamp: number
|
|
60
|
+
confirmations: number,
|
|
61
|
+
hash?: TEth.Hex
|
|
62
|
+
timeout?: NodeJS.Timer
|
|
63
|
+
receipt?: TEth.TxReceipt
|
|
64
|
+
error?: Error
|
|
65
|
+
knownLogs?: ITxLogItem[]
|
|
66
|
+
}
|
|
46
67
|
export interface ITxWriterOptions {
|
|
47
68
|
timeout?: number | boolean
|
|
48
69
|
retries?: number
|
|
@@ -80,7 +101,7 @@ export interface ITxWriterOptions {
|
|
|
80
101
|
|
|
81
102
|
const DEFAULTS: ITxWriterOptions = {};
|
|
82
103
|
|
|
83
|
-
export class TxWriter extends class_EventEmitter<ITxWriterEvents> {
|
|
104
|
+
export class TxWriter extends class_EventEmitter<ITxWriterEvents> implements ITxWriterEmitter {
|
|
84
105
|
|
|
85
106
|
onSent = new class_Dfr<string | TEth.Hex>();
|
|
86
107
|
onCompleted = new class_Dfr<TEth.TxReceipt>();
|
|
@@ -108,17 +129,9 @@ export class TxWriter extends class_EventEmitter<ITxWriterEvents> {
|
|
|
108
129
|
}
|
|
109
130
|
|
|
110
131
|
id = Math.round(Math.random() * 10**10) + '';
|
|
111
|
-
tx:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
hash?: TEth.Hex
|
|
115
|
-
timeout?: NodeJS.Timer
|
|
116
|
-
receipt?: TEth.TxReceipt
|
|
117
|
-
error?: Error
|
|
118
|
-
knownLogs?: ITxLogItem[]
|
|
119
|
-
} = null
|
|
120
|
-
|
|
121
|
-
txs: TxWriter['tx'][] = []
|
|
132
|
+
tx: ITxWriterTransaction = null
|
|
133
|
+
|
|
134
|
+
txs: ITxWriterTransaction[] = []
|
|
122
135
|
options: ITxWriterOptions;
|
|
123
136
|
|
|
124
137
|
|
|
@@ -173,9 +186,8 @@ export class TxWriter extends class_EventEmitter<ITxWriterEvents> {
|
|
|
173
186
|
|
|
174
187
|
let agent = TxWriterAccountAgents.get(this.account);
|
|
175
188
|
if (agent != null) {
|
|
176
|
-
|
|
177
189
|
let sender = await this.getSender();
|
|
178
|
-
let innerWriter:
|
|
190
|
+
let innerWriter: ITxWriterEmitter;
|
|
179
191
|
try {
|
|
180
192
|
innerWriter = await agent.process(sender, this.account, this);
|
|
181
193
|
} catch (error) {
|
|
@@ -479,7 +491,7 @@ export class TxWriter extends class_EventEmitter<ITxWriterEvents> {
|
|
|
479
491
|
}
|
|
480
492
|
this.sendTxInner();
|
|
481
493
|
}
|
|
482
|
-
private pipeInnerWriter (innerWriter:
|
|
494
|
+
private pipeInnerWriter (innerWriter: ITxWriterEmitter) {
|
|
483
495
|
innerWriter.onCompleted.then(
|
|
484
496
|
(receipt) => {
|
|
485
497
|
this.tx = innerWriter.tx;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { EoAccount, TAccount, TimelockAccount } from '@dequanto/models/TAccount';
|
|
2
|
+
import { ITxWriterAccountAgent } from './TxWriterAccountAgents';
|
|
3
|
+
import { $account } from '@dequanto/utils/$account';
|
|
4
|
+
import { ITxWriterEmitter, ITxWriterEvents, ITxWriterTransaction, TxWriter } from '../TxWriter';
|
|
5
|
+
|
|
6
|
+
import { ChainAccountService } from '@dequanto/ChainAccountService';
|
|
7
|
+
import { $promise } from '@dequanto/utils/$promise';
|
|
8
|
+
import { class_Dfr, class_EventEmitter } from 'atma-utils';
|
|
9
|
+
import { TEth } from '@dequanto/models/TEth';
|
|
10
|
+
import { $require } from '@dequanto/utils/$require';
|
|
11
|
+
import { $date } from '@dequanto/utils/$date';
|
|
12
|
+
import { ITimelockTx } from '@dequanto/services/TimelockService/ITimelockService';
|
|
13
|
+
import { Web3Client } from '@dequanto/clients/Web3Client';
|
|
14
|
+
|
|
15
|
+
import { TimelockService } from '@dequanto/services/TimelockService/TimelockService';
|
|
16
|
+
import { TimelockControllerFactory } from '@dequanto/prebuilt-factories/TimelockControllerFactory';
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export class TimelockAgent implements ITxWriterAccountAgent {
|
|
20
|
+
supports (account: TAccount) {
|
|
21
|
+
return $account.isTimelock(account);
|
|
22
|
+
}
|
|
23
|
+
async process (senderMix: string | EoAccount, timelockAccount: TimelockAccount, outerWriter: TxWriter) {
|
|
24
|
+
|
|
25
|
+
let { client, options } = outerWriter;
|
|
26
|
+
let TimelockController = TimelockControllerFactory();
|
|
27
|
+
let timelock = new TimelockController(timelockAccount.address, client);
|
|
28
|
+
let service = new TimelockService(timelock, {
|
|
29
|
+
simulate: false,
|
|
30
|
+
});
|
|
31
|
+
let sender = typeof senderMix === 'string'
|
|
32
|
+
? await ChainAccountService.get(senderMix) as EoAccount
|
|
33
|
+
: senderMix;
|
|
34
|
+
|
|
35
|
+
let inner = new TimelockTxWriter(
|
|
36
|
+
client,
|
|
37
|
+
sender,
|
|
38
|
+
service,
|
|
39
|
+
outerWriter,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
await inner.process();
|
|
43
|
+
return inner;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class TimelockTxWriter extends class_EventEmitter<ITxWriterEvents> implements ITxWriterEmitter {
|
|
48
|
+
|
|
49
|
+
onSent = new class_Dfr<string | TEth.Hex>()
|
|
50
|
+
onCompleted = new class_Dfr<TEth.TxReceipt>()
|
|
51
|
+
receipt: TEth.TxReceipt
|
|
52
|
+
tx: ITxWriterTransaction
|
|
53
|
+
|
|
54
|
+
schedule: ITimelockTx
|
|
55
|
+
delayTimer: any
|
|
56
|
+
|
|
57
|
+
constructor (
|
|
58
|
+
private client: Web3Client,
|
|
59
|
+
private sender: TEth.IAccount,
|
|
60
|
+
private service: TimelockService,
|
|
61
|
+
private outerWriter: TxWriter,
|
|
62
|
+
) {
|
|
63
|
+
super();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async process () {
|
|
67
|
+
let { sender, service, client, outerWriter } = this;
|
|
68
|
+
|
|
69
|
+
let { error, result } = await $promise.caught(service.processData(sender, outerWriter.builder));
|
|
70
|
+
if (error) {
|
|
71
|
+
this.onCompleted.reject(error);
|
|
72
|
+
this.emit('error', error);
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
if (result.status === 'completed') {
|
|
76
|
+
$require.Hex(result.tx, 'Timelock transaction hash expected');
|
|
77
|
+
let receipt = await client.getTransactionReceipt(result.tx);
|
|
78
|
+
let block = await client.getBlock(receipt.blockNumber);
|
|
79
|
+
let latestBlock = await client.getBlockNumber();
|
|
80
|
+
$require.notNull(receipt, `Receipt for ${result.tx} not found`);
|
|
81
|
+
|
|
82
|
+
let tx = {
|
|
83
|
+
timestamp: block.timestamp,
|
|
84
|
+
confirmations: latestBlock - block.number,
|
|
85
|
+
hash: receipt.transactionHash,
|
|
86
|
+
receipt: receipt,
|
|
87
|
+
error: null,
|
|
88
|
+
knownLogs: null,
|
|
89
|
+
} as ITxWriterTransaction;
|
|
90
|
+
|
|
91
|
+
this.tx = tx;
|
|
92
|
+
this.emit('transactionHash', receipt.transactionHash);
|
|
93
|
+
this.emit('receipt', receipt);
|
|
94
|
+
this.onCompleted.resolve(receipt);
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
if (result.status === 'pending') {
|
|
98
|
+
let readyAt = $date.fromUnixTimestamp(result.schedule.validAt);
|
|
99
|
+
let readyAtF = $date.format(readyAt, 'yyyy-MM-DD HH:mm:ss');
|
|
100
|
+
this.emit('log', `Timelock transaction pending: ${result.schedule.id}, ready at: ${readyAtF}`);
|
|
101
|
+
this.onSent.resolve(result.schedule.id);
|
|
102
|
+
|
|
103
|
+
let ms = readyAt.valueOf() - Date.now();
|
|
104
|
+
$require.gt(ms, 0, `The transaction must be in 'ready' state`);
|
|
105
|
+
this.delayTimer = setTimeout(() => {
|
|
106
|
+
this.process();
|
|
107
|
+
}, ms);
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
if (result.status === 'ready') {
|
|
111
|
+
throw new Error(`[TimelockAgent] Service emits 'ready' status, however it should execute the transaction directly`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
throw new Error(`[TimelockAgent] Unsupported status: ${result.status}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { EoAccount, TAccount } from '@dequanto/models/TAccount';
|
|
2
|
-
import type { TxWriter } from '../TxWriter';
|
|
2
|
+
import type { ITxWriterEmitter, TxWriter } from '../TxWriter';
|
|
3
3
|
import { SafeAgent } from './SafeAgent';
|
|
4
4
|
import { Erc4337Agent } from './Erc4337Agent';
|
|
5
|
+
import { TimelockAgent } from './TimelockAgent';
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
export interface ITxWriterAccountAgent {
|
|
9
10
|
supports (account: TAccount): boolean
|
|
10
|
-
process (sender: EoAccount, account: TAccount, outerWriter: TxWriter): Promise<
|
|
11
|
+
process (sender: EoAccount, account: TAccount, outerWriter: TxWriter): Promise<ITxWriterEmitter>
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export namespace TxWriterAccountAgents {
|
|
@@ -15,6 +16,7 @@ export namespace TxWriterAccountAgents {
|
|
|
15
16
|
const agents: ITxWriterAccountAgent[] = [
|
|
16
17
|
new SafeAgent(),
|
|
17
18
|
new Erc4337Agent(),
|
|
19
|
+
new TimelockAgent(),
|
|
18
20
|
];
|
|
19
21
|
|
|
20
22
|
export function register (agent: ITxWriterAccountAgent) {
|
package/src/utils/$account.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { EoAccount, Erc4337Account, SafeAccount, TAccount } from "@dequanto/models/TAccount";
|
|
1
|
+
import { EoAccount, Erc4337Account, SafeAccount, TAccount, TimelockAccount } from "@dequanto/models/TAccount";
|
|
2
2
|
import { $address } from './$address';
|
|
3
|
+
import { $require } from './$require';
|
|
3
4
|
|
|
4
5
|
export namespace $account {
|
|
5
6
|
|
|
@@ -11,10 +12,11 @@ export namespace $account {
|
|
|
11
12
|
return { name: account };
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
let acc = isSafe(account) || isErc4337 (account)
|
|
15
|
+
let acc = isSafe(account) || isErc4337 (account) || isTimelock(account)
|
|
15
16
|
? account.operator
|
|
16
17
|
: account;
|
|
17
18
|
|
|
19
|
+
$require.notNull(acc, `Sender not resolved for ${ account?.address ?? account }`);
|
|
18
20
|
return acc as EoAccount;
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -45,4 +47,18 @@ export namespace $account {
|
|
|
45
47
|
}
|
|
46
48
|
return false;
|
|
47
49
|
}
|
|
50
|
+
|
|
51
|
+
export function isTimelock (account:TAccount): account is TimelockAccount {
|
|
52
|
+
if (account == null) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
let rgx = /^timelock\//;
|
|
56
|
+
if (typeof account === 'string') {
|
|
57
|
+
return rgx.test(account);
|
|
58
|
+
}
|
|
59
|
+
if (account.type === 'timelock' || rgx.test(account.name)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
48
64
|
}
|
package/src/utils/$date.ts
CHANGED
|
@@ -250,6 +250,17 @@ export namespace $date {
|
|
|
250
250
|
result.setHours(23, 59, 59, 999);
|
|
251
251
|
return result;
|
|
252
252
|
}
|
|
253
|
+
export function weekNumber(date = new Date()) {
|
|
254
|
+
date = new Date(date);
|
|
255
|
+
date.setHours(0, 0, 0, 0);
|
|
256
|
+
|
|
257
|
+
// Set to nearest Thursday: current date + 4 - current day number
|
|
258
|
+
const dayNum = date.getDay() || 7;
|
|
259
|
+
date.setDate(date.getDate() + 4 - dayNum);
|
|
260
|
+
// Calculate week number
|
|
261
|
+
const yearStart = new Date(Date.UTC(date.getFullYear(), 0, 1));
|
|
262
|
+
return Math.ceil((((date.getTime() - yearStart.getTime()) / 86400000) + 1) / 7);
|
|
263
|
+
}
|
|
253
264
|
export function monthStart(date = new Date()) {
|
|
254
265
|
let result = new Date(date);
|
|
255
266
|
result.setDate(1);
|
|
@@ -264,7 +275,6 @@ export namespace $date {
|
|
|
264
275
|
return result;
|
|
265
276
|
}
|
|
266
277
|
|
|
267
|
-
|
|
268
278
|
/** date1 + X === date2 */
|
|
269
279
|
export function daysBetween(a: Date, b: Date, abs: boolean = true) {
|
|
270
280
|
let aStart = dayStart(a);
|