@atomiqlabs/chain-starknet 1.0.0-beta.0

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.
Files changed (136) hide show
  1. package/LICENSE +201 -0
  2. package/dist/get_serialized_block.d.ts +1 -0
  3. package/dist/get_serialized_block.js +28 -0
  4. package/dist/index.d.ts +34 -0
  5. package/dist/index.js +50 -0
  6. package/dist/starknet/StarknetChainType.d.ts +9 -0
  7. package/dist/starknet/StarknetChainType.js +2 -0
  8. package/dist/starknet/StarknetInitializer.d.ts +18 -0
  9. package/dist/starknet/StarknetInitializer.js +49 -0
  10. package/dist/starknet/base/StarknetAction.d.ts +27 -0
  11. package/dist/starknet/base/StarknetAction.js +73 -0
  12. package/dist/starknet/base/StarknetBase.d.ts +34 -0
  13. package/dist/starknet/base/StarknetBase.js +29 -0
  14. package/dist/starknet/base/StarknetModule.d.ts +14 -0
  15. package/dist/starknet/base/StarknetModule.js +13 -0
  16. package/dist/starknet/base/modules/ERC20Abi.d.ts +755 -0
  17. package/dist/starknet/base/modules/ERC20Abi.js +1032 -0
  18. package/dist/starknet/base/modules/StarknetAccounts.d.ts +6 -0
  19. package/dist/starknet/base/modules/StarknetAccounts.js +24 -0
  20. package/dist/starknet/base/modules/StarknetAddresses.d.ts +9 -0
  21. package/dist/starknet/base/modules/StarknetAddresses.js +26 -0
  22. package/dist/starknet/base/modules/StarknetBlocks.d.ts +19 -0
  23. package/dist/starknet/base/modules/StarknetBlocks.js +49 -0
  24. package/dist/starknet/base/modules/StarknetEvents.d.ts +44 -0
  25. package/dist/starknet/base/modules/StarknetEvents.js +88 -0
  26. package/dist/starknet/base/modules/StarknetFees.d.ts +55 -0
  27. package/dist/starknet/base/modules/StarknetFees.js +102 -0
  28. package/dist/starknet/base/modules/StarknetSignatures.d.ts +30 -0
  29. package/dist/starknet/base/modules/StarknetSignatures.js +71 -0
  30. package/dist/starknet/base/modules/StarknetTokens.d.ts +67 -0
  31. package/dist/starknet/base/modules/StarknetTokens.js +97 -0
  32. package/dist/starknet/base/modules/StarknetTransactions.d.ts +87 -0
  33. package/dist/starknet/base/modules/StarknetTransactions.js +226 -0
  34. package/dist/starknet/btcrelay/BtcRelayAbi.d.ts +250 -0
  35. package/dist/starknet/btcrelay/BtcRelayAbi.js +341 -0
  36. package/dist/starknet/btcrelay/StarknetBtcRelay.d.ts +166 -0
  37. package/dist/starknet/btcrelay/StarknetBtcRelay.js +323 -0
  38. package/dist/starknet/btcrelay/headers/StarknetBtcHeader.d.ts +32 -0
  39. package/dist/starknet/btcrelay/headers/StarknetBtcHeader.js +74 -0
  40. package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.d.ts +52 -0
  41. package/dist/starknet/btcrelay/headers/StarknetBtcStoredHeader.js +113 -0
  42. package/dist/starknet/contract/StarknetContractBase.d.ts +13 -0
  43. package/dist/starknet/contract/StarknetContractBase.js +18 -0
  44. package/dist/starknet/contract/modules/StarknetContractEvents.d.ts +40 -0
  45. package/dist/starknet/contract/modules/StarknetContractEvents.js +77 -0
  46. package/dist/starknet/events/StarknetChainEvents.d.ts +19 -0
  47. package/dist/starknet/events/StarknetChainEvents.js +51 -0
  48. package/dist/starknet/events/StarknetChainEventsBrowser.d.ts +73 -0
  49. package/dist/starknet/events/StarknetChainEventsBrowser.js +210 -0
  50. package/dist/starknet/swaps/EscrowManagerAbi.d.ts +445 -0
  51. package/dist/starknet/swaps/EscrowManagerAbi.js +601 -0
  52. package/dist/starknet/swaps/StarknetSwapContract.d.ts +215 -0
  53. package/dist/starknet/swaps/StarknetSwapContract.js +452 -0
  54. package/dist/starknet/swaps/StarknetSwapData.d.ts +74 -0
  55. package/dist/starknet/swaps/StarknetSwapData.js +316 -0
  56. package/dist/starknet/swaps/StarknetSwapModule.d.ts +9 -0
  57. package/dist/starknet/swaps/StarknetSwapModule.js +12 -0
  58. package/dist/starknet/swaps/handlers/IHandler.d.ts +13 -0
  59. package/dist/starknet/swaps/handlers/IHandler.js +2 -0
  60. package/dist/starknet/swaps/handlers/claim/ClaimHandlers.d.ts +13 -0
  61. package/dist/starknet/swaps/handlers/claim/ClaimHandlers.js +13 -0
  62. package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.d.ts +22 -0
  63. package/dist/starknet/swaps/handlers/claim/HashlockClaimHandler.js +44 -0
  64. package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +25 -0
  65. package/dist/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.js +48 -0
  66. package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +26 -0
  67. package/dist/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.js +40 -0
  68. package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +20 -0
  69. package/dist/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.js +29 -0
  70. package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +64 -0
  71. package/dist/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +86 -0
  72. package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.d.ts +17 -0
  73. package/dist/starknet/swaps/handlers/refund/TimelockRefundHandler.js +27 -0
  74. package/dist/starknet/swaps/modules/StarknetLpVault.d.ts +69 -0
  75. package/dist/starknet/swaps/modules/StarknetLpVault.js +122 -0
  76. package/dist/starknet/swaps/modules/StarknetSwapClaim.d.ts +53 -0
  77. package/dist/starknet/swaps/modules/StarknetSwapClaim.js +100 -0
  78. package/dist/starknet/swaps/modules/StarknetSwapInit.d.ts +84 -0
  79. package/dist/starknet/swaps/modules/StarknetSwapInit.js +164 -0
  80. package/dist/starknet/swaps/modules/StarknetSwapRefund.d.ts +64 -0
  81. package/dist/starknet/swaps/modules/StarknetSwapRefund.js +131 -0
  82. package/dist/starknet/swaps/modules/SwapClaim.d.ts +54 -0
  83. package/dist/starknet/swaps/modules/SwapClaim.js +115 -0
  84. package/dist/starknet/swaps/modules/SwapInit.d.ts +79 -0
  85. package/dist/starknet/swaps/modules/SwapInit.js +174 -0
  86. package/dist/starknet/swaps/modules/SwapRefund.d.ts +63 -0
  87. package/dist/starknet/swaps/modules/SwapRefund.js +149 -0
  88. package/dist/starknet/wallet/StarknetKeypairWallet.d.ts +6 -0
  89. package/dist/starknet/wallet/StarknetKeypairWallet.js +26 -0
  90. package/dist/starknet/wallet/StarknetSigner.d.ts +12 -0
  91. package/dist/starknet/wallet/StarknetSigner.js +46 -0
  92. package/dist/utils/Utils.d.ts +38 -0
  93. package/dist/utils/Utils.js +255 -0
  94. package/package.json +39 -0
  95. package/src/index.ts +41 -0
  96. package/src/starknet/StarknetChainType.ts +20 -0
  97. package/src/starknet/StarknetInitializer.ts +75 -0
  98. package/src/starknet/base/StarknetAction.ts +90 -0
  99. package/src/starknet/base/StarknetBase.ts +56 -0
  100. package/src/starknet/base/StarknetModule.ts +20 -0
  101. package/src/starknet/base/modules/ERC20Abi.ts +1029 -0
  102. package/src/starknet/base/modules/StarknetAccounts.ts +26 -0
  103. package/src/starknet/base/modules/StarknetAddresses.ts +23 -0
  104. package/src/starknet/base/modules/StarknetBlocks.ts +59 -0
  105. package/src/starknet/base/modules/StarknetEvents.ts +105 -0
  106. package/src/starknet/base/modules/StarknetFees.ts +136 -0
  107. package/src/starknet/base/modules/StarknetSignatures.ts +91 -0
  108. package/src/starknet/base/modules/StarknetTokens.ts +116 -0
  109. package/src/starknet/base/modules/StarknetTransactions.ts +254 -0
  110. package/src/starknet/btcrelay/BtcRelayAbi.ts +338 -0
  111. package/src/starknet/btcrelay/StarknetBtcRelay.ts +415 -0
  112. package/src/starknet/btcrelay/headers/StarknetBtcHeader.ts +101 -0
  113. package/src/starknet/btcrelay/headers/StarknetBtcStoredHeader.ts +142 -0
  114. package/src/starknet/contract/StarknetContractBase.ts +29 -0
  115. package/src/starknet/contract/modules/StarknetContractEvents.ts +108 -0
  116. package/src/starknet/events/StarknetChainEvents.ts +63 -0
  117. package/src/starknet/events/StarknetChainEventsBrowser.ts +289 -0
  118. package/src/starknet/swaps/EscrowManagerAbi.ts +600 -0
  119. package/src/starknet/swaps/StarknetSwapContract.ts +694 -0
  120. package/src/starknet/swaps/StarknetSwapData.ts +441 -0
  121. package/src/starknet/swaps/StarknetSwapModule.ts +17 -0
  122. package/src/starknet/swaps/handlers/IHandler.ts +20 -0
  123. package/src/starknet/swaps/handlers/claim/ClaimHandlers.ts +23 -0
  124. package/src/starknet/swaps/handlers/claim/HashlockClaimHandler.ts +54 -0
  125. package/src/starknet/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +73 -0
  126. package/src/starknet/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +67 -0
  127. package/src/starknet/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +49 -0
  128. package/src/starknet/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +151 -0
  129. package/src/starknet/swaps/handlers/refund/TimelockRefundHandler.ts +39 -0
  130. package/src/starknet/swaps/modules/StarknetLpVault.ts +148 -0
  131. package/src/starknet/swaps/modules/StarknetSwapClaim.ts +142 -0
  132. package/src/starknet/swaps/modules/StarknetSwapInit.ts +226 -0
  133. package/src/starknet/swaps/modules/StarknetSwapRefund.ts +202 -0
  134. package/src/starknet/wallet/StarknetKeypairWallet.ts +34 -0
  135. package/src/starknet/wallet/StarknetSigner.ts +55 -0
  136. package/src/utils/Utils.ts +247 -0
@@ -0,0 +1,26 @@
1
+ import {StarknetModule} from "../StarknetModule";
2
+ import {StarknetTx} from "./StarknetTransactions";
3
+ import {DeployAccountContractPayload} from "starknet";
4
+
5
+
6
+ export class StarknetAccounts extends StarknetModule {
7
+
8
+ public async getAccountDeployTransaction(deploymentData: DeployAccountContractPayload): Promise<StarknetTx> {
9
+ const feeDetails = this.root.Fees.getFeeDetails(5000, 0, await this.root.Fees.getFeeRate());
10
+ const details = {
11
+ ...feeDetails,
12
+ walletAddress: deploymentData.contractAddress,
13
+ cairoVersion: "1" as const,
14
+ chainId: this.root.starknetChainId,
15
+ nonce: 0,
16
+ accountDeploymentData: [],
17
+ skipValidate: false
18
+ };
19
+ return {
20
+ type: "DEPLOY_ACCOUNT",
21
+ tx: deploymentData,
22
+ details
23
+ };
24
+ }
25
+
26
+ }
@@ -0,0 +1,23 @@
1
+ import {StarknetModule} from "../StarknetModule";
2
+ import {validateAndParseAddress} from "starknet";
3
+
4
+ export class StarknetAddresses extends StarknetModule {
5
+
6
+ ///////////////////
7
+ //// Address utils
8
+ /**
9
+ * Checks whether an address is a valid starknet address
10
+ *
11
+ * @param value
12
+ */
13
+ isValidAddress(value: string): boolean {
14
+ if(value.length!==66) return false;
15
+ try {
16
+ validateAndParseAddress(value);
17
+ return true;
18
+ } catch (e) {
19
+ return false;
20
+ }
21
+ }
22
+
23
+ }
@@ -0,0 +1,59 @@
1
+ import {StarknetModule} from "../StarknetModule";
2
+
3
+ export type StarknetBlockTag = "pending" | "latest";
4
+
5
+ export class StarknetBlocks extends StarknetModule {
6
+
7
+ private BLOCK_CACHE_TIME = 5*1000;
8
+
9
+ private blockCache: {
10
+ [key in StarknetBlockTag]?: {
11
+ blockTime: Promise<number>,
12
+ timestamp: number
13
+ }
14
+ } = {};
15
+
16
+ /**
17
+ * Initiates fetch of a given block & saves it to cache
18
+ *
19
+ * @private
20
+ * @param blockTag
21
+ */
22
+ private fetchAndSaveBlockTime(blockTag: StarknetBlockTag): {
23
+ blockTime: Promise<number>,
24
+ timestamp: number
25
+ } {
26
+ const blockTimePromise = this.provider.getBlockWithTxHashes(blockTag).then(result => result.timestamp);
27
+ const timestamp = Date.now();
28
+ this.blockCache[blockTag] = {
29
+ blockTime: blockTimePromise,
30
+ timestamp
31
+ };
32
+ blockTimePromise.catch(e => {
33
+ if(this.blockCache[blockTag]!=null && this.blockCache[blockTag].blockTime===blockTimePromise) delete this.blockCache[blockTag];
34
+ throw e;
35
+ })
36
+ return {
37
+ blockTime: blockTimePromise,
38
+ timestamp
39
+ };
40
+ }
41
+
42
+ ///////////////////
43
+ //// Slots
44
+ /**
45
+ * Gets the block for a given blocktag, with caching
46
+ *
47
+ * @param blockTag
48
+ */
49
+ public getBlockTime(blockTag: StarknetBlockTag): Promise<number> {
50
+ let cachedBlockData = this.blockCache[blockTag];
51
+
52
+ if(cachedBlockData==null || Date.now()-cachedBlockData.timestamp>this.BLOCK_CACHE_TIME) {
53
+ cachedBlockData = this.fetchAndSaveBlockTime(blockTag);
54
+ }
55
+
56
+ return cachedBlockData.blockTime;
57
+ }
58
+
59
+ }
@@ -0,0 +1,105 @@
1
+ import {StarknetModule} from "../StarknetModule";
2
+
3
+ export type StarknetEvent = {
4
+ block_hash: string;
5
+ block_number: number;
6
+ transaction_hash: string;
7
+ from_address: string;
8
+ keys: string[];
9
+ data: string[];
10
+ }
11
+
12
+ export class StarknetEvents extends StarknetModule {
13
+
14
+ public readonly EVENTS_LIMIT = 100;
15
+ public readonly FORWARD_BLOCK_RANGE = 2000;
16
+
17
+ /**
18
+ * Returns the all the events occuring in a block range as identified by the contract and keys
19
+ *
20
+ * @param contract
21
+ * @param keys
22
+ * @param startBlock
23
+ * @param endBlock
24
+ * @param abortSignal
25
+ */
26
+ public async getBlockEvents(contract: string, keys: string[][], startBlock?: number, endBlock: number = startBlock, abortSignal?: AbortSignal): Promise<StarknetEvent[]> {
27
+ const events: StarknetEvent[] = [];
28
+ let result = null;
29
+ while(result==null || result?.continuation_token!=null) {
30
+ result = await this.root.provider.getEvents({
31
+ address: contract,
32
+ from_block: startBlock==null ? "pending" : {block_number: startBlock},
33
+ to_block: endBlock==null ? "pending" : {block_number: endBlock},
34
+ keys,
35
+ chunk_size: this.EVENTS_LIMIT,
36
+ continuation_token: result?.continuation_token
37
+ });
38
+ if(abortSignal!=null) abortSignal.throwIfAborted();
39
+ events.push(...result.events);
40
+ }
41
+ return events;
42
+ }
43
+
44
+ /**
45
+ * Runs a search backwards in time, processing events from a specific contract and keys
46
+ *
47
+ * @param contract
48
+ * @param keys
49
+ * @param processor called for every batch of returned signatures, should return a value if the correct signature
50
+ * was found, or null if the search should continue
51
+ * @param abortSignal
52
+ */
53
+ public async findInEvents<T>(
54
+ contract: string, keys: string[][],
55
+ processor: (signatures: StarknetEvent[]) => Promise<T>,
56
+ abortSignal?: AbortSignal
57
+ ): Promise<T> {
58
+ const latestBlockNumber = await this.provider.getBlockNumber();
59
+
60
+ for(let blockNumber = latestBlockNumber; blockNumber >= 0; blockNumber-=this.FORWARD_BLOCK_RANGE) {
61
+ const eventsResult = await this.getBlockEvents(
62
+ contract, keys,
63
+ Math.max(blockNumber-this.FORWARD_BLOCK_RANGE, 0), blockNumber===latestBlockNumber ? null : blockNumber,
64
+ abortSignal
65
+ );
66
+ const result: T = await processor(eventsResult.reverse());
67
+ if(result!=null) return result;
68
+ }
69
+ return null;
70
+ }
71
+
72
+ /**
73
+ * Runs a search forwards in time, processing events from a specific contract and keys
74
+ *
75
+ * @param contract
76
+ * @param keys
77
+ * @param processor called for every batch of returned signatures, should return a value if the correct signature
78
+ * was found, or null if the search should continue
79
+ * @param abortSignal
80
+ * @param logFetchLimit
81
+ */
82
+ public async findInEventsForward<T>(
83
+ contract: string, keys: string[][],
84
+ processor: (signatures: StarknetEvent[]) => Promise<T>,
85
+ abortSignal?: AbortSignal,
86
+ logFetchLimit?: number
87
+ ): Promise<T> {
88
+ if(logFetchLimit==null || logFetchLimit>this.EVENTS_LIMIT) logFetchLimit = this.EVENTS_LIMIT;
89
+ let eventsResult = null;
90
+ while(eventsResult==null || eventsResult?.continuation_token!=null) {
91
+ eventsResult = await this.root.provider.getEvents({
92
+ address: contract,
93
+ to_block: "latest",
94
+ keys,
95
+ chunk_size: logFetchLimit ?? this.EVENTS_LIMIT,
96
+ continuation_token: eventsResult?.continuation_token
97
+ });
98
+ if(abortSignal!=null) abortSignal.throwIfAborted();
99
+ const result: T = await processor(eventsResult.events);
100
+ if(result!=null) return result;
101
+ }
102
+ return null;
103
+ }
104
+
105
+ }
@@ -0,0 +1,136 @@
1
+ import {getLogger, toBigInt, toHex} from "../../../utils/Utils";
2
+ import {Provider} from "starknet";
3
+ import {StarknetTokens} from "./StarknetTokens";
4
+
5
+ const MAX_FEE_AGE = 5000;
6
+
7
+ const ERC20_ADDRESS_ETH = "";
8
+ const ERC20_ADDRESS_STRK = "";
9
+
10
+ export class StarknetFees {
11
+
12
+ private readonly logger = getLogger("StarknetFees: ");
13
+
14
+ private readonly feeDA: "L1" | "L2";
15
+ private readonly nonceDA: "L1" | "L2";
16
+ private readonly provider: Provider;
17
+ private readonly gasToken: "ETH" | "STRK";
18
+ private readonly maxFeeRate: bigint;
19
+ private readonly feeMultiplierPPM: bigint;
20
+
21
+ private blockFeeCache: {
22
+ timestamp: number,
23
+ feeRate: Promise<bigint>
24
+ } = null;
25
+
26
+ constructor(
27
+ provider: Provider,
28
+ gasToken: "ETH" | "STRK" = "ETH",
29
+ maxFeeRate: number = gasToken==="ETH" ? 100_000_000_000 /*100 GWei*/ : 1_000_000_000_000_000 /*100 * 10000 GWei*/,
30
+ feeMultiplier: number = 1.25,
31
+ da?: {fee?: "L1" | "L2", nonce?: "L1" | "L2"}
32
+ ) {
33
+ this.provider = provider;
34
+ this.gasToken = gasToken;
35
+ this.maxFeeRate = BigInt(maxFeeRate);
36
+ this.feeDA = da?.fee ?? "L1";
37
+ this.nonceDA = da?.nonce ?? "L1";
38
+ this.feeMultiplierPPM = BigInt(Math.floor(feeMultiplier*1000000));
39
+ }
40
+
41
+ /**
42
+ * Gets starknet fee rate
43
+ *
44
+ * @private
45
+ * @returns {Promise<BN>} L1 gas price denominated in Wei
46
+ */
47
+ private async _getFeeRate(): Promise<bigint> {
48
+ const block = await this.provider.getBlockWithTxHashes("latest");
49
+ let l1GasCost = toBigInt(this.gasToken==="ETH" ? block.l1_gas_price.price_in_wei : block.l1_gas_price.price_in_fri);
50
+ l1GasCost = l1GasCost * this.feeMultiplierPPM / 1000000n;
51
+
52
+ this.logger.debug("_getFeeRate(): L1 fee rate: "+l1GasCost.toString(10));
53
+
54
+ return l1GasCost;
55
+ }
56
+
57
+ /**
58
+ * Gets the gas price with caching, format: <gas price in Wei>;<transaction version: v1/v3>
59
+ *
60
+ * @private
61
+ */
62
+ public async getFeeRate(): Promise<string> {
63
+ if(this.blockFeeCache==null || Date.now() - this.blockFeeCache.timestamp > MAX_FEE_AGE) {
64
+ let obj = {
65
+ timestamp: Date.now(),
66
+ feeRate: null
67
+ };
68
+ obj.feeRate = this._getFeeRate().catch(e => {
69
+ if(this.blockFeeCache===obj) this.blockFeeCache=null;
70
+ throw e;
71
+ });
72
+ this.blockFeeCache = obj;
73
+ }
74
+
75
+ let feeRate = await this.blockFeeCache.feeRate;
76
+ if(feeRate>this.maxFeeRate) feeRate = this.maxFeeRate;
77
+
78
+ const fee = feeRate.toString(10)+";"+(this.gasToken === "ETH" ? "v1" : "v3");
79
+
80
+ this.logger.debug("getFeeRate(): calculated fee: "+fee);
81
+
82
+ return fee;
83
+ }
84
+
85
+ public getDefaultGasToken(): string {
86
+ return this.gasToken==="ETH" ? StarknetTokens.ERC20_ETH : StarknetTokens.ERC20_STRK;
87
+ }
88
+
89
+ /**
90
+ * Calculates the total gas fee fee paid for a given gas limit at a given fee rate
91
+ *
92
+ * @param gas
93
+ * @param feeRate
94
+ */
95
+ public static getGasFee(gas: number, feeRate: string): bigint {
96
+ if(feeRate==null) return 0n;
97
+
98
+ const arr = feeRate.split(";");
99
+ const gasPrice = BigInt(arr[0]);
100
+
101
+ return gasPrice * BigInt(gas);
102
+ }
103
+
104
+ public static getGasToken(feeRate: string): string {
105
+ if(feeRate==null) return null;
106
+
107
+ const arr = feeRate.split(";");
108
+ const txVersion = arr[1] as "v1" | 'v3';
109
+
110
+ return txVersion==="v1" ? StarknetTokens.ERC20_ETH : StarknetTokens.ERC20_STRK;
111
+ }
112
+
113
+ getFeeDetails(L1GasLimit: number, L2GasLimit: number, feeRate: string) {
114
+ if(feeRate==null) return null;
115
+
116
+ const arr = feeRate.split(";");
117
+ const gasPrice = BigInt(arr[0]);
118
+ const version = arr[1] as "v1" | "v3";
119
+
120
+ const maxFee = toHex(BigInt(L1GasLimit) * gasPrice, 16);
121
+
122
+ return {
123
+ maxFee: maxFee,
124
+ version: version==="v1" ? "0x1" : "0x3" as "0x1" | "0x3",
125
+ resourceBounds: {
126
+ l1_gas: {max_amount: toHex(L1GasLimit, 16), max_price_per_unit: toHex(gasPrice, 16)},
127
+ l2_gas: {max_amount: "0x0", max_price_per_unit: "0x0"}
128
+ },
129
+ tip: "0x0",
130
+ paymasterData: [],
131
+ nonceDataAvailabilityMode: this.nonceDA,
132
+ feeDataAvailabilityMode: this.feeDA
133
+ }
134
+ }
135
+
136
+ }
@@ -0,0 +1,91 @@
1
+ import * as createHash from "create-hash";
2
+ import {Buffer} from "buffer";
3
+ import {StarknetModule} from "../StarknetModule";
4
+ import {StarknetSigner} from "../../wallet/StarknetSigner";
5
+ import {
6
+ Account, cairo,
7
+ shortString,
8
+ stark,
9
+ StarknetDomain, StarknetType,
10
+ TypedData
11
+ } from "starknet";
12
+ import {StarknetBase} from "../StarknetBase";
13
+ import {toHex} from "../../../utils/Utils";
14
+
15
+ const StarknetDomain = [
16
+ { name: 'name', type: 'shortstring' },
17
+ { name: 'version', type: 'shortstring' },
18
+ { name: 'chainId', type: 'shortstring' },
19
+ { name: 'revision', type: 'shortstring' },
20
+ ];
21
+
22
+ const DataHash = [
23
+ { name: 'Data hash', type: 'u256' }
24
+ ];
25
+
26
+ export class StarknetSignatures extends StarknetModule {
27
+
28
+ private readonly domain: StarknetDomain;
29
+
30
+ constructor(root: StarknetBase, domainName: string = "atomiq.exchange") {
31
+ super(root);
32
+ this.domain = {
33
+ name: domainName,
34
+ version: '1',
35
+ chainId: shortString.decodeShortString(root.starknetChainId),
36
+ revision: '1'
37
+ };
38
+ }
39
+
40
+ public getTypedMessage(type: StarknetType[], typeName: string, message: object): TypedData {
41
+ return {
42
+ types: {
43
+ StarknetDomain,
44
+ [typeName]: type,
45
+ },
46
+ primaryType: typeName,
47
+ domain: this.domain,
48
+ message
49
+ };
50
+ }
51
+
52
+ public async signTypedMessage(signer: StarknetSigner, type: StarknetType[], typeName: string, message: object): Promise<string> {
53
+ const signature = await signer.account.signMessage(this.getTypedMessage(type, typeName, message));
54
+ return JSON.stringify(stark.formatSignature(signature));
55
+ }
56
+
57
+ public async isValidSignature(signature: string, address: string, type: StarknetType[], typeName: string, message: object) {
58
+ return new Account(this.provider, address, null).verifyMessage(
59
+ this.getTypedMessage(type, typeName, message),
60
+ JSON.parse(signature)
61
+ )
62
+ }
63
+
64
+ ///////////////////
65
+ //// Data signatures
66
+ /**
67
+ * Produces a signature over the sha256 of a specified data Buffer, only works with providers which
68
+ * expose their private key (i.e. backend based, not browser wallet based)
69
+ *
70
+ * @param signer
71
+ * @param data data to sign
72
+ */
73
+ public getDataSignature(signer: StarknetSigner, data: Buffer): Promise<string> {
74
+ const buff = createHash("sha256").update(data).digest();
75
+ return this.signTypedMessage(signer, DataHash, 'DataHash', {"Data hash": cairo.uint256(toHex(buff))});
76
+ }
77
+
78
+ /**
79
+ * Checks whether a signature is a valid signature produced by the account over a data message (computes
80
+ * sha256 hash of the message)
81
+ *
82
+ * @param data signed data
83
+ * @param signature data signature
84
+ * @param address public key of the signer
85
+ */
86
+ public isValidDataSignature(data: Buffer, signature: string, address: string): Promise<boolean> {
87
+ const buff = createHash("sha256").update(data).digest();
88
+ return this.isValidSignature(signature, address, DataHash, 'DataHash', {"Data hash": cairo.uint256(toHex(buff))});
89
+ }
90
+
91
+ }
@@ -0,0 +1,116 @@
1
+ import {StarknetModule} from "../StarknetModule";
2
+ import {StarknetAction} from "../StarknetAction";
3
+ import {ERC20Abi} from "./ERC20Abi";
4
+ import { Contract } from "starknet";
5
+ import {toBigInt} from "../../../utils/Utils";
6
+
7
+
8
+ export class StarknetTokens extends StarknetModule {
9
+
10
+ public static readonly ERC20_ETH = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7";
11
+ public static readonly ERC20_STRK = "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d";
12
+
13
+ public static readonly GasCosts = {
14
+ TRANSFER: {l1: 400, l2: 0},
15
+ APPROVE: {l1: 400, l2: 0}
16
+ };
17
+
18
+ private getContract(address: string) {
19
+ return new Contract(ERC20Abi, address, this.root.provider).typedv2(ERC20Abi);
20
+ }
21
+
22
+ /**
23
+ * Action for transferring the erc20 token
24
+ *
25
+ * @param signer
26
+ * @param recipient
27
+ * @param token
28
+ * @param amount
29
+ * @constructor
30
+ * @private
31
+ */
32
+ private Transfer(signer: string, recipient: string, token: string, amount: bigint): StarknetAction {
33
+ const erc20 = this.getContract(token);
34
+ return new StarknetAction(signer, this.root,
35
+ erc20.populateTransaction.transfer(recipient, amount),
36
+ StarknetTokens.GasCosts.TRANSFER
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Approves spend of tokens for a specific spender
42
+ *
43
+ * @param signer
44
+ * @param spender
45
+ * @param token
46
+ * @param amount
47
+ * @constructor
48
+ * @private
49
+ */
50
+ public Approve(signer: string, spender: string, token: string, amount: bigint): StarknetAction {
51
+ const erc20 = this.getContract(token);
52
+ return new StarknetAction(signer, this.root,
53
+ erc20.populateTransaction.approve(spender, amount),
54
+ StarknetTokens.GasCosts.APPROVE
55
+ );
56
+ }
57
+
58
+ ///////////////////
59
+ //// Tokens
60
+ /**
61
+ * Checks if the provided string is a valid starknet token
62
+ *
63
+ * @param token
64
+ */
65
+ public isValidToken(token: string) {
66
+ return this.root.Addresses.isValidAddress(token);
67
+ }
68
+
69
+ /**
70
+ * Returns the token balance of the address
71
+ *
72
+ * @param address
73
+ * @param token
74
+ */
75
+ public async getTokenBalance(address: string, token: string): Promise<bigint> {
76
+ const erc20 = this.getContract(token);
77
+ const balance = await erc20.balance_of(address);
78
+ const balanceBN = toBigInt(balance);
79
+
80
+ this.logger.debug("getTokenBalance(): token balance fetched, token: "+token+
81
+ " address: "+address+" amount: "+balanceBN.toString());
82
+
83
+ return balanceBN;
84
+ }
85
+
86
+ /**
87
+ * Returns the native currency address, return the default used by the fee module
88
+ */
89
+ public getNativeCurrencyAddress(): string {
90
+ return this.root.Fees.getDefaultGasToken();
91
+ }
92
+
93
+ ///////////////////
94
+ //// Transfers
95
+ /**
96
+ * Creates transactions for sending the over the tokens
97
+ *
98
+ * @param signer
99
+ * @param token token to send
100
+ * @param amount amount of the token to send
101
+ * @param recipient recipient's address
102
+ * @param feeRate fee rate to use for the transactions
103
+ * @private
104
+ */
105
+ public async txsTransfer(signer: string, token: string, amount: bigint, recipient: string, feeRate?: string) {
106
+ const action = this.Transfer(signer, recipient, token, amount);
107
+
108
+ feeRate = feeRate ?? await this.root.Fees.getFeeRate();
109
+
110
+ this.logger.debug("txsTransfer(): transfer TX created, recipient: "+recipient.toString()+
111
+ " token: "+token.toString()+ " amount: "+amount.toString(10));
112
+
113
+ return [await action.tx(feeRate)];
114
+ }
115
+
116
+ }