@atomiqlabs/chain-starknet 1.0.9 → 2.0.0-beta.1
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/index.d.ts +13 -9
- package/dist/index.js +13 -9
- package/dist/starknet/StarknetChainType.d.ts +6 -2
- package/dist/starknet/StarknetInitializer.d.ts +3 -2
- package/dist/starknet/StarknetInitializer.js +17 -6
- package/dist/starknet/btcrelay/StarknetBtcRelay.d.ts +28 -7
- package/dist/starknet/btcrelay/StarknetBtcRelay.js +75 -20
- package/dist/starknet/{base → chain}/StarknetAction.d.ts +2 -2
- package/dist/starknet/chain/StarknetChainInterface.d.ts +52 -0
- package/dist/starknet/chain/StarknetChainInterface.js +91 -0
- package/dist/starknet/{base → chain}/StarknetModule.d.ts +3 -3
- package/dist/starknet/{base → chain}/modules/StarknetAddresses.d.ts +1 -1
- package/dist/starknet/{base → chain}/modules/StarknetAddresses.js +1 -1
- package/dist/starknet/{base → chain}/modules/StarknetSignatures.d.ts +2 -2
- package/dist/starknet/{base → chain}/modules/StarknetTokens.js +2 -1
- package/dist/starknet/{base → chain}/modules/StarknetTransactions.d.ts +7 -1
- package/dist/starknet/{base → chain}/modules/StarknetTransactions.js +45 -16
- package/dist/starknet/contract/StarknetContractBase.d.ts +5 -5
- package/dist/starknet/contract/StarknetContractBase.js +5 -7
- package/dist/starknet/contract/StarknetContractModule.d.ts +8 -0
- package/dist/starknet/contract/StarknetContractModule.js +11 -0
- package/dist/starknet/contract/modules/StarknetContractEvents.d.ts +15 -4
- package/dist/starknet/contract/modules/StarknetContractEvents.js +26 -6
- package/dist/starknet/events/StarknetChainEvents.d.ts +3 -1
- package/dist/starknet/events/StarknetChainEvents.js +9 -9
- package/dist/starknet/events/StarknetChainEventsBrowser.d.ts +23 -6
- package/dist/starknet/events/StarknetChainEventsBrowser.js +104 -13
- package/dist/starknet/provider/RpcProviderWithRetries.d.ts +21 -0
- package/dist/starknet/provider/RpcProviderWithRetries.js +32 -0
- package/dist/starknet/spv_swap/SpvVaultContractAbi.d.ts +488 -0
- package/dist/starknet/spv_swap/SpvVaultContractAbi.js +656 -0
- package/dist/starknet/spv_swap/StarknetSpvVaultContract.d.ts +65 -0
- package/dist/starknet/spv_swap/StarknetSpvVaultContract.js +372 -0
- package/dist/starknet/spv_swap/StarknetSpvVaultData.d.ts +49 -0
- package/dist/starknet/spv_swap/StarknetSpvVaultData.js +144 -0
- package/dist/starknet/spv_swap/StarknetSpvWithdrawalData.d.ts +24 -0
- package/dist/starknet/spv_swap/StarknetSpvWithdrawalData.js +61 -0
- package/dist/starknet/swaps/StarknetSwapContract.d.ts +4 -22
- package/dist/starknet/swaps/StarknetSwapContract.js +23 -80
- package/dist/starknet/swaps/StarknetSwapModule.d.ts +6 -5
- package/dist/starknet/swaps/StarknetSwapModule.js +5 -6
- package/dist/starknet/swaps/handlers/IHandler.d.ts +2 -2
- package/dist/starknet/swaps/handlers/claim/ClaimHandlers.d.ts +1 -1
- package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.d.ts +2 -2
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +2 -2
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +2 -2
- package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +2 -2
- package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +2 -21
- package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +7 -41
- package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.d.ts +2 -2
- package/dist/starknet/swaps/modules/StarknetLpVault.d.ts +1 -1
- package/dist/starknet/swaps/modules/StarknetLpVault.js +9 -9
- package/dist/starknet/swaps/modules/StarknetSwapClaim.d.ts +1 -1
- package/dist/starknet/swaps/modules/StarknetSwapClaim.js +8 -8
- package/dist/starknet/swaps/modules/StarknetSwapInit.d.ts +1 -1
- package/dist/starknet/swaps/modules/StarknetSwapInit.js +9 -9
- package/dist/starknet/swaps/modules/StarknetSwapRefund.d.ts +1 -3
- package/dist/starknet/swaps/modules/StarknetSwapRefund.js +8 -11
- package/dist/starknet/wallet/StarknetSigner.js +1 -1
- package/dist/utils/Utils.d.ts +2 -2
- package/dist/utils/Utils.js +3 -1
- package/package.json +2 -2
- package/src/index.ts +15 -9
- package/src/starknet/StarknetChainType.ts +10 -2
- package/src/starknet/StarknetInitializer.ts +23 -7
- package/src/starknet/btcrelay/StarknetBtcRelay.ts +104 -30
- package/src/starknet/{base → chain}/StarknetAction.ts +3 -3
- package/src/starknet/chain/StarknetChainInterface.ts +149 -0
- package/src/starknet/{base → chain}/StarknetModule.ts +3 -3
- package/src/starknet/{base → chain}/modules/StarknetAddresses.ts +1 -1
- package/src/starknet/{base → chain}/modules/StarknetSignatures.ts +2 -2
- package/src/starknet/{base → chain}/modules/StarknetTokens.ts +2 -1
- package/src/starknet/{base → chain}/modules/StarknetTransactions.ts +43 -18
- package/src/starknet/contract/StarknetContractBase.ts +9 -12
- package/src/starknet/contract/StarknetContractModule.ts +16 -0
- package/src/starknet/contract/modules/StarknetContractEvents.ts +33 -7
- package/src/starknet/events/StarknetChainEvents.ts +15 -11
- package/src/starknet/events/StarknetChainEventsBrowser.ts +157 -26
- package/src/starknet/provider/RpcProviderWithRetries.ts +43 -0
- package/src/starknet/spv_swap/SpvVaultContractAbi.ts +656 -0
- package/src/starknet/spv_swap/StarknetSpvVaultContract.ts +475 -0
- package/src/starknet/spv_swap/StarknetSpvVaultData.ts +194 -0
- package/src/starknet/spv_swap/StarknetSpvWithdrawalData.ts +68 -0
- package/src/starknet/swaps/StarknetSwapContract.ts +28 -116
- package/src/starknet/swaps/StarknetSwapModule.ts +8 -8
- package/src/starknet/swaps/handlers/IHandler.ts +2 -2
- package/src/starknet/swaps/handlers/claim/ClaimHandlers.ts +1 -1
- package/src/starknet/swaps/handlers/claim/HashlockClaimHandler.ts +2 -2
- package/src/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +2 -2
- package/src/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +2 -2
- package/src/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +2 -2
- package/src/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +12 -61
- package/src/starknet/swaps/handlers/refund/TimelockRefundHandler.ts +2 -2
- package/src/starknet/swaps/modules/StarknetLpVault.ts +10 -10
- package/src/starknet/swaps/modules/StarknetSwapClaim.ts +9 -9
- package/src/starknet/swaps/modules/StarknetSwapInit.ts +10 -10
- package/src/starknet/swaps/modules/StarknetSwapRefund.ts +9 -13
- package/src/starknet/wallet/StarknetSigner.ts +1 -1
- package/src/utils/Utils.ts +4 -3
- package/dist/starknet/base/StarknetBase.d.ts +0 -34
- package/dist/starknet/base/StarknetBase.js +0 -29
- package/src/starknet/base/StarknetBase.ts +0 -56
- /package/dist/starknet/{base → chain}/StarknetAction.js +0 -0
- /package/dist/starknet/{base → chain}/StarknetModule.js +0 -0
- /package/dist/starknet/{base → chain}/modules/ERC20Abi.d.ts +0 -0
- /package/dist/starknet/{base → chain}/modules/ERC20Abi.js +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetAccounts.d.ts +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetAccounts.js +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetBlocks.d.ts +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetBlocks.js +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetEvents.d.ts +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetEvents.js +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetFees.d.ts +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetFees.js +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetSignatures.js +0 -0
- /package/dist/starknet/{base → chain}/modules/StarknetTokens.d.ts +0 -0
- /package/src/starknet/{base → chain}/modules/ERC20Abi.ts +0 -0
- /package/src/starknet/{base → chain}/modules/StarknetAccounts.ts +0 -0
- /package/src/starknet/{base → chain}/modules/StarknetBlocks.ts +0 -0
- /package/src/starknet/{base → chain}/modules/StarknetEvents.ts +0 -0
- /package/src/starknet/{base → chain}/modules/StarknetFees.ts +0 -0
|
@@ -1,29 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {StarknetFees} from "../base/modules/StarknetFees";
|
|
1
|
+
import {StarknetChainInterface} from "../chain/StarknetChainInterface";
|
|
2
|
+
import {Contract, TypedContractV2} from "starknet";
|
|
4
3
|
import {Abi} from "abi-wan-kanabi";
|
|
5
4
|
import {StarknetContractEvents} from "./modules/StarknetContractEvents";
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Base class providing program specific utilities
|
|
9
8
|
*/
|
|
10
|
-
export class StarknetContractBase<T extends Abi>
|
|
9
|
+
export class StarknetContractBase<T extends Abi> {
|
|
11
10
|
|
|
12
11
|
contract: TypedContractV2<T>;
|
|
13
12
|
|
|
14
13
|
public readonly Events: StarknetContractEvents<T>;
|
|
14
|
+
public readonly Chain: StarknetChainInterface;
|
|
15
15
|
|
|
16
16
|
constructor(
|
|
17
|
-
|
|
18
|
-
provider: Provider,
|
|
17
|
+
chainInterface: StarknetChainInterface,
|
|
19
18
|
contractAddress: string,
|
|
20
|
-
contractAbi: T
|
|
21
|
-
retryPolicy?: StarknetRetryPolicy,
|
|
22
|
-
solanaFeeEstimator: StarknetFees = new StarknetFees(provider)
|
|
19
|
+
contractAbi: T
|
|
23
20
|
) {
|
|
24
|
-
|
|
25
|
-
this.contract = new Contract(contractAbi, contractAddress, provider).typedv2(contractAbi);
|
|
26
|
-
this.Events = new StarknetContractEvents(this, contractAbi);
|
|
21
|
+
this.Chain = chainInterface;
|
|
22
|
+
this.contract = new Contract(contractAbi, contractAddress, chainInterface.provider).typedv2(contractAbi);
|
|
23
|
+
this.Events = new StarknetContractEvents(chainInterface, this, contractAbi);
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {Abi} from "abi-wan-kanabi";
|
|
2
|
+
import {StarknetContractBase} from "./StarknetContractBase";
|
|
3
|
+
import {StarknetChainInterface} from "../chain/StarknetChainInterface";
|
|
4
|
+
import {StarknetModule} from "../chain/StarknetModule";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export class StarknetContractModule<TAbi extends Abi> extends StarknetModule {
|
|
8
|
+
|
|
9
|
+
readonly contract: StarknetContractBase<TAbi>;
|
|
10
|
+
|
|
11
|
+
constructor(chainInterface: StarknetChainInterface, contract: StarknetContractBase<TAbi>) {
|
|
12
|
+
super(chainInterface)
|
|
13
|
+
this.contract = contract;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {Abi} from "abi-wan-kanabi";
|
|
2
2
|
import {EventToPrimitiveType, ExtractAbiEventNames} from "abi-wan-kanabi/dist/kanabi";
|
|
3
|
-
import {StarknetEvent, StarknetEvents} from "../../
|
|
3
|
+
import {StarknetEvent, StarknetEvents} from "../../chain/modules/StarknetEvents";
|
|
4
4
|
import {CallData, events, hash} from "starknet";
|
|
5
5
|
import {StarknetContractBase} from "../StarknetContractBase";
|
|
6
6
|
import {toHex} from "../../../utils/Utils";
|
|
7
|
+
import {StarknetChainInterface} from "../../chain/StarknetChainInterface";
|
|
7
8
|
|
|
8
9
|
export type StarknetAbiEvent<TAbi extends Abi, TEventName extends ExtractAbiEventNames<TAbi>> = {
|
|
9
10
|
name: TEventName,
|
|
@@ -17,11 +18,12 @@ export type StarknetAbiEvent<TAbi extends Abi, TEventName extends ExtractAbiEven
|
|
|
17
18
|
|
|
18
19
|
export class StarknetContractEvents<TAbi extends Abi> extends StarknetEvents {
|
|
19
20
|
|
|
20
|
-
readonly
|
|
21
|
+
readonly contract: StarknetContractBase<TAbi>;
|
|
21
22
|
readonly abi: TAbi;
|
|
22
23
|
|
|
23
|
-
constructor(
|
|
24
|
-
super(
|
|
24
|
+
constructor(chainInterface: StarknetChainInterface, contract: StarknetContractBase<TAbi>, abi: TAbi) {
|
|
25
|
+
super(chainInterface);
|
|
26
|
+
this.contract = contract;
|
|
25
27
|
this.abi = abi;
|
|
26
28
|
}
|
|
27
29
|
|
|
@@ -76,12 +78,12 @@ export class StarknetContractEvents<TAbi extends Abi> extends StarknetEvents {
|
|
|
76
78
|
startBlockHeight?: number,
|
|
77
79
|
endBlockHeight: number = startBlockHeight
|
|
78
80
|
): Promise<StarknetAbiEvent<TAbi, T>[]> {
|
|
79
|
-
const blockEvents = await super.getBlockEvents(this.
|
|
81
|
+
const blockEvents = await super.getBlockEvents(this.contract.contract.address, this.toFilter(events, keys), startBlockHeight, endBlockHeight);
|
|
80
82
|
return this.toStarknetAbiEvents(blockEvents);
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
/**
|
|
84
|
-
* Runs a search
|
|
86
|
+
* Runs a search backwards in time, processing the events for a specific topic public key
|
|
85
87
|
*
|
|
86
88
|
* @param events
|
|
87
89
|
* @param keys
|
|
@@ -95,7 +97,31 @@ export class StarknetContractEvents<TAbi extends Abi> extends StarknetEvents {
|
|
|
95
97
|
processor: (event: StarknetAbiEvent<TAbi, TEvent>) => Promise<T>,
|
|
96
98
|
abortSignal?: AbortSignal
|
|
97
99
|
) {
|
|
98
|
-
return this.findInEvents<T>(this.
|
|
100
|
+
return this.findInEvents<T>(this.contract.contract.address, this.toFilter(events, keys), async (events: StarknetEvent[]) => {
|
|
101
|
+
const parsedEvents = this.toStarknetAbiEvents<TEvent>(events);
|
|
102
|
+
for(let event of parsedEvents) {
|
|
103
|
+
const result: T = await processor(event);
|
|
104
|
+
if(result!=null) return result;
|
|
105
|
+
}
|
|
106
|
+
}, abortSignal);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Runs a search forwards in time, processing the events for a specific topic public key
|
|
111
|
+
*
|
|
112
|
+
* @param events
|
|
113
|
+
* @param keys
|
|
114
|
+
* @param processor called for every event, should return a value if the correct event was found, or null
|
|
115
|
+
* if the search should continue
|
|
116
|
+
* @param abortSignal
|
|
117
|
+
*/
|
|
118
|
+
public async findInContractEventsForward<T, TEvent extends ExtractAbiEventNames<TAbi>>(
|
|
119
|
+
events: TEvent[],
|
|
120
|
+
keys: string[],
|
|
121
|
+
processor: (event: StarknetAbiEvent<TAbi, TEvent>) => Promise<T>,
|
|
122
|
+
abortSignal?: AbortSignal
|
|
123
|
+
) {
|
|
124
|
+
return this.findInEventsForward<T>(this.contract.contract.address, this.toFilter(events, keys), async (events: StarknetEvent[]) => {
|
|
99
125
|
const parsedEvents = this.toStarknetAbiEvents<TEvent>(events);
|
|
100
126
|
for(let event of parsedEvents) {
|
|
101
127
|
const result: T = await processor(event);
|
|
@@ -2,6 +2,8 @@ import {StarknetChainEventsBrowser} from "./StarknetChainEventsBrowser";
|
|
|
2
2
|
//@ts-ignore
|
|
3
3
|
import * as fs from "fs/promises";
|
|
4
4
|
import {StarknetSwapContract} from "../swaps/StarknetSwapContract";
|
|
5
|
+
import {StarknetChainInterface} from "../chain/StarknetChainInterface";
|
|
6
|
+
import {StarknetSpvVaultContract} from "../spv_swap/StarknetSpvVaultContract";
|
|
5
7
|
|
|
6
8
|
const BLOCKHEIGHT_FILENAME = "/strk-blockheight.txt";
|
|
7
9
|
|
|
@@ -11,10 +13,12 @@ export class StarknetChainEvents extends StarknetChainEventsBrowser {
|
|
|
11
13
|
|
|
12
14
|
constructor(
|
|
13
15
|
directory: string,
|
|
16
|
+
chainInterface: StarknetChainInterface,
|
|
14
17
|
starknetSwapContract: StarknetSwapContract,
|
|
18
|
+
starknetSpvVaultContract: StarknetSpvVaultContract,
|
|
15
19
|
pollIntervalSeconds?: number
|
|
16
20
|
) {
|
|
17
|
-
super(starknetSwapContract, pollIntervalSeconds);
|
|
21
|
+
super(chainInterface, starknetSwapContract, starknetSpvVaultContract, pollIntervalSeconds);
|
|
18
22
|
this.directory = directory;
|
|
19
23
|
}
|
|
20
24
|
|
|
@@ -23,22 +27,22 @@ export class StarknetChainEvents extends StarknetChainEventsBrowser {
|
|
|
23
27
|
*
|
|
24
28
|
* @private
|
|
25
29
|
*/
|
|
26
|
-
private async getLastEventData(): Promise<{blockNumber: number,
|
|
30
|
+
private async getLastEventData(): Promise<{blockNumber: number, txHashes: string[]}> {
|
|
27
31
|
try {
|
|
28
|
-
const txt = (await fs.readFile(this.directory+BLOCKHEIGHT_FILENAME)).toString();
|
|
32
|
+
const txt: string = (await fs.readFile(this.directory+BLOCKHEIGHT_FILENAME)).toString();
|
|
29
33
|
const arr = txt.split(";");
|
|
30
34
|
if(arr.length<2) return {
|
|
31
35
|
blockNumber: parseInt(arr[0]),
|
|
32
|
-
|
|
36
|
+
txHashes: null
|
|
33
37
|
};
|
|
34
38
|
return {
|
|
35
39
|
blockNumber: parseInt(arr[0]),
|
|
36
|
-
|
|
40
|
+
txHashes: arr.slice(1)
|
|
37
41
|
};
|
|
38
42
|
} catch (e) {
|
|
39
43
|
return {
|
|
40
44
|
blockNumber: null,
|
|
41
|
-
|
|
45
|
+
txHashes: null
|
|
42
46
|
};
|
|
43
47
|
}
|
|
44
48
|
}
|
|
@@ -48,16 +52,16 @@ export class StarknetChainEvents extends StarknetChainEventsBrowser {
|
|
|
48
52
|
*
|
|
49
53
|
* @private
|
|
50
54
|
*/
|
|
51
|
-
private saveLastEventData(blockNumber: number,
|
|
52
|
-
return fs.writeFile(this.directory+BLOCKHEIGHT_FILENAME, blockNumber.toString()+";"+
|
|
55
|
+
private saveLastEventData(blockNumber: number, txHashes: string[]): Promise<void> {
|
|
56
|
+
return fs.writeFile(this.directory+BLOCKHEIGHT_FILENAME, blockNumber.toString()+";"+txHashes.join(";"));
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
async init(): Promise<void> {
|
|
56
|
-
const {blockNumber,
|
|
60
|
+
const {blockNumber, txHashes} = await this.getLastEventData();
|
|
57
61
|
await this.setupPoll(
|
|
58
62
|
blockNumber,
|
|
59
|
-
|
|
60
|
-
(blockNumber: number,
|
|
63
|
+
txHashes,
|
|
64
|
+
(blockNumber: number, txHashes: string[]) => this.saveLastEventData(blockNumber, txHashes)
|
|
61
65
|
);
|
|
62
66
|
}
|
|
63
67
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ChainEvent,
|
|
2
3
|
ChainEvents,
|
|
3
4
|
ChainSwapType,
|
|
4
5
|
ClaimEvent,
|
|
5
6
|
EventListener,
|
|
6
7
|
InitializeEvent,
|
|
7
|
-
RefundEvent,
|
|
8
|
-
SwapEvent
|
|
8
|
+
RefundEvent, SpvVaultClaimEvent, SpvVaultCloseEvent, SpvVaultDepositEvent, SpvVaultFrontEvent, SpvVaultOpenEvent
|
|
9
9
|
} from "@atomiqlabs/base";
|
|
10
10
|
import {StarknetSwapData} from "../swaps/StarknetSwapData";
|
|
11
11
|
import {
|
|
@@ -13,8 +13,7 @@ import {
|
|
|
13
13
|
bytes31SpanToBuffer, findLastIndex,
|
|
14
14
|
getLogger,
|
|
15
15
|
onceAsync,
|
|
16
|
-
parseInitFunctionCalldata,
|
|
17
|
-
timeoutPromise,
|
|
16
|
+
parseInitFunctionCalldata, toBigInt,
|
|
18
17
|
toHex
|
|
19
18
|
} from "../../utils/Utils";
|
|
20
19
|
import {StarknetSwapContract} from "../swaps/StarknetSwapContract";
|
|
@@ -23,6 +22,9 @@ import {StarknetAbiEvent} from "../contract/modules/StarknetContractEvents";
|
|
|
23
22
|
import {EscrowManagerAbiType} from "../swaps/EscrowManagerAbi";
|
|
24
23
|
import {ExtractAbiFunctionNames} from "abi-wan-kanabi/dist/kanabi";
|
|
25
24
|
import {IClaimHandler} from "../swaps/handlers/claim/ClaimHandlers";
|
|
25
|
+
import {StarknetSpvVaultContract} from "../spv_swap/StarknetSpvVaultContract";
|
|
26
|
+
import {StarknetChainInterface} from "../chain/StarknetChainInterface";
|
|
27
|
+
import {SpvVaultContractAbiType} from "../spv_swap/SpvVaultContractAbi";
|
|
26
28
|
|
|
27
29
|
export type StarknetTraceCall = {
|
|
28
30
|
calldata: string[],
|
|
@@ -41,6 +43,7 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData>
|
|
|
41
43
|
protected readonly listeners: EventListener<StarknetSwapData>[] = [];
|
|
42
44
|
protected readonly provider: Provider;
|
|
43
45
|
protected readonly starknetSwapContract: StarknetSwapContract;
|
|
46
|
+
protected readonly starknetSpvVaultContract: StarknetSpvVaultContract;
|
|
44
47
|
protected eventListeners: number[] = [];
|
|
45
48
|
protected readonly logger = getLogger("StarknetChainEventsBrowser: ");
|
|
46
49
|
|
|
@@ -52,9 +55,15 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData>
|
|
|
52
55
|
|
|
53
56
|
private timeout: number;
|
|
54
57
|
|
|
55
|
-
constructor(
|
|
56
|
-
|
|
58
|
+
constructor(
|
|
59
|
+
chainInterface: StarknetChainInterface,
|
|
60
|
+
starknetSwapContract: StarknetSwapContract,
|
|
61
|
+
starknetSpvVaultContract: StarknetSpvVaultContract,
|
|
62
|
+
pollIntervalSeconds: number = 5
|
|
63
|
+
) {
|
|
64
|
+
this.provider = chainInterface.provider;
|
|
57
65
|
this.starknetSwapContract = starknetSwapContract;
|
|
66
|
+
this.starknetSpvVaultContract = starknetSpvVaultContract;
|
|
58
67
|
this.pollIntervalSeconds = pollIntervalSeconds;
|
|
59
68
|
}
|
|
60
69
|
|
|
@@ -146,6 +155,75 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData>
|
|
|
146
155
|
return new ClaimEvent<StarknetSwapData>(escrowHash, witnessResult);
|
|
147
156
|
}
|
|
148
157
|
|
|
158
|
+
protected parseSpvOpenEvent(
|
|
159
|
+
event: StarknetAbiEvent<SpvVaultContractAbiType, "spv_swap_vault::events::Opened">
|
|
160
|
+
): SpvVaultOpenEvent {
|
|
161
|
+
const owner = toHex(event.params.owner);
|
|
162
|
+
const vaultId = toBigInt(event.params.vault_id);
|
|
163
|
+
const btcTxId = bigNumberishToBuffer(event.params.btc_tx_hash, 32).reverse().toString("hex");
|
|
164
|
+
const vout = Number(toBigInt(event.params.vout));
|
|
165
|
+
|
|
166
|
+
this.logger.debug("SpvOpenEvent owner: "+owner+" vaultId: "+vaultId+" utxo: "+btcTxId+":"+vout);
|
|
167
|
+
return new SpvVaultOpenEvent(owner, vaultId, btcTxId, vout);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
protected parseSpvDepositEvent(
|
|
171
|
+
event: StarknetAbiEvent<SpvVaultContractAbiType, "spv_swap_vault::events::Deposited">
|
|
172
|
+
): SpvVaultDepositEvent {
|
|
173
|
+
const owner = toHex(event.params.owner);
|
|
174
|
+
const vaultId = toBigInt(event.params.vault_id);
|
|
175
|
+
const amounts = [toBigInt(event.params.amounts["0"] as BigNumberish), toBigInt(event.params.amounts["1"] as BigNumberish)];
|
|
176
|
+
const depositCount = Number(toBigInt(event.params.deposit_count));
|
|
177
|
+
|
|
178
|
+
this.logger.debug("SpvDepositEvent owner: "+owner+" vaultId: "+vaultId+" depositCount: "+depositCount+" amounts: ", amounts);
|
|
179
|
+
return new SpvVaultDepositEvent(owner, vaultId, amounts, depositCount);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
protected parseSpvFrontEvent(
|
|
183
|
+
event: StarknetAbiEvent<SpvVaultContractAbiType, "spv_swap_vault::events::Fronted">
|
|
184
|
+
): SpvVaultFrontEvent {
|
|
185
|
+
const owner = toHex(event.params.owner);
|
|
186
|
+
const vaultId = toBigInt(event.params.vault_id);
|
|
187
|
+
const btcTxId = bigNumberishToBuffer(event.params.btc_tx_hash, 32).reverse().toString("hex");
|
|
188
|
+
const recipient = toHex(event.params.recipient);
|
|
189
|
+
const executionHash = toHex(event.params.execution_hash);
|
|
190
|
+
const amounts = [toBigInt(event.params.amounts["0"] as BigNumberish), toBigInt(event.params.amounts["1"] as BigNumberish)];
|
|
191
|
+
const frontingAddress = toHex(event.params.caller);
|
|
192
|
+
|
|
193
|
+
this.logger.debug("SpvFrontEvent owner: "+owner+" vaultId: "+vaultId+" btcTxId: "+btcTxId+
|
|
194
|
+
" recipient: "+recipient+" frontedBy: "+frontingAddress+" amounts: ", amounts);
|
|
195
|
+
return new SpvVaultFrontEvent(owner, vaultId, btcTxId, recipient, executionHash, amounts, frontingAddress);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
protected parseSpvClaimEvent(
|
|
199
|
+
event: StarknetAbiEvent<SpvVaultContractAbiType, "spv_swap_vault::events::Claimed">
|
|
200
|
+
): SpvVaultClaimEvent {
|
|
201
|
+
const owner = toHex(event.params.owner);
|
|
202
|
+
const vaultId = toBigInt(event.params.vault_id);
|
|
203
|
+
const btcTxId = bigNumberishToBuffer(event.params.btc_tx_hash, 32).reverse().toString("hex");
|
|
204
|
+
const recipient = toHex(event.params.recipient);
|
|
205
|
+
const executionHash = toHex(event.params.execution_hash);
|
|
206
|
+
const amounts = [toBigInt(event.params.amounts["0"] as BigNumberish), toBigInt(event.params.amounts["1"] as BigNumberish)];
|
|
207
|
+
const caller = toHex(event.params.caller);
|
|
208
|
+
const frontingAddress = toHex(event.params.fronting_address);
|
|
209
|
+
const withdrawCount = Number(toBigInt(event.params.withdraw_count));
|
|
210
|
+
|
|
211
|
+
this.logger.debug("SpvClaimEvent owner: "+owner+" vaultId: "+vaultId+" btcTxId: "+btcTxId+" withdrawCount: "+withdrawCount+
|
|
212
|
+
" recipient: "+recipient+" frontedBy: "+frontingAddress+" claimedBy: "+caller+" amounts: ", amounts);
|
|
213
|
+
return new SpvVaultClaimEvent(owner, vaultId, btcTxId, recipient, executionHash, amounts, caller, frontingAddress, withdrawCount);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
protected parseSpvCloseEvent(
|
|
217
|
+
event: StarknetAbiEvent<SpvVaultContractAbiType, "spv_swap_vault::events::Closed">
|
|
218
|
+
): SpvVaultCloseEvent {
|
|
219
|
+
const owner = toHex(event.params.owner);
|
|
220
|
+
const vaultId = toBigInt(event.params.vault_id);
|
|
221
|
+
const btcTxId = bigNumberishToBuffer(event.params.btc_tx_hash, 32).reverse().toString("hex");
|
|
222
|
+
const error = bigNumberishToBuffer(event.params.error).toString();
|
|
223
|
+
|
|
224
|
+
return new SpvVaultCloseEvent(owner, vaultId, btcTxId, error);
|
|
225
|
+
}
|
|
226
|
+
|
|
149
227
|
/**
|
|
150
228
|
* Processes event as received from the chain, parses it & calls event listeners
|
|
151
229
|
*
|
|
@@ -156,10 +234,13 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData>
|
|
|
156
234
|
* @protected
|
|
157
235
|
*/
|
|
158
236
|
protected async processEvents(
|
|
159
|
-
events : StarknetAbiEvent<
|
|
237
|
+
events : (StarknetAbiEvent<
|
|
160
238
|
EscrowManagerAbiType,
|
|
161
239
|
"escrow_manager::events::Initialize" | "escrow_manager::events::Refund" | "escrow_manager::events::Claim"
|
|
162
|
-
>
|
|
240
|
+
> | StarknetAbiEvent<
|
|
241
|
+
SpvVaultContractAbiType,
|
|
242
|
+
"spv_swap_vault::events::Opened" | "spv_swap_vault::events::Deposited" | "spv_swap_vault::events::Fronted" | "spv_swap_vault::events::Claimed" | "spv_swap_vault::events::Closed"
|
|
243
|
+
>)[],
|
|
163
244
|
currentBlockNumber: number,
|
|
164
245
|
currentBlockTimestamp: number,
|
|
165
246
|
pendingEventTime: number
|
|
@@ -172,10 +253,10 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData>
|
|
|
172
253
|
return blockTimestampsCache[blockNumberString];
|
|
173
254
|
}
|
|
174
255
|
|
|
175
|
-
const parsedEvents:
|
|
256
|
+
const parsedEvents: ChainEvent<StarknetSwapData>[] = [];
|
|
176
257
|
|
|
177
258
|
for(let event of events) {
|
|
178
|
-
let parsedEvent:
|
|
259
|
+
let parsedEvent: ChainEvent<StarknetSwapData>;
|
|
179
260
|
switch(event.name) {
|
|
180
261
|
case "escrow_manager::events::Claim":
|
|
181
262
|
parsedEvent = this.parseClaimEvent(event as any);
|
|
@@ -186,6 +267,21 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData>
|
|
|
186
267
|
case "escrow_manager::events::Initialize":
|
|
187
268
|
parsedEvent = this.parseInitializeEvent(event as any);
|
|
188
269
|
break;
|
|
270
|
+
case "spv_swap_vault::events::Opened":
|
|
271
|
+
parsedEvent = this.parseSpvOpenEvent(event as any);
|
|
272
|
+
break;
|
|
273
|
+
case "spv_swap_vault::events::Deposited":
|
|
274
|
+
parsedEvent = this.parseSpvDepositEvent(event as any);
|
|
275
|
+
break;
|
|
276
|
+
case "spv_swap_vault::events::Fronted":
|
|
277
|
+
parsedEvent = this.parseSpvFrontEvent(event as any);
|
|
278
|
+
break;
|
|
279
|
+
case "spv_swap_vault::events::Claimed":
|
|
280
|
+
parsedEvent = this.parseSpvClaimEvent(event as any);
|
|
281
|
+
break;
|
|
282
|
+
case "spv_swap_vault::events::Closed":
|
|
283
|
+
parsedEvent = this.parseSpvCloseEvent(event as any);
|
|
284
|
+
break;
|
|
189
285
|
}
|
|
190
286
|
const timestamp = event.blockNumber==null ? pendingEventTime : await getBlockTimestamp(event.blockNumber);
|
|
191
287
|
parsedEvent.meta = {
|
|
@@ -201,32 +297,67 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData>
|
|
|
201
297
|
}
|
|
202
298
|
}
|
|
203
299
|
|
|
204
|
-
protected async
|
|
205
|
-
const currentBlock = await this.provider.getBlockWithTxHashes("latest");
|
|
300
|
+
protected async checkEventsEcrowManager(lastTxHash: string, lastBlockNumber?: number, currentBlock?: {timestamp: number, block_number: number}): Promise<string> {
|
|
206
301
|
const currentBlockNumber: number = (currentBlock as any).block_number;
|
|
207
302
|
lastBlockNumber ??= currentBlockNumber;
|
|
208
303
|
const logStartHeight = currentBlockNumber>lastBlockNumber ? lastBlockNumber+1 : lastBlockNumber;
|
|
209
|
-
this.logger.debug("checkEvents(): Requesting logs: "+logStartHeight+"...pending");
|
|
210
|
-
|
|
304
|
+
this.logger.debug("checkEvents(EscrowManager): Requesting logs: "+logStartHeight+"...pending");
|
|
305
|
+
let events = await this.starknetSwapContract.Events.getContractBlockEvents(
|
|
211
306
|
["escrow_manager::events::Initialize", "escrow_manager::events::Claim", "escrow_manager::events::Refund"],
|
|
212
307
|
[],
|
|
213
308
|
logStartHeight,
|
|
214
309
|
null
|
|
215
310
|
);
|
|
216
311
|
if(lastTxHash!=null) {
|
|
217
|
-
const latestProcessedEventIndex = findLastIndex(events, val => val.txHash
|
|
218
|
-
if
|
|
219
|
-
events.splice(0, latestProcessedEventIndex
|
|
220
|
-
this.logger.debug("checkEvents(): Splicing processed events, resulting size: "+events.length);
|
|
312
|
+
const latestProcessedEventIndex = findLastIndex(events, val => val.txHash===lastTxHash);
|
|
313
|
+
if(latestProcessedEventIndex!==-1) {
|
|
314
|
+
events.splice(0, latestProcessedEventIndex+1);
|
|
315
|
+
this.logger.debug("checkEvents(EscrowManager): Splicing processed events, resulting size: "+events.length);
|
|
221
316
|
}
|
|
222
317
|
}
|
|
223
318
|
if(events.length>0) {
|
|
224
|
-
await this.processEvents(events,
|
|
225
|
-
lastTxHash = events[events.length
|
|
319
|
+
await this.processEvents(events, currentBlock?.block_number, currentBlock?.timestamp, Math.floor(Date.now()/1000));
|
|
320
|
+
lastTxHash = events[events.length-1].txHash;
|
|
226
321
|
}
|
|
322
|
+
return lastTxHash;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
protected async checkEventsSpvVaults(lastTxHash: string, lastBlockNumber?: number, currentBlock?: {timestamp: number, block_number: number}): Promise<string> {
|
|
326
|
+
const currentBlockNumber: number = (currentBlock as any).block_number;
|
|
327
|
+
lastBlockNumber ??= currentBlockNumber;
|
|
328
|
+
const logStartHeight = currentBlockNumber>lastBlockNumber ? lastBlockNumber+1 : lastBlockNumber;
|
|
329
|
+
this.logger.debug("checkEvents(SpvVaults): Requesting logs: "+logStartHeight+"...pending");
|
|
330
|
+
let events = await this.starknetSpvVaultContract.Events.getContractBlockEvents(
|
|
331
|
+
["spv_swap_vault::events::Opened", "spv_swap_vault::events::Deposited", "spv_swap_vault::events::Closed", "spv_swap_vault::events::Fronted", "spv_swap_vault::events::Claimed"],
|
|
332
|
+
[],
|
|
333
|
+
logStartHeight,
|
|
334
|
+
null
|
|
335
|
+
);
|
|
336
|
+
if(lastTxHash!=null) {
|
|
337
|
+
const latestProcessedEventIndex = findLastIndex(events, val => val.txHash===lastTxHash);
|
|
338
|
+
if(latestProcessedEventIndex!==-1) {
|
|
339
|
+
events.splice(0, latestProcessedEventIndex+1);
|
|
340
|
+
this.logger.debug("checkEvents(SpvVaults): Splicing processed events, resulting size: "+events.length);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if(events.length>0) {
|
|
344
|
+
await this.processEvents(events, currentBlock?.block_number, currentBlock?.timestamp, Math.floor(Date.now()/1000));
|
|
345
|
+
lastTxHash = events[events.length-1].txHash;
|
|
346
|
+
}
|
|
347
|
+
return lastTxHash;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
protected async checkEvents(lastBlockNumber: number, lastTxHashes: string[]): Promise<{txHashes: string[], blockNumber: number}> {
|
|
351
|
+
lastTxHashes ??= [];
|
|
352
|
+
|
|
353
|
+
const currentBlock = await this.provider.getBlockWithTxHashes("latest");
|
|
354
|
+
const currentBlockNumber: number = (currentBlock as any).block_number;
|
|
355
|
+
|
|
356
|
+
lastTxHashes[0] = await this.checkEventsEcrowManager(lastTxHashes[0], lastBlockNumber, currentBlock as any);
|
|
357
|
+
lastTxHashes[1] = await this.checkEventsSpvVaults(lastTxHashes[1], lastBlockNumber, currentBlock as any);
|
|
227
358
|
|
|
228
359
|
return {
|
|
229
|
-
|
|
360
|
+
txHashes: lastTxHashes,
|
|
230
361
|
blockNumber: currentBlockNumber
|
|
231
362
|
};
|
|
232
363
|
}
|
|
@@ -238,16 +369,16 @@ export class StarknetChainEventsBrowser implements ChainEvents<StarknetSwapData>
|
|
|
238
369
|
*/
|
|
239
370
|
protected async setupPoll(
|
|
240
371
|
lastBlockNumber?: number,
|
|
241
|
-
|
|
242
|
-
saveLatestProcessedBlockNumber?: (blockNumber: number,
|
|
372
|
+
lastTxHashes?: string[],
|
|
373
|
+
saveLatestProcessedBlockNumber?: (blockNumber: number, lastTxHashes: string[]) => Promise<void>
|
|
243
374
|
) {
|
|
244
375
|
this.stopped = false;
|
|
245
376
|
let func;
|
|
246
377
|
func = async () => {
|
|
247
|
-
await this.checkEvents(lastBlockNumber,
|
|
378
|
+
await this.checkEvents(lastBlockNumber, lastTxHashes).then(({blockNumber, txHashes}) => {
|
|
248
379
|
lastBlockNumber = blockNumber;
|
|
249
|
-
|
|
250
|
-
if(saveLatestProcessedBlockNumber!=null) return saveLatestProcessedBlockNumber(blockNumber,
|
|
380
|
+
lastTxHashes = txHashes;
|
|
381
|
+
if(saveLatestProcessedBlockNumber!=null) return saveLatestProcessedBlockNumber(blockNumber, lastTxHashes);
|
|
251
382
|
}).catch(e => {
|
|
252
383
|
this.logger.error("setupPoll(): Failed to fetch starknet log: ", e);
|
|
253
384
|
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RpcChannel,
|
|
3
|
+
RpcProvider,
|
|
4
|
+
RpcProviderOptions
|
|
5
|
+
} from "starknet";
|
|
6
|
+
import {tryWithRetries} from "../../utils/Utils";
|
|
7
|
+
|
|
8
|
+
export class RpcChannelWithRetries extends RpcChannel {
|
|
9
|
+
|
|
10
|
+
readonly retryPolicy?: {
|
|
11
|
+
maxRetries?: number, delay?: number, exponential?: boolean
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
constructor(options?: RpcProviderOptions, retryPolicy?: {
|
|
15
|
+
maxRetries?: number, delay?: number, exponential?: boolean
|
|
16
|
+
}) {
|
|
17
|
+
super(options);
|
|
18
|
+
this.retryPolicy = retryPolicy;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
protected fetchEndpoint(method: any, params?: any): Promise<any> {
|
|
22
|
+
return tryWithRetries(() => super.fetchEndpoint(method, params), this.retryPolicy, e => {
|
|
23
|
+
if(!e.message.startsWith("RPC: ")) return false;
|
|
24
|
+
const arr = e.message.split("\n");
|
|
25
|
+
const errorCode = parseInt(arr[arr.length-1]);
|
|
26
|
+
if(isNaN(errorCode)) return false;
|
|
27
|
+
if(errorCode < 0) return false; //Not defined error, e.g. Rate limit (-32097)
|
|
28
|
+
return true;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class RpcProviderWithRetries extends RpcProvider {
|
|
35
|
+
|
|
36
|
+
constructor(options?: RpcProviderOptions, retryPolicy?: {
|
|
37
|
+
maxRetries?: number, delay?: number, exponential?: boolean
|
|
38
|
+
}) {
|
|
39
|
+
super(options);
|
|
40
|
+
this.channel = new RpcChannelWithRetries({ ...options, waitMode: false }, retryPolicy);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
}
|