@atomiqlabs/chain-evm 1.0.0-dev.22 → 1.0.0-dev.28
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/citrea/CitreaBtcRelay.d.ts +21 -0
- package/dist/chains/citrea/CitreaBtcRelay.js +43 -0
- package/dist/chains/citrea/CitreaChainType.d.ts +4 -4
- package/dist/chains/citrea/CitreaFees.d.ts +29 -0
- package/dist/chains/citrea/CitreaFees.js +67 -0
- package/dist/chains/citrea/CitreaInitializer.d.ts +3 -3
- package/dist/chains/citrea/CitreaInitializer.js +15 -8
- package/dist/chains/citrea/CitreaSpvVaultContract.d.ts +15 -0
- package/dist/chains/citrea/CitreaSpvVaultContract.js +75 -0
- package/dist/chains/citrea/CitreaSwapContract.d.ts +22 -0
- package/dist/chains/citrea/CitreaSwapContract.js +96 -0
- package/dist/chains/citrea/CitreaTokens.d.ts +9 -0
- package/dist/chains/citrea/CitreaTokens.js +20 -0
- package/dist/evm/btcrelay/EVMBtcRelay.d.ts +8 -1
- package/dist/evm/btcrelay/EVMBtcRelay.js +15 -11
- package/dist/evm/chain/EVMChainInterface.d.ts +6 -6
- package/dist/evm/chain/EVMChainInterface.js +1 -2
- package/dist/evm/chain/modules/EVMAddresses.d.ts +1 -0
- package/dist/evm/chain/modules/EVMAddresses.js +5 -0
- package/dist/evm/chain/modules/EVMFees.d.ts +8 -7
- package/dist/evm/chain/modules/EVMFees.js +3 -3
- package/dist/evm/chain/modules/EVMTokens.d.ts +2 -0
- package/dist/evm/chain/modules/EVMTokens.js +10 -2
- package/dist/evm/spv_swap/EVMSpvVaultContract.d.ts +17 -3
- package/dist/evm/spv_swap/EVMSpvVaultContract.js +83 -13
- package/dist/evm/spv_swap/EVMSpvVaultData.d.ts +1 -0
- package/dist/evm/spv_swap/EVMSpvVaultData.js +21 -0
- package/dist/evm/swaps/EVMSwapContract.d.ts +4 -4
- package/dist/evm/swaps/EVMSwapContract.js +4 -4
- package/dist/evm/swaps/modules/EVMLpVault.js +2 -2
- package/dist/evm/swaps/modules/EVMSwapClaim.d.ts +1 -0
- package/dist/evm/swaps/modules/EVMSwapClaim.js +40 -4
- package/dist/evm/swaps/modules/EVMSwapInit.d.ts +3 -3
- package/dist/evm/swaps/modules/EVMSwapInit.js +43 -9
- package/dist/evm/swaps/modules/EVMSwapRefund.d.ts +2 -2
- package/dist/evm/swaps/modules/EVMSwapRefund.js +42 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +2 -2
- package/src/chains/citrea/CitreaBtcRelay.ts +58 -0
- package/src/chains/citrea/CitreaChainType.ts +6 -6
- package/src/chains/citrea/CitreaFees.ts +77 -0
- package/src/chains/citrea/CitreaInitializer.ts +17 -6
- package/src/chains/citrea/CitreaSpvVaultContract.ts +76 -0
- package/src/chains/citrea/CitreaSwapContract.ts +103 -0
- package/src/chains/citrea/CitreaTokens.ts +22 -0
- package/src/evm/btcrelay/EVMBtcRelay.ts +17 -12
- package/src/evm/chain/EVMChainInterface.ts +7 -8
- package/src/evm/chain/modules/EVMAddresses.ts +6 -0
- package/src/evm/chain/modules/EVMFees.ts +10 -11
- package/src/evm/chain/modules/EVMTokens.ts +13 -2
- package/src/evm/spv_swap/EVMSpvVaultContract.ts +84 -14
- package/src/evm/spv_swap/EVMSpvVaultData.ts +24 -1
- package/src/evm/swaps/EVMSwapContract.ts +4 -4
- package/src/evm/swaps/modules/EVMLpVault.ts +2 -2
- package/src/evm/swaps/modules/EVMSwapClaim.ts +36 -4
- package/src/evm/swaps/modules/EVMSwapInit.ts +44 -10
- package/src/evm/swaps/modules/EVMSwapRefund.ts +38 -7
- package/src/index.ts +1 -0
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.EVMAddresses = void 0;
|
|
4
4
|
const EVMModule_1 = require("../EVMModule");
|
|
5
5
|
const ethers_1 = require("ethers");
|
|
6
|
+
const lib_esm_1 = require("ethers/lib.esm");
|
|
6
7
|
class EVMAddresses extends EVMModule_1.EVMModule {
|
|
7
8
|
///////////////////
|
|
8
9
|
//// Address utils
|
|
@@ -22,5 +23,9 @@ class EVMAddresses extends EVMModule_1.EVMModule {
|
|
|
22
23
|
return false;
|
|
23
24
|
}
|
|
24
25
|
}
|
|
26
|
+
static randomAddress() {
|
|
27
|
+
const wallet = lib_esm_1.Wallet.createRandom();
|
|
28
|
+
return wallet.address;
|
|
29
|
+
}
|
|
25
30
|
}
|
|
26
31
|
exports.EVMAddresses = EVMAddresses;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { JsonRpcApiProvider, TransactionRequest } from "ethers";
|
|
2
2
|
export type EVMFeeRate = {
|
|
3
3
|
maxFeePerGas: bigint;
|
|
4
4
|
maxPriorityFee: bigint;
|
|
5
5
|
};
|
|
6
6
|
export declare class EVMFees {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
protected MAX_FEE_AGE: number;
|
|
8
|
+
protected readonly logger: import("../../../utils/Utils").LoggerType;
|
|
9
|
+
protected readonly provider: JsonRpcApiProvider;
|
|
10
|
+
protected readonly maxFeeRatePerGas: bigint;
|
|
11
|
+
protected readonly priorityFee: bigint;
|
|
12
|
+
protected readonly feeMultiplierPPM: bigint;
|
|
12
13
|
private blockFeeCache;
|
|
13
|
-
constructor(provider:
|
|
14
|
+
constructor(provider: JsonRpcApiProvider, maxFeeRatePerGas?: bigint, priorityFee?: bigint, feeMultiplier?: number);
|
|
14
15
|
/**
|
|
15
16
|
* Gets evm fee rate
|
|
16
17
|
*
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EVMFees = void 0;
|
|
4
4
|
const Utils_1 = require("../../../utils/Utils");
|
|
5
|
-
const MAX_FEE_AGE = 5000;
|
|
6
5
|
class EVMFees {
|
|
7
6
|
constructor(provider, maxFeeRatePerGas = 500n * 1000000000n, priorityFee = 1n * 1000000000n, feeMultiplier = 1.25) {
|
|
7
|
+
this.MAX_FEE_AGE = 5000;
|
|
8
8
|
this.logger = (0, Utils_1.getLogger)("EVMFees: ");
|
|
9
9
|
this.blockFeeCache = null;
|
|
10
10
|
this.provider = provider;
|
|
@@ -30,7 +30,7 @@ class EVMFees {
|
|
|
30
30
|
* @private
|
|
31
31
|
*/
|
|
32
32
|
async getFeeRate() {
|
|
33
|
-
if (this.blockFeeCache == null || Date.now() - this.blockFeeCache.timestamp > MAX_FEE_AGE) {
|
|
33
|
+
if (this.blockFeeCache == null || Date.now() - this.blockFeeCache.timestamp > this.MAX_FEE_AGE) {
|
|
34
34
|
let obj = {
|
|
35
35
|
timestamp: Date.now(),
|
|
36
36
|
feeRate: null
|
|
@@ -67,7 +67,7 @@ class EVMFees {
|
|
|
67
67
|
const [baseFee, priorityFee] = feeRate.split(",");
|
|
68
68
|
tx.maxFeePerGas = BigInt(baseFee) + BigInt(priorityFee);
|
|
69
69
|
tx.maxPriorityFeePerGas = BigInt(priorityFee);
|
|
70
|
-
tx.gasLimit = BigInt(gas)
|
|
70
|
+
tx.gasLimit = BigInt(gas);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
exports.EVMFees = EVMFees;
|
|
@@ -46,4 +46,6 @@ export declare class EVMTokens extends EVMModule<any> {
|
|
|
46
46
|
* @private
|
|
47
47
|
*/
|
|
48
48
|
Approve(signer: string, token: string, amount: bigint, spender: string, feeRate?: string): Promise<TransactionRequest>;
|
|
49
|
+
getApproveFee(feeRate?: string): Promise<bigint>;
|
|
50
|
+
getTransferFee(feeRate?: string): Promise<bigint>;
|
|
49
51
|
}
|
|
@@ -96,10 +96,18 @@ class EVMTokens extends EVMModule_1.EVMModule {
|
|
|
96
96
|
" token: " + token.toString() + " amount: " + amount.toString(10));
|
|
97
97
|
return tx;
|
|
98
98
|
}
|
|
99
|
+
async getApproveFee(feeRate) {
|
|
100
|
+
feeRate ?? (feeRate = await this.root.Fees.getFeeRate());
|
|
101
|
+
return EVMFees_1.EVMFees.getGasFee(EVMTokens.GasCosts.APPROVE, feeRate);
|
|
102
|
+
}
|
|
103
|
+
async getTransferFee(feeRate) {
|
|
104
|
+
feeRate ?? (feeRate = await this.root.Fees.getFeeRate());
|
|
105
|
+
return EVMFees_1.EVMFees.getGasFee(EVMTokens.GasCosts.APPROVE, feeRate);
|
|
106
|
+
}
|
|
99
107
|
}
|
|
100
108
|
exports.EVMTokens = EVMTokens;
|
|
101
109
|
EVMTokens.ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
102
110
|
EVMTokens.GasCosts = {
|
|
103
|
-
TRANSFER: 80000,
|
|
104
|
-
APPROVE: 80000
|
|
111
|
+
TRANSFER: 80000 + 21000,
|
|
112
|
+
APPROVE: 80000 + 21000
|
|
105
113
|
};
|
|
@@ -15,7 +15,19 @@ import { EVMBtcStoredHeader } from "../btcrelay/headers/EVMBtcStoredHeader";
|
|
|
15
15
|
export declare function packOwnerAndVaultId(owner: string, vaultId: bigint): string;
|
|
16
16
|
export declare function unpackOwnerAndVaultId(data: string): [string, bigint];
|
|
17
17
|
export declare class EVMSpvVaultContract<ChainId extends string> extends EVMContractBase<SpvVaultManager> implements SpvVaultContract<EVMTx, EVMSigner, ChainId, EVMSpvVaultData, EVMSpvWithdrawalData> {
|
|
18
|
-
|
|
18
|
+
static readonly GasCosts: {
|
|
19
|
+
DEPOSIT_BASE: number;
|
|
20
|
+
DEPOSIT_ERC20: number;
|
|
21
|
+
OPEN: number;
|
|
22
|
+
CLAIM_BASE: number;
|
|
23
|
+
CLAIM_NATIVE_TRANSFER: number;
|
|
24
|
+
CLAIM_ERC20_TRANSFER: number;
|
|
25
|
+
CLAIM_EXECUTION_SCHEDULE: number;
|
|
26
|
+
FRONT_BASE: number;
|
|
27
|
+
FRONT_NATIVE_TRANSFER: number;
|
|
28
|
+
FRONT_ERC20_TRANSFER: number;
|
|
29
|
+
FRONT_EXECUTION_SCHEDULE: number;
|
|
30
|
+
};
|
|
19
31
|
readonly chainId: ChainId;
|
|
20
32
|
readonly btcRelay: EVMBtcRelay<any>;
|
|
21
33
|
readonly bitcoinRpc: BitcoinRpc<any>;
|
|
@@ -59,6 +71,8 @@ export declare class EVMSpvVaultContract<ChainId extends string> extends EVMCont
|
|
|
59
71
|
txsDeposit(signer: string, vault: EVMSpvVaultData, rawAmounts: bigint[], feeRate?: string): Promise<EVMTx[]>;
|
|
60
72
|
txsFrontLiquidity(signer: string, vault: EVMSpvVaultData, realWithdrawalTx: EVMSpvWithdrawalData, withdrawSequence: number, feeRate?: string): Promise<EVMTx[]>;
|
|
61
73
|
txsOpen(signer: string, vault: EVMSpvVaultData, feeRate?: string): Promise<EVMTx[]>;
|
|
62
|
-
|
|
63
|
-
|
|
74
|
+
getClaimGas(signer: string, vault: EVMSpvVaultData, data?: EVMSpvWithdrawalData): number;
|
|
75
|
+
getFrontGas(signer: string, vault: EVMSpvVaultData, data?: EVMSpvWithdrawalData): number;
|
|
76
|
+
getClaimFee(signer: string, vault: EVMSpvVaultData, withdrawalData: EVMSpvWithdrawalData, feeRate?: string): Promise<bigint>;
|
|
77
|
+
getFrontFee(signer: string, vault?: EVMSpvVaultData, withdrawalData?: EVMSpvWithdrawalData, feeRate?: string): Promise<bigint>;
|
|
64
78
|
}
|
|
@@ -49,14 +49,25 @@ class EVMSpvVaultContract extends EVMContractBase_1.EVMContractBase {
|
|
|
49
49
|
return tx;
|
|
50
50
|
}
|
|
51
51
|
async Deposit(signer, vault, rawAmounts, feeRate) {
|
|
52
|
+
let totalGas = EVMSpvVaultContract.GasCosts.DEPOSIT_BASE;
|
|
52
53
|
let value = 0n;
|
|
53
|
-
if (vault.token0.token.toLowerCase() === this.Chain.getNativeCurrencyAddress().toLowerCase())
|
|
54
|
+
if (vault.token0.token.toLowerCase() === this.Chain.getNativeCurrencyAddress().toLowerCase()) {
|
|
54
55
|
value += rawAmounts[0] * vault.token0.multiplier;
|
|
55
|
-
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
if (rawAmounts[0] > 0n)
|
|
59
|
+
totalGas += EVMSpvVaultContract.GasCosts.DEPOSIT_ERC20;
|
|
60
|
+
}
|
|
61
|
+
if (vault.token1.token.toLowerCase() === this.Chain.getNativeCurrencyAddress().toLowerCase()) {
|
|
56
62
|
value += (rawAmounts[1] ?? 0n) * vault.token1.multiplier;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
if (rawAmounts[1] != null && rawAmounts[1] > 0n && vault.token0.token.toLowerCase() !== vault.token1.token.toLowerCase())
|
|
66
|
+
totalGas += EVMSpvVaultContract.GasCosts.DEPOSIT_ERC20;
|
|
67
|
+
}
|
|
57
68
|
const tx = await this.contract.deposit.populateTransaction(vault.owner, vault.vaultId, vault.getVaultParamsStruct(), rawAmounts[0], rawAmounts[1] ?? 0n, { value });
|
|
58
69
|
tx.from = signer;
|
|
59
|
-
EVMFees_1.EVMFees.applyFeeRate(tx,
|
|
70
|
+
EVMFees_1.EVMFees.applyFeeRate(tx, totalGas, feeRate);
|
|
60
71
|
return tx;
|
|
61
72
|
}
|
|
62
73
|
async Front(signer, vault, data, withdrawalSequence, feeRate) {
|
|
@@ -68,13 +79,13 @@ class EVMSpvVaultContract extends EVMContractBase_1.EVMContractBase {
|
|
|
68
79
|
value += (frontingAmount[1] ?? 0n) * vault.token1.multiplier;
|
|
69
80
|
const tx = await this.contract.front.populateTransaction(vault.owner, vault.vaultId, vault.getVaultParamsStruct(), withdrawalSequence, data.getTxHash(), data.serializeToStruct(), { value });
|
|
70
81
|
tx.from = signer;
|
|
71
|
-
EVMFees_1.EVMFees.applyFeeRate(tx,
|
|
82
|
+
EVMFees_1.EVMFees.applyFeeRate(tx, this.getFrontGas(signer, vault, data), feeRate);
|
|
72
83
|
return tx;
|
|
73
84
|
}
|
|
74
85
|
async Claim(signer, vault, data, blockheader, merkle, position, feeRate) {
|
|
75
86
|
const tx = await this.contract.claim.populateTransaction(vault.owner, vault.vaultId, vault.getVaultParamsStruct(), "0x" + data.btcTx.hex, blockheader.serializeToStruct(), merkle, position);
|
|
76
87
|
tx.from = signer;
|
|
77
|
-
EVMFees_1.EVMFees.applyFeeRate(tx,
|
|
88
|
+
EVMFees_1.EVMFees.applyFeeRate(tx, this.getClaimGas(signer, vault, data), feeRate);
|
|
78
89
|
return tx;
|
|
79
90
|
}
|
|
80
91
|
async checkWithdrawalTx(tx) {
|
|
@@ -392,19 +403,78 @@ class EVMSpvVaultContract extends EVMContractBase_1.EVMContractBase {
|
|
|
392
403
|
" vaultId: " + vault.getVaultId().toString(10));
|
|
393
404
|
return [tx];
|
|
394
405
|
}
|
|
395
|
-
|
|
406
|
+
getClaimGas(signer, vault, data) {
|
|
407
|
+
let totalGas = EVMSpvVaultContract.GasCosts.CLAIM_BASE;
|
|
408
|
+
if (data == null || (data.rawAmounts[0] != null && data.rawAmounts[0] > 0n)) {
|
|
409
|
+
const transferFee = vault.token0.token.toLowerCase() === this.Chain.getNativeCurrencyAddress() ?
|
|
410
|
+
EVMSpvVaultContract.GasCosts.CLAIM_NATIVE_TRANSFER : EVMSpvVaultContract.GasCosts.CLAIM_ERC20_TRANSFER;
|
|
411
|
+
totalGas += transferFee;
|
|
412
|
+
if (data == null || data.frontingFeeRate > 0n)
|
|
413
|
+
totalGas += transferFee; //Also needs to pay out to fronter
|
|
414
|
+
if (data == null || (data.callerFeeRate > 0n && !data.isRecipient(signer)))
|
|
415
|
+
totalGas += transferFee; //Also needs to pay out to caller
|
|
416
|
+
}
|
|
417
|
+
if (data == null || (data.rawAmounts[1] != null && data.rawAmounts[1] > 0n)) {
|
|
418
|
+
const transferFee = vault.token1.token.toLowerCase() === this.Chain.getNativeCurrencyAddress() ?
|
|
419
|
+
EVMSpvVaultContract.GasCosts.CLAIM_NATIVE_TRANSFER : EVMSpvVaultContract.GasCosts.CLAIM_ERC20_TRANSFER;
|
|
420
|
+
totalGas += transferFee;
|
|
421
|
+
if (data == null || data.frontingFeeRate > 0n)
|
|
422
|
+
totalGas += transferFee; //Also needs to pay out to fronter
|
|
423
|
+
if (data == null || (data.callerFeeRate > 0n && !data.isRecipient(signer)))
|
|
424
|
+
totalGas += transferFee; //Also needs to pay out to caller
|
|
425
|
+
}
|
|
426
|
+
if (data == null || (data.executionHash != null && data.executionHash !== ethers_1.ZeroHash))
|
|
427
|
+
totalGas += EVMSpvVaultContract.GasCosts.CLAIM_EXECUTION_SCHEDULE;
|
|
428
|
+
return totalGas;
|
|
429
|
+
}
|
|
430
|
+
getFrontGas(signer, vault, data) {
|
|
431
|
+
let totalGas = EVMSpvVaultContract.GasCosts.FRONT_BASE;
|
|
432
|
+
if (data == null || (data.rawAmounts[0] != null && data.rawAmounts[0] > 0n)) {
|
|
433
|
+
totalGas += vault.token0.token.toLowerCase() === this.Chain.getNativeCurrencyAddress() ?
|
|
434
|
+
EVMSpvVaultContract.GasCosts.FRONT_NATIVE_TRANSFER : EVMSpvVaultContract.GasCosts.FRONT_ERC20_TRANSFER;
|
|
435
|
+
}
|
|
436
|
+
if (data == null || (data.rawAmounts[1] != null && data.rawAmounts[1] > 0n)) {
|
|
437
|
+
totalGas += vault.token1.token.toLowerCase() === this.Chain.getNativeCurrencyAddress() ?
|
|
438
|
+
EVMSpvVaultContract.GasCosts.FRONT_NATIVE_TRANSFER : EVMSpvVaultContract.GasCosts.FRONT_ERC20_TRANSFER;
|
|
439
|
+
}
|
|
440
|
+
if (data == null || (data.executionHash != null && data.executionHash !== ethers_1.ZeroHash))
|
|
441
|
+
totalGas += EVMSpvVaultContract.GasCosts.FRONT_EXECUTION_SCHEDULE;
|
|
442
|
+
return totalGas;
|
|
443
|
+
}
|
|
444
|
+
async getClaimFee(signer, vault, withdrawalData, feeRate) {
|
|
396
445
|
feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
|
|
397
|
-
return EVMFees_1.EVMFees.getGasFee(
|
|
446
|
+
return EVMFees_1.EVMFees.getGasFee(this.getClaimGas(signer, vault, withdrawalData), feeRate);
|
|
398
447
|
}
|
|
399
|
-
async getFrontFee(signer, withdrawalData, feeRate) {
|
|
448
|
+
async getFrontFee(signer, vault, withdrawalData, feeRate) {
|
|
449
|
+
vault ?? (vault = EVMSpvVaultData_1.EVMSpvVaultData.randomVault());
|
|
400
450
|
feeRate ?? (feeRate = await this.Chain.Fees.getFeeRate());
|
|
401
|
-
|
|
451
|
+
let totalFee = EVMFees_1.EVMFees.getGasFee(this.getFrontGas(signer, vault, withdrawalData), feeRate);
|
|
452
|
+
if (withdrawalData == null || (withdrawalData.rawAmounts[0] != null && withdrawalData.rawAmounts[0] > 0n)) {
|
|
453
|
+
if (vault.token0.token.toLowerCase() !== this.Chain.getNativeCurrencyAddress().toLowerCase()) {
|
|
454
|
+
totalFee += await this.Chain.Tokens.getApproveFee(feeRate);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
if (withdrawalData == null || (withdrawalData.rawAmounts[1] != null && withdrawalData.rawAmounts[1] > 0n)) {
|
|
458
|
+
if (vault.token1.token.toLowerCase() !== this.Chain.getNativeCurrencyAddress().toLowerCase()) {
|
|
459
|
+
if (vault.token1.token.toLowerCase() !== vault.token0.token.toLowerCase() || withdrawalData == null || withdrawalData.rawAmounts[0] == null || withdrawalData.rawAmounts[0] === 0n) {
|
|
460
|
+
totalFee += await this.Chain.Tokens.getApproveFee(feeRate);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return totalFee;
|
|
402
465
|
}
|
|
403
466
|
}
|
|
404
467
|
exports.EVMSpvVaultContract = EVMSpvVaultContract;
|
|
405
468
|
EVMSpvVaultContract.GasCosts = {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
469
|
+
DEPOSIT_BASE: 15000 + 21000,
|
|
470
|
+
DEPOSIT_ERC20: 40000,
|
|
471
|
+
OPEN: 80000 + 21000,
|
|
472
|
+
CLAIM_BASE: 85000 + 21000,
|
|
473
|
+
CLAIM_NATIVE_TRANSFER: 7500,
|
|
474
|
+
CLAIM_ERC20_TRANSFER: 40000,
|
|
475
|
+
CLAIM_EXECUTION_SCHEDULE: 30000,
|
|
476
|
+
FRONT_BASE: 75000 + 21000,
|
|
477
|
+
FRONT_NATIVE_TRANSFER: 7500,
|
|
478
|
+
FRONT_ERC20_TRANSFER: 40000,
|
|
479
|
+
FRONT_EXECUTION_SCHEDULE: 30000
|
|
410
480
|
};
|
|
@@ -35,4 +35,5 @@ export declare class EVMSpvVaultData extends SpvVaultData<EVMSpvWithdrawalData>
|
|
|
35
35
|
updateState(withdrawalTxOrEvent: SpvVaultClaimEvent | SpvVaultCloseEvent | SpvVaultOpenEvent | SpvVaultDepositEvent | EVMSpvWithdrawalData): void;
|
|
36
36
|
getDepositCount(): number;
|
|
37
37
|
getVaultParamsStruct(): SpvVaultParametersStruct;
|
|
38
|
+
static randomVault(): EVMSpvVaultData;
|
|
38
39
|
}
|
|
@@ -6,6 +6,7 @@ const buffer_1 = require("buffer");
|
|
|
6
6
|
const EVMSpvWithdrawalData_1 = require("./EVMSpvWithdrawalData");
|
|
7
7
|
const ethers_1 = require("ethers");
|
|
8
8
|
const ethers_2 = require("ethers");
|
|
9
|
+
const EVMAddresses_1 = require("../chain/modules/EVMAddresses");
|
|
9
10
|
function getVaultParamsCommitment(vaultParams) {
|
|
10
11
|
return (0, ethers_2.keccak256)(ethers_2.AbiCoder.defaultAbiCoder().encode(["address", "address", "address", "uint192", "uint192", "uint256"], [vaultParams.btcRelayContract, vaultParams.token0, vaultParams.token1, vaultParams.token0Multiplier, vaultParams.token1Multiplier, vaultParams.confirmations]));
|
|
11
12
|
}
|
|
@@ -154,6 +155,26 @@ class EVMSpvVaultData extends base_1.SpvVaultData {
|
|
|
154
155
|
confirmations: this.confirmations
|
|
155
156
|
};
|
|
156
157
|
}
|
|
158
|
+
static randomVault() {
|
|
159
|
+
const spvVaultParams = {
|
|
160
|
+
btcRelayContract: EVMAddresses_1.EVMAddresses.randomAddress(),
|
|
161
|
+
token0: EVMAddresses_1.EVMAddresses.randomAddress(),
|
|
162
|
+
token1: EVMAddresses_1.EVMAddresses.randomAddress(),
|
|
163
|
+
token0Multiplier: 1n,
|
|
164
|
+
token1Multiplier: 1n,
|
|
165
|
+
confirmations: 3n,
|
|
166
|
+
};
|
|
167
|
+
return new EVMSpvVaultData(EVMAddresses_1.EVMAddresses.randomAddress(), 0n, {
|
|
168
|
+
spvVaultParametersCommitment: getVaultParamsCommitment(spvVaultParams),
|
|
169
|
+
utxoTxHash: (0, ethers_1.randomBytes)(32),
|
|
170
|
+
utxoVout: 0n,
|
|
171
|
+
openBlockheight: 0n,
|
|
172
|
+
withdrawCount: 0n,
|
|
173
|
+
depositCount: 0n,
|
|
174
|
+
token0Amount: 0n,
|
|
175
|
+
token1Amount: 0n
|
|
176
|
+
}, spvVaultParams);
|
|
177
|
+
}
|
|
157
178
|
}
|
|
158
179
|
exports.EVMSpvVaultData = EVMSpvVaultData;
|
|
159
180
|
base_1.SpvVaultData.deserializers["EVM"] = EVMSpvVaultData;
|
|
@@ -182,11 +182,11 @@ export declare class EVMSwapContract<ChainId extends string = string> extends EV
|
|
|
182
182
|
getClaimFeeRate(signer: string, swapData: EVMSwapData): Promise<string>;
|
|
183
183
|
getClaimFee(signer: string, swapData: EVMSwapData, feeRate?: string): Promise<bigint>;
|
|
184
184
|
/**
|
|
185
|
-
* Get the estimated
|
|
185
|
+
* Get the estimated fee of the commit transaction
|
|
186
186
|
*/
|
|
187
|
-
getCommitFee(swapData: EVMSwapData, feeRate?: string): Promise<bigint>;
|
|
187
|
+
getCommitFee(signer: string, swapData: EVMSwapData, feeRate?: string): Promise<bigint>;
|
|
188
188
|
/**
|
|
189
|
-
* Get the estimated
|
|
189
|
+
* Get the estimated transaction fee of the refund transaction
|
|
190
190
|
*/
|
|
191
|
-
getRefundFee(swapData: EVMSwapData, feeRate?: string): Promise<bigint>;
|
|
191
|
+
getRefundFee(signer: string, swapData: EVMSwapData, feeRate?: string): Promise<bigint>;
|
|
192
192
|
}
|
|
@@ -358,15 +358,15 @@ class EVMSwapContract extends EVMContractBase_1.EVMContractBase {
|
|
|
358
358
|
return this.Claim.getClaimFee(swapData, feeRate);
|
|
359
359
|
}
|
|
360
360
|
/**
|
|
361
|
-
* Get the estimated
|
|
361
|
+
* Get the estimated fee of the commit transaction
|
|
362
362
|
*/
|
|
363
|
-
getCommitFee(swapData, feeRate) {
|
|
363
|
+
getCommitFee(signer, swapData, feeRate) {
|
|
364
364
|
return this.Init.getInitFee(swapData, feeRate);
|
|
365
365
|
}
|
|
366
366
|
/**
|
|
367
|
-
* Get the estimated
|
|
367
|
+
* Get the estimated transaction fee of the refund transaction
|
|
368
368
|
*/
|
|
369
|
-
getRefundFee(swapData, feeRate) {
|
|
369
|
+
getRefundFee(signer, swapData, feeRate) {
|
|
370
370
|
return this.Refund.getRefundFee(swapData, feeRate);
|
|
371
371
|
}
|
|
372
372
|
}
|
|
@@ -46,6 +46,7 @@ export declare class EVMSwapClaim extends EVMSwapModule {
|
|
|
46
46
|
hex: string;
|
|
47
47
|
height: number;
|
|
48
48
|
}, requiredConfirmations: number, vout: number, commitedHeader?: EVMBtcStoredHeader, synchronizer?: RelaySynchronizer<EVMBtcStoredHeader, EVMTx, any>, feeRate?: string): Promise<EVMTx[] | null>;
|
|
49
|
+
getClaimGas(swapData: EVMSwapData): number;
|
|
49
50
|
/**
|
|
50
51
|
* Get the estimated starknet transaction fee of the claim transaction
|
|
51
52
|
*/
|
|
@@ -19,7 +19,7 @@ class EVMSwapClaim extends EVMSwapModule_1.EVMSwapModule {
|
|
|
19
19
|
//TODO: Claim with success action not supported yet!
|
|
20
20
|
const tx = await this.swapContract.claim.populateTransaction(swapData.toEscrowStruct(), witness);
|
|
21
21
|
tx.from = signer;
|
|
22
|
-
EVMFees_1.EVMFees.applyFeeRate(tx,
|
|
22
|
+
EVMFees_1.EVMFees.applyFeeRate(tx, this.getClaimGas(swapData) + (claimHandlerGas ?? 0), feeRate);
|
|
23
23
|
return tx;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
@@ -81,13 +81,46 @@ class EVMSwapClaim extends EVMSwapModule_1.EVMSwapModule {
|
|
|
81
81
|
const claimTx = await this.Claim(signer, swapData, witness, feeRate, claimHandler.getGas(swapData));
|
|
82
82
|
return [...initialTxns, claimTx];
|
|
83
83
|
}
|
|
84
|
+
getClaimGas(swapData) {
|
|
85
|
+
let totalGas = EVMSwapClaim.GasCosts.BASE;
|
|
86
|
+
if (swapData.reputation)
|
|
87
|
+
totalGas += EVMSwapClaim.GasCosts.REPUTATION;
|
|
88
|
+
if (swapData.isPayOut()) {
|
|
89
|
+
if (swapData.isToken(this.root.getNativeCurrencyAddress())) {
|
|
90
|
+
totalGas += EVMSwapClaim.GasCosts.NATIVE_TRANSFER;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
totalGas += EVMSwapClaim.GasCosts.ERC20_TRANSFER;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
totalGas += EVMSwapClaim.GasCosts.LP_VAULT_TRANSFER;
|
|
98
|
+
}
|
|
99
|
+
if (swapData.getClaimerBounty() > 0n) {
|
|
100
|
+
if (swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
101
|
+
totalGas += EVMSwapClaim.GasCosts.NATIVE_TRANSFER;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
totalGas += EVMSwapClaim.GasCosts.ERC20_TRANSFER;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (swapData.getSecurityDeposit() > swapData.getClaimerBounty()) {
|
|
108
|
+
if (swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
109
|
+
totalGas += EVMSwapClaim.GasCosts.NATIVE_TRANSFER;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
totalGas += EVMSwapClaim.GasCosts.ERC20_TRANSFER;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return totalGas;
|
|
116
|
+
}
|
|
84
117
|
/**
|
|
85
118
|
* Get the estimated starknet transaction fee of the claim transaction
|
|
86
119
|
*/
|
|
87
120
|
async getClaimFee(swapData, feeRate) {
|
|
88
121
|
feeRate ?? (feeRate = await this.root.Fees.getFeeRate());
|
|
89
122
|
//TODO: Claim with success action not supported yet!
|
|
90
|
-
let gasRequired =
|
|
123
|
+
let gasRequired = this.getClaimGas(swapData);
|
|
91
124
|
const claimHandler = this.contract.claimHandlersByAddress[swapData.claimHandler.toLowerCase()];
|
|
92
125
|
if (claimHandler != null)
|
|
93
126
|
gasRequired += claimHandler.getGas(swapData);
|
|
@@ -96,6 +129,9 @@ class EVMSwapClaim extends EVMSwapModule_1.EVMSwapModule {
|
|
|
96
129
|
}
|
|
97
130
|
exports.EVMSwapClaim = EVMSwapClaim;
|
|
98
131
|
EVMSwapClaim.GasCosts = {
|
|
99
|
-
|
|
100
|
-
|
|
132
|
+
BASE: 30000 + 21000,
|
|
133
|
+
ERC20_TRANSFER: 40000,
|
|
134
|
+
NATIVE_TRANSFER: 7500,
|
|
135
|
+
LP_VAULT_TRANSFER: 10000,
|
|
136
|
+
REPUTATION: 25000
|
|
101
137
|
};
|
|
@@ -80,9 +80,9 @@ export declare class EVMSwapInit extends EVMSwapModule {
|
|
|
80
80
|
* @param feeRate fee rate to use for the transaction
|
|
81
81
|
*/
|
|
82
82
|
txsInit(sender: string, swapData: EVMSwapData, timeout: string, prefix: string, signature: string, skipChecks?: boolean, feeRate?: string): Promise<EVMTx[]>;
|
|
83
|
+
private getInitGas;
|
|
83
84
|
/**
|
|
84
|
-
* Get the estimated
|
|
85
|
-
* and also deposit for ATAs
|
|
85
|
+
* Get the estimated fee of the init transaction
|
|
86
86
|
*/
|
|
87
|
-
getInitFee(swapData
|
|
87
|
+
getInitFee(swapData: EVMSwapData, feeRate?: string): Promise<bigint>;
|
|
88
88
|
}
|
|
@@ -39,15 +39,17 @@ class EVMSwapInit extends EVMSwapModule_1.EVMSwapModule {
|
|
|
39
39
|
*/
|
|
40
40
|
async Init(sender, swapData, timeout, signature, feeRate) {
|
|
41
41
|
let value = 0n;
|
|
42
|
-
if (swapData.
|
|
43
|
-
|
|
42
|
+
if (swapData.isPayIn()) {
|
|
43
|
+
if (swapData.isOfferer(sender) && swapData.isToken(this.root.getNativeCurrencyAddress()))
|
|
44
|
+
value += swapData.getAmount();
|
|
45
|
+
}
|
|
44
46
|
if (swapData.isDepositToken(this.root.getNativeCurrencyAddress()))
|
|
45
47
|
value += swapData.getTotalDeposit();
|
|
46
48
|
const tx = await this.swapContract.initialize.populateTransaction(swapData.toEscrowStruct(), signature, timeout, "0x" + (swapData.extraData ?? ""), {
|
|
47
49
|
value
|
|
48
50
|
});
|
|
49
51
|
tx.from = sender;
|
|
50
|
-
EVMFees_1.EVMFees.applyFeeRate(tx,
|
|
52
|
+
EVMFees_1.EVMFees.applyFeeRate(tx, this.getInitGas(swapData), feeRate);
|
|
51
53
|
return tx;
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
@@ -206,7 +208,7 @@ class EVMSwapInit extends EVMSwapModule_1.EVMSwapModule {
|
|
|
206
208
|
feeRate ?? (feeRate = await this.root.Fees.getFeeRate());
|
|
207
209
|
const txs = [];
|
|
208
210
|
const requiredApprovals = {};
|
|
209
|
-
if (swapData.
|
|
211
|
+
if (swapData.isPayIn() && swapData.isOfferer(sender)) {
|
|
210
212
|
if (!swapData.isToken(this.root.getNativeCurrencyAddress())) {
|
|
211
213
|
requiredApprovals[swapData.token.toLowerCase()] = swapData.amount;
|
|
212
214
|
}
|
|
@@ -225,17 +227,49 @@ class EVMSwapInit extends EVMSwapModule_1.EVMSwapModule {
|
|
|
225
227
|
" feerate: " + feeRate);
|
|
226
228
|
return txs;
|
|
227
229
|
}
|
|
230
|
+
getInitGas(swapData) {
|
|
231
|
+
let totalGas = EVMSwapInit.GasCosts.BASE;
|
|
232
|
+
if (swapData.isPayIn()) {
|
|
233
|
+
if (!swapData.isToken(this.root.getNativeCurrencyAddress())) {
|
|
234
|
+
totalGas += EVMSwapInit.GasCosts.ERC20_TRANSFER;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
totalGas += EVMSwapInit.GasCosts.LP_VAULT_TRANSFER;
|
|
239
|
+
}
|
|
240
|
+
if (swapData.getTotalDeposit() > 0) {
|
|
241
|
+
if (!swapData.isPayIn() || !swapData.isDepositToken(swapData.token)) {
|
|
242
|
+
if (!swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
243
|
+
totalGas += EVMSwapInit.GasCosts.ERC20_TRANSFER;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return totalGas;
|
|
248
|
+
}
|
|
228
249
|
/**
|
|
229
|
-
* Get the estimated
|
|
230
|
-
* and also deposit for ATAs
|
|
250
|
+
* Get the estimated fee of the init transaction
|
|
231
251
|
*/
|
|
232
252
|
async getInitFee(swapData, feeRate) {
|
|
233
253
|
feeRate ?? (feeRate = await this.root.Fees.getFeeRate());
|
|
234
|
-
|
|
254
|
+
let totalFee = EVMFees_1.EVMFees.getGasFee(this.getInitGas(swapData), feeRate);
|
|
255
|
+
if (swapData.isPayIn()) {
|
|
256
|
+
if (!swapData.isToken(this.root.getNativeCurrencyAddress())) {
|
|
257
|
+
totalFee += await this.root.Tokens.getApproveFee(feeRate);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (swapData.getTotalDeposit() > 0) {
|
|
261
|
+
if (!swapData.isPayIn() || !swapData.isDepositToken(swapData.token)) {
|
|
262
|
+
if (!swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
263
|
+
totalFee += await this.root.Tokens.getApproveFee(feeRate);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return totalFee;
|
|
235
268
|
}
|
|
236
269
|
}
|
|
237
270
|
exports.EVMSwapInit = EVMSwapInit;
|
|
238
271
|
EVMSwapInit.GasCosts = {
|
|
239
|
-
|
|
240
|
-
|
|
272
|
+
BASE: 45000 + 21000,
|
|
273
|
+
ERC20_TRANSFER: 40000,
|
|
274
|
+
LP_VAULT_TRANSFER: 10000
|
|
241
275
|
};
|
|
@@ -54,9 +54,9 @@ export declare class EVMSwapRefund extends EVMSwapModule {
|
|
|
54
54
|
* @param feeRate fee rate to be used for the transactions
|
|
55
55
|
*/
|
|
56
56
|
txsRefundWithAuthorization(signer: string, swapData: EVMSwapData, timeout: string, prefix: string, signature: string, check?: boolean, feeRate?: string): Promise<EVMTx[]>;
|
|
57
|
+
getRefundGas(swapData: EVMSwapData): number;
|
|
57
58
|
/**
|
|
58
|
-
* Get the estimated
|
|
59
|
-
* ATA needs to be initialized again (i.e. adding the ATA rent exempt lamports to the fee)
|
|
59
|
+
* Get the estimated transaction fee of the refund transaction
|
|
60
60
|
*/
|
|
61
61
|
getRefundFee(swapData: EVMSwapData, feeRate?: string): Promise<bigint>;
|
|
62
62
|
}
|
|
@@ -23,7 +23,7 @@ class EVMSwapRefund extends EVMSwapModule_1.EVMSwapModule {
|
|
|
23
23
|
async Refund(signer, swapData, witness, feeRate, handlerGas) {
|
|
24
24
|
const tx = await this.swapContract.refund.populateTransaction(swapData.toEscrowStruct(), witness);
|
|
25
25
|
tx.from = signer;
|
|
26
|
-
EVMFees_1.EVMFees.applyFeeRate(tx, (swapData
|
|
26
|
+
EVMFees_1.EVMFees.applyFeeRate(tx, this.getRefundGas(swapData) + (handlerGas ?? 0), feeRate);
|
|
27
27
|
return tx;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
@@ -39,7 +39,7 @@ class EVMSwapRefund extends EVMSwapModule_1.EVMSwapModule {
|
|
|
39
39
|
async RefundWithSignature(sender, swapData, timeout, signature, feeRate) {
|
|
40
40
|
const tx = await this.swapContract.cooperativeRefund.populateTransaction(swapData.toEscrowStruct(), signature, BigInt(timeout));
|
|
41
41
|
tx.from = sender;
|
|
42
|
-
EVMFees_1.EVMFees.applyFeeRate(tx, swapData
|
|
42
|
+
EVMFees_1.EVMFees.applyFeeRate(tx, this.getRefundGas(swapData), feeRate);
|
|
43
43
|
return tx;
|
|
44
44
|
}
|
|
45
45
|
async signSwapRefund(signer, swapData, authorizationTimeout) {
|
|
@@ -116,17 +116,52 @@ class EVMSwapRefund extends EVMSwapModule_1.EVMSwapModule {
|
|
|
116
116
|
" auth expiry: " + timeout + " signature: " + signature);
|
|
117
117
|
return [tx];
|
|
118
118
|
}
|
|
119
|
+
getRefundGas(swapData) {
|
|
120
|
+
let totalGas = EVMSwapRefund.GasCosts.BASE;
|
|
121
|
+
if (swapData.reputation)
|
|
122
|
+
totalGas += EVMSwapRefund.GasCosts.REPUTATION;
|
|
123
|
+
if (swapData.isPayIn()) {
|
|
124
|
+
if (swapData.isToken(this.root.getNativeCurrencyAddress())) {
|
|
125
|
+
totalGas += EVMSwapRefund.GasCosts.NATIVE_TRANSFER;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
totalGas += EVMSwapRefund.GasCosts.ERC20_TRANSFER;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
totalGas += EVMSwapRefund.GasCosts.LP_VAULT_TRANSFER;
|
|
133
|
+
}
|
|
134
|
+
if (swapData.getSecurityDeposit() > 0n) {
|
|
135
|
+
if (swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
136
|
+
totalGas += EVMSwapRefund.GasCosts.NATIVE_TRANSFER;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
totalGas += EVMSwapRefund.GasCosts.ERC20_TRANSFER;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (swapData.getClaimerBounty() > swapData.getSecurityDeposit()) {
|
|
143
|
+
if (swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
144
|
+
totalGas += EVMSwapRefund.GasCosts.NATIVE_TRANSFER;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
totalGas += EVMSwapRefund.GasCosts.ERC20_TRANSFER;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return totalGas;
|
|
151
|
+
}
|
|
119
152
|
/**
|
|
120
|
-
* Get the estimated
|
|
121
|
-
* ATA needs to be initialized again (i.e. adding the ATA rent exempt lamports to the fee)
|
|
153
|
+
* Get the estimated transaction fee of the refund transaction
|
|
122
154
|
*/
|
|
123
155
|
async getRefundFee(swapData, feeRate) {
|
|
124
156
|
feeRate ?? (feeRate = await this.root.Fees.getFeeRate());
|
|
125
|
-
return EVMFees_1.EVMFees.getGasFee(swapData
|
|
157
|
+
return EVMFees_1.EVMFees.getGasFee(this.getRefundGas(swapData), feeRate);
|
|
126
158
|
}
|
|
127
159
|
}
|
|
128
160
|
exports.EVMSwapRefund = EVMSwapRefund;
|
|
129
161
|
EVMSwapRefund.GasCosts = {
|
|
130
|
-
|
|
131
|
-
|
|
162
|
+
BASE: 35000 + 21000,
|
|
163
|
+
ERC20_TRANSFER: 40000,
|
|
164
|
+
NATIVE_TRANSFER: 7500,
|
|
165
|
+
LP_VAULT_TRANSFER: 10000,
|
|
166
|
+
REPUTATION: 25000
|
|
132
167
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -35,3 +35,4 @@ export * from "./evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler";
|
|
|
35
35
|
export * from "./evm/wallet/EVMSigner";
|
|
36
36
|
export * from "./chains/citrea/CitreaInitializer";
|
|
37
37
|
export * from "./chains/citrea/CitreaChainType";
|
|
38
|
+
export * from "./chains/citrea/CitreaFees";
|
package/dist/index.js
CHANGED
|
@@ -51,3 +51,4 @@ __exportStar(require("./evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHan
|
|
|
51
51
|
__exportStar(require("./evm/wallet/EVMSigner"), exports);
|
|
52
52
|
__exportStar(require("./chains/citrea/CitreaInitializer"), exports);
|
|
53
53
|
__exportStar(require("./chains/citrea/CitreaChainType"), exports);
|
|
54
|
+
__exportStar(require("./chains/citrea/CitreaFees"), exports);
|