@atomiqlabs/chain-evm 2.1.11 → 2.1.14
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 +75 -0
- package/dist/chains/EVMOptions.d.ts +66 -0
- package/dist/chains/EVMOptions.js +2 -0
- package/dist/chains/alpen/AlpenInitializer.d.ts +3 -30
- package/dist/chains/alpen/AlpenInitializer.js +3 -3
- package/dist/chains/botanix/BotanixInitializer.d.ts +3 -30
- package/dist/chains/botanix/BotanixInitializer.js +3 -3
- package/dist/chains/citrea/CitreaBtcRelay.d.ts +5 -0
- package/dist/chains/citrea/CitreaBtcRelay.js +7 -2
- package/dist/chains/citrea/CitreaFees.d.ts +3 -5
- package/dist/chains/citrea/CitreaFees.js +3 -5
- package/dist/chains/citrea/CitreaInitializer.d.ts +3 -29
- package/dist/chains/citrea/CitreaInitializer.js +3 -3
- package/dist/chains/citrea/CitreaSpvVaultContract.d.ts +5 -0
- package/dist/chains/citrea/CitreaSpvVaultContract.js +7 -2
- package/dist/chains/citrea/CitreaSwapContract.d.ts +7 -2
- package/dist/chains/citrea/CitreaSwapContract.js +10 -5
- package/dist/chains/citrea/CitreaTokens.d.ts +5 -0
- package/dist/chains/citrea/CitreaTokens.js +5 -0
- package/dist/chains/goat/GoatInitializer.d.ts +3 -30
- package/dist/chains/goat/GoatInitializer.js +3 -3
- package/dist/evm/btcrelay/EVMBtcRelay.d.ts +41 -10
- package/dist/evm/btcrelay/EVMBtcRelay.js +50 -18
- package/dist/evm/btcrelay/headers/EVMBtcHeader.d.ts +53 -7
- package/dist/evm/btcrelay/headers/EVMBtcHeader.js +43 -5
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.d.ts +53 -8
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.js +41 -1
- package/dist/evm/chain/EVMChainInterface.d.ts +57 -2
- package/dist/evm/chain/EVMChainInterface.js +7 -7
- package/dist/evm/chain/EVMModule.d.ts +5 -0
- package/dist/evm/chain/EVMModule.js +6 -1
- package/dist/evm/chain/modules/EVMBlocks.d.ts +7 -0
- package/dist/evm/chain/modules/EVMBlocks.js +2 -0
- package/dist/evm/chain/modules/EVMEvents.js +19 -19
- package/dist/evm/chain/modules/EVMFees.d.ts +41 -5
- package/dist/evm/chain/modules/EVMFees.js +24 -5
- package/dist/evm/chain/modules/EVMTokens.d.ts +1 -1
- package/dist/evm/chain/modules/EVMTokens.js +1 -1
- package/dist/evm/chain/modules/EVMTransactions.d.ts +20 -2
- package/dist/evm/chain/modules/EVMTransactions.js +11 -8
- package/dist/evm/contract/EVMContractBase.d.ts +28 -10
- package/dist/evm/contract/EVMContractBase.js +9 -18
- package/dist/evm/contract/EVMContractModule.d.ts +5 -0
- package/dist/evm/contract/EVMContractModule.js +5 -0
- package/dist/evm/contract/modules/EVMContractEvents.d.ts +7 -1
- package/dist/evm/contract/modules/EVMContractEvents.js +23 -3
- package/dist/evm/events/EVMChainEvents.d.ts +8 -0
- package/dist/evm/events/EVMChainEvents.js +8 -0
- package/dist/evm/events/EVMChainEventsBrowser.d.ts +87 -19
- package/dist/evm/events/EVMChainEventsBrowser.js +53 -18
- package/dist/evm/providers/JsonRpcProviderWithRetries.d.ts +9 -0
- package/dist/evm/providers/JsonRpcProviderWithRetries.js +9 -0
- package/dist/evm/providers/ReconnectingWebSocketProvider.d.ts +5 -0
- package/dist/evm/providers/ReconnectingWebSocketProvider.js +5 -0
- package/dist/evm/providers/WebSocketProviderWithRetries.d.ts +9 -0
- package/dist/evm/providers/WebSocketProviderWithRetries.js +9 -0
- package/dist/evm/spv_swap/EVMSpvVaultContract.d.ts +46 -21
- package/dist/evm/spv_swap/EVMSpvVaultContract.js +62 -22
- package/dist/evm/spv_swap/EVMSpvVaultData.d.ts +57 -2
- package/dist/evm/spv_swap/EVMSpvVaultData.js +57 -2
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.d.ts +12 -0
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.js +12 -0
- package/dist/evm/swaps/EVMSwapContract.d.ts +58 -13
- package/dist/evm/swaps/EVMSwapContract.js +81 -54
- package/dist/evm/swaps/EVMSwapData.d.ts +27 -6
- package/dist/evm/swaps/EVMSwapData.js +26 -0
- package/dist/evm/swaps/EVMSwapModule.d.ts +5 -0
- package/dist/evm/swaps/EVMSwapModule.js +5 -0
- package/dist/evm/swaps/handlers/IHandler.d.ts +5 -0
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.d.ts +15 -0
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.js +5 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +5 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +10 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +5 -0
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +15 -0
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +7 -2
- package/dist/evm/swaps/modules/EVMLpVault.d.ts +5 -0
- package/dist/evm/swaps/modules/EVMLpVault.js +9 -4
- package/dist/evm/swaps/modules/EVMSwapClaim.d.ts +7 -2
- package/dist/evm/swaps/modules/EVMSwapClaim.js +11 -6
- package/dist/evm/swaps/modules/EVMSwapInit.d.ts +10 -0
- package/dist/evm/swaps/modules/EVMSwapInit.js +11 -6
- package/dist/evm/swaps/modules/EVMSwapRefund.d.ts +5 -0
- package/dist/evm/swaps/modules/EVMSwapRefund.js +9 -4
- package/dist/evm/wallet/EVMBrowserSigner.d.ts +22 -2
- package/dist/evm/wallet/EVMBrowserSigner.js +40 -2
- package/dist/evm/wallet/EVMPersistentSigner.d.ts +13 -2
- package/dist/evm/wallet/EVMPersistentSigner.js +13 -1
- package/dist/evm/wallet/EVMSigner.d.ts +30 -1
- package/dist/evm/wallet/EVMSigner.js +34 -1
- package/dist/index.d.ts +71 -0
- package/dist/index.js +70 -0
- package/dist/node/index.d.ts +10 -0
- package/dist/node/index.js +15 -0
- package/dist/utils/Utils.d.ts +50 -0
- package/dist/utils/Utils.js +45 -0
- package/node/index.d.ts +1 -0
- package/node/index.js +3 -0
- package/package.json +4 -3
- package/src/chains/EVMOptions.ts +70 -0
- package/src/chains/alpen/AlpenInitializer.ts +5 -27
- package/src/chains/botanix/BotanixChainType.ts +5 -5
- package/src/chains/botanix/BotanixInitializer.ts +5 -27
- package/src/chains/citrea/CitreaBtcRelay.ts +8 -3
- package/src/chains/citrea/CitreaFees.ts +3 -6
- package/src/chains/citrea/CitreaInitializer.ts +5 -27
- package/src/chains/citrea/CitreaSpvVaultContract.ts +7 -2
- package/src/chains/citrea/CitreaSwapContract.ts +11 -6
- package/src/chains/citrea/CitreaTokens.ts +6 -1
- package/src/chains/goat/GoatChainType.ts +5 -5
- package/src/chains/goat/GoatInitializer.ts +3 -25
- package/src/evm/btcrelay/EVMBtcRelay.ts +54 -22
- package/src/evm/btcrelay/headers/EVMBtcHeader.ts +60 -13
- package/src/evm/btcrelay/headers/EVMBtcStoredHeader.ts +55 -10
- package/src/evm/chain/EVMChainInterface.ts +66 -14
- package/src/evm/chain/EVMModule.ts +6 -1
- package/src/evm/chain/modules/EVMBlocks.ts +7 -0
- package/src/evm/chain/modules/EVMEvents.ts +19 -19
- package/src/evm/chain/modules/EVMFees.ts +41 -5
- package/src/evm/chain/modules/EVMTokens.ts +1 -1
- package/src/evm/chain/modules/EVMTransactions.ts +27 -8
- package/src/evm/contract/EVMContractBase.ts +29 -24
- package/src/evm/contract/EVMContractModule.ts +5 -0
- package/src/evm/contract/modules/EVMContractEvents.ts +27 -8
- package/src/evm/events/EVMChainEvents.ts +8 -0
- package/src/evm/events/EVMChainEventsBrowser.ts +103 -29
- package/src/evm/providers/JsonRpcProviderWithRetries.ts +10 -1
- package/src/evm/providers/ReconnectingWebSocketProvider.ts +6 -1
- package/src/evm/providers/WebSocketProviderWithRetries.ts +10 -1
- package/src/evm/spv_swap/EVMSpvVaultContract.ts +73 -31
- package/src/evm/spv_swap/EVMSpvVaultData.ts +57 -2
- package/src/evm/spv_swap/EVMSpvWithdrawalData.ts +12 -0
- package/src/evm/swaps/EVMSwapContract.ts +108 -63
- package/src/evm/swaps/EVMSwapData.ts +27 -1
- package/src/evm/swaps/EVMSwapModule.ts +5 -0
- package/src/evm/swaps/handlers/IHandler.ts +5 -0
- package/src/evm/swaps/handlers/claim/ClaimHandlers.ts +15 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +5 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +10 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +5 -0
- package/src/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +17 -2
- package/src/evm/swaps/modules/EVMLpVault.ts +10 -5
- package/src/evm/swaps/modules/EVMSwapClaim.ts +12 -7
- package/src/evm/swaps/modules/EVMSwapInit.ts +17 -7
- package/src/evm/swaps/modules/EVMSwapRefund.ts +9 -4
- package/src/evm/wallet/EVMBrowserSigner.ts +44 -5
- package/src/evm/wallet/EVMPersistentSigner.ts +14 -2
- package/src/evm/wallet/EVMSigner.ts +37 -1
- package/src/index.ts +72 -0
- package/src/node/index.ts +10 -0
- package/src/utils/Utils.ts +50 -1
|
@@ -5,6 +5,11 @@ import {CitreaFees} from "./CitreaFees";
|
|
|
5
5
|
|
|
6
6
|
const logger = getLogger("CitreaBtcRelay: ");
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Citrea BTC relay wrapper with fee estimation that includes Citrea state-diff costs.
|
|
10
|
+
*
|
|
11
|
+
* @category Networks/Citrea
|
|
12
|
+
*/
|
|
8
13
|
export class CitreaBtcRelay<B extends BtcBlock> extends EVMBtcRelay<B> {
|
|
9
14
|
|
|
10
15
|
public static StateDiffSize = {
|
|
@@ -32,7 +37,7 @@ export class CitreaBtcRelay<B extends BtcBlock> extends EVMBtcRelay<B> {
|
|
|
32
37
|
|
|
33
38
|
const synchronizationFee = (BigInt(blockheightDelta) * await this.getFeePerBlock(feeRate))
|
|
34
39
|
+ CitreaFees.getGasFee(
|
|
35
|
-
EVMBtcRelay.
|
|
40
|
+
EVMBtcRelay._GasCosts.GAS_BASE_MAIN * numTxs,
|
|
36
41
|
feeRate,
|
|
37
42
|
CitreaBtcRelay.StateDiffSize.STATE_DIFF_BASE * numTxs
|
|
38
43
|
);
|
|
@@ -50,10 +55,10 @@ export class CitreaBtcRelay<B extends BtcBlock> extends EVMBtcRelay<B> {
|
|
|
50
55
|
public async getFeePerBlock(feeRate?: string): Promise<bigint> {
|
|
51
56
|
feeRate ??= await this.Chain.Fees.getFeeRate();
|
|
52
57
|
return CitreaFees.getGasFee(
|
|
53
|
-
EVMBtcRelay.
|
|
58
|
+
EVMBtcRelay._GasCosts.GAS_PER_BLOCKHEADER,
|
|
54
59
|
feeRate,
|
|
55
60
|
CitreaBtcRelay.StateDiffSize.STATE_DIFF_PER_BLOCKHEADER
|
|
56
61
|
);
|
|
57
62
|
}
|
|
58
63
|
|
|
59
|
-
}
|
|
64
|
+
}
|
|
@@ -6,10 +6,9 @@ import {getLogger} from "../../utils/Utils";
|
|
|
6
6
|
*/
|
|
7
7
|
export class CitreaFees extends EVMFees {
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
13
12
|
protected readonly logger = getLogger("CitreaFees: ");
|
|
14
13
|
|
|
15
14
|
private _blockFeeCache?: {
|
|
@@ -35,8 +34,6 @@ export class CitreaFees extends EVMFees {
|
|
|
35
34
|
|
|
36
35
|
/**
|
|
37
36
|
* Gets the gas price with caching, format: <gas price in Wei>;<transaction version: v1/v3>
|
|
38
|
-
*
|
|
39
|
-
* @private
|
|
40
37
|
*/
|
|
41
38
|
public async getFeeRate(): Promise<string> {
|
|
42
39
|
if(this._blockFeeCache==null || Date.now() - this._blockFeeCache.timestamp > this.MAX_FEE_AGE) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {BaseTokenType, BitcoinNetwork, BitcoinRpc, ChainData, ChainInitializer, ChainSwapType} from "@atomiqlabs/base";
|
|
2
|
-
import {
|
|
3
|
-
import {EVMChainInterface
|
|
2
|
+
import {JsonRpcProvider, WebSocketProvider} from "ethers";
|
|
3
|
+
import {EVMChainInterface} from "../../evm/chain/EVMChainInterface";
|
|
4
4
|
import {CitreaChainType} from "./CitreaChainType";
|
|
5
5
|
import {EVMChainEventsBrowser} from "../../evm/events/EVMChainEventsBrowser";
|
|
6
6
|
import {EVMSwapData} from "../../evm/swaps/EVMSwapData";
|
|
@@ -11,6 +11,7 @@ import {CitreaBtcRelay} from "./CitreaBtcRelay";
|
|
|
11
11
|
import {CitreaSwapContract} from "./CitreaSwapContract";
|
|
12
12
|
import {CitreaTokens} from "./CitreaTokens";
|
|
13
13
|
import {CitreaSpvVaultContract} from "./CitreaSpvVaultContract";
|
|
14
|
+
import {EVMOptions} from "../EVMOptions";
|
|
14
15
|
|
|
15
16
|
const CitreaChainIds = {
|
|
16
17
|
MAINNET: 4114,
|
|
@@ -75,7 +76,7 @@ export type CitreaAssetsType = BaseTokenType<"CBTC" | "WBTC" | "USDC">;
|
|
|
75
76
|
* Default Citrea token assets configuration
|
|
76
77
|
* @category Networks/Citrea
|
|
77
78
|
*/
|
|
78
|
-
|
|
79
|
+
const CitreaAssets: CitreaAssetsType = {
|
|
79
80
|
CBTC: {
|
|
80
81
|
address: "0x0000000000000000000000000000000000000000",
|
|
81
82
|
decimals: 18,
|
|
@@ -97,30 +98,7 @@ export const CitreaAssets: CitreaAssetsType = {
|
|
|
97
98
|
* Configuration options for initializing Citrea chain
|
|
98
99
|
* @category Networks/Citrea
|
|
99
100
|
*/
|
|
100
|
-
export type CitreaOptions =
|
|
101
|
-
rpcUrl: string | JsonRpcApiProvider,
|
|
102
|
-
retryPolicy?: EVMRetryPolicy,
|
|
103
|
-
chainType?: "MAINNET" | "TESTNET4",
|
|
104
|
-
|
|
105
|
-
swapContract?: string,
|
|
106
|
-
swapContractDeploymentHeight?: number,
|
|
107
|
-
btcRelayContract?: string,
|
|
108
|
-
btcRelayDeploymentHeight?: number,
|
|
109
|
-
spvVaultContract?: string,
|
|
110
|
-
spvVaultDeploymentHeight?: number,
|
|
111
|
-
handlerContracts?: {
|
|
112
|
-
refund?: {
|
|
113
|
-
timelock?: string
|
|
114
|
-
},
|
|
115
|
-
claim?: {
|
|
116
|
-
[type in ChainSwapType]?: string
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
fees?: CitreaFees,
|
|
121
|
-
|
|
122
|
-
evmConfig?: Partial<Omit<EVMConfiguration, "safeBlockTag" | "finalizedBlockTag" | "finalityCheckStrategy">>
|
|
123
|
-
}
|
|
101
|
+
export type CitreaOptions = EVMOptions<"MAINNET" | "TESTNET4", CitreaFees>;
|
|
124
102
|
|
|
125
103
|
/**
|
|
126
104
|
* Initialize Citrea chain integration
|
|
@@ -6,6 +6,11 @@ import {CitreaFees} from "./CitreaFees";
|
|
|
6
6
|
import {EVMAddresses} from "../../evm/chain/modules/EVMAddresses";
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Citrea SPV vault wrapper with fee estimation adjusted by expected state-diff size.
|
|
11
|
+
*
|
|
12
|
+
* @category Networks/Citrea
|
|
13
|
+
*/
|
|
9
14
|
export class CitreaSpvVaultContract extends EVMSpvVaultContract<"CITREA"> {
|
|
10
15
|
|
|
11
16
|
public static readonly StateDiffSize = {
|
|
@@ -30,7 +35,7 @@ export class CitreaSpvVaultContract extends EVMSpvVaultContract<"CITREA"> {
|
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
async getClaimFee(signer: string, vault?: EVMSpvVaultData, data?: EVMSpvWithdrawalData, feeRate?: string): Promise<bigint> {
|
|
33
|
-
vault ??= EVMSpvVaultData.
|
|
38
|
+
vault ??= EVMSpvVaultData._randomVault();
|
|
34
39
|
feeRate ??= await this.Chain.Fees.getFeeRate();
|
|
35
40
|
const tokenStateChanges: Set<string> = new Set();
|
|
36
41
|
|
|
@@ -56,7 +61,7 @@ export class CitreaSpvVaultContract extends EVMSpvVaultContract<"CITREA"> {
|
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
async getFrontFee(signer: string, vault?: EVMSpvVaultData, data?: EVMSpvWithdrawalData, feeRate?: string): Promise<bigint> {
|
|
59
|
-
vault ??= EVMSpvVaultData.
|
|
64
|
+
vault ??= EVMSpvVaultData._randomVault();
|
|
60
65
|
feeRate ??= await this.Chain.Fees.getFeeRate();
|
|
61
66
|
const tokenStateChanges: Set<string> = new Set();
|
|
62
67
|
|
|
@@ -2,6 +2,11 @@ import {EVMSwapContract} from "../../evm/swaps/EVMSwapContract";
|
|
|
2
2
|
import {EVMSwapData} from "../../evm/swaps/EVMSwapData";
|
|
3
3
|
import {CitreaFees} from "./CitreaFees";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Citrea swap contract wrapper with fee estimation adjusted by expected state-diff size.
|
|
7
|
+
*
|
|
8
|
+
* @category Networks/Citrea
|
|
9
|
+
*/
|
|
5
10
|
export class CitreaSwapContract extends EVMSwapContract<"CITREA"> {
|
|
6
11
|
|
|
7
12
|
public static readonly StateDiffSize = {
|
|
@@ -27,7 +32,7 @@ export class CitreaSwapContract extends EVMSwapContract<"CITREA"> {
|
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
/**
|
|
30
|
-
*
|
|
35
|
+
* Returns estimated fee of the commit transaction, including Citrea state-diff overhead.
|
|
31
36
|
*/
|
|
32
37
|
async getCommitFee(signer: string, swapData: EVMSwapData, feeRate?: string): Promise<bigint> {
|
|
33
38
|
feeRate ??= await this.Chain.Fees.getFeeRate();
|
|
@@ -45,7 +50,7 @@ export class CitreaSwapContract extends EVMSwapContract<"CITREA"> {
|
|
|
45
50
|
}
|
|
46
51
|
diffSize += this.calculateStateDiff(signer, tokenStateChanges);
|
|
47
52
|
|
|
48
|
-
const gasFee = await this.
|
|
53
|
+
const gasFee = await this._Init.getInitFee(swapData, feeRate);
|
|
49
54
|
return gasFee + CitreaFees.getGasFee(0, feeRate, diffSize);
|
|
50
55
|
}
|
|
51
56
|
|
|
@@ -69,12 +74,12 @@ export class CitreaSwapContract extends EVMSwapContract<"CITREA"> {
|
|
|
69
74
|
}
|
|
70
75
|
diffSize += this.calculateStateDiff(signer, tokenStateChanges);
|
|
71
76
|
|
|
72
|
-
const gasFee = await this.
|
|
77
|
+
const gasFee = await this._Claim.getClaimFee(swapData, feeRate);
|
|
73
78
|
return gasFee + CitreaFees.getGasFee(0, feeRate, diffSize);
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
/**
|
|
77
|
-
*
|
|
82
|
+
* Returns estimated fee of the refund transaction, including Citrea state-diff overhead.
|
|
78
83
|
*/
|
|
79
84
|
async getRefundFee(signer: string, swapData: EVMSwapData, feeRate?: string): Promise<bigint> {
|
|
80
85
|
feeRate ??= await this.Chain.Fees.getFeeRate();
|
|
@@ -96,8 +101,8 @@ export class CitreaSwapContract extends EVMSwapContract<"CITREA"> {
|
|
|
96
101
|
}
|
|
97
102
|
diffSize += this.calculateStateDiff(signer, tokenStateChanges);
|
|
98
103
|
|
|
99
|
-
const gasFee = await this.
|
|
104
|
+
const gasFee = await this._Refund.getRefundFee(swapData, feeRate);
|
|
100
105
|
return gasFee + CitreaFees.getGasFee(0, feeRate, diffSize);
|
|
101
106
|
}
|
|
102
107
|
|
|
103
|
-
}
|
|
108
|
+
}
|
|
@@ -2,6 +2,11 @@ import {EVMTokens} from "../../evm/chain/modules/EVMTokens";
|
|
|
2
2
|
import {CitreaFees} from "./CitreaFees";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Citrea-specific token module that augments fee estimation with state-diff costs.
|
|
7
|
+
*
|
|
8
|
+
* @category Networks/Citrea
|
|
9
|
+
*/
|
|
5
10
|
export class CitreaTokens extends EVMTokens {
|
|
6
11
|
|
|
7
12
|
public static readonly StateDiffSize = {
|
|
@@ -19,4 +24,4 @@ export class CitreaTokens extends EVMTokens {
|
|
|
19
24
|
return CitreaFees.getGasFee(EVMTokens.GasCosts.APPROVE, feeRate, CitreaTokens.StateDiffSize.TRANSFER_DIFF_SIZE);
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
}
|
|
27
|
+
}
|
|
@@ -12,11 +12,11 @@ import {EVMBtcRelay} from "../../evm/btcrelay/EVMBtcRelay";
|
|
|
12
12
|
import {EVMSpvVaultContract} from "../../evm/spv_swap/EVMSpvVaultContract";
|
|
13
13
|
import {Signer} from "ethers";
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
* Type definition for the GOAT Network chain implementation
|
|
17
|
-
* @category Networks/GOAT
|
|
18
|
-
*/
|
|
19
|
-
export type GoatChainType = ChainType<
|
|
15
|
+
/**
|
|
16
|
+
* Type definition for the GOAT Network chain implementation
|
|
17
|
+
* @category Networks/GOAT
|
|
18
|
+
*/
|
|
19
|
+
export type GoatChainType = ChainType<
|
|
20
20
|
"GOAT",
|
|
21
21
|
never,
|
|
22
22
|
EVMPreFetchVerification,
|
|
@@ -10,6 +10,7 @@ import {EVMSwapData} from "../../evm/swaps/EVMSwapData";
|
|
|
10
10
|
import {EVMSpvVaultData} from "../../evm/spv_swap/EVMSpvVaultData";
|
|
11
11
|
import {EVMSpvWithdrawalData} from "../../evm/spv_swap/EVMSpvWithdrawalData";
|
|
12
12
|
import {GoatChainType} from "./GoatChainType";
|
|
13
|
+
import {EVMOptions} from "../EVMOptions";
|
|
13
14
|
|
|
14
15
|
const GoatChainIds = {
|
|
15
16
|
MAINNET: 2345,
|
|
@@ -96,7 +97,7 @@ export type GoatAssetsType = BaseTokenType<"BTC" | "PBTC" | "_PBTC_DEV">;
|
|
|
96
97
|
* Default GOAT Network token assets configuration
|
|
97
98
|
* @category Networks/GOAT
|
|
98
99
|
*/
|
|
99
|
-
|
|
100
|
+
const GoatAssets: GoatAssetsType = {
|
|
100
101
|
BTC: {
|
|
101
102
|
address: "0x0000000000000000000000000000000000000000",
|
|
102
103
|
decimals: 18,
|
|
@@ -118,30 +119,7 @@ export const GoatAssets: GoatAssetsType = {
|
|
|
118
119
|
* Configuration options for initializing GOAT Network chain
|
|
119
120
|
* @category Networks/GOAT
|
|
120
121
|
*/
|
|
121
|
-
export type GoatOptions =
|
|
122
|
-
rpcUrl: string | JsonRpcApiProvider,
|
|
123
|
-
retryPolicy?: EVMRetryPolicy,
|
|
124
|
-
chainType?: "MAINNET" | "TESTNET" | "TESTNET4",
|
|
125
|
-
|
|
126
|
-
swapContract?: string,
|
|
127
|
-
swapContractDeploymentHeight?: number,
|
|
128
|
-
btcRelayContract?: string,
|
|
129
|
-
btcRelayDeploymentHeight?: number,
|
|
130
|
-
spvVaultContract?: string,
|
|
131
|
-
spvVaultDeploymentHeight?: number,
|
|
132
|
-
handlerContracts?: {
|
|
133
|
-
refund?: {
|
|
134
|
-
timelock?: string
|
|
135
|
-
},
|
|
136
|
-
claim?: {
|
|
137
|
-
[type in ChainSwapType]?: string
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
fees?: EVMFees,
|
|
142
|
-
|
|
143
|
-
evmConfig?: Partial<Omit<EVMConfiguration, "safeBlockTag" | "finalizedBlockTag" | "finalityCheckStrategy">>
|
|
144
|
-
}
|
|
122
|
+
export type GoatOptions = EVMOptions<"MAINNET" | "TESTNET" | "TESTNET4">;
|
|
145
123
|
|
|
146
124
|
/**
|
|
147
125
|
* Initialize GOAT Network chain integration
|
|
@@ -27,13 +27,18 @@ function serializeBlockHeader(e: BtcBlock): EVMBtcHeader {
|
|
|
27
27
|
const logger = getLogger("EVMBtcRelay: ");
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
+
* EVM BTC Relay bitcoin light client contract representation.
|
|
31
|
+
*
|
|
30
32
|
* @category BTC Relay
|
|
31
33
|
*/
|
|
32
34
|
export class EVMBtcRelay<B extends BtcBlock>
|
|
33
35
|
extends EVMContractBase<BtcRelayTypechain>
|
|
34
36
|
implements BtcRelay<EVMBtcStoredHeader, EVMTx, B, EVMSigner> {
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
static _GasCosts = {
|
|
37
42
|
GAS_PER_BLOCKHEADER: 30_000,
|
|
38
43
|
GAS_BASE_MAIN: 15_000 + 21_000,
|
|
39
44
|
GAS_PER_BLOCKHEADER_FORK: 65_000,
|
|
@@ -41,37 +46,64 @@ export class EVMBtcRelay<B extends BtcBlock>
|
|
|
41
46
|
GAS_BASE_FORK: 25_000 + 21_000
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Returns a transaction that submits new main-chain bitcoin blockheaders to the light client.
|
|
51
|
+
*
|
|
52
|
+
* @param signer EVM signer address
|
|
53
|
+
* @param mainHeaders New bitcoin blockheaders to submit
|
|
54
|
+
* @param storedHeader Current latest committed and stored bitcoin blockheader in the light client
|
|
55
|
+
* @param feeRate Fee rate to apply to the transaction
|
|
56
|
+
*/
|
|
57
|
+
private async SaveMainHeaders(signer: string, mainHeaders: EVMBtcHeader[], storedHeader: EVMBtcStoredHeader, feeRate: string): Promise<EVMTx> {
|
|
45
58
|
const tx = await this.contract.submitMainBlockheaders.populateTransaction(Buffer.concat([
|
|
46
59
|
storedHeader.serialize(),
|
|
47
60
|
Buffer.concat(mainHeaders.map(header => header.serializeCompact()))
|
|
48
61
|
]));
|
|
49
62
|
tx.from = signer;
|
|
50
|
-
EVMFees.applyFeeRate(tx, EVMBtcRelay.
|
|
63
|
+
EVMFees.applyFeeRate(tx, EVMBtcRelay._GasCosts.GAS_BASE_MAIN + (EVMBtcRelay._GasCosts.GAS_PER_BLOCKHEADER * mainHeaders.length), feeRate);
|
|
51
64
|
return tx;
|
|
52
65
|
}
|
|
53
66
|
|
|
54
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Returns a transaction that submits a short competing branch.
|
|
69
|
+
* If the submitted chain has higher total chainwork than the current canonical chain, it becomes canonical.
|
|
70
|
+
*
|
|
71
|
+
* @param signer EVM signer address
|
|
72
|
+
* @param forkHeaders Fork bitcoin blockheaders to submit
|
|
73
|
+
* @param storedHeader Committed and stored bitcoin blockheader from which to fork the light client
|
|
74
|
+
* @param feeRate Fee rate to apply to the transaction
|
|
75
|
+
*/
|
|
76
|
+
private async SaveShortForkHeaders(signer: string, forkHeaders: EVMBtcHeader[], storedHeader: EVMBtcStoredHeader, feeRate: string): Promise<EVMTx> {
|
|
55
77
|
const tx = await this.contract.submitShortForkBlockheaders.populateTransaction(Buffer.concat([
|
|
56
78
|
storedHeader.serialize(),
|
|
57
79
|
Buffer.concat(forkHeaders.map(header => header.serializeCompact()))
|
|
58
80
|
]));
|
|
59
81
|
tx.from = signer;
|
|
60
|
-
EVMFees.applyFeeRate(tx, EVMBtcRelay.
|
|
82
|
+
EVMFees.applyFeeRate(tx, EVMBtcRelay._GasCosts.GAS_BASE_MAIN + (EVMBtcRelay._GasCosts.GAS_PER_BLOCKHEADER * forkHeaders.length), feeRate);
|
|
61
83
|
return tx;
|
|
62
84
|
}
|
|
63
85
|
|
|
64
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Returns a transaction that submits blockheaders to an existing long fork.
|
|
88
|
+
*
|
|
89
|
+
* @param signer EVM signer address
|
|
90
|
+
* @param forkId Fork ID to submit the fork blockheaders to
|
|
91
|
+
* @param forkHeaders Fork bitcoin blockheaders to submit
|
|
92
|
+
* @param storedHeader Either a committed and stored blockheader from which to fork, or the current fork tip
|
|
93
|
+
* @param feeRate Fee rate to apply to the transaction
|
|
94
|
+
* @param totalForkHeaders Total blockheaders in the fork, used for gas estimation when reorg happens
|
|
95
|
+
*/
|
|
96
|
+
private async SaveLongForkHeaders(signer: string, forkId: number, forkHeaders: EVMBtcHeader[], storedHeader: EVMBtcStoredHeader, feeRate: string, totalForkHeaders: number = 100): Promise<EVMTx> {
|
|
65
97
|
const tx = await this.contract.submitForkBlockheaders.populateTransaction(forkId, Buffer.concat([
|
|
66
98
|
storedHeader.serialize(),
|
|
67
99
|
Buffer.concat(forkHeaders.map(header => header.serializeCompact()))
|
|
68
100
|
]));
|
|
69
101
|
tx.from = signer;
|
|
70
|
-
EVMFees.applyFeeRate(tx, EVMBtcRelay.
|
|
102
|
+
EVMFees.applyFeeRate(tx, EVMBtcRelay._GasCosts.GAS_BASE_FORK + (EVMBtcRelay._GasCosts.GAS_PER_BLOCKHEADER_FORK * forkHeaders.length) + (EVMBtcRelay._GasCosts.GAS_PER_BLOCKHEADER_FORKED * totalForkHeaders), feeRate);
|
|
71
103
|
return tx;
|
|
72
104
|
}
|
|
73
105
|
|
|
74
|
-
|
|
106
|
+
readonly _bitcoinRpc: BitcoinRpc<B>;
|
|
75
107
|
|
|
76
108
|
readonly maxHeadersPerTx: number = 100;
|
|
77
109
|
readonly maxForkHeadersPerTx: number = 50;
|
|
@@ -85,12 +117,12 @@ export class EVMBtcRelay<B extends BtcBlock>
|
|
|
85
117
|
contractDeploymentHeight?: number
|
|
86
118
|
) {
|
|
87
119
|
super(chainInterface, contractAddress, BtcRelayAbi, contractDeploymentHeight);
|
|
88
|
-
this.
|
|
120
|
+
this._bitcoinRpc = bitcoinRpc;
|
|
89
121
|
}
|
|
90
122
|
|
|
91
123
|
/**
|
|
92
|
-
* Computes subsequent
|
|
93
|
-
*
|
|
124
|
+
* Computes subsequent committed headers as they will appear on-chain once transactions
|
|
125
|
+
* are submitted and confirmed.
|
|
94
126
|
*
|
|
95
127
|
* @param initialStoredHeader
|
|
96
128
|
* @param syncedHeaders
|
|
@@ -198,7 +230,7 @@ export class EVMBtcRelay<B extends BtcBlock>
|
|
|
198
230
|
private getBlock(commitHash?: string, blockHash?: Buffer): Promise<[EVMBtcStoredHeader, string] | null> {
|
|
199
231
|
const blockHashString = blockHash==null ? null : "0x"+Buffer.from([...blockHash]).reverse().toString("hex");
|
|
200
232
|
|
|
201
|
-
const generator = () => this.
|
|
233
|
+
const generator = () => this._Events.findInContractEvents<[EVMBtcStoredHeader, string] | null, "StoreHeader" | "StoreForkHeader">(
|
|
202
234
|
["StoreHeader", "StoreForkHeader"],
|
|
203
235
|
[
|
|
204
236
|
commitHash ?? null,
|
|
@@ -263,7 +295,7 @@ export class EVMBtcRelay<B extends BtcBlock>
|
|
|
263
295
|
const [storedBlockHeader, commitHash] = result;
|
|
264
296
|
|
|
265
297
|
//Check if block is part of the main chain
|
|
266
|
-
const chainCommitment = await this.contract.getCommitHash(storedBlockHeader.
|
|
298
|
+
const chainCommitment = await this.contract.getCommitHash(storedBlockHeader.getBlockheight());
|
|
267
299
|
if(chainCommitment!==commitHash) return null;
|
|
268
300
|
|
|
269
301
|
logger.debug("retrieveLogAndBlockheight(): block found," +
|
|
@@ -282,11 +314,11 @@ export class EVMBtcRelay<B extends BtcBlock>
|
|
|
282
314
|
const [storedBlockHeader, commitHash] = result;
|
|
283
315
|
|
|
284
316
|
//Check if block is part of the main chain
|
|
285
|
-
const chainCommitment = await this.contract.getCommitHash(storedBlockHeader.
|
|
317
|
+
const chainCommitment = await this.contract.getCommitHash(storedBlockHeader.getBlockheight());
|
|
286
318
|
if(chainCommitment!==commitHash) return null;
|
|
287
319
|
|
|
288
320
|
logger.debug("retrieveLogByCommitHash(): block found," +
|
|
289
|
-
" commit hash: "+commitmentHashStr+" blockhash: "+blockData.blockhash+" height: "+storedBlockHeader.
|
|
321
|
+
" commit hash: "+commitmentHashStr+" blockhash: "+blockData.blockhash+" height: "+storedBlockHeader.getBlockheight());
|
|
290
322
|
|
|
291
323
|
return storedBlockHeader;
|
|
292
324
|
}
|
|
@@ -298,17 +330,17 @@ export class EVMBtcRelay<B extends BtcBlock>
|
|
|
298
330
|
resultStoredHeader: EVMBtcStoredHeader,
|
|
299
331
|
resultBitcoinHeader: B
|
|
300
332
|
} | null> {
|
|
301
|
-
const data = await this.
|
|
333
|
+
const data = await this._Events.findInContractEvents(
|
|
302
334
|
["StoreHeader", "StoreForkHeader"],
|
|
303
335
|
null,
|
|
304
336
|
async (event) => {
|
|
305
337
|
const blockHashHex = Buffer.from(event.args.blockHash.substring(2), "hex").reverse().toString("hex");
|
|
306
338
|
const commitHash = event.args.commitHash;
|
|
307
339
|
|
|
308
|
-
const isInBtcMainChain = await this.
|
|
340
|
+
const isInBtcMainChain = await this._bitcoinRpc.isInMainChain(blockHashHex).catch(() => false);
|
|
309
341
|
if(!isInBtcMainChain) return null;
|
|
310
342
|
|
|
311
|
-
const blockHeader = await this.
|
|
343
|
+
const blockHeader = await this._bitcoinRpc.getBlockHeader(blockHashHex);
|
|
312
344
|
if(blockHeader==null) return null;
|
|
313
345
|
|
|
314
346
|
if(commitHash !== await this.contract.getCommitHash(blockHeader.getHeight())) return null;
|
|
@@ -408,7 +440,7 @@ export class EVMBtcRelay<B extends BtcBlock>
|
|
|
408
440
|
if(blockheightDelta<=0) return 0n;
|
|
409
441
|
|
|
410
442
|
const synchronizationFee = (BigInt(blockheightDelta) * await this.getFeePerBlock(feeRate))
|
|
411
|
-
+ EVMFees.getGasFee(EVMBtcRelay.
|
|
443
|
+
+ EVMFees.getGasFee(EVMBtcRelay._GasCosts.GAS_BASE_MAIN * Math.ceil(blockheightDelta / this.maxHeadersPerTx), feeRate);
|
|
412
444
|
logger.debug("estimateSynchronizeFee(): required blockheight: "+requiredBlockheight+
|
|
413
445
|
" blockheight delta: "+blockheightDelta+" fee: "+synchronizationFee.toString(10));
|
|
414
446
|
|
|
@@ -420,7 +452,7 @@ export class EVMBtcRelay<B extends BtcBlock>
|
|
|
420
452
|
*/
|
|
421
453
|
public async getFeePerBlock(feeRate?: string): Promise<bigint> {
|
|
422
454
|
feeRate ??= await this.Chain.Fees.getFeeRate();
|
|
423
|
-
return EVMFees.getGasFee(EVMBtcRelay.
|
|
455
|
+
return EVMFees.getGasFee(EVMBtcRelay._GasCosts.GAS_PER_BLOCKHEADER, feeRate);
|
|
424
456
|
}
|
|
425
457
|
|
|
426
458
|
/**
|
|
@@ -453,8 +485,8 @@ export class EVMBtcRelay<B extends BtcBlock>
|
|
|
453
485
|
* @param signer
|
|
454
486
|
* @param btcRelay
|
|
455
487
|
* @param btcTxs
|
|
456
|
-
* @param txs
|
|
457
|
-
*
|
|
488
|
+
* @param txs EVM transaction array. If BTC relay synchronization is needed, synchronization
|
|
489
|
+
* transactions are appended here.
|
|
458
490
|
* @param synchronizer optional synchronizer to use to synchronize the btc relay in case it is not yet synchronized
|
|
459
491
|
* to the required blockheight
|
|
460
492
|
* @param feeRate Fee rate to use for synchronization transactions
|
|
@@ -2,6 +2,11 @@ import {BtcHeader} from "@atomiqlabs/base";
|
|
|
2
2
|
import {Buffer} from "buffer";
|
|
3
3
|
import {sha256} from "@noble/hashes/sha2";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Constructor payload for EVM bitcoin blockheader representation.
|
|
7
|
+
*
|
|
8
|
+
* @category BTC Relay
|
|
9
|
+
*/
|
|
5
10
|
export type EVMBtcHeaderType = {
|
|
6
11
|
version: number;
|
|
7
12
|
previousBlockhash?: Buffer;
|
|
@@ -13,21 +18,30 @@ export type EVMBtcHeaderType = {
|
|
|
13
18
|
};
|
|
14
19
|
|
|
15
20
|
/**
|
|
21
|
+
* Representation of a bitcoin blockheader submitted to EVM BTC relay contracts.
|
|
22
|
+
*
|
|
16
23
|
* @category BTC Relay
|
|
17
24
|
*/
|
|
18
25
|
export class EVMBtcHeader implements BtcHeader {
|
|
19
26
|
|
|
20
|
-
version: number;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
private readonly version: number;
|
|
28
|
+
private readonly merkleRoot: Buffer;
|
|
29
|
+
private readonly timestamp: number;
|
|
30
|
+
private readonly nbits: number;
|
|
31
|
+
private readonly nonce: number;
|
|
32
|
+
private readonly hash?: Buffer;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
_previousBlockhash?: Buffer;
|
|
27
38
|
|
|
39
|
+
/**
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
28
42
|
constructor(data: EVMBtcHeaderType) {
|
|
29
43
|
this.version = data.version;
|
|
30
|
-
this.
|
|
44
|
+
this._previousBlockhash = data.previousBlockhash;
|
|
31
45
|
this.merkleRoot = data.merkleRoot;
|
|
32
46
|
this.timestamp = data.timestamp;
|
|
33
47
|
this.nbits = data.nbits;
|
|
@@ -35,35 +49,60 @@ export class EVMBtcHeader implements BtcHeader {
|
|
|
35
49
|
this.hash = data.hash;
|
|
36
50
|
}
|
|
37
51
|
|
|
52
|
+
/**
|
|
53
|
+
* @inheritDoc
|
|
54
|
+
*/
|
|
38
55
|
getMerkleRoot(): Buffer {
|
|
39
56
|
return this.merkleRoot;
|
|
40
57
|
}
|
|
41
58
|
|
|
59
|
+
/**
|
|
60
|
+
* @inheritDoc
|
|
61
|
+
*/
|
|
42
62
|
getNbits(): number {
|
|
43
63
|
return this.nbits;
|
|
44
64
|
}
|
|
45
65
|
|
|
66
|
+
/**
|
|
67
|
+
* @inheritDoc
|
|
68
|
+
*/
|
|
46
69
|
getNonce(): number {
|
|
47
70
|
return this.nonce;
|
|
48
71
|
}
|
|
49
72
|
|
|
73
|
+
/**
|
|
74
|
+
* @inheritDoc
|
|
75
|
+
*/
|
|
50
76
|
getReversedPrevBlockhash(): Buffer {
|
|
51
|
-
if(this.
|
|
52
|
-
return this.
|
|
77
|
+
if(this._previousBlockhash==null) throw new Error("Previous blockhash is not known from compact blockheader!");
|
|
78
|
+
return this._previousBlockhash;
|
|
53
79
|
}
|
|
54
80
|
|
|
81
|
+
/**
|
|
82
|
+
* @inheritDoc
|
|
83
|
+
*/
|
|
55
84
|
getTimestamp(): number {
|
|
56
85
|
return this.timestamp;
|
|
57
86
|
}
|
|
58
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @inheritDoc
|
|
90
|
+
*/
|
|
59
91
|
getVersion(): number {
|
|
60
92
|
return this.version;
|
|
61
93
|
}
|
|
62
94
|
|
|
95
|
+
/**
|
|
96
|
+
* @inheritDoc
|
|
97
|
+
*/
|
|
63
98
|
getHash(): Buffer {
|
|
64
99
|
return Buffer.from(sha256(sha256(this.serialize())));
|
|
65
100
|
}
|
|
66
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Serializes the bitcoin blockheader into compact 48-byte representation
|
|
104
|
+
* (without previous blockhash).
|
|
105
|
+
*/
|
|
67
106
|
serializeCompact(): Buffer {
|
|
68
107
|
const buffer = Buffer.alloc(48);
|
|
69
108
|
buffer.writeUInt32LE(this.version, 0);
|
|
@@ -74,11 +113,14 @@ export class EVMBtcHeader implements BtcHeader {
|
|
|
74
113
|
return buffer;
|
|
75
114
|
}
|
|
76
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Serializes the bitcoin blockheader into full 80-byte representation.
|
|
118
|
+
*/
|
|
77
119
|
serialize(): Buffer {
|
|
78
|
-
if(this.
|
|
120
|
+
if(this._previousBlockhash==null) throw new Error("Cannot serialize compact blockheader without previous blockhash!");
|
|
79
121
|
const buffer = Buffer.alloc(80);
|
|
80
122
|
buffer.writeUInt32LE(this.version, 0);
|
|
81
|
-
this.
|
|
123
|
+
this._previousBlockhash.copy(buffer, 4);
|
|
82
124
|
this.merkleRoot.copy(buffer, 36);
|
|
83
125
|
buffer.writeUInt32LE(this.timestamp, 68);
|
|
84
126
|
buffer.writeUInt32LE(this.nbits, 72);
|
|
@@ -86,6 +128,11 @@ export class EVMBtcHeader implements BtcHeader {
|
|
|
86
128
|
return buffer;
|
|
87
129
|
}
|
|
88
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Deserializes a bitcoin blockheader from 80-byte full or 48-byte compact representation.
|
|
133
|
+
*
|
|
134
|
+
* @param rawData Serialized blockheader bytes
|
|
135
|
+
*/
|
|
89
136
|
static deserialize(rawData: Buffer): EVMBtcHeader {
|
|
90
137
|
if(rawData.length===80) {
|
|
91
138
|
//Regular blockheader
|
|
@@ -112,4 +159,4 @@ export class EVMBtcHeader implements BtcHeader {
|
|
|
112
159
|
}
|
|
113
160
|
}
|
|
114
161
|
|
|
115
|
-
}
|
|
162
|
+
}
|