@atomiqlabs/chain-evm 1.0.0-dev.75 → 1.0.0-dev.77
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/LICENSE +201 -201
- package/dist/chains/botanix/BotanixChainType.d.ts +13 -13
- package/dist/chains/botanix/BotanixChainType.js +2 -2
- package/dist/chains/botanix/BotanixInitializer.d.ts +30 -30
- package/dist/chains/botanix/BotanixInitializer.js +122 -122
- package/dist/chains/citrea/CitreaBtcRelay.d.ts +21 -21
- package/dist/chains/citrea/CitreaBtcRelay.js +43 -43
- package/dist/chains/citrea/CitreaChainType.d.ts +13 -13
- package/dist/chains/citrea/CitreaChainType.js +2 -2
- package/dist/chains/citrea/CitreaFees.d.ts +29 -29
- package/dist/chains/citrea/CitreaFees.js +67 -67
- package/dist/chains/citrea/CitreaInitializer.d.ts +30 -30
- package/dist/chains/citrea/CitreaInitializer.js +129 -129
- package/dist/chains/citrea/CitreaSpvVaultContract.d.ts +15 -15
- package/dist/chains/citrea/CitreaSpvVaultContract.js +74 -74
- package/dist/chains/citrea/CitreaSwapContract.d.ts +22 -22
- package/dist/chains/citrea/CitreaSwapContract.js +96 -96
- package/dist/chains/citrea/CitreaTokens.d.ts +9 -9
- package/dist/chains/citrea/CitreaTokens.js +20 -20
- package/dist/evm/btcrelay/BtcRelayAbi.d.ts +198 -198
- package/dist/evm/btcrelay/BtcRelayAbi.js +261 -261
- package/dist/evm/btcrelay/BtcRelayTypechain.d.ts +172 -172
- package/dist/evm/btcrelay/BtcRelayTypechain.js +2 -2
- package/dist/evm/btcrelay/EVMBtcRelay.d.ts +197 -197
- package/dist/evm/btcrelay/EVMBtcRelay.js +435 -435
- package/dist/evm/btcrelay/headers/EVMBtcHeader.d.ts +33 -33
- package/dist/evm/btcrelay/headers/EVMBtcHeader.js +84 -84
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.d.ts +56 -56
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.js +123 -123
- package/dist/evm/chain/EVMChainInterface.d.ts +51 -51
- package/dist/evm/chain/EVMChainInterface.js +89 -89
- package/dist/evm/chain/EVMModule.d.ts +9 -9
- package/dist/evm/chain/EVMModule.js +13 -13
- package/dist/evm/chain/modules/ERC20Abi.d.ts +168 -168
- package/dist/evm/chain/modules/ERC20Abi.js +225 -225
- package/dist/evm/chain/modules/EVMAddresses.d.ts +10 -10
- package/dist/evm/chain/modules/EVMAddresses.js +30 -30
- package/dist/evm/chain/modules/EVMBlocks.d.ts +20 -20
- package/dist/evm/chain/modules/EVMBlocks.js +64 -64
- package/dist/evm/chain/modules/EVMEvents.d.ts +36 -36
- package/dist/evm/chain/modules/EVMEvents.js +122 -122
- package/dist/evm/chain/modules/EVMFees.d.ts +36 -36
- package/dist/evm/chain/modules/EVMFees.js +74 -74
- package/dist/evm/chain/modules/EVMSignatures.d.ts +29 -29
- package/dist/evm/chain/modules/EVMSignatures.js +68 -68
- package/dist/evm/chain/modules/EVMTokens.d.ts +70 -70
- package/dist/evm/chain/modules/EVMTokens.js +142 -142
- package/dist/evm/chain/modules/EVMTransactions.d.ts +94 -94
- package/dist/evm/chain/modules/EVMTransactions.js +286 -286
- package/dist/evm/contract/EVMContractBase.d.ts +22 -22
- package/dist/evm/contract/EVMContractBase.js +34 -34
- package/dist/evm/contract/EVMContractModule.d.ts +8 -8
- package/dist/evm/contract/EVMContractModule.js +11 -11
- package/dist/evm/contract/modules/EVMContractEvents.d.ts +42 -42
- package/dist/evm/contract/modules/EVMContractEvents.js +75 -75
- package/dist/evm/events/EVMChainEvents.d.ts +22 -22
- package/dist/evm/events/EVMChainEvents.js +69 -69
- package/dist/evm/events/EVMChainEventsBrowser.d.ts +102 -102
- package/dist/evm/events/EVMChainEventsBrowser.js +413 -404
- package/dist/evm/providers/JsonRpcProviderWithRetries.d.ts +15 -15
- package/dist/evm/providers/JsonRpcProviderWithRetries.js +19 -19
- package/dist/evm/providers/ReconnectingWebSocketProvider.d.ts +22 -22
- package/dist/evm/providers/ReconnectingWebSocketProvider.js +87 -87
- package/dist/evm/providers/SocketProvider.d.ts +111 -111
- package/dist/evm/providers/SocketProvider.js +334 -334
- package/dist/evm/providers/WebSocketProviderWithRetries.d.ts +17 -17
- package/dist/evm/providers/WebSocketProviderWithRetries.js +19 -19
- package/dist/evm/spv_swap/EVMSpvVaultContract.d.ts +79 -79
- package/dist/evm/spv_swap/EVMSpvVaultContract.js +482 -482
- package/dist/evm/spv_swap/EVMSpvVaultData.d.ts +39 -39
- package/dist/evm/spv_swap/EVMSpvVaultData.js +0 -180
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.d.ts +19 -19
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.js +55 -55
- package/dist/evm/spv_swap/SpvVaultContractAbi.d.ts +91 -91
- package/dist/evm/spv_swap/SpvVaultContractAbi.js +849 -849
- package/dist/evm/spv_swap/SpvVaultContractTypechain.d.ts +450 -450
- package/dist/evm/spv_swap/SpvVaultContractTypechain.js +2 -2
- package/dist/evm/swaps/EVMSwapContract.d.ts +193 -193
- package/dist/evm/swaps/EVMSwapContract.js +378 -378
- package/dist/evm/swaps/EVMSwapData.d.ts +66 -66
- package/dist/evm/swaps/EVMSwapData.js +260 -260
- package/dist/evm/swaps/EVMSwapModule.d.ts +9 -9
- package/dist/evm/swaps/EVMSwapModule.js +11 -11
- package/dist/evm/swaps/EscrowManagerAbi.d.ts +120 -120
- package/dist/evm/swaps/EscrowManagerAbi.js +985 -985
- package/dist/evm/swaps/EscrowManagerTypechain.d.ts +475 -475
- package/dist/evm/swaps/EscrowManagerTypechain.js +2 -2
- package/dist/evm/swaps/handlers/IHandler.d.ts +13 -13
- package/dist/evm/swaps/handlers/IHandler.js +2 -2
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.d.ts +10 -10
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.js +13 -13
- package/dist/evm/swaps/handlers/claim/HashlockClaimHandler.d.ts +20 -20
- package/dist/evm/swaps/handlers/claim/HashlockClaimHandler.js +39 -39
- package/dist/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +24 -24
- package/dist/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.js +59 -59
- package/dist/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +25 -25
- package/dist/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.js +51 -51
- package/dist/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +21 -21
- package/dist/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.js +28 -28
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +48 -48
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +63 -63
- package/dist/evm/swaps/handlers/refund/TimelockRefundHandler.d.ts +17 -17
- package/dist/evm/swaps/handlers/refund/TimelockRefundHandler.js +28 -28
- package/dist/evm/swaps/modules/EVMLpVault.d.ts +69 -69
- package/dist/evm/swaps/modules/EVMLpVault.js +134 -134
- package/dist/evm/swaps/modules/EVMSwapClaim.d.ts +54 -54
- package/dist/evm/swaps/modules/EVMSwapClaim.js +137 -137
- package/dist/evm/swaps/modules/EVMSwapInit.d.ts +88 -88
- package/dist/evm/swaps/modules/EVMSwapInit.js +274 -274
- package/dist/evm/swaps/modules/EVMSwapRefund.d.ts +62 -62
- package/dist/evm/swaps/modules/EVMSwapRefund.js +167 -167
- package/dist/evm/typechain/common.d.ts +50 -50
- package/dist/evm/typechain/common.js +2 -2
- package/dist/evm/wallet/EVMBrowserSigner.d.ts +5 -5
- package/dist/evm/wallet/EVMBrowserSigner.js +11 -11
- package/dist/evm/wallet/EVMPersistentSigner.d.ts +29 -29
- package/dist/evm/wallet/EVMPersistentSigner.js +222 -222
- package/dist/evm/wallet/EVMSigner.d.ts +11 -11
- package/dist/evm/wallet/EVMSigner.js +24 -24
- package/dist/index.d.ts +44 -44
- package/dist/index.js +60 -60
- package/dist/utils/Utils.d.ts +17 -17
- package/dist/utils/Utils.js +81 -81
- package/package.json +39 -39
- package/src/chains/botanix/BotanixChainType.ts +28 -28
- package/src/chains/botanix/BotanixInitializer.ts +171 -171
- package/src/chains/citrea/CitreaBtcRelay.ts +57 -57
- package/src/chains/citrea/CitreaChainType.ts +28 -28
- package/src/chains/citrea/CitreaFees.ts +77 -77
- package/src/chains/citrea/CitreaInitializer.ts +178 -178
- package/src/chains/citrea/CitreaSpvVaultContract.ts +75 -75
- package/src/chains/citrea/CitreaSwapContract.ts +102 -102
- package/src/chains/citrea/CitreaTokens.ts +21 -21
- package/src/evm/btcrelay/BtcRelayAbi.ts +258 -258
- package/src/evm/btcrelay/BtcRelayTypechain.ts +371 -371
- package/src/evm/btcrelay/EVMBtcRelay.ts +537 -537
- package/src/evm/btcrelay/headers/EVMBtcHeader.ts +109 -109
- package/src/evm/btcrelay/headers/EVMBtcStoredHeader.ts +152 -152
- package/src/evm/chain/EVMChainInterface.ts +155 -155
- package/src/evm/chain/EVMModule.ts +21 -21
- package/src/evm/chain/modules/ERC20Abi.ts +222 -222
- package/src/evm/chain/modules/EVMAddresses.ts +28 -28
- package/src/evm/chain/modules/EVMBlocks.ts +75 -75
- package/src/evm/chain/modules/EVMEvents.ts +139 -139
- package/src/evm/chain/modules/EVMFees.ts +104 -104
- package/src/evm/chain/modules/EVMSignatures.ts +76 -76
- package/src/evm/chain/modules/EVMTokens.ts +155 -155
- package/src/evm/chain/modules/EVMTransactions.ts +325 -325
- package/src/evm/contract/EVMContractBase.ts +63 -63
- package/src/evm/contract/EVMContractModule.ts +16 -16
- package/src/evm/contract/modules/EVMContractEvents.ts +102 -102
- package/src/evm/events/EVMChainEvents.ts +82 -82
- package/src/evm/events/EVMChainEventsBrowser.ts +534 -525
- package/src/evm/providers/JsonRpcProviderWithRetries.ts +24 -24
- package/src/evm/providers/ReconnectingWebSocketProvider.ts +101 -101
- package/src/evm/providers/SocketProvider.ts +368 -368
- package/src/evm/providers/WebSocketProviderWithRetries.ts +27 -27
- package/src/evm/spv_swap/EVMSpvVaultContract.ts +615 -615
- package/src/evm/spv_swap/EVMSpvVaultData.ts +224 -224
- package/src/evm/spv_swap/EVMSpvWithdrawalData.ts +70 -70
- package/src/evm/spv_swap/SpvVaultContractAbi.ts +846 -846
- package/src/evm/spv_swap/SpvVaultContractTypechain.ts +685 -685
- package/src/evm/swaps/EVMSwapContract.ts +600 -600
- package/src/evm/swaps/EVMSwapData.ts +378 -378
- package/src/evm/swaps/EVMSwapModule.ts +16 -16
- package/src/evm/swaps/EscrowManagerAbi.ts +982 -982
- package/src/evm/swaps/EscrowManagerTypechain.ts +723 -723
- package/src/evm/swaps/handlers/IHandler.ts +17 -17
- package/src/evm/swaps/handlers/claim/ClaimHandlers.ts +20 -20
- package/src/evm/swaps/handlers/claim/HashlockClaimHandler.ts +46 -46
- package/src/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +82 -82
- package/src/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +76 -76
- package/src/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +46 -46
- package/src/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +115 -115
- package/src/evm/swaps/handlers/refund/TimelockRefundHandler.ts +37 -37
- package/src/evm/swaps/modules/EVMLpVault.ts +154 -154
- package/src/evm/swaps/modules/EVMSwapClaim.ts +172 -172
- package/src/evm/swaps/modules/EVMSwapInit.ts +328 -328
- package/src/evm/swaps/modules/EVMSwapRefund.ts +229 -229
- package/src/evm/typechain/common.ts +131 -131
- package/src/evm/wallet/EVMBrowserSigner.ts +11 -11
- package/src/evm/wallet/EVMPersistentSigner.ts +298 -298
- package/src/evm/wallet/EVMSigner.ts +31 -31
- package/src/index.ts +53 -53
- package/src/utils/Utils.ts +92 -92
|
@@ -1,229 +1,229 @@
|
|
|
1
|
-
import {SignatureVerificationError, SwapDataVerificationError} from "@atomiqlabs/base";
|
|
2
|
-
import {tryWithRetries} from "../../../utils/Utils";
|
|
3
|
-
import {IHandler} from "../handlers/IHandler";
|
|
4
|
-
import {EVMSwapModule} from "../EVMSwapModule";
|
|
5
|
-
import {Buffer} from "buffer";
|
|
6
|
-
import {EVMSwapData} from "../EVMSwapData";
|
|
7
|
-
import {TransactionRequest} from "ethers";
|
|
8
|
-
import {EVMFees} from "../../chain/modules/EVMFees";
|
|
9
|
-
import {EVMSigner} from "../../wallet/EVMSigner";
|
|
10
|
-
import {EVMTx} from "../../chain/modules/EVMTransactions";
|
|
11
|
-
|
|
12
|
-
const Refund = [
|
|
13
|
-
{ name: "swapHash", type: "bytes32" },
|
|
14
|
-
{ name: "timeout", type: "uint256" }
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
export class EVMSwapRefund extends EVMSwapModule {
|
|
18
|
-
|
|
19
|
-
private static readonly GasCosts = {
|
|
20
|
-
BASE: 35_000 + 21_000,
|
|
21
|
-
ERC20_TRANSFER: 40_000,
|
|
22
|
-
NATIVE_TRANSFER: 35_500,
|
|
23
|
-
LP_VAULT_TRANSFER: 10_000,
|
|
24
|
-
REPUTATION: 25_000
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Action for generic Refund instruction
|
|
29
|
-
*
|
|
30
|
-
* @param signer
|
|
31
|
-
* @param swapData
|
|
32
|
-
* @param witness
|
|
33
|
-
* @param feeRate
|
|
34
|
-
* @param handlerGas
|
|
35
|
-
* @private
|
|
36
|
-
*/
|
|
37
|
-
private async Refund(
|
|
38
|
-
signer: string,
|
|
39
|
-
swapData: EVMSwapData,
|
|
40
|
-
witness: Buffer,
|
|
41
|
-
feeRate: string,
|
|
42
|
-
handlerGas?: number
|
|
43
|
-
): Promise<TransactionRequest> {
|
|
44
|
-
const tx = await this.swapContract.refund.populateTransaction(swapData.toEscrowStruct(), witness);
|
|
45
|
-
tx.from = signer;
|
|
46
|
-
EVMFees.applyFeeRate(tx, this.getRefundGas(swapData) + (handlerGas ?? 0), feeRate)
|
|
47
|
-
return tx;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Action for cooperative refunding with signature
|
|
52
|
-
*
|
|
53
|
-
* @param sender
|
|
54
|
-
* @param swapData
|
|
55
|
-
* @param timeout
|
|
56
|
-
* @param signature
|
|
57
|
-
* @param feeRate
|
|
58
|
-
* @private
|
|
59
|
-
*/
|
|
60
|
-
private async RefundWithSignature(
|
|
61
|
-
sender: string,
|
|
62
|
-
swapData: EVMSwapData,
|
|
63
|
-
timeout: string,
|
|
64
|
-
signature: string,
|
|
65
|
-
feeRate: string
|
|
66
|
-
): Promise<TransactionRequest> {
|
|
67
|
-
const tx = await this.swapContract.cooperativeRefund.populateTransaction(swapData.toEscrowStruct(), signature, BigInt(timeout));
|
|
68
|
-
tx.from = sender;
|
|
69
|
-
EVMFees.applyFeeRate(tx, this.getRefundGas(swapData), feeRate)
|
|
70
|
-
return tx;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
public async signSwapRefund(
|
|
74
|
-
signer: EVMSigner,
|
|
75
|
-
swapData: EVMSwapData,
|
|
76
|
-
authorizationTimeout: number
|
|
77
|
-
): Promise<{ prefix: string; timeout: string; signature: string }> {
|
|
78
|
-
const authPrefix = "refund";
|
|
79
|
-
const authTimeout = Math.floor(Date.now()/1000)+authorizationTimeout;
|
|
80
|
-
|
|
81
|
-
const signature = await this.root.Signatures.signTypedMessage(this.contract.contractAddress, signer, Refund, "Refund", {
|
|
82
|
-
"swapHash": "0x"+swapData.getEscrowHash(),
|
|
83
|
-
"timeout": BigInt(authTimeout)
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
return {
|
|
87
|
-
prefix: authPrefix,
|
|
88
|
-
timeout: authTimeout.toString(10),
|
|
89
|
-
signature: signature
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public async isSignatureValid(
|
|
94
|
-
swapData: EVMSwapData,
|
|
95
|
-
timeout: string,
|
|
96
|
-
prefix: string,
|
|
97
|
-
signature: string
|
|
98
|
-
): Promise<null> {
|
|
99
|
-
if(prefix!=="refund") throw new SignatureVerificationError("Invalid prefix");
|
|
100
|
-
|
|
101
|
-
const expiryTimestamp = BigInt(timeout);
|
|
102
|
-
const currentTimestamp = BigInt(Math.floor(Date.now() / 1000));
|
|
103
|
-
|
|
104
|
-
const isExpired = (expiryTimestamp - currentTimestamp) < BigInt(this.contract.authGracePeriod);
|
|
105
|
-
if(isExpired) throw new SignatureVerificationError("Authorization expired!");
|
|
106
|
-
|
|
107
|
-
const valid = await this.root.Signatures.isValidSignature(this.contract.contractAddress, signature, swapData.claimer, Refund, "Refund", {
|
|
108
|
-
"swapHash": "0x"+swapData.getEscrowHash(),
|
|
109
|
-
"timeout": BigInt(expiryTimestamp)
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
if(!valid) {
|
|
113
|
-
throw new SignatureVerificationError("Invalid signature!");
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Creates transactions required for refunding timed out swap
|
|
121
|
-
*
|
|
122
|
-
* @param signer
|
|
123
|
-
* @param swapData swap data to refund
|
|
124
|
-
* @param check whether to check if swap is already expired and refundable
|
|
125
|
-
* @param feeRate fee rate to be used for the transactions
|
|
126
|
-
* @param witnessData
|
|
127
|
-
*/
|
|
128
|
-
public async txsRefund<T>(
|
|
129
|
-
signer: string,
|
|
130
|
-
swapData: EVMSwapData,
|
|
131
|
-
check?: boolean,
|
|
132
|
-
feeRate?: string,
|
|
133
|
-
witnessData?: T
|
|
134
|
-
): Promise<EVMTx[]> {
|
|
135
|
-
const refundHandler: IHandler<any, T> = this.contract.refundHandlersByAddress[swapData.refundHandler.toLowerCase()];
|
|
136
|
-
if(refundHandler==null) throw new Error("Invalid refund handler");
|
|
137
|
-
|
|
138
|
-
if(check && !await tryWithRetries(() => this.contract.isRequestRefundable(swapData.offerer.toString(), swapData), this.retryPolicy)) {
|
|
139
|
-
throw new SwapDataVerificationError("Not refundable yet!");
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
feeRate ??= await this.root.Fees.getFeeRate();
|
|
143
|
-
|
|
144
|
-
const {initialTxns, witness} = await refundHandler.getWitness(signer, swapData, witnessData, feeRate);
|
|
145
|
-
|
|
146
|
-
const tx = await this.Refund(signer, swapData, witness, feeRate, refundHandler.getGas(swapData));
|
|
147
|
-
|
|
148
|
-
this.logger.debug("txsRefund(): creating refund transaction, swap: "+swapData.getClaimHash());
|
|
149
|
-
|
|
150
|
-
return [...initialTxns, tx];
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Creates transactions required for refunding the swap with authorization signature, also unwraps WSOL to SOL
|
|
155
|
-
*
|
|
156
|
-
* @param signer
|
|
157
|
-
* @param swapData swap data to refund
|
|
158
|
-
* @param timeout signature timeout
|
|
159
|
-
* @param prefix signature prefix of the counterparty
|
|
160
|
-
* @param signature signature of the counterparty
|
|
161
|
-
* @param check whether to check if swap is committed before attempting refund
|
|
162
|
-
* @param feeRate fee rate to be used for the transactions
|
|
163
|
-
*/
|
|
164
|
-
public async txsRefundWithAuthorization(
|
|
165
|
-
signer: string,
|
|
166
|
-
swapData: EVMSwapData,
|
|
167
|
-
timeout: string,
|
|
168
|
-
prefix: string,
|
|
169
|
-
signature: string,
|
|
170
|
-
check?: boolean,
|
|
171
|
-
feeRate?: string
|
|
172
|
-
): Promise<EVMTx[]> {
|
|
173
|
-
if(check && !await tryWithRetries(() => this.contract.isCommited(swapData), this.retryPolicy)) {
|
|
174
|
-
throw new SwapDataVerificationError("Not correctly committed");
|
|
175
|
-
}
|
|
176
|
-
await tryWithRetries(
|
|
177
|
-
() => this.isSignatureValid(swapData, timeout, prefix, signature),
|
|
178
|
-
this.retryPolicy,
|
|
179
|
-
(e) => e instanceof SignatureVerificationError
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
feeRate ??= await this.root.Fees.getFeeRate();
|
|
183
|
-
|
|
184
|
-
const tx = await this.RefundWithSignature(signer, swapData, timeout, signature, feeRate);
|
|
185
|
-
|
|
186
|
-
this.logger.debug("txsRefundWithAuthorization(): creating refund transaction, swap: "+swapData.getClaimHash()+
|
|
187
|
-
" auth expiry: "+timeout+" signature: "+signature);
|
|
188
|
-
|
|
189
|
-
return [tx];
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
getRefundGas(swapData: EVMSwapData): number {
|
|
193
|
-
let totalGas = EVMSwapRefund.GasCosts.BASE;
|
|
194
|
-
if(swapData.reputation) totalGas += EVMSwapRefund.GasCosts.REPUTATION;
|
|
195
|
-
if(swapData.isPayIn()) {
|
|
196
|
-
if(swapData.isToken(this.root.getNativeCurrencyAddress())) {
|
|
197
|
-
totalGas += EVMSwapRefund.GasCosts.NATIVE_TRANSFER;
|
|
198
|
-
} else {
|
|
199
|
-
totalGas += EVMSwapRefund.GasCosts.ERC20_TRANSFER;
|
|
200
|
-
}
|
|
201
|
-
} else {
|
|
202
|
-
totalGas += EVMSwapRefund.GasCosts.LP_VAULT_TRANSFER;
|
|
203
|
-
}
|
|
204
|
-
if(swapData.getSecurityDeposit() > 0n) {
|
|
205
|
-
if(swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
206
|
-
totalGas += EVMSwapRefund.GasCosts.NATIVE_TRANSFER;
|
|
207
|
-
} else {
|
|
208
|
-
totalGas += EVMSwapRefund.GasCosts.ERC20_TRANSFER;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
if(swapData.getClaimerBounty() > swapData.getSecurityDeposit()) {
|
|
212
|
-
if(swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
213
|
-
totalGas += EVMSwapRefund.GasCosts.NATIVE_TRANSFER;
|
|
214
|
-
} else {
|
|
215
|
-
totalGas += EVMSwapRefund.GasCosts.ERC20_TRANSFER;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return totalGas;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Get the estimated transaction fee of the refund transaction
|
|
223
|
-
*/
|
|
224
|
-
async getRefundFee(swapData: EVMSwapData, feeRate?: string): Promise<bigint> {
|
|
225
|
-
feeRate ??= await this.root.Fees.getFeeRate();
|
|
226
|
-
return EVMFees.getGasFee(this.getRefundGas(swapData), feeRate);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
}
|
|
1
|
+
import {SignatureVerificationError, SwapDataVerificationError} from "@atomiqlabs/base";
|
|
2
|
+
import {tryWithRetries} from "../../../utils/Utils";
|
|
3
|
+
import {IHandler} from "../handlers/IHandler";
|
|
4
|
+
import {EVMSwapModule} from "../EVMSwapModule";
|
|
5
|
+
import {Buffer} from "buffer";
|
|
6
|
+
import {EVMSwapData} from "../EVMSwapData";
|
|
7
|
+
import {TransactionRequest} from "ethers";
|
|
8
|
+
import {EVMFees} from "../../chain/modules/EVMFees";
|
|
9
|
+
import {EVMSigner} from "../../wallet/EVMSigner";
|
|
10
|
+
import {EVMTx} from "../../chain/modules/EVMTransactions";
|
|
11
|
+
|
|
12
|
+
const Refund = [
|
|
13
|
+
{ name: "swapHash", type: "bytes32" },
|
|
14
|
+
{ name: "timeout", type: "uint256" }
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
export class EVMSwapRefund extends EVMSwapModule {
|
|
18
|
+
|
|
19
|
+
private static readonly GasCosts = {
|
|
20
|
+
BASE: 35_000 + 21_000,
|
|
21
|
+
ERC20_TRANSFER: 40_000,
|
|
22
|
+
NATIVE_TRANSFER: 35_500,
|
|
23
|
+
LP_VAULT_TRANSFER: 10_000,
|
|
24
|
+
REPUTATION: 25_000
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Action for generic Refund instruction
|
|
29
|
+
*
|
|
30
|
+
* @param signer
|
|
31
|
+
* @param swapData
|
|
32
|
+
* @param witness
|
|
33
|
+
* @param feeRate
|
|
34
|
+
* @param handlerGas
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
private async Refund(
|
|
38
|
+
signer: string,
|
|
39
|
+
swapData: EVMSwapData,
|
|
40
|
+
witness: Buffer,
|
|
41
|
+
feeRate: string,
|
|
42
|
+
handlerGas?: number
|
|
43
|
+
): Promise<TransactionRequest> {
|
|
44
|
+
const tx = await this.swapContract.refund.populateTransaction(swapData.toEscrowStruct(), witness);
|
|
45
|
+
tx.from = signer;
|
|
46
|
+
EVMFees.applyFeeRate(tx, this.getRefundGas(swapData) + (handlerGas ?? 0), feeRate)
|
|
47
|
+
return tx;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Action for cooperative refunding with signature
|
|
52
|
+
*
|
|
53
|
+
* @param sender
|
|
54
|
+
* @param swapData
|
|
55
|
+
* @param timeout
|
|
56
|
+
* @param signature
|
|
57
|
+
* @param feeRate
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
private async RefundWithSignature(
|
|
61
|
+
sender: string,
|
|
62
|
+
swapData: EVMSwapData,
|
|
63
|
+
timeout: string,
|
|
64
|
+
signature: string,
|
|
65
|
+
feeRate: string
|
|
66
|
+
): Promise<TransactionRequest> {
|
|
67
|
+
const tx = await this.swapContract.cooperativeRefund.populateTransaction(swapData.toEscrowStruct(), signature, BigInt(timeout));
|
|
68
|
+
tx.from = sender;
|
|
69
|
+
EVMFees.applyFeeRate(tx, this.getRefundGas(swapData), feeRate)
|
|
70
|
+
return tx;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public async signSwapRefund(
|
|
74
|
+
signer: EVMSigner,
|
|
75
|
+
swapData: EVMSwapData,
|
|
76
|
+
authorizationTimeout: number
|
|
77
|
+
): Promise<{ prefix: string; timeout: string; signature: string }> {
|
|
78
|
+
const authPrefix = "refund";
|
|
79
|
+
const authTimeout = Math.floor(Date.now()/1000)+authorizationTimeout;
|
|
80
|
+
|
|
81
|
+
const signature = await this.root.Signatures.signTypedMessage(this.contract.contractAddress, signer, Refund, "Refund", {
|
|
82
|
+
"swapHash": "0x"+swapData.getEscrowHash(),
|
|
83
|
+
"timeout": BigInt(authTimeout)
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
prefix: authPrefix,
|
|
88
|
+
timeout: authTimeout.toString(10),
|
|
89
|
+
signature: signature
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public async isSignatureValid(
|
|
94
|
+
swapData: EVMSwapData,
|
|
95
|
+
timeout: string,
|
|
96
|
+
prefix: string,
|
|
97
|
+
signature: string
|
|
98
|
+
): Promise<null> {
|
|
99
|
+
if(prefix!=="refund") throw new SignatureVerificationError("Invalid prefix");
|
|
100
|
+
|
|
101
|
+
const expiryTimestamp = BigInt(timeout);
|
|
102
|
+
const currentTimestamp = BigInt(Math.floor(Date.now() / 1000));
|
|
103
|
+
|
|
104
|
+
const isExpired = (expiryTimestamp - currentTimestamp) < BigInt(this.contract.authGracePeriod);
|
|
105
|
+
if(isExpired) throw new SignatureVerificationError("Authorization expired!");
|
|
106
|
+
|
|
107
|
+
const valid = await this.root.Signatures.isValidSignature(this.contract.contractAddress, signature, swapData.claimer, Refund, "Refund", {
|
|
108
|
+
"swapHash": "0x"+swapData.getEscrowHash(),
|
|
109
|
+
"timeout": BigInt(expiryTimestamp)
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
if(!valid) {
|
|
113
|
+
throw new SignatureVerificationError("Invalid signature!");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Creates transactions required for refunding timed out swap
|
|
121
|
+
*
|
|
122
|
+
* @param signer
|
|
123
|
+
* @param swapData swap data to refund
|
|
124
|
+
* @param check whether to check if swap is already expired and refundable
|
|
125
|
+
* @param feeRate fee rate to be used for the transactions
|
|
126
|
+
* @param witnessData
|
|
127
|
+
*/
|
|
128
|
+
public async txsRefund<T>(
|
|
129
|
+
signer: string,
|
|
130
|
+
swapData: EVMSwapData,
|
|
131
|
+
check?: boolean,
|
|
132
|
+
feeRate?: string,
|
|
133
|
+
witnessData?: T
|
|
134
|
+
): Promise<EVMTx[]> {
|
|
135
|
+
const refundHandler: IHandler<any, T> = this.contract.refundHandlersByAddress[swapData.refundHandler.toLowerCase()];
|
|
136
|
+
if(refundHandler==null) throw new Error("Invalid refund handler");
|
|
137
|
+
|
|
138
|
+
if(check && !await tryWithRetries(() => this.contract.isRequestRefundable(swapData.offerer.toString(), swapData), this.retryPolicy)) {
|
|
139
|
+
throw new SwapDataVerificationError("Not refundable yet!");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
feeRate ??= await this.root.Fees.getFeeRate();
|
|
143
|
+
|
|
144
|
+
const {initialTxns, witness} = await refundHandler.getWitness(signer, swapData, witnessData, feeRate);
|
|
145
|
+
|
|
146
|
+
const tx = await this.Refund(signer, swapData, witness, feeRate, refundHandler.getGas(swapData));
|
|
147
|
+
|
|
148
|
+
this.logger.debug("txsRefund(): creating refund transaction, swap: "+swapData.getClaimHash());
|
|
149
|
+
|
|
150
|
+
return [...initialTxns, tx];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Creates transactions required for refunding the swap with authorization signature, also unwraps WSOL to SOL
|
|
155
|
+
*
|
|
156
|
+
* @param signer
|
|
157
|
+
* @param swapData swap data to refund
|
|
158
|
+
* @param timeout signature timeout
|
|
159
|
+
* @param prefix signature prefix of the counterparty
|
|
160
|
+
* @param signature signature of the counterparty
|
|
161
|
+
* @param check whether to check if swap is committed before attempting refund
|
|
162
|
+
* @param feeRate fee rate to be used for the transactions
|
|
163
|
+
*/
|
|
164
|
+
public async txsRefundWithAuthorization(
|
|
165
|
+
signer: string,
|
|
166
|
+
swapData: EVMSwapData,
|
|
167
|
+
timeout: string,
|
|
168
|
+
prefix: string,
|
|
169
|
+
signature: string,
|
|
170
|
+
check?: boolean,
|
|
171
|
+
feeRate?: string
|
|
172
|
+
): Promise<EVMTx[]> {
|
|
173
|
+
if(check && !await tryWithRetries(() => this.contract.isCommited(swapData), this.retryPolicy)) {
|
|
174
|
+
throw new SwapDataVerificationError("Not correctly committed");
|
|
175
|
+
}
|
|
176
|
+
await tryWithRetries(
|
|
177
|
+
() => this.isSignatureValid(swapData, timeout, prefix, signature),
|
|
178
|
+
this.retryPolicy,
|
|
179
|
+
(e) => e instanceof SignatureVerificationError
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
feeRate ??= await this.root.Fees.getFeeRate();
|
|
183
|
+
|
|
184
|
+
const tx = await this.RefundWithSignature(signer, swapData, timeout, signature, feeRate);
|
|
185
|
+
|
|
186
|
+
this.logger.debug("txsRefundWithAuthorization(): creating refund transaction, swap: "+swapData.getClaimHash()+
|
|
187
|
+
" auth expiry: "+timeout+" signature: "+signature);
|
|
188
|
+
|
|
189
|
+
return [tx];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
getRefundGas(swapData: EVMSwapData): number {
|
|
193
|
+
let totalGas = EVMSwapRefund.GasCosts.BASE;
|
|
194
|
+
if(swapData.reputation) totalGas += EVMSwapRefund.GasCosts.REPUTATION;
|
|
195
|
+
if(swapData.isPayIn()) {
|
|
196
|
+
if(swapData.isToken(this.root.getNativeCurrencyAddress())) {
|
|
197
|
+
totalGas += EVMSwapRefund.GasCosts.NATIVE_TRANSFER;
|
|
198
|
+
} else {
|
|
199
|
+
totalGas += EVMSwapRefund.GasCosts.ERC20_TRANSFER;
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
totalGas += EVMSwapRefund.GasCosts.LP_VAULT_TRANSFER;
|
|
203
|
+
}
|
|
204
|
+
if(swapData.getSecurityDeposit() > 0n) {
|
|
205
|
+
if(swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
206
|
+
totalGas += EVMSwapRefund.GasCosts.NATIVE_TRANSFER;
|
|
207
|
+
} else {
|
|
208
|
+
totalGas += EVMSwapRefund.GasCosts.ERC20_TRANSFER;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if(swapData.getClaimerBounty() > swapData.getSecurityDeposit()) {
|
|
212
|
+
if(swapData.isDepositToken(this.root.getNativeCurrencyAddress())) {
|
|
213
|
+
totalGas += EVMSwapRefund.GasCosts.NATIVE_TRANSFER;
|
|
214
|
+
} else {
|
|
215
|
+
totalGas += EVMSwapRefund.GasCosts.ERC20_TRANSFER;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return totalGas;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Get the estimated transaction fee of the refund transaction
|
|
223
|
+
*/
|
|
224
|
+
async getRefundFee(swapData: EVMSwapData, feeRate?: string): Promise<bigint> {
|
|
225
|
+
feeRate ??= await this.root.Fees.getFeeRate();
|
|
226
|
+
return EVMFees.getGasFee(this.getRefundGas(swapData), feeRate);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
}
|