@atomiqlabs/chain-evm 2.1.14 → 2.2.1
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/README.md +1 -1
- package/dist/evm/chain/EVMChainInterface.d.ts +4 -0
- package/dist/evm/chain/EVMChainInterface.js +7 -0
- package/dist/evm/chain/modules/EVMTransactions.d.ts +2 -3
- package/dist/evm/chain/modules/EVMTransactions.js +23 -17
- package/package.json +3 -2
- package/src/evm/chain/EVMChainInterface.ts +8 -0
- package/src/evm/chain/modules/EVMTransactions.ts +16 -12
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ const Factory = new SwapperFactory<SupportedChains>(chains); //Create swapper fa
|
|
|
67
67
|
const swapper: TypedSwapper<SupportedChains> = Factory.newSwapper({
|
|
68
68
|
chains: {
|
|
69
69
|
CITREA: {
|
|
70
|
-
rpcUrl: citreaRpc, //You can also pass
|
|
70
|
+
rpcUrl: citreaRpc, //You can also pass JsonRpcApiProvider object here
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
bitcoinNetwork: BitcoinNetwork.MAINNET //or BitcoinNetwork.TESTNET3, BitcoinNetwork.TESTNET4 - this also sets the deployment to use for EVM chains
|
|
@@ -160,6 +160,10 @@ export declare class EVMChainInterface<ChainId extends string = string> implemen
|
|
|
160
160
|
* @inheritDoc
|
|
161
161
|
*/
|
|
162
162
|
sendSignedAndConfirm(signedTxs: Transaction[], waitForConfirmation?: boolean, abortSignal?: AbortSignal, parallel?: boolean, onBeforePublish?: (txId: string, rawTx: string) => Promise<void>): Promise<string[]>;
|
|
163
|
+
/**
|
|
164
|
+
* @inheritDoc
|
|
165
|
+
*/
|
|
166
|
+
prepareTxs(txs: EVMTx[]): Promise<EVMTx[]>;
|
|
163
167
|
/**
|
|
164
168
|
* @inheritDoc
|
|
165
169
|
*/
|
|
@@ -118,6 +118,13 @@ class EVMChainInterface {
|
|
|
118
118
|
sendSignedAndConfirm(signedTxs, waitForConfirmation, abortSignal, parallel, onBeforePublish) {
|
|
119
119
|
return this.Transactions.sendSignedAndConfirm(signedTxs, waitForConfirmation, abortSignal, parallel, onBeforePublish);
|
|
120
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* @inheritDoc
|
|
123
|
+
*/
|
|
124
|
+
async prepareTxs(txs) {
|
|
125
|
+
await this.Transactions.prepareTransactions(txs);
|
|
126
|
+
return txs;
|
|
127
|
+
}
|
|
121
128
|
/**
|
|
122
129
|
* @inheritDoc
|
|
123
130
|
*/
|
|
@@ -56,12 +56,11 @@ export declare class EVMTransactions extends EVMModule<any> {
|
|
|
56
56
|
* Prepares EVM transactions, assigns nonces when needed, and optionally applies access lists
|
|
57
57
|
* before signing.
|
|
58
58
|
*
|
|
59
|
-
* @param signer
|
|
60
59
|
* @param txs
|
|
60
|
+
* @param signer
|
|
61
61
|
* @param useAccessList Whether to use access lists for sending txns
|
|
62
|
-
* @private
|
|
63
62
|
*/
|
|
64
|
-
|
|
63
|
+
prepareTransactions(txs: TransactionRequest[], signer?: EVMSigner, useAccessList?: boolean): Promise<void>;
|
|
65
64
|
/**
|
|
66
65
|
* Sends out a signed transaction to the RPC
|
|
67
66
|
*
|
|
@@ -117,19 +117,24 @@ class EVMTransactions extends EVMModule_1.EVMModule {
|
|
|
117
117
|
* Prepares EVM transactions, assigns nonces when needed, and optionally applies access lists
|
|
118
118
|
* before signing.
|
|
119
119
|
*
|
|
120
|
-
* @param signer
|
|
121
120
|
* @param txs
|
|
121
|
+
* @param signer
|
|
122
122
|
* @param useAccessList Whether to use access lists for sending txns
|
|
123
|
-
* @private
|
|
124
123
|
*/
|
|
125
|
-
async prepareTransactions(
|
|
124
|
+
async prepareTransactions(txs, signer, useAccessList) {
|
|
125
|
+
if (txs.length === 0)
|
|
126
|
+
return;
|
|
127
|
+
const signerAddress = signer?.getAddress()
|
|
128
|
+
?? (txs[0].from == null ? null : await (0, ethers_1.resolveAddress)(txs[0].from, this.provider));
|
|
129
|
+
if (signerAddress == null)
|
|
130
|
+
throw new Error("Cannot get tx sender address!");
|
|
126
131
|
for (let tx of txs) {
|
|
127
132
|
tx.chainId = this.root.evmChainId;
|
|
128
|
-
tx.from =
|
|
133
|
+
tx.from = signerAddress;
|
|
129
134
|
}
|
|
130
|
-
if (!signer.isManagingNoncesInternally) {
|
|
131
|
-
let nonce = await this.root.provider.getTransactionCount(
|
|
132
|
-
const latestKnownNonce = this.latestPendingNonces[
|
|
135
|
+
if (signer == null || !signer.isManagingNoncesInternally) {
|
|
136
|
+
let nonce = await this.root.provider.getTransactionCount(signerAddress, "pending");
|
|
137
|
+
const latestKnownNonce = this.latestPendingNonces[signerAddress];
|
|
133
138
|
if (latestKnownNonce != null && latestKnownNonce > nonce) {
|
|
134
139
|
this.logger.debug("prepareTransactions(): Using nonce from local cache!");
|
|
135
140
|
nonce = latestKnownNonce;
|
|
@@ -139,20 +144,21 @@ class EVMTransactions extends EVMModule_1.EVMModule {
|
|
|
139
144
|
if (tx.nonce != null)
|
|
140
145
|
nonce = tx.nonce; //Take the nonce from last tx
|
|
141
146
|
if (nonce == null)
|
|
142
|
-
nonce = await this.root.provider.getTransactionCount(
|
|
147
|
+
nonce = await this.root.provider.getTransactionCount(signerAddress, "pending"); //Fetch the nonce
|
|
143
148
|
if (tx.nonce == null)
|
|
144
149
|
tx.nonce = nonce;
|
|
145
150
|
this.logger.debug("sendAndConfirm(): transaction prepared (" + (i + 1) + "/" + txs.length + "), nonce: " + tx.nonce);
|
|
146
151
|
nonce++;
|
|
147
152
|
}
|
|
148
153
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
if (signer != null)
|
|
155
|
+
for (let tx of txs) {
|
|
156
|
+
if (useAccessList)
|
|
157
|
+
await this.applyAccessList(tx);
|
|
158
|
+
for (let callback of this.cbksBeforeTxSigned) {
|
|
159
|
+
await callback(tx);
|
|
160
|
+
}
|
|
154
161
|
}
|
|
155
|
-
}
|
|
156
162
|
}
|
|
157
163
|
/**
|
|
158
164
|
* Sends out a signed transaction to the RPC
|
|
@@ -191,7 +197,7 @@ class EVMTransactions extends EVMModule_1.EVMModule {
|
|
|
191
197
|
* @param useAccessLists
|
|
192
198
|
*/
|
|
193
199
|
async sendAndConfirm(signer, txs, waitForConfirmation, abortSignal, parallel, onBeforePublish, useAccessLists) {
|
|
194
|
-
await this.prepareTransactions(
|
|
200
|
+
await this.prepareTransactions(txs, signer, useAccessLists ?? this.root._config.useAccessLists);
|
|
195
201
|
const signedTxs = [];
|
|
196
202
|
//Don't separate the signing process from the sending when using browser-based wallet
|
|
197
203
|
if (signer.signTransaction != null)
|
|
@@ -329,7 +335,7 @@ class EVMTransactions extends EVMModule_1.EVMModule {
|
|
|
329
335
|
const tx = ethers_1.Transaction.from({
|
|
330
336
|
...unsignedTx,
|
|
331
337
|
to: unsignedTx.to == null ? null : await (0, ethers_1.resolveAddress)(unsignedTx.to),
|
|
332
|
-
from:
|
|
338
|
+
from: null,
|
|
333
339
|
authorizationList: unsignedTx.authorizationList == null ? null : unsignedTx.authorizationList.map(val => ({
|
|
334
340
|
...val,
|
|
335
341
|
nonce: BigInt(val.nonce),
|
|
@@ -337,7 +343,7 @@ class EVMTransactions extends EVMModule_1.EVMModule {
|
|
|
337
343
|
signature: ethers_1.Signature.from(val.signature)
|
|
338
344
|
}))
|
|
339
345
|
});
|
|
340
|
-
return
|
|
346
|
+
return tx.unsignedSerialized;
|
|
341
347
|
}
|
|
342
348
|
/**
|
|
343
349
|
* Serializes the signed EVM transaction
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomiqlabs/chain-evm",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "EVM specific base implementation",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types:": "./dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
+
"build": "npx -y -p typescript@4.9 tsc",
|
|
8
9
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
9
10
|
"build:ts4": "npx -p typescript@4.9 tsc --noEmit",
|
|
10
11
|
"build:ts5": "npx -p typescript@5.3 tsc --noEmit"
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
"author": "adambor",
|
|
27
28
|
"license": "Apache-2.0",
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"@atomiqlabs/base": "^13.
|
|
30
|
+
"@atomiqlabs/base": "^13.2.0",
|
|
30
31
|
"@noble/hashes": "^1.8.0",
|
|
31
32
|
"@scure/btc-signer": "^1.6.0",
|
|
32
33
|
"buffer": "6.0.3",
|
|
@@ -264,6 +264,14 @@ export class EVMChainInterface<ChainId extends string = string> implements Chain
|
|
|
264
264
|
return this.Transactions.sendSignedAndConfirm(signedTxs, waitForConfirmation, abortSignal, parallel, onBeforePublish);
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
+
/**
|
|
268
|
+
* @inheritDoc
|
|
269
|
+
*/
|
|
270
|
+
async prepareTxs(txs: EVMTx[]): Promise<EVMTx[]> {
|
|
271
|
+
await this.Transactions.prepareTransactions(txs);
|
|
272
|
+
return txs;
|
|
273
|
+
}
|
|
274
|
+
|
|
267
275
|
/**
|
|
268
276
|
* @inheritDoc
|
|
269
277
|
*/
|
|
@@ -161,20 +161,24 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
161
161
|
* Prepares EVM transactions, assigns nonces when needed, and optionally applies access lists
|
|
162
162
|
* before signing.
|
|
163
163
|
*
|
|
164
|
-
* @param signer
|
|
165
164
|
* @param txs
|
|
165
|
+
* @param signer
|
|
166
166
|
* @param useAccessList Whether to use access lists for sending txns
|
|
167
|
-
* @private
|
|
168
167
|
*/
|
|
169
|
-
|
|
168
|
+
public async prepareTransactions(txs: TransactionRequest[], signer?: EVMSigner, useAccessList?: boolean): Promise<void> {
|
|
169
|
+
if(txs.length===0) return;
|
|
170
|
+
const signerAddress = signer?.getAddress()
|
|
171
|
+
?? (txs[0].from==null ? null : await resolveAddress(txs[0].from, this.provider));
|
|
172
|
+
if(signerAddress==null) throw new Error("Cannot get tx sender address!");
|
|
173
|
+
|
|
170
174
|
for(let tx of txs) {
|
|
171
175
|
tx.chainId = this.root.evmChainId;
|
|
172
|
-
tx.from =
|
|
176
|
+
tx.from = signerAddress;
|
|
173
177
|
}
|
|
174
178
|
|
|
175
|
-
if(!signer.isManagingNoncesInternally) {
|
|
176
|
-
let nonce: number = await this.root.provider.getTransactionCount(
|
|
177
|
-
const latestKnownNonce = this.latestPendingNonces[
|
|
179
|
+
if(signer==null || !signer.isManagingNoncesInternally) {
|
|
180
|
+
let nonce: number = await this.root.provider.getTransactionCount(signerAddress, "pending");
|
|
181
|
+
const latestKnownNonce = this.latestPendingNonces[signerAddress];
|
|
178
182
|
if(latestKnownNonce!=null && latestKnownNonce > nonce) {
|
|
179
183
|
this.logger.debug("prepareTransactions(): Using nonce from local cache!");
|
|
180
184
|
nonce = latestKnownNonce;
|
|
@@ -183,7 +187,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
183
187
|
for(let i=0;i<txs.length;i++) {
|
|
184
188
|
const tx = txs[i];
|
|
185
189
|
if(tx.nonce!=null) nonce = tx.nonce; //Take the nonce from last tx
|
|
186
|
-
if(nonce==null) nonce = await this.root.provider.getTransactionCount(
|
|
190
|
+
if(nonce==null) nonce = await this.root.provider.getTransactionCount(signerAddress, "pending"); //Fetch the nonce
|
|
187
191
|
if(tx.nonce==null) tx.nonce = nonce;
|
|
188
192
|
|
|
189
193
|
this.logger.debug("sendAndConfirm(): transaction prepared ("+(i+1)+"/"+txs.length+"), nonce: "+tx.nonce);
|
|
@@ -192,7 +196,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
192
196
|
}
|
|
193
197
|
}
|
|
194
198
|
|
|
195
|
-
for(let tx of txs) {
|
|
199
|
+
if(signer!=null) for(let tx of txs) {
|
|
196
200
|
if(useAccessList) await this.applyAccessList(tx);
|
|
197
201
|
for(let callback of this.cbksBeforeTxSigned) {
|
|
198
202
|
await callback(tx);
|
|
@@ -246,7 +250,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
246
250
|
abortSignal?: AbortSignal, parallel?: boolean, onBeforePublish?: (txId: string, rawTx: string) => Promise<void>,
|
|
247
251
|
useAccessLists?: boolean
|
|
248
252
|
): Promise<string[]> {
|
|
249
|
-
await this.prepareTransactions(
|
|
253
|
+
await this.prepareTransactions(txs, signer, useAccessLists ?? this.root._config.useAccessLists);
|
|
250
254
|
const signedTxs: Transaction[] = [];
|
|
251
255
|
|
|
252
256
|
//Don't separate the signing process from the sending when using browser-based wallet
|
|
@@ -395,7 +399,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
395
399
|
const tx = Transaction.from({
|
|
396
400
|
...unsignedTx,
|
|
397
401
|
to: unsignedTx.to==null ? null : await resolveAddress(unsignedTx.to),
|
|
398
|
-
from:
|
|
402
|
+
from: null, // Unsigned transaction cannot have its `from` field populated
|
|
399
403
|
authorizationList: unsignedTx.authorizationList==null ? null : unsignedTx.authorizationList.map(val => ({
|
|
400
404
|
...val,
|
|
401
405
|
nonce: BigInt(val.nonce),
|
|
@@ -403,7 +407,7 @@ export class EVMTransactions extends EVMModule<any> {
|
|
|
403
407
|
signature: Signature.from(val.signature)
|
|
404
408
|
}))
|
|
405
409
|
});
|
|
406
|
-
return
|
|
410
|
+
return tx.unsignedSerialized;
|
|
407
411
|
}
|
|
408
412
|
|
|
409
413
|
/**
|