@atomiqlabs/chain-evm 2.2.1 → 2.4.0
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/dist/chains/alpen/AlpenInitializer.js +1 -1
- package/dist/chains/botanix/BotanixInitializer.js +1 -1
- package/dist/chains/citrea/CitreaInitializer.js +1 -1
- package/dist/chains/goat/GoatInitializer.js +1 -1
- package/dist/evm/chain/EVMChainInterface.d.ts +4 -2
- package/dist/evm/chain/EVMChainInterface.js +10 -1
- package/dist/evm/swaps/EVMSwapData.d.ts +4 -0
- package/dist/evm/swaps/EVMSwapData.js +7 -0
- package/dist/utils/Utils.d.ts +4 -0
- package/dist/utils/Utils.js +19 -1
- package/package.json +2 -2
- package/src/chains/alpen/AlpenInitializer.ts +1 -1
- package/src/chains/botanix/BotanixInitializer.ts +1 -1
- package/src/chains/citrea/CitreaInitializer.ts +1 -1
- package/src/chains/goat/GoatInitializer.ts +1 -1
- package/src/evm/chain/EVMChainInterface.ts +16 -2
- package/src/evm/swaps/EVMSwapData.ts +8 -0
- package/src/utils/Utils.ts +32 -0
|
@@ -120,7 +120,7 @@ function initializeAlpen(options, bitcoinRpc, network) {
|
|
|
120
120
|
maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5,
|
|
121
121
|
useAccessLists: options?.evmConfig?.useAccessLists,
|
|
122
122
|
defaultAccessListAddresses: options?.evmConfig?.defaultAccessListAddresses
|
|
123
|
-
}, options.retryPolicy, Fees);
|
|
123
|
+
}, options.retryPolicy, Fees, network);
|
|
124
124
|
const btcRelay = new EVMBtcRelay_1.EVMBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract ?? defaultContractAddresses.btcRelayContract, options.btcRelayDeploymentHeight ?? defaultContractAddresses.btcRelayDeploymentHeight);
|
|
125
125
|
const swapContract = new EVMSwapContract_1.EVMSwapContract(chainInterface, btcRelay, options.swapContract ?? defaultContractAddresses.swapContract, {
|
|
126
126
|
refund: {
|
|
@@ -102,7 +102,7 @@ function initializeBotanix(options, bitcoinRpc, network) {
|
|
|
102
102
|
type: "timer",
|
|
103
103
|
delayMs: 1000
|
|
104
104
|
}
|
|
105
|
-
}, options.retryPolicy, Fees);
|
|
105
|
+
}, options.retryPolicy, Fees, network);
|
|
106
106
|
const btcRelay = new EVMBtcRelay_1.EVMBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract ?? defaultContractAddresses.btcRelayContract, options.btcRelayDeploymentHeight ?? defaultContractAddresses.btcRelayDeploymentHeight);
|
|
107
107
|
const swapContract = new EVMSwapContract_1.EVMSwapContract(chainInterface, btcRelay, options.swapContract ?? defaultContractAddresses.swapContract, {
|
|
108
108
|
refund: {
|
|
@@ -111,7 +111,7 @@ function initializeCitrea(options, bitcoinRpc, network) {
|
|
|
111
111
|
maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5,
|
|
112
112
|
useAccessLists: options?.evmConfig?.useAccessLists,
|
|
113
113
|
defaultAccessListAddresses: options?.evmConfig?.defaultAccessListAddresses
|
|
114
|
-
}, options.retryPolicy, Fees);
|
|
114
|
+
}, options.retryPolicy, Fees, network);
|
|
115
115
|
chainInterface.Tokens = new CitreaTokens_1.CitreaTokens(chainInterface); //Override with custom token module allowing l1 state diff based fee calculation
|
|
116
116
|
const btcRelay = new CitreaBtcRelay_1.CitreaBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract ?? defaultContractAddresses.btcRelayContract, options.btcRelayDeploymentHeight ?? defaultContractAddresses.btcRelayDeploymentHeight);
|
|
117
117
|
const swapContract = new CitreaSwapContract_1.CitreaSwapContract(chainInterface, btcRelay, options.swapContract ?? defaultContractAddresses.swapContract, {
|
|
@@ -130,7 +130,7 @@ function initializeGoat(options, bitcoinRpc, network) {
|
|
|
130
130
|
maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5,
|
|
131
131
|
useAccessLists: options?.evmConfig?.useAccessLists,
|
|
132
132
|
defaultAccessListAddresses: options?.evmConfig?.defaultAccessListAddresses
|
|
133
|
-
}, options.retryPolicy, Fees);
|
|
133
|
+
}, options.retryPolicy, Fees, network);
|
|
134
134
|
const btcRelay = new EVMBtcRelay_1.EVMBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract ?? defaultContractAddresses.btcRelayContract, options.btcRelayDeploymentHeight ?? defaultContractAddresses.btcRelayDeploymentHeight);
|
|
135
135
|
const swapContract = new EVMSwapContract_1.EVMSwapContract(chainInterface, btcRelay, options.swapContract ?? defaultContractAddresses.swapContract, {
|
|
136
136
|
refund: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChainInterface, TransactionConfirmationOptions } from "@atomiqlabs/base";
|
|
1
|
+
import { BitcoinNetwork, ChainInterface, TransactionConfirmationOptions } from "@atomiqlabs/base";
|
|
2
2
|
import { LoggerType } from "../../utils/Utils";
|
|
3
3
|
import { JsonRpcApiProvider, Signer, Transaction, TransactionRequest } from "ethers";
|
|
4
4
|
import { EVMBlocks, EVMBlockTag } from "./modules/EVMBlocks";
|
|
@@ -107,7 +107,8 @@ export declare class EVMChainInterface<ChainId extends string = string> implemen
|
|
|
107
107
|
* @internal
|
|
108
108
|
*/
|
|
109
109
|
protected logger: LoggerType;
|
|
110
|
-
|
|
110
|
+
private readonly bitcoinNetwork?;
|
|
111
|
+
constructor(chainId: ChainId, evmChainId: number, provider: JsonRpcApiProvider, config: EVMConfiguration, retryPolicy?: EVMRetryPolicy, evmFeeEstimator?: EVMFees, bitcoinNetwork?: BitcoinNetwork);
|
|
111
112
|
/**
|
|
112
113
|
* @inheritDoc
|
|
113
114
|
*/
|
|
@@ -207,4 +208,5 @@ export declare class EVMChainInterface<ChainId extends string = string> implemen
|
|
|
207
208
|
* @inheritDoc
|
|
208
209
|
*/
|
|
209
210
|
wrapSigner(signer: Signer): Promise<EVMSigner>;
|
|
211
|
+
verifyNetwork(bitcoinNetwork: BitcoinNetwork): Promise<void>;
|
|
210
212
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EVMChainInterface = void 0;
|
|
4
|
+
const base_1 = require("@atomiqlabs/base");
|
|
4
5
|
const Utils_1 = require("../../utils/Utils");
|
|
5
6
|
const ethers_1 = require("ethers");
|
|
6
7
|
const EVMBlocks_1 = require("./modules/EVMBlocks");
|
|
@@ -17,7 +18,7 @@ const EVMBrowserSigner_1 = require("../wallet/EVMBrowserSigner");
|
|
|
17
18
|
* @category Chain Interface
|
|
18
19
|
*/
|
|
19
20
|
class EVMChainInterface {
|
|
20
|
-
constructor(chainId, evmChainId, provider, config, retryPolicy, evmFeeEstimator = new EVMFees_1.EVMFees(provider)) {
|
|
21
|
+
constructor(chainId, evmChainId, provider, config, retryPolicy, evmFeeEstimator = new EVMFees_1.EVMFees(provider), bitcoinNetwork) {
|
|
21
22
|
var _a, _b, _c, _d;
|
|
22
23
|
this.chainId = chainId;
|
|
23
24
|
this.evmChainId = evmChainId;
|
|
@@ -28,6 +29,7 @@ class EVMChainInterface {
|
|
|
28
29
|
(_b = this._config).finalizedBlockTag ?? (_b.finalizedBlockTag = "finalized");
|
|
29
30
|
(_c = this._config).finalityCheckStrategy ?? (_c.finalityCheckStrategy = { type: "timer" });
|
|
30
31
|
(_d = this._config.finalityCheckStrategy).delayMs ?? (_d.delayMs = 1000);
|
|
32
|
+
this.bitcoinNetwork = bitcoinNetwork;
|
|
31
33
|
this.logger = (0, Utils_1.getLogger)("EVMChainInterface(" + this.evmChainId + "): ");
|
|
32
34
|
this.Fees = evmFeeEstimator;
|
|
33
35
|
this.Tokens = new EVMTokens_1.EVMTokens(this);
|
|
@@ -195,5 +197,12 @@ class EVMChainInterface {
|
|
|
195
197
|
}
|
|
196
198
|
return new EVMSigner_1.EVMSigner(signer, address);
|
|
197
199
|
}
|
|
200
|
+
async verifyNetwork(bitcoinNetwork) {
|
|
201
|
+
if (this.bitcoinNetwork != null && bitcoinNetwork !== this.bitcoinNetwork)
|
|
202
|
+
throw new Error(`Network mismatch, the chain interface was not setup for ${base_1.BitcoinNetwork[bitcoinNetwork]}, chain interface network: ${base_1.BitcoinNetwork[this.bitcoinNetwork]}`);
|
|
203
|
+
const network = await this.provider.getNetwork();
|
|
204
|
+
if (network.chainId !== BigInt(this.evmChainId))
|
|
205
|
+
throw new Error(`Network mismatch, the underlying RPC provider isn't using the correct chainId, expected: ${this.evmChainId}, provider returned: ${network.chainId.toString(10)}`);
|
|
206
|
+
}
|
|
198
207
|
}
|
|
199
208
|
exports.EVMChainInterface = EVMChainInterface;
|
|
@@ -178,4 +178,8 @@ export declare class EVMSwapData extends SwapData {
|
|
|
178
178
|
* @param claimHandlerImpl Claim handler implementation used to resolve swap type
|
|
179
179
|
*/
|
|
180
180
|
static deserializeFromStruct(struct: EscrowDataStruct, claimHandlerImpl: IClaimHandler<any, any>): EVMSwapData;
|
|
181
|
+
/**
|
|
182
|
+
* @inheritDoc
|
|
183
|
+
*/
|
|
184
|
+
getEscrowStruct(): any;
|
|
181
185
|
}
|
|
@@ -4,6 +4,7 @@ exports.EVMSwapData = void 0;
|
|
|
4
4
|
const base_1 = require("@atomiqlabs/base");
|
|
5
5
|
const ethers_1 = require("ethers");
|
|
6
6
|
const TimelockRefundHandler_1 = require("./handlers/refund/TimelockRefundHandler");
|
|
7
|
+
const Utils_1 = require("../../utils/Utils");
|
|
7
8
|
const FLAG_PAY_OUT = 0x01n;
|
|
8
9
|
const FLAG_PAY_IN = 0x02n;
|
|
9
10
|
const FLAG_REPUTATION = 0x04n;
|
|
@@ -413,6 +414,12 @@ class EVMSwapData extends base_1.SwapData {
|
|
|
413
414
|
const { payOut, payIn, reputation, sequence } = EVMSwapData.toFlags(BigInt(struct.flags));
|
|
414
415
|
return new EVMSwapData(struct.offerer, struct.claimer, struct.token, struct.refundHandler, struct.claimHandler, payOut, payIn, reputation, sequence, (0, ethers_1.hexlify)(struct.claimData), (0, ethers_1.hexlify)(struct.refundData), BigInt(struct.amount), struct.depositToken, BigInt(struct.securityDeposit), BigInt(struct.claimerBounty), claimHandlerImpl.getType(), undefined, struct.successActionCommitment);
|
|
415
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* @inheritDoc
|
|
419
|
+
*/
|
|
420
|
+
getEscrowStruct() {
|
|
421
|
+
return (0, Utils_1.replaceBigInts)(this.toEscrowStruct());
|
|
422
|
+
}
|
|
416
423
|
}
|
|
417
424
|
exports.EVMSwapData = EVMSwapData;
|
|
418
425
|
base_1.SwapData.deserializers["evm"] = EVMSwapData;
|
package/dist/utils/Utils.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export type ReplaceBigInt<T> = T extends bigint ? string : T extends (infer U)[] ? ReplaceBigInt<U>[] : T extends readonly (infer U)[] ? readonly ReplaceBigInt<U>[] : T extends object ? {
|
|
2
|
+
[K in keyof T]: ReplaceBigInt<T[K]>;
|
|
3
|
+
} : T;
|
|
1
4
|
/**
|
|
2
5
|
* Logger interface used across EVM modules.
|
|
3
6
|
*
|
|
@@ -67,3 +70,4 @@ export declare const allowedEthersErrorNumbers: Set<number>;
|
|
|
67
70
|
* @category Internal/Utils
|
|
68
71
|
*/
|
|
69
72
|
export declare const allowedEthersErrorMessages: Set<string>;
|
|
73
|
+
export declare function replaceBigInts<T>(obj: T): ReplaceBigInt<T>;
|
package/dist/utils/Utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.allowedEthersErrorMessages = exports.allowedEthersErrorNumbers = exports.allowedEthersErrorCodes = exports.bigIntMax = exports.uint32ReverseEndianness = exports.tryWithRetries = exports.getLogger = exports.onceAsync = exports.timeoutPromise = void 0;
|
|
3
|
+
exports.replaceBigInts = exports.allowedEthersErrorMessages = exports.allowedEthersErrorNumbers = exports.allowedEthersErrorCodes = exports.bigIntMax = exports.uint32ReverseEndianness = exports.tryWithRetries = exports.getLogger = exports.onceAsync = exports.timeoutPromise = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Returns a promise that resolves after `timeoutMillis` unless aborted first.
|
|
6
6
|
*
|
|
@@ -142,3 +142,21 @@ exports.allowedEthersErrorNumbers = new Set([
|
|
|
142
142
|
exports.allowedEthersErrorMessages = new Set([
|
|
143
143
|
"already known"
|
|
144
144
|
]);
|
|
145
|
+
function replaceBigInts(obj) {
|
|
146
|
+
const replace = (value) => {
|
|
147
|
+
if (typeof (value) === "bigint")
|
|
148
|
+
return "0x" + value.toString(16);
|
|
149
|
+
if (value == null || typeof (value) !== "object")
|
|
150
|
+
return value;
|
|
151
|
+
if (Array.isArray(value)) {
|
|
152
|
+
return value.map(replace);
|
|
153
|
+
}
|
|
154
|
+
const mapped = {};
|
|
155
|
+
for (const key of Object.keys(value)) {
|
|
156
|
+
mapped[key] = replace(value[key]);
|
|
157
|
+
}
|
|
158
|
+
return mapped;
|
|
159
|
+
};
|
|
160
|
+
return replace(obj);
|
|
161
|
+
}
|
|
162
|
+
exports.replaceBigInts = replaceBigInts;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomiqlabs/chain-evm",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "EVM specific base implementation",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types:": "./dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"author": "adambor",
|
|
28
28
|
"license": "Apache-2.0",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@atomiqlabs/base": "^13.
|
|
30
|
+
"@atomiqlabs/base": "^13.4.0",
|
|
31
31
|
"@noble/hashes": "^1.8.0",
|
|
32
32
|
"@scure/btc-signer": "^1.6.0",
|
|
33
33
|
"buffer": "6.0.3",
|
|
@@ -145,7 +145,7 @@ export function initializeAlpen(
|
|
|
145
145
|
maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5,
|
|
146
146
|
useAccessLists: options?.evmConfig?.useAccessLists,
|
|
147
147
|
defaultAccessListAddresses: options?.evmConfig?.defaultAccessListAddresses
|
|
148
|
-
}, options.retryPolicy, Fees);
|
|
148
|
+
}, options.retryPolicy, Fees, network);
|
|
149
149
|
|
|
150
150
|
const btcRelay = new EVMBtcRelay(
|
|
151
151
|
chainInterface, bitcoinRpc, network, options.btcRelayContract ?? defaultContractAddresses.btcRelayContract,
|
|
@@ -127,7 +127,7 @@ export function initializeBotanix(
|
|
|
127
127
|
type: "timer",
|
|
128
128
|
delayMs: 1000
|
|
129
129
|
}
|
|
130
|
-
}, options.retryPolicy, Fees);
|
|
130
|
+
}, options.retryPolicy, Fees, network);
|
|
131
131
|
|
|
132
132
|
const btcRelay = new EVMBtcRelay(
|
|
133
133
|
chainInterface, bitcoinRpc, network, options.btcRelayContract ?? defaultContractAddresses.btcRelayContract,
|
|
@@ -135,7 +135,7 @@ export function initializeCitrea(
|
|
|
135
135
|
maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5,
|
|
136
136
|
useAccessLists: options?.evmConfig?.useAccessLists,
|
|
137
137
|
defaultAccessListAddresses: options?.evmConfig?.defaultAccessListAddresses
|
|
138
|
-
}, options.retryPolicy, Fees);
|
|
138
|
+
}, options.retryPolicy, Fees, network);
|
|
139
139
|
chainInterface.Tokens = new CitreaTokens(chainInterface); //Override with custom token module allowing l1 state diff based fee calculation
|
|
140
140
|
|
|
141
141
|
const btcRelay = new CitreaBtcRelay(
|
|
@@ -155,7 +155,7 @@ export function initializeGoat(
|
|
|
155
155
|
maxParallelCalls: options?.evmConfig?.maxParallelCalls ?? 5,
|
|
156
156
|
useAccessLists: options?.evmConfig?.useAccessLists,
|
|
157
157
|
defaultAccessListAddresses: options?.evmConfig?.defaultAccessListAddresses
|
|
158
|
-
}, options.retryPolicy, Fees);
|
|
158
|
+
}, options.retryPolicy, Fees, network);
|
|
159
159
|
|
|
160
160
|
const btcRelay = new EVMBtcRelay(
|
|
161
161
|
chainInterface, bitcoinRpc, network, options.btcRelayContract ?? defaultContractAddresses.btcRelayContract,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {ChainInterface, TransactionConfirmationOptions} from "@atomiqlabs/base";
|
|
1
|
+
import {BitcoinNetwork, ChainInterface, TransactionConfirmationOptions} from "@atomiqlabs/base";
|
|
2
2
|
import {getLogger, LoggerType} from "../../utils/Utils";
|
|
3
3
|
import {
|
|
4
4
|
BrowserProvider,
|
|
@@ -128,13 +128,16 @@ export class EVMChainInterface<ChainId extends string = string> implements Chain
|
|
|
128
128
|
*/
|
|
129
129
|
protected logger: LoggerType;
|
|
130
130
|
|
|
131
|
+
private readonly bitcoinNetwork?: BitcoinNetwork;
|
|
132
|
+
|
|
131
133
|
constructor(
|
|
132
134
|
chainId: ChainId,
|
|
133
135
|
evmChainId: number,
|
|
134
136
|
provider: JsonRpcApiProvider,
|
|
135
137
|
config: EVMConfiguration,
|
|
136
138
|
retryPolicy?: EVMRetryPolicy,
|
|
137
|
-
evmFeeEstimator: EVMFees = new EVMFees(provider)
|
|
139
|
+
evmFeeEstimator: EVMFees = new EVMFees(provider),
|
|
140
|
+
bitcoinNetwork?: BitcoinNetwork
|
|
138
141
|
) {
|
|
139
142
|
this.chainId = chainId;
|
|
140
143
|
this.evmChainId = evmChainId;
|
|
@@ -146,6 +149,8 @@ export class EVMChainInterface<ChainId extends string = string> implements Chain
|
|
|
146
149
|
this._config.finalityCheckStrategy ??= {type: "timer"};
|
|
147
150
|
this._config.finalityCheckStrategy.delayMs ??= 1000;
|
|
148
151
|
|
|
152
|
+
this.bitcoinNetwork = bitcoinNetwork;
|
|
153
|
+
|
|
149
154
|
this.logger = getLogger("EVMChainInterface("+this.evmChainId+"): ");
|
|
150
155
|
|
|
151
156
|
this.Fees = evmFeeEstimator;
|
|
@@ -358,4 +363,13 @@ export class EVMChainInterface<ChainId extends string = string> implements Chain
|
|
|
358
363
|
return new EVMSigner(signer, address);
|
|
359
364
|
}
|
|
360
365
|
|
|
366
|
+
async verifyNetwork(bitcoinNetwork: BitcoinNetwork): Promise<void> {
|
|
367
|
+
if(this.bitcoinNetwork!=null && bitcoinNetwork!==this.bitcoinNetwork)
|
|
368
|
+
throw new Error(`Network mismatch, the chain interface was not setup for ${BitcoinNetwork[bitcoinNetwork]}, chain interface network: ${BitcoinNetwork[this.bitcoinNetwork]}`);
|
|
369
|
+
|
|
370
|
+
const network = await this.provider.getNetwork();
|
|
371
|
+
if(network.chainId!==BigInt(this.evmChainId))
|
|
372
|
+
throw new Error(`Network mismatch, the underlying RPC provider isn't using the correct chainId, expected: ${this.evmChainId}, provider returned: ${network.chainId.toString(10)}`);
|
|
373
|
+
}
|
|
374
|
+
|
|
361
375
|
}
|
|
@@ -3,6 +3,7 @@ import {AbiCoder, hexlify, keccak256, ZeroHash} from "ethers";
|
|
|
3
3
|
import {EscrowDataStruct, EscrowDataStructOutput} from "./EscrowManagerTypechain";
|
|
4
4
|
import {IClaimHandler} from "./handlers/claim/ClaimHandlers";
|
|
5
5
|
import {TimelockRefundHandler} from "./handlers/refund/TimelockRefundHandler";
|
|
6
|
+
import {replaceBigInts} from "../../utils/Utils";
|
|
6
7
|
|
|
7
8
|
const FLAG_PAY_OUT: bigint = 0x01n;
|
|
8
9
|
const FLAG_PAY_IN: bigint = 0x02n;
|
|
@@ -513,6 +514,13 @@ export class EVMSwapData extends SwapData {
|
|
|
513
514
|
);
|
|
514
515
|
}
|
|
515
516
|
|
|
517
|
+
/**
|
|
518
|
+
* @inheritDoc
|
|
519
|
+
*/
|
|
520
|
+
getEscrowStruct(): any {
|
|
521
|
+
return replaceBigInts(this.toEscrowStruct());
|
|
522
|
+
}
|
|
523
|
+
|
|
516
524
|
}
|
|
517
525
|
|
|
518
526
|
SwapData.deserializers["evm"] = EVMSwapData;
|
package/src/utils/Utils.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
|
|
2
|
+
|
|
3
|
+
export type ReplaceBigInt<T> =
|
|
4
|
+
T extends bigint
|
|
5
|
+
? string
|
|
6
|
+
: T extends (infer U)[]
|
|
7
|
+
? ReplaceBigInt<U>[]
|
|
8
|
+
: T extends readonly (infer U)[]
|
|
9
|
+
? readonly ReplaceBigInt<U>[]
|
|
10
|
+
: T extends object
|
|
11
|
+
? { [K in keyof T]: ReplaceBigInt<T[K]> }
|
|
12
|
+
: T;
|
|
13
|
+
|
|
2
14
|
/**
|
|
3
15
|
* Logger interface used across EVM modules.
|
|
4
16
|
*
|
|
@@ -159,3 +171,23 @@ export const allowedEthersErrorNumbers: Set<number> = new Set([
|
|
|
159
171
|
export const allowedEthersErrorMessages: Set<string> = new Set([
|
|
160
172
|
"already known"
|
|
161
173
|
]);
|
|
174
|
+
|
|
175
|
+
export function replaceBigInts<T>(obj: T): ReplaceBigInt<T> {
|
|
176
|
+
const replace = (value: any): any => {
|
|
177
|
+
if(typeof(value)==="bigint") return "0x"+value.toString(16);
|
|
178
|
+
if(value==null || typeof(value)!=="object") return value;
|
|
179
|
+
|
|
180
|
+
if(Array.isArray(value)) {
|
|
181
|
+
return value.map(replace);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const mapped: any = {};
|
|
185
|
+
for(const key of Object.keys(value)) {
|
|
186
|
+
mapped[key] = replace(value[key]);
|
|
187
|
+
}
|
|
188
|
+
return mapped;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
return replace(obj);
|
|
192
|
+
}
|
|
193
|
+
|