@atomiqlabs/chain-starknet 8.0.13 → 8.1.7
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/starknet/StarknetInitializer.d.ts +3 -0
- package/dist/starknet/StarknetInitializer.js +3 -3
- package/dist/starknet/btcrelay/StarknetBtcRelay.d.ts +1 -1
- package/dist/starknet/btcrelay/StarknetBtcRelay.js +10 -2
- package/dist/starknet/chain/modules/StarknetTransactions.d.ts +7 -0
- package/dist/starknet/chain/modules/StarknetTransactions.js +21 -0
- package/dist/starknet/contract/StarknetContractBase.d.ts +2 -1
- package/dist/starknet/contract/StarknetContractBase.js +2 -1
- package/dist/starknet/contract/modules/StarknetContractEvents.js +1 -1
- package/dist/starknet/events/StarknetChainEventsBrowser.d.ts +0 -12
- package/dist/starknet/events/StarknetChainEventsBrowser.js +2 -61
- package/dist/starknet/spv_swap/StarknetSpvVaultContract.d.ts +8 -2
- package/dist/starknet/spv_swap/StarknetSpvVaultContract.js +45 -8
- package/dist/starknet/swaps/StarknetSwapContract.d.ts +35 -3
- package/dist/starknet/swaps/StarknetSwapContract.js +178 -2
- package/package.json +2 -2
- package/src/starknet/StarknetInitializer.ts +6 -3
- package/src/starknet/btcrelay/StarknetBtcRelay.ts +15 -2
- package/src/starknet/chain/modules/StarknetTransactions.ts +24 -0
- package/src/starknet/contract/StarknetContractBase.ts +4 -1
- package/src/starknet/contract/modules/StarknetContractEvents.ts +1 -1
- package/src/starknet/events/StarknetChainEventsBrowser.ts +2 -64
- package/src/starknet/spv_swap/StarknetSpvVaultContract.ts +68 -10
- package/src/starknet/swaps/StarknetSwapContract.ts +242 -6
|
@@ -30,8 +30,11 @@ export type StarknetOptions = {
|
|
|
30
30
|
};
|
|
31
31
|
chainId?: constants.StarknetChainId;
|
|
32
32
|
swapContract?: string;
|
|
33
|
+
swapContractDeploymentHeight?: number;
|
|
33
34
|
btcRelayContract?: string;
|
|
35
|
+
btcRelayContractDeploymentHeight?: number;
|
|
34
36
|
spvVaultContract?: string;
|
|
37
|
+
spvVaultContractDeploymentHeight?: number;
|
|
35
38
|
handlerContracts?: {
|
|
36
39
|
refund?: {
|
|
37
40
|
timelock?: string;
|
|
@@ -71,9 +71,9 @@ function initializeStarknet(options, bitcoinRpc, network) {
|
|
|
71
71
|
const chainId = options.chainId ??
|
|
72
72
|
(network === base_1.BitcoinNetwork.MAINNET ? starknet_1.constants.StarknetChainId.SN_MAIN : starknet_1.constants.StarknetChainId.SN_SEPOLIA);
|
|
73
73
|
const chainInterface = new StarknetChainInterface_1.StarknetChainInterface(chainId, provider, wsChannel, Fees, options.starknetConfig);
|
|
74
|
-
const btcRelay = new StarknetBtcRelay_1.StarknetBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract);
|
|
75
|
-
const swapContract = new StarknetSwapContract_1.StarknetSwapContract(chainInterface, btcRelay, options.swapContract, options.handlerContracts);
|
|
76
|
-
const spvVaultContract = new StarknetSpvVaultContract_1.StarknetSpvVaultContract(chainInterface, btcRelay, bitcoinRpc, options.spvVaultContract);
|
|
74
|
+
const btcRelay = new StarknetBtcRelay_1.StarknetBtcRelay(chainInterface, bitcoinRpc, network, options.btcRelayContract, options.btcRelayContractDeploymentHeight);
|
|
75
|
+
const swapContract = new StarknetSwapContract_1.StarknetSwapContract(chainInterface, btcRelay, options.swapContract, options.handlerContracts, options.swapContractDeploymentHeight);
|
|
76
|
+
const spvVaultContract = new StarknetSpvVaultContract_1.StarknetSpvVaultContract(chainInterface, btcRelay, bitcoinRpc, options.spvVaultContract, options.spvVaultContractDeploymentHeight);
|
|
77
77
|
const chainEvents = new StarknetChainEventsBrowser_1.StarknetChainEventsBrowser(chainInterface, swapContract, spvVaultContract);
|
|
78
78
|
return {
|
|
79
79
|
chainId: "STARKNET",
|
|
@@ -47,7 +47,7 @@ export declare class StarknetBtcRelay<B extends BtcBlock> extends StarknetContra
|
|
|
47
47
|
readonly maxHeadersPerTx: number;
|
|
48
48
|
readonly maxForkHeadersPerTx: number;
|
|
49
49
|
readonly maxShortForkHeadersPerTx: number;
|
|
50
|
-
constructor(chainInterface: StarknetChainInterface, bitcoinRpc: BitcoinRpc<B>, bitcoinNetwork: BitcoinNetwork, contractAddress?: string | undefined);
|
|
50
|
+
constructor(chainInterface: StarknetChainInterface, bitcoinRpc: BitcoinRpc<B>, bitcoinNetwork: BitcoinNetwork, contractAddress?: string | undefined, contractDeploymentHeight?: number);
|
|
51
51
|
/**
|
|
52
52
|
* Computes subsequent commited headers as they will appear on the blockchain when transactions
|
|
53
53
|
* are submitted & confirmed
|
|
@@ -29,6 +29,11 @@ const btcRelayAddreses = {
|
|
|
29
29
|
[base_1.BitcoinNetwork.TESTNET]: "0x068601c79da2231d21e015ccfd59c243861156fa523a12c9f987ec28eb8dbc8c",
|
|
30
30
|
[base_1.BitcoinNetwork.MAINNET]: "0x057b14a4231b82f1e525ff35a722d893ca3dd2bde0baa6cee97937c5be861dbc"
|
|
31
31
|
};
|
|
32
|
+
const btcRelayDeploymentHeights = {
|
|
33
|
+
[base_1.BitcoinNetwork.TESTNET4]: 760719,
|
|
34
|
+
[base_1.BitcoinNetwork.TESTNET]: 633915,
|
|
35
|
+
[base_1.BitcoinNetwork.MAINNET]: 1278562
|
|
36
|
+
};
|
|
32
37
|
function serializeCalldata(headers, storedHeader, span) {
|
|
33
38
|
span.push((0, Utils_1.toHex)(headers.length));
|
|
34
39
|
headers.forEach(header => {
|
|
@@ -91,10 +96,13 @@ class StarknetBtcRelay extends StarknetContractBase_1.StarknetContractBase {
|
|
|
91
96
|
calldata: serializeCalldata(forkHeaders, storedHeader, [(0, Utils_1.toHex)(forkId)])
|
|
92
97
|
}, (0, StarknetFees_1.starknetGasAdd)((0, StarknetFees_1.starknetGasMul)(GAS_PER_BLOCKHEADER, forkHeaders.length), (0, StarknetFees_1.starknetGasMul)(GAS_PER_BLOCKHEADER_FORK, totalForkHeaders)));
|
|
93
98
|
}
|
|
94
|
-
constructor(chainInterface, bitcoinRpc, bitcoinNetwork, contractAddress = btcRelayAddreses[bitcoinNetwork]) {
|
|
99
|
+
constructor(chainInterface, bitcoinRpc, bitcoinNetwork, contractAddress = btcRelayAddreses[bitcoinNetwork], contractDeploymentHeight) {
|
|
95
100
|
if (contractAddress == null)
|
|
96
101
|
throw new Error("No BtcRelay address specified!");
|
|
97
|
-
super(chainInterface, contractAddress, BtcRelayAbi_1.BtcRelayAbi
|
|
102
|
+
super(chainInterface, contractAddress, BtcRelayAbi_1.BtcRelayAbi, contractDeploymentHeight ??
|
|
103
|
+
(btcRelayAddreses[bitcoinNetwork] === contractAddress
|
|
104
|
+
? btcRelayDeploymentHeights[bitcoinNetwork]
|
|
105
|
+
: undefined));
|
|
98
106
|
this.maxHeadersPerTx = 40;
|
|
99
107
|
this.maxForkHeadersPerTx = 30;
|
|
100
108
|
this.maxShortForkHeadersPerTx = 40;
|
|
@@ -21,6 +21,12 @@ export type StarknetTxDeployAccount = StarknetTxBase & {
|
|
|
21
21
|
export declare function isStarknetTxDeployAccount(obj: any): obj is StarknetTxDeployAccount;
|
|
22
22
|
export type StarknetTx = StarknetTxInvoke | StarknetTxDeployAccount;
|
|
23
23
|
export type SignedStarknetTx = StarknetTx;
|
|
24
|
+
export type StarknetTraceCall = {
|
|
25
|
+
calldata: string[];
|
|
26
|
+
contract_address: string;
|
|
27
|
+
entry_point_selector: string;
|
|
28
|
+
calls: StarknetTraceCall[];
|
|
29
|
+
};
|
|
24
30
|
export declare class StarknetTransactions extends StarknetModule {
|
|
25
31
|
private readonly latestConfirmedNonces;
|
|
26
32
|
private readonly latestPendingNonces;
|
|
@@ -108,6 +114,7 @@ export declare class StarknetTransactions extends StarknetModule {
|
|
|
108
114
|
* @param txId
|
|
109
115
|
*/
|
|
110
116
|
getTxIdStatus(txId: string): Promise<"pending" | "success" | "not_found" | "reverted">;
|
|
117
|
+
traceTransaction(txId: string, blockHash?: string): Promise<StarknetTraceCall | null>;
|
|
111
118
|
onBeforeTxReplace(callback: (oldTx: string, oldTxId: string, newTx: string, newTxId: string) => Promise<void>): void;
|
|
112
119
|
offBeforeTxReplace(callback: (oldTx: string, oldTxId: string, newTx: string, newTxId: string) => Promise<void>): boolean;
|
|
113
120
|
onBeforeTxSigned(callback: (tx: StarknetTx) => Promise<void>): void;
|
|
@@ -588,6 +588,27 @@ class StarknetTransactions extends StarknetModule_1.StarknetModule {
|
|
|
588
588
|
return "reverted";
|
|
589
589
|
return status;
|
|
590
590
|
}
|
|
591
|
+
async traceTransaction(txId, blockHash) {
|
|
592
|
+
let trace;
|
|
593
|
+
try {
|
|
594
|
+
trace = await this.provider.getTransactionTrace(txId);
|
|
595
|
+
}
|
|
596
|
+
catch (e) {
|
|
597
|
+
this.logger.warn("getSwapDataGetter(): getter: starknet_traceTransaction not supported by the RPC: ", e);
|
|
598
|
+
if (blockHash == null)
|
|
599
|
+
throw e;
|
|
600
|
+
const blockTraces = await this.provider.getBlockTransactionsTraces(blockHash);
|
|
601
|
+
const foundTrace = blockTraces.find(val => (0, Utils_1.toHex)(val.transaction_hash) === (0, Utils_1.toHex)(txId));
|
|
602
|
+
if (foundTrace == null)
|
|
603
|
+
throw new Error(`Cannot find ${txId} in the block traces, block: ${blockHash}`);
|
|
604
|
+
trace = foundTrace.trace_root;
|
|
605
|
+
}
|
|
606
|
+
if (trace == null)
|
|
607
|
+
return null;
|
|
608
|
+
if (trace.execute_invocation.revert_reason != null)
|
|
609
|
+
return null;
|
|
610
|
+
return trace.execute_invocation;
|
|
611
|
+
}
|
|
591
612
|
onBeforeTxReplace(callback) {
|
|
592
613
|
this._cbksBeforeTxReplace.push(callback);
|
|
593
614
|
}
|
|
@@ -9,5 +9,6 @@ export declare class StarknetContractBase<T extends Abi> {
|
|
|
9
9
|
contract: TypedContractV2<T>;
|
|
10
10
|
readonly Events: StarknetContractEvents<T>;
|
|
11
11
|
readonly Chain: StarknetChainInterface;
|
|
12
|
-
|
|
12
|
+
readonly contractDeploymentHeight?: number;
|
|
13
|
+
constructor(chainInterface: StarknetChainInterface, contractAddress: string, contractAbi: T, contractDeploymentHeight?: number);
|
|
13
14
|
}
|
|
@@ -7,7 +7,7 @@ const StarknetContractEvents_1 = require("./modules/StarknetContractEvents");
|
|
|
7
7
|
* Base class providing program specific utilities
|
|
8
8
|
*/
|
|
9
9
|
class StarknetContractBase {
|
|
10
|
-
constructor(chainInterface, contractAddress, contractAbi) {
|
|
10
|
+
constructor(chainInterface, contractAddress, contractAbi, contractDeploymentHeight) {
|
|
11
11
|
this.Chain = chainInterface;
|
|
12
12
|
this.contract = new starknet_1.Contract({
|
|
13
13
|
abi: contractAbi,
|
|
@@ -15,6 +15,7 @@ class StarknetContractBase {
|
|
|
15
15
|
providerOrAccount: chainInterface.provider
|
|
16
16
|
}).typedv2(contractAbi);
|
|
17
17
|
this.Events = new StarknetContractEvents_1.StarknetContractEvents(chainInterface, this, contractAbi);
|
|
18
|
+
this.contractDeploymentHeight = contractDeploymentHeight;
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
exports.StarknetContractBase = StarknetContractBase;
|
|
@@ -105,7 +105,7 @@ class StarknetContractEvents extends StarknetEvents_1.StarknetEvents {
|
|
|
105
105
|
return result;
|
|
106
106
|
}
|
|
107
107
|
return null;
|
|
108
|
-
}, startHeight, abortSignal);
|
|
108
|
+
}, Math.max(startHeight ?? 0, this.contract.contractDeploymentHeight ?? 0), abortSignal);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
exports.StarknetContractEvents = StarknetContractEvents;
|
|
@@ -2,8 +2,6 @@ import { ChainEvents, EventListener } from "@atomiqlabs/base";
|
|
|
2
2
|
import { StarknetSwapData } from "../swaps/StarknetSwapData";
|
|
3
3
|
import { StarknetSwapContract } from "../swaps/StarknetSwapContract";
|
|
4
4
|
import { Provider, SubscriptionStarknetEventsEvent, WebSocketChannel } from "starknet";
|
|
5
|
-
import { EscrowManagerAbiType } from "../swaps/EscrowManagerAbi";
|
|
6
|
-
import { ExtractAbiFunctionNames } from "abi-wan-kanabi/dist/kanabi";
|
|
7
5
|
import { StarknetSpvVaultContract } from "../spv_swap/StarknetSpvVaultContract";
|
|
8
6
|
import { StarknetChainInterface } from "../chain/StarknetChainInterface";
|
|
9
7
|
/**
|
|
@@ -35,8 +33,6 @@ export declare class StarknetChainEventsBrowser implements ChainEvents<StarknetS
|
|
|
35
33
|
protected readonly logger: import("../../utils/Utils").LoggerType;
|
|
36
34
|
protected escrowContractSubscription?: SubscriptionStarknetEventsEvent;
|
|
37
35
|
protected spvVaultContractSubscription?: SubscriptionStarknetEventsEvent;
|
|
38
|
-
protected initFunctionName: ExtractAbiFunctionNames<EscrowManagerAbiType>;
|
|
39
|
-
protected initEntryPointSelector: bigint;
|
|
40
36
|
protected stopped: boolean;
|
|
41
37
|
protected pollIntervalSeconds: number;
|
|
42
38
|
private timeout;
|
|
@@ -59,14 +55,6 @@ export declare class StarknetChainEventsBrowser implements ChainEvents<StarknetS
|
|
|
59
55
|
* @private
|
|
60
56
|
*/
|
|
61
57
|
private isEventProcessed;
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
* @param call
|
|
65
|
-
* @param escrowHash
|
|
66
|
-
* @param claimHandler
|
|
67
|
-
* @private
|
|
68
|
-
*/
|
|
69
|
-
private findInitSwapData;
|
|
70
58
|
/**
|
|
71
59
|
* Returns async getter for fetching on-demand initialize event swap data
|
|
72
60
|
*
|
|
@@ -2,30 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StarknetChainEventsBrowser = void 0;
|
|
4
4
|
const base_1 = require("@atomiqlabs/base");
|
|
5
|
-
const StarknetSwapData_1 = require("../swaps/StarknetSwapData");
|
|
6
5
|
const Utils_1 = require("../../utils/Utils");
|
|
7
6
|
const starknet_1 = require("starknet");
|
|
8
7
|
const sha2_1 = require("@noble/hashes/sha2");
|
|
9
8
|
const buffer_1 = require("buffer");
|
|
10
9
|
const PROCESSED_EVENTS_BACKLOG = 5000;
|
|
11
10
|
const LOGS_SLIDING_WINDOW = 60;
|
|
12
|
-
function parseInitFunctionCalldata(calldata, claimHandler) {
|
|
13
|
-
const escrow = StarknetSwapData_1.StarknetSwapData.fromSerializedFeltArray(calldata, claimHandler);
|
|
14
|
-
if (calldata.length < 1)
|
|
15
|
-
throw new Error("Calldata invalid length");
|
|
16
|
-
const signatureLen = Number((0, Utils_1.toBigInt)(calldata.shift()));
|
|
17
|
-
if (calldata.length < signatureLen + 2)
|
|
18
|
-
throw new Error("Calldata invalid length");
|
|
19
|
-
const signature = calldata.splice(0, signatureLen);
|
|
20
|
-
const timeout = (0, Utils_1.toBigInt)(calldata.shift());
|
|
21
|
-
const extraDataLen = Number((0, Utils_1.toBigInt)(calldata.shift()));
|
|
22
|
-
if (calldata.length < extraDataLen)
|
|
23
|
-
throw new Error("Calldata invalid length");
|
|
24
|
-
const extraData = calldata.splice(0, extraDataLen);
|
|
25
|
-
if (calldata.length !== 0)
|
|
26
|
-
throw new Error("Calldata not read fully!");
|
|
27
|
-
return { escrow, signature, timeout, extraData };
|
|
28
|
-
}
|
|
29
11
|
/**
|
|
30
12
|
* Starknet on-chain event handler for front-end systems without access to fs, uses WS or long-polling to subscribe, might lose
|
|
31
13
|
* out on some events if the network is unreliable, front-end systems should take this into consideration and not
|
|
@@ -39,8 +21,6 @@ class StarknetChainEventsBrowser {
|
|
|
39
21
|
this.processedEvents = new Set();
|
|
40
22
|
this.listeners = [];
|
|
41
23
|
this.logger = (0, Utils_1.getLogger)("StarknetChainEventsBrowser: ");
|
|
42
|
-
this.initFunctionName = "initialize";
|
|
43
|
-
this.initEntryPointSelector = BigInt(starknet_1.hash.starknetKeccak(this.initFunctionName));
|
|
44
24
|
this.stopped = true;
|
|
45
25
|
this.wsStarted = false;
|
|
46
26
|
this.Chain = chainInterface;
|
|
@@ -82,32 +62,6 @@ class StarknetChainEventsBrowser {
|
|
|
82
62
|
const eventFingerprint = typeof (eventOrFingerprint) === "string" ? eventOrFingerprint : this.getEventFingerprint(eventOrFingerprint);
|
|
83
63
|
return this.processedEvents.has(eventFingerprint);
|
|
84
64
|
}
|
|
85
|
-
/**
|
|
86
|
-
*
|
|
87
|
-
* @param call
|
|
88
|
-
* @param escrowHash
|
|
89
|
-
* @param claimHandler
|
|
90
|
-
* @private
|
|
91
|
-
*/
|
|
92
|
-
findInitSwapData(call, escrowHash, claimHandler) {
|
|
93
|
-
if (BigInt(call.contract_address) === BigInt(this.starknetSwapContract.contract.address) &&
|
|
94
|
-
BigInt(call.entry_point_selector) === this.initEntryPointSelector) {
|
|
95
|
-
//Found, check correct escrow hash
|
|
96
|
-
const { escrow, extraData } = parseInitFunctionCalldata(call.calldata, claimHandler);
|
|
97
|
-
if ("0x" + escrow.getEscrowHash() === (0, Utils_1.toHex)(escrowHash)) {
|
|
98
|
-
if (extraData.length !== 0) {
|
|
99
|
-
escrow.setExtraData((0, Utils_1.bytes31SpanToBuffer)(extraData, 42).toString("hex"));
|
|
100
|
-
}
|
|
101
|
-
return escrow;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
for (let _call of call.calls) {
|
|
105
|
-
const found = this.findInitSwapData(_call, escrowHash, claimHandler);
|
|
106
|
-
if (found != null)
|
|
107
|
-
return found;
|
|
108
|
-
}
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
65
|
/**
|
|
112
66
|
* Returns async getter for fetching on-demand initialize event swap data
|
|
113
67
|
*
|
|
@@ -118,23 +72,10 @@ class StarknetChainEventsBrowser {
|
|
|
118
72
|
*/
|
|
119
73
|
getSwapDataGetter(event, claimHandler) {
|
|
120
74
|
return async () => {
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
trace = await this.provider.getTransactionTrace(event.txHash);
|
|
124
|
-
}
|
|
125
|
-
catch (e) {
|
|
126
|
-
this.logger.warn("getSwapDataGetter(): getter: starknet_traceTransaction not supported by the RPC: ", e);
|
|
127
|
-
const blockTraces = await this.provider.getBlockTransactionsTraces(event.blockHash);
|
|
128
|
-
const foundTrace = blockTraces.find(val => (0, Utils_1.toHex)(val.transaction_hash) === (0, Utils_1.toHex)(event.txHash));
|
|
129
|
-
if (foundTrace == null)
|
|
130
|
-
throw new Error(`Cannot find ${event.txHash} in the block traces, block: ${event.blockHash}`);
|
|
131
|
-
trace = foundTrace.trace_root;
|
|
132
|
-
}
|
|
75
|
+
const trace = await this.Chain.Transactions.traceTransaction(event.txHash, event.blockHash);
|
|
133
76
|
if (trace == null)
|
|
134
77
|
return null;
|
|
135
|
-
|
|
136
|
-
return null;
|
|
137
|
-
return this.findInitSwapData(trace.execute_invocation, event.params.escrow_hash, claimHandler);
|
|
78
|
+
return this.starknetSwapContract.findInitSwapData(trace, event.params.escrow_hash, claimHandler);
|
|
138
79
|
};
|
|
139
80
|
}
|
|
140
81
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BitcoinRpc, BtcTx, RelaySynchronizer, SpvVaultContract, SpvVaultTokenData, SpvWithdrawalState, SpvWithdrawalTransactionData, TransactionConfirmationOptions } from "@atomiqlabs/base";
|
|
1
|
+
import { BitcoinRpc, BtcTx, RelaySynchronizer, SpvVaultContract, SpvVaultTokenData, SpvWithdrawalClaimedState, SpvWithdrawalFrontedState, SpvWithdrawalState, SpvWithdrawalTransactionData, TransactionConfirmationOptions } from "@atomiqlabs/base";
|
|
2
2
|
import { Buffer } from "buffer";
|
|
3
3
|
import { StarknetTx } from "../chain/modules/StarknetTransactions";
|
|
4
4
|
import { StarknetContractBase } from "../contract/StarknetContractBase";
|
|
@@ -23,7 +23,7 @@ export declare class StarknetSpvVaultContract extends StarknetContractBase<typeo
|
|
|
23
23
|
readonly claimTimeout: number;
|
|
24
24
|
readonly maxClaimsPerTx: number;
|
|
25
25
|
readonly logger: import("../../utils/Utils").LoggerType;
|
|
26
|
-
constructor(chainInterface: StarknetChainInterface, btcRelay: StarknetBtcRelay<any>, bitcoinRpc: BitcoinRpc<any>, contractAddress?: string);
|
|
26
|
+
constructor(chainInterface: StarknetChainInterface, btcRelay: StarknetBtcRelay<any>, bitcoinRpc: BitcoinRpc<any>, contractAddress?: string, contractDeploymentHeight?: number);
|
|
27
27
|
/**
|
|
28
28
|
* Returns a {@link StarknetAction} that opens up the spv vault with the passed data
|
|
29
29
|
*
|
|
@@ -136,6 +136,12 @@ export declare class StarknetSpvVaultContract extends StarknetContractBase<typeo
|
|
|
136
136
|
* @inheritDoc
|
|
137
137
|
*/
|
|
138
138
|
getWithdrawalState(withdrawalTx: StarknetSpvWithdrawalData, scStartBlockheight?: number): Promise<SpvWithdrawalState>;
|
|
139
|
+
getHistoricalWithdrawalStates(recipient: string, startBlockheight?: number): Promise<{
|
|
140
|
+
withdrawals: {
|
|
141
|
+
[btcTxId: string]: SpvWithdrawalClaimedState | SpvWithdrawalFrontedState;
|
|
142
|
+
};
|
|
143
|
+
latestBlockheight?: number;
|
|
144
|
+
}>;
|
|
139
145
|
/**
|
|
140
146
|
* @inheritDoc
|
|
141
147
|
*/
|
|
@@ -17,6 +17,10 @@ const spvVaultContractAddreses = {
|
|
|
17
17
|
[starknet_1.constants.StarknetChainId.SN_SEPOLIA]: "0x02d581ea838cd5ca46ba08660eddd064d50a0392f618e95310432147928d572e",
|
|
18
18
|
[starknet_1.constants.StarknetChainId.SN_MAIN]: "0x01932042992647771f3d0aa6ee526e65359c891fe05a285faaf4d3ffa373e132"
|
|
19
19
|
};
|
|
20
|
+
const spvVaultContractDeploymentHeights = {
|
|
21
|
+
[starknet_1.constants.StarknetChainId.SN_SEPOLIA]: 1118191,
|
|
22
|
+
[starknet_1.constants.StarknetChainId.SN_MAIN]: 1617295
|
|
23
|
+
};
|
|
20
24
|
const STARK_PRIME_MOD = 2n ** 251n + 17n * 2n ** 192n + 1n;
|
|
21
25
|
function decodeUtxo(utxo) {
|
|
22
26
|
const [txId, vout] = utxo.split(":");
|
|
@@ -31,8 +35,11 @@ function decodeUtxo(utxo) {
|
|
|
31
35
|
* @category Swaps
|
|
32
36
|
*/
|
|
33
37
|
class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBase {
|
|
34
|
-
constructor(chainInterface, btcRelay, bitcoinRpc, contractAddress = spvVaultContractAddreses[chainInterface.starknetChainId]) {
|
|
35
|
-
super(chainInterface, contractAddress, SpvVaultContractAbi_1.SpvVaultContractAbi
|
|
38
|
+
constructor(chainInterface, btcRelay, bitcoinRpc, contractAddress = spvVaultContractAddreses[chainInterface.starknetChainId], contractDeploymentHeight) {
|
|
39
|
+
super(chainInterface, contractAddress, SpvVaultContractAbi_1.SpvVaultContractAbi, contractDeploymentHeight ??
|
|
40
|
+
(spvVaultContractAddreses[chainInterface.starknetChainId] === contractAddress
|
|
41
|
+
? spvVaultContractDeploymentHeights[chainInterface.starknetChainId]
|
|
42
|
+
: undefined));
|
|
36
43
|
this.chainId = "STARKNET";
|
|
37
44
|
this.claimTimeout = 180;
|
|
38
45
|
this.maxClaimsPerTx = 10;
|
|
@@ -265,29 +272,44 @@ class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBa
|
|
|
265
272
|
case "spv_swap_vault::events::Fronted":
|
|
266
273
|
return {
|
|
267
274
|
type: base_1.SpvWithdrawalStateType.FRONTED,
|
|
268
|
-
|
|
275
|
+
btcTxId: (0, Utils_1.bigNumberishToBuffer)(event.params.btc_tx_hash, 32).reverse().toString("hex"),
|
|
269
276
|
owner: (0, Utils_1.toHex)(event.params.owner),
|
|
270
277
|
vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
|
|
271
278
|
recipient: (0, Utils_1.toHex)(event.params.recipient),
|
|
272
|
-
fronter: (0, Utils_1.toHex)(event.params.
|
|
279
|
+
fronter: (0, Utils_1.toHex)(event.params.caller),
|
|
280
|
+
txId: event.txHash,
|
|
281
|
+
getTxBlock: async () => ({
|
|
282
|
+
blockHeight: event.blockNumber,
|
|
283
|
+
blockTime: await this.Chain.Blocks.getBlockTime(event.blockNumber)
|
|
284
|
+
})
|
|
273
285
|
};
|
|
274
286
|
case "spv_swap_vault::events::Claimed":
|
|
275
287
|
return {
|
|
276
288
|
type: base_1.SpvWithdrawalStateType.CLAIMED,
|
|
277
|
-
|
|
289
|
+
btcTxId: (0, Utils_1.bigNumberishToBuffer)(event.params.btc_tx_hash, 32).reverse().toString("hex"),
|
|
278
290
|
owner: (0, Utils_1.toHex)(event.params.owner),
|
|
279
291
|
vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
|
|
280
292
|
recipient: (0, Utils_1.toHex)(event.params.recipient),
|
|
281
293
|
claimer: (0, Utils_1.toHex)(event.params.caller),
|
|
282
|
-
fronter: (0, Utils_1.toHex)(event.params.fronting_address)
|
|
294
|
+
fronter: (0, Utils_1.toHex)(event.params.fronting_address),
|
|
295
|
+
txId: event.txHash,
|
|
296
|
+
getTxBlock: async () => ({
|
|
297
|
+
blockHeight: event.blockNumber,
|
|
298
|
+
blockTime: await this.Chain.Blocks.getBlockTime(event.blockNumber)
|
|
299
|
+
})
|
|
283
300
|
};
|
|
284
301
|
case "spv_swap_vault::events::Closed":
|
|
285
302
|
return {
|
|
286
303
|
type: base_1.SpvWithdrawalStateType.CLOSED,
|
|
287
|
-
|
|
304
|
+
btcTxId: (0, Utils_1.bigNumberishToBuffer)(event.params.btc_tx_hash, 32).reverse().toString("hex"),
|
|
288
305
|
owner: (0, Utils_1.toHex)(event.params.owner),
|
|
289
306
|
vaultId: (0, Utils_1.toBigInt)(event.params.vault_id),
|
|
290
|
-
error: (0, Utils_1.bigNumberishToBuffer)(event.params.error).toString()
|
|
307
|
+
error: (0, Utils_1.bigNumberishToBuffer)(event.params.error).toString(),
|
|
308
|
+
txId: event.txHash,
|
|
309
|
+
getTxBlock: async () => ({
|
|
310
|
+
blockHeight: event.blockNumber,
|
|
311
|
+
blockTime: await this.Chain.Blocks.getBlockTime(event.blockNumber)
|
|
312
|
+
})
|
|
291
313
|
};
|
|
292
314
|
default:
|
|
293
315
|
return null;
|
|
@@ -354,6 +376,21 @@ class StarknetSpvVaultContract extends StarknetContractBase_1.StarknetContractBa
|
|
|
354
376
|
}, scStartBlockheight);
|
|
355
377
|
return result;
|
|
356
378
|
}
|
|
379
|
+
async getHistoricalWithdrawalStates(recipient, startBlockheight) {
|
|
380
|
+
const { height: latestBlockheight } = await this.Chain.getFinalizedBlock();
|
|
381
|
+
const withdrawals = {};
|
|
382
|
+
const eventTypes = ["spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed"];
|
|
383
|
+
await this.Events.findInContractEventsForward(eventTypes, [null, null, null, null, recipient], async (_event) => {
|
|
384
|
+
const eventResult = this.parseWithdrawalEvent(_event);
|
|
385
|
+
if (eventResult == null || eventResult.type === base_1.SpvWithdrawalStateType.CLOSED)
|
|
386
|
+
return null;
|
|
387
|
+
withdrawals[eventResult.btcTxId] = eventResult;
|
|
388
|
+
}, startBlockheight);
|
|
389
|
+
return {
|
|
390
|
+
withdrawals,
|
|
391
|
+
latestBlockheight
|
|
392
|
+
};
|
|
393
|
+
}
|
|
357
394
|
/**
|
|
358
395
|
* @inheritDoc
|
|
359
396
|
*/
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ChainSwapType, IntermediaryReputationType, RelaySynchronizer, SignatureData, SwapCommitState, SwapContract, TransactionConfirmationOptions } from "@atomiqlabs/base";
|
|
2
2
|
import { Buffer } from "buffer";
|
|
3
|
-
import { EscrowManagerAbi } from "./EscrowManagerAbi";
|
|
3
|
+
import { EscrowManagerAbi, EscrowManagerAbiType } from "./EscrowManagerAbi";
|
|
4
4
|
import { StarknetContractBase } from "../contract/StarknetContractBase";
|
|
5
|
-
import { StarknetTx } from "../chain/modules/StarknetTransactions";
|
|
5
|
+
import { StarknetTraceCall, StarknetTx } from "../chain/modules/StarknetTransactions";
|
|
6
6
|
import { StarknetSigner } from "../wallet/StarknetSigner";
|
|
7
|
+
import { BigNumberish } from "starknet";
|
|
7
8
|
import { StarknetChainInterface } from "../chain/StarknetChainInterface";
|
|
8
9
|
import { StarknetBtcRelay } from "../btcrelay/StarknetBtcRelay";
|
|
9
10
|
import { StarknetSwapData } from "./StarknetSwapData";
|
|
@@ -14,6 +15,7 @@ import { IClaimHandler } from "./handlers/claim/ClaimHandlers";
|
|
|
14
15
|
import { StarknetSwapClaim } from "./modules/StarknetSwapClaim";
|
|
15
16
|
import { IHandler } from "./handlers/IHandler";
|
|
16
17
|
import { StarknetBtcStoredHeader } from "../btcrelay/headers/StarknetBtcStoredHeader";
|
|
18
|
+
import { ExtractAbiFunctionNames } from "abi-wan-kanabi/dist/kanabi";
|
|
17
19
|
/**
|
|
18
20
|
* Starknet swap contract (escrow manager) contract representation handling PrTLC (on-chain) and HTLC (lightning)
|
|
19
21
|
* based swaps
|
|
@@ -59,6 +61,8 @@ export declare class StarknetSwapContract extends StarknetContractBase<typeof Es
|
|
|
59
61
|
};
|
|
60
62
|
readonly timelockRefundHandler: IHandler<any, any>;
|
|
61
63
|
readonly btcRelay: StarknetBtcRelay<any>;
|
|
64
|
+
protected readonly initFunctionName: ExtractAbiFunctionNames<EscrowManagerAbiType>;
|
|
65
|
+
protected readonly initEntryPointSelector: bigint;
|
|
62
66
|
/**
|
|
63
67
|
* Constructs the swap contract (escrow manager)
|
|
64
68
|
*
|
|
@@ -66,6 +70,7 @@ export declare class StarknetSwapContract extends StarknetContractBase<typeof Es
|
|
|
66
70
|
* @param btcRelay Btc relay light client contract
|
|
67
71
|
* @param contractAddress Optional underlying contract address (default is used otherwise)
|
|
68
72
|
* @param _handlerAddresses Optional handler addresses (defaults are used otherwise)
|
|
73
|
+
* @param contractDeploymentHeight The height at which this contract was deployed (default is used otherwise)
|
|
69
74
|
*/
|
|
70
75
|
constructor(chainInterface: StarknetChainInterface, btcRelay: StarknetBtcRelay<any>, contractAddress?: string, _handlerAddresses?: {
|
|
71
76
|
refund?: {
|
|
@@ -74,7 +79,7 @@ export declare class StarknetSwapContract extends StarknetContractBase<typeof Es
|
|
|
74
79
|
claim?: {
|
|
75
80
|
[type in ChainSwapType]?: string;
|
|
76
81
|
};
|
|
77
|
-
});
|
|
82
|
+
}, contractDeploymentHeight?: number);
|
|
78
83
|
/**
|
|
79
84
|
* @inheritDoc
|
|
80
85
|
*/
|
|
@@ -160,10 +165,37 @@ export declare class StarknetSwapContract extends StarknetContractBase<typeof Es
|
|
|
160
165
|
}[]): Promise<{
|
|
161
166
|
[p: string]: SwapCommitState;
|
|
162
167
|
}>;
|
|
168
|
+
/**
|
|
169
|
+
* @inheritDoc
|
|
170
|
+
*/
|
|
171
|
+
getHistoricalSwaps(signer: string, startBlockheight?: number): Promise<{
|
|
172
|
+
swaps: {
|
|
173
|
+
[escrowHash: string]: {
|
|
174
|
+
init?: {
|
|
175
|
+
data: StarknetSwapData;
|
|
176
|
+
getInitTxId: () => Promise<string>;
|
|
177
|
+
getTxBlock: () => Promise<{
|
|
178
|
+
blockTime: number;
|
|
179
|
+
blockHeight: number;
|
|
180
|
+
}>;
|
|
181
|
+
};
|
|
182
|
+
state: SwapCommitState;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
latestBlockheight?: number;
|
|
186
|
+
}>;
|
|
163
187
|
/**
|
|
164
188
|
* @inheritDoc
|
|
165
189
|
*/
|
|
166
190
|
createSwapData(type: ChainSwapType, offerer: string, claimer: string, token: string, amount: bigint, claimData: string, sequence: bigint, expiry: bigint, payIn: boolean, payOut: boolean, securityDeposit: bigint, claimerBounty: bigint, depositToken?: string): Promise<StarknetSwapData>;
|
|
191
|
+
/**
|
|
192
|
+
*
|
|
193
|
+
* @param call
|
|
194
|
+
* @param escrowHash
|
|
195
|
+
* @param claimHandler
|
|
196
|
+
* @private
|
|
197
|
+
*/
|
|
198
|
+
findInitSwapData(call: StarknetTraceCall, escrowHash: BigNumberish, claimHandler: IClaimHandler<any, any>): StarknetSwapData | null;
|
|
167
199
|
/**
|
|
168
200
|
*
|
|
169
201
|
* @param address
|