@atomiqlabs/chain-starknet 8.1.11 → 8.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +72 -3
- package/dist/node/index.d.ts +10 -0
- package/dist/node/index.js +15 -0
- package/dist/starknet/StarknetInitializer.d.ts +39 -6
- package/dist/starknet/StarknetInitializer.js +3 -3
- package/dist/starknet/btcrelay/StarknetBtcRelay.d.ts +7 -6
- package/dist/starknet/btcrelay/StarknetBtcRelay.js +8 -8
- package/dist/starknet/btcrelay/headers/StarknetBtcHeader.d.ts +2 -0
- package/dist/starknet/btcrelay/headers/StarknetBtcHeader.js +2 -0
- package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.d.ts +3 -1
- package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.js +3 -1
- package/dist/starknet/chain/StarknetAction.js +1 -1
- package/dist/starknet/chain/StarknetChainInterface.d.ts +25 -0
- package/dist/starknet/chain/StarknetChainInterface.js +7 -0
- package/dist/starknet/chain/modules/StarknetFees.d.ts +15 -19
- package/dist/starknet/chain/modules/StarknetFees.js +23 -29
- package/dist/starknet/chain/modules/StarknetTransactions.d.ts +32 -6
- package/dist/starknet/chain/modules/StarknetTransactions.js +47 -17
- package/dist/starknet/contract/StarknetContractBase.d.ts +12 -3
- package/dist/starknet/contract/StarknetContractBase.js +2 -2
- package/dist/starknet/contract/modules/StarknetContractEvents.js +1 -1
- package/dist/starknet/events/StarknetChainEvents.d.ts +3 -0
- package/dist/starknet/events/StarknetChainEvents.js +3 -0
- package/dist/starknet/events/StarknetChainEventsBrowser.d.ts +45 -7
- package/dist/starknet/events/StarknetChainEventsBrowser.js +20 -9
- package/dist/starknet/spv_swap/StarknetSpvVaultContract.js +4 -4
- package/dist/starknet/swaps/StarknetSwapContract.js +5 -5
- package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +1 -1
- package/dist/starknet/swaps/modules/StarknetSwapClaim.js +2 -2
- package/dist/starknet/swaps/modules/StarknetSwapRefund.js +1 -1
- package/dist/starknet/wallet/StarknetBrowserSigner.d.ts +9 -1
- package/dist/starknet/wallet/StarknetBrowserSigner.js +31 -1
- package/dist/starknet/wallet/StarknetSigner.d.ts +44 -3
- package/dist/starknet/wallet/StarknetSigner.js +52 -2
- package/dist/utils/Utils.d.ts +1 -1
- package/dist/utils/Utils.js +2 -2
- package/node/index.d.ts +1 -0
- package/node/index.js +3 -0
- package/package.json +5 -4
- package/src/index.ts +76 -2
- package/src/node/index.ts +10 -0
- package/src/starknet/StarknetInitializer.ts +40 -1
- package/src/starknet/btcrelay/StarknetBtcRelay.ts +19 -16
- package/src/starknet/btcrelay/headers/StarknetBtcHeader.ts +2 -0
- package/src/starknet/btcrelay/headers/StarknetBtcStoredHeader.ts +3 -1
- package/src/starknet/chain/StarknetAction.ts +2 -2
- package/src/starknet/chain/StarknetChainInterface.ts +29 -1
- package/src/starknet/chain/modules/StarknetFees.ts +23 -27
- package/src/starknet/chain/modules/StarknetTransactions.ts +59 -18
- package/src/starknet/contract/StarknetContractBase.ts +14 -5
- package/src/starknet/contract/modules/StarknetContractEvents.ts +1 -1
- package/src/starknet/events/StarknetChainEvents.ts +3 -0
- package/src/starknet/events/StarknetChainEventsBrowser.ts +51 -10
- package/src/starknet/spv_swap/StarknetSpvVaultContract.ts +4 -4
- package/src/starknet/swaps/StarknetSwapContract.ts +5 -5
- package/src/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +1 -1
- package/src/starknet/swaps/modules/StarknetSwapClaim.ts +3 -3
- package/src/starknet/swaps/modules/StarknetSwapRefund.ts +2 -2
- package/src/starknet/wallet/StarknetBrowserSigner.ts +39 -2
- package/src/starknet/wallet/StarknetSigner.ts +62 -3
- package/src/utils/Utils.ts +3 -3
|
@@ -7,5 +7,13 @@ import { Account } from "starknet";
|
|
|
7
7
|
* @category Wallets
|
|
8
8
|
*/
|
|
9
9
|
export declare class StarknetBrowserSigner extends StarknetSigner {
|
|
10
|
-
|
|
10
|
+
private usesECDSADN?;
|
|
11
|
+
getReproducibleEntropy?: (appName: string) => Promise<Buffer>;
|
|
12
|
+
/**
|
|
13
|
+
* @param account Signer account to request signatures and send transaction through
|
|
14
|
+
* @param usesECDSADN Optional flag indicating whether the signer supports signing using ECDSA-DN (deterministic
|
|
15
|
+
* nonce) algorithm, this allows the wallet to produce reproducible entropy. Only pass `true` here if you are
|
|
16
|
+
* 100% sure that the signer supports this!
|
|
17
|
+
*/
|
|
18
|
+
constructor(account: Account, usesECDSADN?: boolean);
|
|
11
19
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StarknetBrowserSigner = void 0;
|
|
4
4
|
const StarknetSigner_1 = require("./StarknetSigner");
|
|
5
|
+
const Utils_1 = require("../../utils/Utils");
|
|
5
6
|
/**
|
|
6
7
|
* Browser-based Starknet signer, use with browser based signer accounts, this ensures that
|
|
7
8
|
* no signTransaction calls are made and only sendTransaction is supported!
|
|
@@ -9,9 +10,38 @@ const StarknetSigner_1 = require("./StarknetSigner");
|
|
|
9
10
|
* @category Wallets
|
|
10
11
|
*/
|
|
11
12
|
class StarknetBrowserSigner extends StarknetSigner_1.StarknetSigner {
|
|
12
|
-
|
|
13
|
+
/**
|
|
14
|
+
* @param account Signer account to request signatures and send transaction through
|
|
15
|
+
* @param usesECDSADN Optional flag indicating whether the signer supports signing using ECDSA-DN (deterministic
|
|
16
|
+
* nonce) algorithm, this allows the wallet to produce reproducible entropy. Only pass `true` here if you are
|
|
17
|
+
* 100% sure that the signer supports this!
|
|
18
|
+
*/
|
|
19
|
+
constructor(account, usesECDSADN) {
|
|
13
20
|
super(account, false);
|
|
21
|
+
this.usesECDSADN = usesECDSADN;
|
|
14
22
|
this.signTransaction = undefined;
|
|
23
|
+
if (this.usesECDSADN !== false) {
|
|
24
|
+
this.getReproducibleEntropy = async (appName) => {
|
|
25
|
+
if (this.usesECDSADN === false)
|
|
26
|
+
throw new Error("This wallet doesn't support generating recoverable entropy!");
|
|
27
|
+
const typedData = StarknetSigner_1.StarknetSigner.getReproducibleEntropyMessage(await account.getChainId(), appName);
|
|
28
|
+
const signature = await account.signMessage(typedData);
|
|
29
|
+
const serializedSignature = (0, Utils_1.serializeSignature)(signature);
|
|
30
|
+
if (this.usesECDSADN !== true) {
|
|
31
|
+
const secondSignature = (0, Utils_1.serializeSignature)(await account.signMessage(typedData));
|
|
32
|
+
if (serializedSignature.length === secondSignature.length &&
|
|
33
|
+
serializedSignature.every((value, index) => secondSignature[index] === value)) {
|
|
34
|
+
this.usesECDSADN = true;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
this.usesECDSADN = false;
|
|
38
|
+
this.getReproducibleEntropy = undefined;
|
|
39
|
+
throw new Error("This wallet doesn't support generating recoverable entropy!");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return Buffer.concat(serializedSignature.map((value) => (0, Utils_1.bigNumberishToBuffer)(value, 32)));
|
|
43
|
+
};
|
|
44
|
+
}
|
|
15
45
|
}
|
|
16
46
|
}
|
|
17
47
|
exports.StarknetBrowserSigner = StarknetBrowserSigner;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AbstractSigner } from "@atomiqlabs/base";
|
|
2
|
-
import { Account, DeployAccountContractPayload, Invocation, DeployAccountContractTransaction } from "starknet";
|
|
2
|
+
import { Account, DeployAccountContractPayload, Invocation, DeployAccountContractTransaction, constants } from "starknet";
|
|
3
3
|
import { StarknetTx, StarknetTxDeployAccount, StarknetTxInvoke } from "../chain/modules/StarknetTransactions";
|
|
4
4
|
/**
|
|
5
5
|
* Starknet signer implementation wrapping a starknet.js {@link Account}, for browser
|
|
@@ -8,6 +8,48 @@ import { StarknetTx, StarknetTxDeployAccount, StarknetTxInvoke } from "../chain/
|
|
|
8
8
|
* @category Wallets
|
|
9
9
|
*/
|
|
10
10
|
export declare class StarknetSigner implements AbstractSigner {
|
|
11
|
+
/**
|
|
12
|
+
* A static message (text message part), which should be signed by the Starknet wallets to generate reproducible entropy. Works when
|
|
13
|
+
* wallets use signing with deterministic nonce, such that signature over the same message always yields the
|
|
14
|
+
* same signature (same entropy).
|
|
15
|
+
*/
|
|
16
|
+
private static readonly STARKNET_REPRODUCIBLE_ENTROPY_MESSAGE;
|
|
17
|
+
/**
|
|
18
|
+
* A static message (warning part), which should be signed by the Starknet wallets to generate reproducible entropy. Works when
|
|
19
|
+
* wallets use signing with deterministic nonce, such that signature over the same message always yields the
|
|
20
|
+
* same signature (same entropy).
|
|
21
|
+
*/
|
|
22
|
+
private static readonly STARKNET_REPRODUCIBLE_ENTROPY_WARNING;
|
|
23
|
+
/**
|
|
24
|
+
* Returns a SNIP-12 message to be signed for extracting reproducible entropy. Works when wallets use signing with
|
|
25
|
+
* deterministic nonce, such that signature over the same message always yields the same signature (same entropy).
|
|
26
|
+
*
|
|
27
|
+
* @param starknetChainId Starknet chain ID to use for the SNIP-12 message
|
|
28
|
+
* @param appName Application name to differentiate reproducible entropy generated across different apps
|
|
29
|
+
*/
|
|
30
|
+
static getReproducibleEntropyMessage(starknetChainId: constants.StarknetChainId, appName: string): {
|
|
31
|
+
types: {
|
|
32
|
+
StarknetDomain: {
|
|
33
|
+
name: string;
|
|
34
|
+
type: string;
|
|
35
|
+
}[];
|
|
36
|
+
Message: {
|
|
37
|
+
name: string;
|
|
38
|
+
type: string;
|
|
39
|
+
}[];
|
|
40
|
+
};
|
|
41
|
+
primaryType: string;
|
|
42
|
+
domain: {
|
|
43
|
+
name: string;
|
|
44
|
+
version: string;
|
|
45
|
+
chainId: string;
|
|
46
|
+
revision: string;
|
|
47
|
+
};
|
|
48
|
+
message: {
|
|
49
|
+
Message: string;
|
|
50
|
+
Warning: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
11
53
|
type: "AtomiqAbstractSigner";
|
|
12
54
|
readonly isManagingNoncesInternally: boolean;
|
|
13
55
|
readonly account: Account;
|
|
@@ -23,9 +65,8 @@ export declare class StarknetSigner implements AbstractSigner {
|
|
|
23
65
|
*/
|
|
24
66
|
getAddress(): string;
|
|
25
67
|
/**
|
|
26
|
-
*
|
|
27
68
|
* @param tx
|
|
28
|
-
* @
|
|
69
|
+
* @internal
|
|
29
70
|
*/
|
|
30
71
|
protected _signTransaction(tx: StarknetTx): Promise<StarknetTx>;
|
|
31
72
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StarknetSigner = void 0;
|
|
4
|
+
const starknet_1 = require("starknet");
|
|
4
5
|
const Utils_1 = require("../../utils/Utils");
|
|
5
6
|
const StarknetTransactions_1 = require("../chain/modules/StarknetTransactions");
|
|
6
7
|
/**
|
|
@@ -10,6 +11,42 @@ const StarknetTransactions_1 = require("../chain/modules/StarknetTransactions");
|
|
|
10
11
|
* @category Wallets
|
|
11
12
|
*/
|
|
12
13
|
class StarknetSigner {
|
|
14
|
+
/**
|
|
15
|
+
* Returns a SNIP-12 message to be signed for extracting reproducible entropy. Works when wallets use signing with
|
|
16
|
+
* deterministic nonce, such that signature over the same message always yields the same signature (same entropy).
|
|
17
|
+
*
|
|
18
|
+
* @param starknetChainId Starknet chain ID to use for the SNIP-12 message
|
|
19
|
+
* @param appName Application name to differentiate reproducible entropy generated across different apps
|
|
20
|
+
*/
|
|
21
|
+
static getReproducibleEntropyMessage(starknetChainId, appName) {
|
|
22
|
+
const message = StarknetSigner.STARKNET_REPRODUCIBLE_ENTROPY_MESSAGE.replace(new RegExp("%APPNAME%", 'g'), appName);
|
|
23
|
+
const warning = StarknetSigner.STARKNET_REPRODUCIBLE_ENTROPY_WARNING.replace(new RegExp("%APPNAME%", 'g'), appName);
|
|
24
|
+
return {
|
|
25
|
+
types: {
|
|
26
|
+
StarknetDomain: [
|
|
27
|
+
{ name: 'name', type: 'shortstring' },
|
|
28
|
+
{ name: 'version', type: 'shortstring' },
|
|
29
|
+
{ name: 'chainId', type: 'shortstring' },
|
|
30
|
+
{ name: 'revision', type: 'shortstring' },
|
|
31
|
+
],
|
|
32
|
+
Message: [
|
|
33
|
+
{ name: 'Message', type: 'string' },
|
|
34
|
+
{ name: 'Warning', type: 'string' }
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
primaryType: 'Message',
|
|
38
|
+
domain: {
|
|
39
|
+
name: appName,
|
|
40
|
+
version: '1',
|
|
41
|
+
chainId: starknet_1.shortString.decodeShortString(starknetChainId),
|
|
42
|
+
revision: '1'
|
|
43
|
+
},
|
|
44
|
+
message: {
|
|
45
|
+
'Message': message,
|
|
46
|
+
'Warning': warning
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
13
50
|
constructor(account, isManagingNoncesInternally = false) {
|
|
14
51
|
this.type = "AtomiqAbstractSigner";
|
|
15
52
|
this.account = account;
|
|
@@ -22,9 +59,8 @@ class StarknetSigner {
|
|
|
22
59
|
return (0, Utils_1.toHex)(this.account.address);
|
|
23
60
|
}
|
|
24
61
|
/**
|
|
25
|
-
*
|
|
26
62
|
* @param tx
|
|
27
|
-
* @
|
|
63
|
+
* @internal
|
|
28
64
|
*/
|
|
29
65
|
async _signTransaction(tx) {
|
|
30
66
|
if ((0, StarknetTransactions_1.isStarknetTxInvoke)(tx)) {
|
|
@@ -112,3 +148,17 @@ class StarknetSigner {
|
|
|
112
148
|
}
|
|
113
149
|
}
|
|
114
150
|
exports.StarknetSigner = StarknetSigner;
|
|
151
|
+
/**
|
|
152
|
+
* A static message (text message part), which should be signed by the Starknet wallets to generate reproducible entropy. Works when
|
|
153
|
+
* wallets use signing with deterministic nonce, such that signature over the same message always yields the
|
|
154
|
+
* same signature (same entropy).
|
|
155
|
+
*/
|
|
156
|
+
StarknetSigner.STARKNET_REPRODUCIBLE_ENTROPY_MESSAGE = "Signing this messages generates a reproducible secret" +
|
|
157
|
+
" to be used on %APPNAME%.";
|
|
158
|
+
/**
|
|
159
|
+
* A static message (warning part), which should be signed by the Starknet wallets to generate reproducible entropy. Works when
|
|
160
|
+
* wallets use signing with deterministic nonce, such that signature over the same message always yields the
|
|
161
|
+
* same signature (same entropy).
|
|
162
|
+
*/
|
|
163
|
+
StarknetSigner.STARKNET_REPRODUCIBLE_ENTROPY_WARNING = "PLEASE DOUBLE CHECK THAT YOU ARE ON THE %APPNAME%" +
|
|
164
|
+
" WEBSITE BEFORE SIGNING THE MESSAGE, SIGNING THIS MESSAGE ON ANY OTHER WEBSITE MIGHT LEAD TO LOSS OF FUNDS!";
|
package/dist/utils/Utils.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export declare function bufferToByteArray(buffer: Buffer, startIndex?: number, e
|
|
|
44
44
|
export declare function poseidonHashRange(buffer: Buffer, startIndex?: number, endIndex?: number): BigNumberish;
|
|
45
45
|
export declare function findLastIndex<T>(array: T[], callback: (value: T, index: number) => boolean): number;
|
|
46
46
|
export declare function bigIntMax(a: bigint, b: bigint): bigint;
|
|
47
|
-
export declare function serializeSignature(signature?: Signature):
|
|
47
|
+
export declare function serializeSignature(signature?: Signature): string[] | undefined;
|
|
48
48
|
export declare function deserializeSignature(signature?: ReplaceBigInt<Signature>): Signature | undefined;
|
|
49
49
|
export declare function serializeResourceBounds(resourceBounds: {
|
|
50
50
|
l2_gas: {
|
package/dist/utils/Utils.js
CHANGED
|
@@ -113,11 +113,11 @@ function calculateHash(tx) {
|
|
|
113
113
|
case "DEPLOY_ACCOUNT":
|
|
114
114
|
if (tx.signed.constructorCalldata == null ||
|
|
115
115
|
tx.signed.addressSalt == null ||
|
|
116
|
-
tx.
|
|
116
|
+
tx.details.walletAddress == null)
|
|
117
117
|
throw new Error("TX not enough data to compute hash!");
|
|
118
118
|
const deployAccountData = starknet_1.CallData.compile(tx.signed.constructorCalldata);
|
|
119
119
|
return tx.txId = starknet_1.hash.calculateDeployAccountTransactionHash({
|
|
120
|
-
contractAddress: tx.
|
|
120
|
+
contractAddress: tx.details.walletAddress,
|
|
121
121
|
classHash: tx.signed.classHash,
|
|
122
122
|
compiledConstructorCalldata: deployAccountData,
|
|
123
123
|
salt: tx.signed.addressSalt,
|
package/node/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../dist/node";
|
package/node/index.js
ADDED
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomiqlabs/chain-starknet",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.2",
|
|
4
4
|
"description": "Starknet specific base implementation",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "tsc",
|
|
8
|
+
"build": "npx -y -p typescript@4.9 tsc",
|
|
9
9
|
"prepublishOnly": "npm run build",
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
11
11
|
"build:ts4": "npx -p typescript@4.9 tsc --noEmit",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"/dist",
|
|
16
|
-
"/src"
|
|
16
|
+
"/src",
|
|
17
|
+
"/node"
|
|
17
18
|
],
|
|
18
19
|
"keywords": [
|
|
19
20
|
"Starknet",
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
"url": "git+https://github.com/atomiqlabs/atomiq-chain-starknet.git"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@atomiqlabs/base": "^13.
|
|
34
|
+
"@atomiqlabs/base": "^13.2.0",
|
|
34
35
|
"@noble/hashes": "^1.7.1",
|
|
35
36
|
"@scure/btc-signer": "^1.6.0",
|
|
36
37
|
"abi-wan-kanabi": "2.2.4",
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # @atomiqlabs/chain-starknet
|
|
3
|
+
*
|
|
4
|
+
* `@atomiqlabs/chain-starknet` is the Starknet integration package for the Atomiq protocol.
|
|
5
|
+
*
|
|
6
|
+
* Within the Atomiq stack, this library provides the Starknet-side building blocks used for Bitcoin-aware swaps and SPV-backed vault flows on Starknet. It includes:
|
|
7
|
+
*
|
|
8
|
+
* - the `StarknetInitializer` used to register Starknet support in the Atomiq SDK
|
|
9
|
+
* - the `StarknetChainInterface` used to talk to Starknet RPCs
|
|
10
|
+
* - Starknet BTC relay, escrow swap, and SPV vault contract wrappers
|
|
11
|
+
* - signer helpers for browser and programmatic Starknet integrations
|
|
12
|
+
* - retrying RPC and websocket helpers for chain access and realtime events
|
|
13
|
+
*
|
|
14
|
+
* This package is intended for direct protocol integrations and for higher-level Atomiq SDK layers that need Starknet chain support.
|
|
15
|
+
*
|
|
16
|
+
* ## Installation
|
|
17
|
+
*
|
|
18
|
+
* Install the package with its `starknet` peer dependency:
|
|
19
|
+
*
|
|
20
|
+
* ```bash
|
|
21
|
+
* npm install @atomiqlabs/chain-starknet starknet
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* ## Supported Chains
|
|
25
|
+
*
|
|
26
|
+
* This package exports a single Starknet initializer:
|
|
27
|
+
*
|
|
28
|
+
* - Starknet via `StarknetInitializer`
|
|
29
|
+
*
|
|
30
|
+
* Canonical deployments currently defined in this package:
|
|
31
|
+
*
|
|
32
|
+
* | Chain | Canonical deployments included |
|
|
33
|
+
* |-------|--------------------------------|
|
|
34
|
+
* | Starknet | `MAINNET`, `TESTNET`, `TESTNET4` |
|
|
35
|
+
*
|
|
36
|
+
* By default, `StarknetInitializer` selects `SN_MAIN` Starknet network when `bitcoinNetwork` is `BitcoinNetwork.MAINNET`, and `SN_SEPOLIA` otherwise. That means both `BitcoinNetwork.TESTNET` and `BitcoinNetwork.TESTNET4` use Starknet Sepolia by default, while the BTC relay contract switches to the matching Bitcoin-network-specific deployment.
|
|
37
|
+
*
|
|
38
|
+
* If you need a non-canonical deployment, pass explicit, `swapContract`, `spvVaultContract`, `btcRelayContract`, or handler contract overrides in the initializer options.
|
|
39
|
+
*
|
|
40
|
+
* ## SDK Example
|
|
41
|
+
*
|
|
42
|
+
* Initialize the Atomiq SDK with Starknet network support:
|
|
43
|
+
*
|
|
44
|
+
* ```ts
|
|
45
|
+
* import {StarknetInitializer} from "@atomiqlabs/chain-starknet";
|
|
46
|
+
* import {BitcoinNetwork, SwapperFactory, TypedSwapper} from "@atomiqlabs/sdk";
|
|
47
|
+
*
|
|
48
|
+
* // Define chains that you want to support here
|
|
49
|
+
* const chains = [StarknetInitializer] as const;
|
|
50
|
+
* type SupportedChains = typeof chains;
|
|
51
|
+
*
|
|
52
|
+
* const Factory = new SwapperFactory<SupportedChains>(chains);
|
|
53
|
+
*
|
|
54
|
+
* const swapper: TypedSwapper<SupportedChains> = Factory.newSwapper({
|
|
55
|
+
* chains: {
|
|
56
|
+
* STARKNET: {
|
|
57
|
+
* rpcUrl: starknetRpc,
|
|
58
|
+
* wsUrl: starknetWs // Optional, but recommended for realtime event subscriptions
|
|
59
|
+
* }
|
|
60
|
+
* },
|
|
61
|
+
* bitcoinNetwork: BitcoinNetwork.MAINNET // or BitcoinNetwork.TESTNET / BitcoinNetwork.TESTNET4
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* If you use the lower-level initializer directly, you can also override the default Starknet chain ID and canonical contract addresses independently when you need custom deployments.
|
|
66
|
+
*
|
|
67
|
+
* @packageDocumentation
|
|
68
|
+
*/
|
|
1
69
|
import * as WebSocket from "ws";
|
|
2
70
|
if(global.window==null) global.WebSocket = WebSocket as any;
|
|
3
71
|
|
|
@@ -6,8 +74,14 @@ export {StarknetBtcHeader} from "./starknet/btcrelay/headers/StarknetBtcHeader";
|
|
|
6
74
|
export * from "./starknet/btcrelay/StarknetBtcRelay";
|
|
7
75
|
|
|
8
76
|
export * from "./starknet/chain/modules/StarknetFees";
|
|
9
|
-
export {
|
|
10
|
-
|
|
77
|
+
export {
|
|
78
|
+
StarknetTx,
|
|
79
|
+
SignedStarknetTx,
|
|
80
|
+
StarknetTxInvoke,
|
|
81
|
+
StarknetTxDeployAccount,
|
|
82
|
+
isStarknetTxDeployAccount,
|
|
83
|
+
isStarknetTxInvoke
|
|
84
|
+
} from "./starknet/chain/modules/StarknetTransactions";
|
|
11
85
|
export * from "./starknet/chain/StarknetChainInterface";
|
|
12
86
|
|
|
13
87
|
export * from "./starknet/events/StarknetChainEventsBrowser";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js-only entrypoint for filesystem-backed Starknet helpers.
|
|
3
|
+
*
|
|
4
|
+
* Import from `@atomiqlabs/chain-starknet/node` when you need runtime features
|
|
5
|
+
* that depend on Node's `fs` module.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
export {StarknetChainEvents} from "../starknet/events/StarknetChainEvents";
|
|
10
|
+
export {StarknetPersistentSigner} from "../starknet/wallet/StarknetPersistentSigner";
|
|
@@ -25,7 +25,7 @@ export type StarknetAssetsType = BaseTokenType<"ETH" | "STRK" | "WBTC" | "TBTC"
|
|
|
25
25
|
*
|
|
26
26
|
* @category Chain Interface
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
const StarknetAssets: StarknetAssetsType = {
|
|
29
29
|
ETH: {
|
|
30
30
|
address: "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
|
|
31
31
|
decimals: 18,
|
|
@@ -65,17 +65,50 @@ export const StarknetAssets: StarknetAssetsType = {
|
|
|
65
65
|
* @category Chain Interface
|
|
66
66
|
*/
|
|
67
67
|
export type StarknetOptions = {
|
|
68
|
+
/**
|
|
69
|
+
* Starknet RPC URL or {@link Provider} object to use for Starknet network access
|
|
70
|
+
*/
|
|
68
71
|
rpcUrl: string | Provider,
|
|
72
|
+
/**
|
|
73
|
+
* Optional WebSocket URL or {@link WebSocketChannel} object to use for realtime events subscriptions
|
|
74
|
+
*/
|
|
69
75
|
wsUrl?: string | WebSocketChannel,
|
|
76
|
+
/**
|
|
77
|
+
* Retry policy for the RPC calls
|
|
78
|
+
*/
|
|
70
79
|
retryPolicy?: {maxRetries?: number, delay?: number, exponential?: boolean},
|
|
80
|
+
/**
|
|
81
|
+
* Starknet chain ID: mainnet or sepolia
|
|
82
|
+
*/
|
|
71
83
|
chainId?: constants.StarknetChainId,
|
|
72
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Contract address of the Escrow Manager contract, uses canonical deployment by default
|
|
87
|
+
*/
|
|
73
88
|
swapContract?: string,
|
|
89
|
+
/**
|
|
90
|
+
* Optional Escrow Manager contract deployment height, which acts as genesis when querying events
|
|
91
|
+
*/
|
|
74
92
|
swapContractDeploymentHeight?: number,
|
|
93
|
+
/**
|
|
94
|
+
* Contract address of the BTC Relay contract, uses canonical deployment by default
|
|
95
|
+
*/
|
|
75
96
|
btcRelayContract?: string,
|
|
97
|
+
/**
|
|
98
|
+
* Optional BTC Relay contract deployment height, which acts as genesis when querying events
|
|
99
|
+
*/
|
|
76
100
|
btcRelayContractDeploymentHeight?: number,
|
|
101
|
+
/**
|
|
102
|
+
* Contract address of the UTXO-controlled vault (SPV Vault manager) contract, uses canonical deployment by default
|
|
103
|
+
*/
|
|
77
104
|
spvVaultContract?: string,
|
|
105
|
+
/**
|
|
106
|
+
* Optional UTXO-controlled vault (SPV Vault manager) contract deployment height, which acts as genesis when querying events
|
|
107
|
+
*/
|
|
78
108
|
spvVaultContractDeploymentHeight?: number,
|
|
109
|
+
/**
|
|
110
|
+
* Contract addresses of the refund and claim handlers, uses canonical deployment by default
|
|
111
|
+
*/
|
|
79
112
|
handlerContracts?: {
|
|
80
113
|
refund?: {
|
|
81
114
|
timelock?: string
|
|
@@ -85,8 +118,14 @@ export type StarknetOptions = {
|
|
|
85
118
|
}
|
|
86
119
|
}
|
|
87
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Starknet network fee API
|
|
123
|
+
*/
|
|
88
124
|
fees?: StarknetFees,
|
|
89
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Starknet configuration
|
|
128
|
+
*/
|
|
90
129
|
starknetConfig?: StarknetConfig
|
|
91
130
|
}
|
|
92
131
|
|
|
@@ -11,8 +11,8 @@ import {StarknetBtcStoredHeader} from "./headers/StarknetBtcStoredHeader";
|
|
|
11
11
|
import {StarknetTx} from "../chain/modules/StarknetTransactions";
|
|
12
12
|
import {StarknetSigner} from "../wallet/StarknetSigner";
|
|
13
13
|
import {BtcRelayAbi} from "./BtcRelayAbi";
|
|
14
|
-
import {BigNumberish,
|
|
15
|
-
import {StarknetFees
|
|
14
|
+
import {BigNumberish, hash} from "starknet";
|
|
15
|
+
import {StarknetFees} from "../chain/modules/StarknetFees";
|
|
16
16
|
import {StarknetChainInterface} from "../chain/StarknetChainInterface";
|
|
17
17
|
import {StarknetAction} from "../chain/StarknetAction";
|
|
18
18
|
|
|
@@ -70,7 +70,7 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
70
70
|
* @param mainHeaders New bitcoin blockheaders to submit
|
|
71
71
|
* @param storedHeader Current latest committed and stored bitcoin blockheader in the light client
|
|
72
72
|
*/
|
|
73
|
-
|
|
73
|
+
private SaveMainHeaders(signer: string, mainHeaders: StarknetBtcHeader[], storedHeader: StarknetBtcStoredHeader): StarknetAction {
|
|
74
74
|
|
|
75
75
|
return new StarknetAction(signer, this.Chain,
|
|
76
76
|
{
|
|
@@ -78,7 +78,7 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
78
78
|
entrypoint: "submit_main_blockheaders",
|
|
79
79
|
calldata: serializeCalldata(mainHeaders, storedHeader, [])
|
|
80
80
|
},
|
|
81
|
-
starknetGasMul(GAS_PER_BLOCKHEADER, mainHeaders.length)
|
|
81
|
+
StarknetFees.starknetGasMul(GAS_PER_BLOCKHEADER, mainHeaders.length)
|
|
82
82
|
)
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -91,14 +91,14 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
91
91
|
* @param forkHeaders Fork bitcoin blockheaders to submit
|
|
92
92
|
* @param storedHeader Committed and stored bitcoin blockheader from which to fork the light client
|
|
93
93
|
*/
|
|
94
|
-
|
|
94
|
+
private SaveShortForkHeaders(signer: string, forkHeaders: StarknetBtcHeader[], storedHeader: StarknetBtcStoredHeader): StarknetAction {
|
|
95
95
|
return new StarknetAction(signer, this.Chain,
|
|
96
96
|
{
|
|
97
97
|
contractAddress: this.contract.address,
|
|
98
98
|
entrypoint: "submit_short_fork_blockheaders",
|
|
99
99
|
calldata: serializeCalldata(forkHeaders, storedHeader, [])
|
|
100
100
|
},
|
|
101
|
-
starknetGasMul(GAS_PER_BLOCKHEADER, forkHeaders.length)
|
|
101
|
+
StarknetFees.starknetGasMul(GAS_PER_BLOCKHEADER, forkHeaders.length)
|
|
102
102
|
)
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -112,21 +112,24 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
112
112
|
* creating the fork), or the tip of the fork (when adding more blockheaders to the fork)
|
|
113
113
|
* @param totalForkHeaders Total blockheaders in the fork - used to estimate the gas usage when re-org happens
|
|
114
114
|
*/
|
|
115
|
-
|
|
115
|
+
private SaveLongForkHeaders(signer: string, forkId: number, forkHeaders: StarknetBtcHeader[], storedHeader: StarknetBtcStoredHeader, totalForkHeaders: number = 100): StarknetAction {
|
|
116
116
|
return new StarknetAction(signer, this.Chain,
|
|
117
117
|
{
|
|
118
118
|
contractAddress: this.contract.address,
|
|
119
119
|
entrypoint: "submit_fork_blockheaders",
|
|
120
120
|
calldata: serializeCalldata(forkHeaders, storedHeader, [toHex(forkId)])
|
|
121
121
|
},
|
|
122
|
-
starknetGasAdd(
|
|
123
|
-
starknetGasMul(GAS_PER_BLOCKHEADER, forkHeaders.length),
|
|
124
|
-
starknetGasMul(GAS_PER_BLOCKHEADER_FORK, totalForkHeaders)
|
|
122
|
+
StarknetFees.starknetGasAdd(
|
|
123
|
+
StarknetFees.starknetGasMul(GAS_PER_BLOCKHEADER, forkHeaders.length),
|
|
124
|
+
StarknetFees.starknetGasMul(GAS_PER_BLOCKHEADER_FORK, totalForkHeaders)
|
|
125
125
|
)
|
|
126
126
|
)
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
/**
|
|
130
|
+
* @internal
|
|
131
|
+
*/
|
|
132
|
+
readonly _bitcoinRpc: BitcoinRpc<B>;
|
|
130
133
|
|
|
131
134
|
readonly maxHeadersPerTx: number = 40;
|
|
132
135
|
readonly maxForkHeadersPerTx: number = 30;
|
|
@@ -147,7 +150,7 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
147
150
|
? btcRelayDeploymentHeights[bitcoinNetwork]
|
|
148
151
|
: undefined)
|
|
149
152
|
);
|
|
150
|
-
this.
|
|
153
|
+
this._bitcoinRpc = bitcoinRpc;
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
/**
|
|
@@ -223,7 +226,7 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
223
226
|
const starknetBlockHash = hash.computePoseidonHashOnElements(bufferToU32Array(Buffer.from([...blockHash]).reverse()));
|
|
224
227
|
keys.push(starknetBlockHash);
|
|
225
228
|
}
|
|
226
|
-
return this.
|
|
229
|
+
return this._Events.findInContractEvents(
|
|
227
230
|
["btc_relay::events::StoreHeader", "btc_relay::events::StoreForkHeader"],
|
|
228
231
|
keys,
|
|
229
232
|
(event) => {
|
|
@@ -314,7 +317,7 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
314
317
|
resultStoredHeader: StarknetBtcStoredHeader,
|
|
315
318
|
resultBitcoinHeader: B
|
|
316
319
|
} | null> {
|
|
317
|
-
const data = await this.
|
|
320
|
+
const data = await this._Events.findInContractEvents(
|
|
318
321
|
["btc_relay::events::StoreHeader", "btc_relay::events::StoreForkHeader"],
|
|
319
322
|
null,
|
|
320
323
|
async (event) => {
|
|
@@ -324,14 +327,14 @@ export class StarknetBtcRelay<B extends BtcBlock>
|
|
|
324
327
|
const commitHash = event.params.commit_hash;
|
|
325
328
|
|
|
326
329
|
const [isInBtcMainChain, btcRelayCommitHash] = await Promise.all([
|
|
327
|
-
this.
|
|
330
|
+
this._bitcoinRpc.isInMainChain(blockHashHex).catch(() => false),
|
|
328
331
|
this.contract.get_commit_hash(storedHeader.getBlockheight())
|
|
329
332
|
]);
|
|
330
333
|
|
|
331
334
|
if(!isInBtcMainChain) return null;
|
|
332
335
|
if(BigInt(commitHash)!==BigInt(btcRelayCommitHash)) return null;
|
|
333
336
|
|
|
334
|
-
const bitcoinBlockHeader = await this.
|
|
337
|
+
const bitcoinBlockHeader = await this._bitcoinRpc.getBlockHeader(blockHashHex);
|
|
335
338
|
if(bitcoinBlockHeader==null) return null;
|
|
336
339
|
|
|
337
340
|
return {
|
|
@@ -33,6 +33,8 @@ export class StarknetBtcHeader implements BtcHeader {
|
|
|
33
33
|
* Constructs the bitcoin blockheader from a struct as returned by the starknet.js lib
|
|
34
34
|
*
|
|
35
35
|
* @param obj Struct as returned by the starknet.js lib
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
36
38
|
*/
|
|
37
39
|
constructor(obj: StarknetBtcHeaderType) {
|
|
38
40
|
this.reversed_version = Number(obj.reversed_version);
|
|
@@ -31,7 +31,9 @@ export class StarknetBtcStoredHeader implements BtcStoredHeader<StarknetBtcHeade
|
|
|
31
31
|
/**
|
|
32
32
|
* Constructs the bitcoin stored blockheader from a struct as returned by the starknet.js lib
|
|
33
33
|
*
|
|
34
|
-
* @param obj Struct as returned by the starknet.js
|
|
34
|
+
* @param obj Struct as returned by the starknet.js
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
35
37
|
*/
|
|
36
38
|
constructor(obj: StarknetBtcStoredHeaderType) {
|
|
37
39
|
this.blockheader = obj.blockheader instanceof StarknetBtcHeader ? obj.blockheader : new StarknetBtcHeader(obj.blockheader);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {Call} from "starknet";
|
|
2
2
|
import {StarknetChainInterface} from "./StarknetChainInterface";
|
|
3
3
|
import {StarknetTx} from "./modules/StarknetTransactions";
|
|
4
|
-
import {
|
|
4
|
+
import {StarknetFees, StarknetGas} from "./modules/StarknetFees";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* An action which contains multiple underlying contract calls (invokes), tracks their total gas limits
|
|
@@ -54,7 +54,7 @@ export class StarknetAction {
|
|
|
54
54
|
*/
|
|
55
55
|
public addIx(instruction: Call, gasLimit?: StarknetGas) {
|
|
56
56
|
this.instructions.push(instruction);
|
|
57
|
-
if(gasLimit!=null) this.gas = starknetGasAdd(this.gas, gasLimit);
|
|
57
|
+
if(gasLimit!=null) this.gas = StarknetFees.starknetGasAdd(this.gas, gasLimit);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
@@ -20,10 +20,28 @@ import {StarknetBrowserSigner} from "../wallet/StarknetBrowserSigner";
|
|
|
20
20
|
* @category Chain Interface
|
|
21
21
|
*/
|
|
22
22
|
export type StarknetConfig = {
|
|
23
|
+
/**
|
|
24
|
+
* Limit of the number of events retrieved by a single `starknet_getEvents` RPC call.
|
|
25
|
+
*
|
|
26
|
+
* Defaults to 100 events
|
|
27
|
+
*/
|
|
23
28
|
getLogChunkSize?: number, //100
|
|
29
|
+
/**
|
|
30
|
+
* When fetching events in the forward direction, sets the limit on the number of blocks
|
|
31
|
+
* to fetch in a single `starknet_getEvents` RPC call.
|
|
32
|
+
*
|
|
33
|
+
* Defaults to 2000 blocks
|
|
34
|
+
*/
|
|
24
35
|
getLogForwardBlockRange?: number, //2000
|
|
36
|
+
/**
|
|
37
|
+
* Maximum numbers of keys allowed to be specified in a single `starknet_getEvents` RPC call
|
|
38
|
+
*
|
|
39
|
+
* Defaults to 64 keys
|
|
40
|
+
*/
|
|
25
41
|
maxGetLogKeys?: number, //64
|
|
26
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Maximum number of parallel contract calls to execute in batch functions
|
|
44
|
+
*/
|
|
27
45
|
maxParallelCalls?: number, //10
|
|
28
46
|
};
|
|
29
47
|
|
|
@@ -39,10 +57,12 @@ export class StarknetChainInterface implements ChainInterface<StarknetTx, Signed
|
|
|
39
57
|
|
|
40
58
|
/**
|
|
41
59
|
* Optional websocket channel for instant notifications
|
|
60
|
+
* @internal
|
|
42
61
|
*/
|
|
43
62
|
readonly wsChannel?: WebSocketChannel;
|
|
44
63
|
/**
|
|
45
64
|
* Underlying starknet.js provider
|
|
65
|
+
* @internal
|
|
46
66
|
*/
|
|
47
67
|
readonly provider: Provider;
|
|
48
68
|
|
|
@@ -191,6 +211,14 @@ export class StarknetChainInterface implements ChainInterface<StarknetTx, Signed
|
|
|
191
211
|
return this.Transactions.sendSignedAndConfirm(signedTxs, waitForConfirmation, abortSignal, parallel, onBeforePublish);
|
|
192
212
|
}
|
|
193
213
|
|
|
214
|
+
/**
|
|
215
|
+
* @inheritDoc
|
|
216
|
+
*/
|
|
217
|
+
async prepareTxs(txs: StarknetTx[]): Promise<StarknetTx[]> {
|
|
218
|
+
await this.Transactions.prepareTransactions(txs);
|
|
219
|
+
return txs;
|
|
220
|
+
}
|
|
221
|
+
|
|
194
222
|
/**
|
|
195
223
|
* @inheritDoc
|
|
196
224
|
*/
|