starknet 4.7.0 → 4.9.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 (95) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/CONTRIBUTING.md +2 -2
  3. package/__mocks__/ERC20.json +32561 -29055
  4. package/__mocks__/l1l2_compiled.json +10107 -0
  5. package/__tests__/account.test.ts +32 -24
  6. package/__tests__/contract.test.ts +25 -14
  7. package/__tests__/defaultProvider.test.ts +19 -49
  8. package/__tests__/fixtures.ts +11 -1
  9. package/__tests__/rpcProvider.test.ts +6 -15
  10. package/__tests__/sequencerProvider.test.ts +57 -11
  11. package/__tests__/utils/merkle.test.ts +113 -3
  12. package/__tests__/utils/typedData.test.ts +3 -3
  13. package/account/default.d.ts +10 -44
  14. package/account/default.js +255 -61
  15. package/account/interface.d.ts +78 -7
  16. package/constants.d.ts +1 -0
  17. package/constants.js +1 -0
  18. package/contract/default.js +6 -6
  19. package/dist/account/default.d.ts +10 -44
  20. package/dist/account/default.js +255 -61
  21. package/dist/account/interface.d.ts +78 -7
  22. package/dist/constants.d.ts +1 -0
  23. package/dist/constants.js +1 -0
  24. package/dist/contract/default.js +6 -6
  25. package/dist/provider/default.d.ts +8 -3
  26. package/dist/provider/default.js +31 -4
  27. package/dist/provider/interface.d.ts +67 -5
  28. package/dist/provider/rpc.d.ts +7 -2
  29. package/dist/provider/rpc.js +83 -8
  30. package/dist/provider/sequencer.d.ts +9 -3
  31. package/dist/provider/sequencer.js +93 -14
  32. package/dist/signer/default.d.ts +4 -1
  33. package/dist/signer/default.js +22 -0
  34. package/dist/signer/interface.d.ts +27 -2
  35. package/dist/types/api/openrpc.d.ts +24 -2
  36. package/dist/types/api/sequencer.d.ts +43 -23
  37. package/dist/types/lib.d.ts +23 -2
  38. package/dist/types/provider.d.ts +19 -10
  39. package/dist/types/signer.d.ts +14 -1
  40. package/dist/utils/hash.d.ts +8 -0
  41. package/dist/utils/hash.js +28 -2
  42. package/dist/utils/merkle.js +4 -5
  43. package/dist/utils/number.d.ts +5 -0
  44. package/dist/utils/number.js +29 -1
  45. package/dist/utils/responseParser/rpc.d.ts +2 -6
  46. package/dist/utils/responseParser/rpc.js +0 -11
  47. package/dist/utils/responseParser/sequencer.js +11 -33
  48. package/package.json +1 -1
  49. package/provider/default.d.ts +8 -3
  50. package/provider/default.js +31 -4
  51. package/provider/interface.d.ts +67 -5
  52. package/provider/rpc.d.ts +7 -2
  53. package/provider/rpc.js +83 -8
  54. package/provider/sequencer.d.ts +9 -3
  55. package/provider/sequencer.js +93 -14
  56. package/signer/default.d.ts +4 -1
  57. package/signer/default.js +22 -0
  58. package/signer/interface.d.ts +27 -2
  59. package/src/account/default.ts +201 -53
  60. package/src/account/interface.ts +104 -6
  61. package/src/constants.ts +1 -0
  62. package/src/contract/default.ts +6 -6
  63. package/src/provider/default.ts +43 -5
  64. package/src/provider/interface.ts +92 -7
  65. package/src/provider/rpc.ts +86 -12
  66. package/src/provider/sequencer.ts +105 -13
  67. package/src/signer/default.ts +54 -2
  68. package/src/signer/interface.ts +31 -2
  69. package/src/types/api/openrpc.ts +28 -2
  70. package/src/types/api/sequencer.ts +54 -25
  71. package/src/types/lib.ts +30 -2
  72. package/src/types/provider.ts +31 -11
  73. package/src/types/signer.ts +18 -1
  74. package/src/utils/hash.ts +70 -2
  75. package/src/utils/merkle.ts +4 -5
  76. package/src/utils/number.ts +27 -0
  77. package/src/utils/responseParser/rpc.ts +4 -20
  78. package/src/utils/responseParser/sequencer.ts +14 -7
  79. package/types/api/openrpc.d.ts +24 -2
  80. package/types/api/sequencer.d.ts +43 -23
  81. package/types/lib.d.ts +23 -2
  82. package/types/provider.d.ts +19 -10
  83. package/types/signer.d.ts +14 -1
  84. package/utils/hash.d.ts +8 -0
  85. package/utils/hash.js +28 -2
  86. package/utils/merkle.js +4 -5
  87. package/utils/number.d.ts +5 -0
  88. package/utils/number.js +29 -1
  89. package/utils/responseParser/rpc.d.ts +2 -6
  90. package/utils/responseParser/rpc.js +0 -11
  91. package/utils/responseParser/sequencer.js +11 -33
  92. package/www/docs/API/account.md +60 -1
  93. package/www/docs/API/provider.md +320 -23
  94. package/www/guides/account.md +1 -1
  95. package/www/guides/erc20.md +13 -7
@@ -3,7 +3,6 @@ import type {
3
3
  Call,
4
4
  CallContractResponse,
5
5
  ContractClass,
6
- DeclareContractPayload,
7
6
  DeclareContractResponse,
8
7
  DeployContractPayload,
9
8
  DeployContractResponse,
@@ -16,6 +15,11 @@ import type {
16
15
  InvocationsDetailsWithNonce,
17
16
  InvokeFunctionResponse,
18
17
  } from '../types';
18
+ import {
19
+ DeclareContractTransaction,
20
+ DeployAccountContractPayload,
21
+ DeployAccountContractTransaction,
22
+ } from '../types/lib';
19
23
  import type { BigNumberish } from '../utils/number';
20
24
  import { BlockIdentifier } from './utils';
21
25
 
@@ -124,16 +128,18 @@ export abstract class ProviderInterface {
124
128
  public abstract deployContract(payload: DeployContractPayload): Promise<DeployContractResponse>;
125
129
 
126
130
  /**
127
- * Declares a given compiled contract (json) to starknet
131
+ * Deploys a given compiled Account contract (json) to starknet
128
132
  *
129
133
  * @param payload payload to be deployed containing:
130
134
  * - compiled contract code
131
- * - optional version
135
+ * - constructor calldata
136
+ * - address salt
132
137
  * @returns a confirmation of sending a transaction on the starknet contract
133
138
  */
134
- public abstract declareContract(
135
- payload: DeclareContractPayload
136
- ): Promise<DeclareContractResponse>;
139
+ public abstract deployAccountContract(
140
+ payload: DeployAccountContractPayload,
141
+ details: InvocationsDetailsWithNonce
142
+ ): Promise<DeployContractResponse>;
137
143
 
138
144
  /**
139
145
  * Invokes a function on starknet
@@ -156,7 +162,25 @@ export abstract class ProviderInterface {
156
162
  ): Promise<InvokeFunctionResponse>;
157
163
 
158
164
  /**
159
- * Estimates the fee for a given transaction
165
+ * Declares a given compiled contract (json) to starknet
166
+ * @param transaction transaction payload to be deployed containing:
167
+ * - compiled contract code
168
+ * - sender address
169
+ * - signature
170
+ * @param details Invocation Details containing:
171
+ * - nonce
172
+ * - optional version
173
+ * - optional maxFee
174
+ * @returns a confirmation of sending a transaction on the starknet contract
175
+ */
176
+ public abstract declareContract(
177
+ transaction: DeclareContractTransaction,
178
+ details: InvocationsDetailsWithNonce
179
+ ): Promise<DeclareContractResponse>;
180
+
181
+ /**
182
+ * Estimates the fee for a given INVOKE transaction
183
+ * @deprecated Please use getInvokeEstimateFee or getDeclareEstimateFee instead
160
184
  *
161
185
  * @param invocation the invocation object containing:
162
186
  * - contractAddress - the address of the contract
@@ -175,6 +199,67 @@ export abstract class ProviderInterface {
175
199
  blockIdentifier: BlockIdentifier
176
200
  ): Promise<EstimateFeeResponse>;
177
201
 
202
+ /**
203
+ * Estimates the fee for a given INVOKE transaction
204
+ *
205
+ * @param invocation the invocation object containing:
206
+ * - contractAddress - the address of the contract
207
+ * - entrypoint - the entrypoint of the contract
208
+ * - calldata - (defaults to []) the calldata
209
+ * - signature - (defaults to []) the signature
210
+ * @param blockIdentifier - block identifier
211
+ * @param details - optional details containing:
212
+ * - nonce - optional nonce
213
+ * - version - optional version
214
+ * @returns the estimated fee
215
+ */
216
+ public abstract getInvokeEstimateFee(
217
+ invocation: Invocation,
218
+ details: InvocationsDetailsWithNonce,
219
+ blockIdentifier: BlockIdentifier
220
+ ): Promise<EstimateFeeResponse>;
221
+
222
+ /**
223
+ * Estimates the fee for a given DECLARE transaction
224
+ *
225
+ * @param transaction transaction payload to be declared containing:
226
+ * - compiled contract code
227
+ * - sender address
228
+ * - signature - (defaults to []) the signature
229
+ * @param details - optional details containing:
230
+ * - nonce
231
+ * - version - optional version
232
+ * - optional maxFee
233
+ * @param blockIdentifier - block identifier
234
+ * @returns the estimated fee
235
+ */
236
+ public abstract getDeclareEstimateFee(
237
+ transaction: DeclareContractTransaction,
238
+ details: InvocationsDetailsWithNonce,
239
+ blockIdentifier: BlockIdentifier
240
+ ): Promise<EstimateFeeResponse>;
241
+
242
+ /**
243
+ * Estimates the fee for a given DEPLOY_ACCOUNT transaction
244
+ *
245
+ * @param transaction transaction payload to be deployed containing:
246
+ * - classHash
247
+ * - constructorCalldata
248
+ * - addressSalt
249
+ * - signature - (defaults to []) the signature
250
+ * @param details - optional details containing:
251
+ * - nonce
252
+ * - version - optional version
253
+ * - optional maxFee
254
+ * @param blockIdentifier - block identifier
255
+ * @returns the estimated fee
256
+ */
257
+ public abstract getDeployAccountEstimateFee(
258
+ transaction: DeployAccountContractTransaction,
259
+ details: InvocationsDetailsWithNonce,
260
+ blockIdentifier: BlockIdentifier
261
+ ): Promise<EstimateFeeResponse>;
262
+
178
263
  /**
179
264
  * Wait for the transaction to be accepted
180
265
  * @param txHash - transaction hash
@@ -2,7 +2,6 @@ import { StarknetChainId } from '../constants';
2
2
  import {
3
3
  Call,
4
4
  CallContractResponse,
5
- DeclareContractPayload,
6
5
  DeclareContractResponse,
7
6
  DeployContractPayload,
8
7
  DeployContractResponse,
@@ -16,6 +15,11 @@ import {
16
15
  InvokeFunctionResponse,
17
16
  } from '../types';
18
17
  import { RPC } from '../types/api';
18
+ import {
19
+ DeclareContractTransaction,
20
+ DeployAccountContractPayload,
21
+ DeployAccountContractTransaction,
22
+ } from '../types/lib';
19
23
  import fetch from '../utils/fetchPonyfill';
20
24
  import { getSelectorFromName } from '../utils/hash';
21
25
  import { stringify } from '../utils/json';
@@ -183,9 +187,7 @@ export class RpcProvider implements ProviderInterface {
183
187
  }
184
188
 
185
189
  public async getTransactionReceipt(txHash: string): Promise<GetTransactionReceiptResponse> {
186
- return this.fetchEndpoint('starknet_getTransactionReceipt', { transaction_hash: txHash }).then(
187
- this.responseParser.parseGetTransactionReceiptResponse
188
- );
190
+ return this.fetchEndpoint('starknet_getTransactionReceipt', { transaction_hash: txHash });
189
191
  }
190
192
 
191
193
  public async getClass(classHash: RPC.Felt): Promise<RPC.ContractClass> {
@@ -214,33 +216,93 @@ export class RpcProvider implements ProviderInterface {
214
216
  invocation: Invocation,
215
217
  invocationDetails: InvocationsDetailsWithNonce,
216
218
  blockIdentifier: BlockIdentifier = 'pending'
219
+ ): Promise<EstimateFeeResponse> {
220
+ return this.getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier);
221
+ }
222
+
223
+ public async getInvokeEstimateFee(
224
+ invocation: Invocation,
225
+ invocationDetails: InvocationsDetailsWithNonce,
226
+ blockIdentifier: BlockIdentifier = 'pending'
217
227
  ): Promise<EstimateFeeResponse> {
218
228
  const block_id = new Block(blockIdentifier).identifier;
219
229
  return this.fetchEndpoint('starknet_estimateFee', {
220
230
  request: {
231
+ type: 'INVOKE',
221
232
  contract_address: invocation.contractAddress,
222
233
  calldata: parseCalldata(invocation.calldata),
223
234
  signature: bigNumberishArrayToHexadecimalStringArray(invocation.signature || []),
224
235
  version: toHex(toBN(invocationDetails?.version || 0)),
236
+ nonce: toHex(toBN(invocationDetails.nonce)),
225
237
  max_fee: toHex(toBN(invocationDetails?.maxFee || 0)),
226
238
  },
227
239
  block_id,
228
240
  }).then(this.responseParser.parseFeeEstimateResponse);
229
241
  }
230
242
 
231
- public async declareContract({
232
- contract,
233
- version,
234
- }: DeclareContractPayload): Promise<DeclareContractResponse> {
235
- const contractDefinition = parseContract(contract);
243
+ // TODO: Revisit after Pathfinder release with JSON-RPC v0.2.1 RPC Spec
244
+
245
+ public async getDeclareEstimateFee(
246
+ { senderAddress, contractDefinition, signature }: DeclareContractTransaction,
247
+ details: InvocationsDetailsWithNonce,
248
+ blockIdentifier: BlockIdentifier = 'pending'
249
+ ): Promise<EstimateFeeResponse> {
250
+ const block_id = new Block(blockIdentifier).identifier;
251
+ return this.fetchEndpoint('starknet_estimateFee', {
252
+ request: {
253
+ type: 'DECLARE',
254
+ contract_class: {
255
+ program: contractDefinition.program,
256
+ entry_points_by_type: contractDefinition.entry_points_by_type,
257
+ abi: contractDefinition.abi, // rpc 2.0
258
+ },
259
+ sender_address: senderAddress,
260
+ signature: bigNumberishArrayToHexadecimalStringArray(signature || []),
261
+ version: toHex(toBN(details?.version || 0)),
262
+ nonce: toHex(toBN(details.nonce)),
263
+ max_fee: toHex(toBN(details?.maxFee || 0)),
264
+ },
265
+ block_id,
266
+ }).then(this.responseParser.parseFeeEstimateResponse);
267
+ }
236
268
 
269
+ public async getDeployAccountEstimateFee(
270
+ { classHash, constructorCalldata, addressSalt, signature }: DeployAccountContractTransaction,
271
+ details: InvocationsDetailsWithNonce,
272
+ blockIdentifier: BlockIdentifier = 'pending'
273
+ ): Promise<EstimateFeeResponse> {
274
+ const block_id = new Block(blockIdentifier).identifier;
275
+ return this.fetchEndpoint('starknet_estimateFee', {
276
+ request: {
277
+ type: 'DEPLOY_ACCOUNT',
278
+ constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata || []),
279
+ class_hash: toHex(toBN(classHash)),
280
+ contract_address_salt: toHex(toBN(addressSalt || 0)),
281
+ signature: bigNumberishArrayToHexadecimalStringArray(signature || []),
282
+ version: toHex(toBN(details?.version || 0)),
283
+ nonce: toHex(toBN(details.nonce)),
284
+ max_fee: toHex(toBN(details?.maxFee || 0)),
285
+ },
286
+ block_id,
287
+ }).then(this.responseParser.parseFeeEstimateResponse);
288
+ }
289
+
290
+ // TODO: Revisit after Pathfinder release with JSON-RPC v0.2.1 RPC Spec
291
+ public async declareContract(
292
+ { contractDefinition, signature, senderAddress }: DeclareContractTransaction,
293
+ details: InvocationsDetailsWithNonce
294
+ ): Promise<DeclareContractResponse> {
237
295
  return this.fetchEndpoint('starknet_addDeclareTransaction', {
238
296
  contract_class: {
239
297
  program: contractDefinition.program,
240
298
  entry_points_by_type: contractDefinition.entry_points_by_type,
241
299
  abi: contractDefinition.abi, // rpc 2.0
242
300
  },
243
- version: toHex(toBN(version || 0)),
301
+ version: toHex(toBN(details.version || 0)),
302
+ max_fee: toHex(toBN(details.maxFee || 0)),
303
+ signature: bigNumberishArrayToHexadecimalStringArray(signature || []),
304
+ sender_address: senderAddress,
305
+ nonce: toHex(toBN(details.nonce)),
244
306
  });
245
307
  }
246
308
 
@@ -262,6 +324,18 @@ export class RpcProvider implements ProviderInterface {
262
324
  });
263
325
  }
264
326
 
327
+ public async deployAccountContract({
328
+ classHash,
329
+ constructorCalldata,
330
+ addressSalt,
331
+ }: DeployAccountContractPayload): Promise<DeployContractResponse> {
332
+ return this.fetchEndpoint('starknet_addDeployAccountTransaction', {
333
+ constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata || []),
334
+ class_hash: toHex(toBN(classHash)),
335
+ contract_address_salt: toHex(toBN(addressSalt || 0)),
336
+ });
337
+ }
338
+
265
339
  public async invokeFunction(
266
340
  functionInvocation: Invocation,
267
341
  details: InvocationsDetailsWithNonce
@@ -317,9 +391,9 @@ export class RpcProvider implements ProviderInterface {
317
391
  // eslint-disable-next-line no-await-in-loop
318
392
  const res = await this.getTransactionReceipt(txHash);
319
393
 
320
- if (successStates.includes(res.status)) {
394
+ if (res.status && successStates.includes(res.status)) {
321
395
  onchain = true;
322
- } else if (errorStates.includes(res.status)) {
396
+ } else if (res.status && errorStates.includes(res.status)) {
323
397
  const message = res.status;
324
398
  const error = new Error(message) as Error & { response: any };
325
399
  error.response = res;
@@ -1,11 +1,10 @@
1
1
  import urljoin from 'url-join';
2
2
 
3
- import { ONE, StarknetChainId, ZERO } from '../constants';
3
+ import { StarknetChainId } from '../constants';
4
4
  import {
5
5
  Call,
6
6
  CallContractResponse,
7
7
  ContractClass,
8
- DeclareContractPayload,
9
8
  DeclareContractResponse,
10
9
  DeployContractPayload,
11
10
  DeployContractResponse,
@@ -18,15 +17,25 @@ import {
18
17
  InvokeFunctionResponse,
19
18
  } from '../types';
20
19
  import {
20
+ CallL1Handler,
21
21
  GetContractAddressesResponse,
22
22
  GetTransactionStatusResponse,
23
23
  GetTransactionTraceResponse,
24
24
  Sequencer,
25
25
  } from '../types/api';
26
+ import { DeclareContractTransaction, DeployAccountContractTransaction } from '../types/lib';
26
27
  import fetch from '../utils/fetchPonyfill';
27
- import { getSelectorFromName } from '../utils/hash';
28
+ import { getSelector, getSelectorFromName } from '../utils/hash';
28
29
  import { parse, parseAlwaysAsBig, stringify } from '../utils/json';
29
- import { BigNumberish, bigNumberishArrayToDecimalStringArray, toBN, toHex } from '../utils/number';
30
+ import {
31
+ BigNumberish,
32
+ bigNumberishArrayToDecimalStringArray,
33
+ getDecimalString,
34
+ getHexString,
35
+ getHexStringArray,
36
+ toBN,
37
+ toHex,
38
+ } from '../utils/number';
30
39
  import { parseContract, wait } from '../utils/provider';
31
40
  import { SequencerAPIResponseParser } from '../utils/responseParser/sequencer';
32
41
  import { randomAddress } from '../utils/stark';
@@ -117,7 +126,12 @@ export class SequencerProvider implements ProviderInterface {
117
126
  }
118
127
 
119
128
  private getFetchMethod(endpoint: keyof Sequencer.Endpoints) {
120
- const postMethodEndpoints = ['add_transaction', 'call_contract', 'estimate_fee'];
129
+ const postMethodEndpoints = [
130
+ 'add_transaction',
131
+ 'call_contract',
132
+ 'estimate_fee',
133
+ 'estimate_message_fee',
134
+ ];
121
135
 
122
136
  return postMethodEndpoints.includes(endpoint) ? 'POST' : 'GET';
123
137
  }
@@ -151,7 +165,7 @@ export class SequencerProvider implements ProviderInterface {
151
165
  // typesafe fetch
152
166
  protected async fetchEndpoint<T extends keyof Sequencer.Endpoints>(
153
167
  endpoint: T,
154
- // typescript type magiuc to create a nice fitting function interface
168
+ // typescript type magic to create a nice fitting function interface
155
169
  ...[query, request]: Sequencer.Endpoints[T]['QUERY'] extends never
156
170
  ? Sequencer.Endpoints[T]['REQUEST'] extends never
157
171
  ? [] // when no query and no request is needed, we can omit the query and request parameters
@@ -307,17 +321,34 @@ export class SequencerProvider implements ProviderInterface {
307
321
  }).then(this.responseParser.parseDeployContractResponse);
308
322
  }
309
323
 
310
- public async declareContract({
311
- contract,
312
- }: DeclareContractPayload): Promise<DeclareContractResponse> {
313
- const contractDefinition = parseContract(contract);
324
+ public async deployAccountContract(
325
+ { classHash, constructorCalldata, addressSalt, signature }: DeployAccountContractTransaction,
326
+ details: InvocationsDetailsWithNonce
327
+ ): Promise<DeployContractResponse> {
328
+ return this.fetchEndpoint('add_transaction', undefined, {
329
+ type: 'DEPLOY_ACCOUNT',
330
+ contract_address_salt: addressSalt ?? randomAddress(),
331
+ constructor_calldata: bigNumberishArrayToDecimalStringArray(constructorCalldata ?? []),
332
+ class_hash: toHex(toBN(classHash)),
333
+ max_fee: toHex(toBN(details.maxFee || 0)),
334
+ version: toHex(toBN(details.version || 0)),
335
+ nonce: toHex(toBN(details.nonce)),
336
+ signature: bigNumberishArrayToDecimalStringArray(signature || []),
337
+ }).then(this.responseParser.parseDeployContractResponse);
338
+ }
314
339
 
340
+ public async declareContract(
341
+ { senderAddress, contractDefinition, signature }: DeclareContractTransaction,
342
+ details: InvocationsDetailsWithNonce
343
+ ): Promise<DeclareContractResponse> {
315
344
  return this.fetchEndpoint('add_transaction', undefined, {
316
345
  type: 'DECLARE',
317
346
  contract_class: contractDefinition,
318
- nonce: toHex(ZERO),
319
- signature: [],
320
- sender_address: toHex(ONE),
347
+ nonce: toHex(toBN(details.nonce)),
348
+ signature: bigNumberishArrayToDecimalStringArray(signature || []),
349
+ sender_address: senderAddress,
350
+ max_fee: toHex(toBN(details.maxFee || 0)),
351
+ version: toHex(toBN(details.version || 1)),
321
352
  }).then(this.responseParser.parseDeclareContractResponse);
322
353
  }
323
354
 
@@ -325,6 +356,14 @@ export class SequencerProvider implements ProviderInterface {
325
356
  invocation: Invocation,
326
357
  invocationDetails: InvocationsDetailsWithNonce,
327
358
  blockIdentifier: BlockIdentifier = 'pending'
359
+ ): Promise<EstimateFeeResponse> {
360
+ return this.getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier);
361
+ }
362
+
363
+ public async getInvokeEstimateFee(
364
+ invocation: Invocation,
365
+ invocationDetails: InvocationsDetailsWithNonce,
366
+ blockIdentifier: BlockIdentifier = 'pending'
328
367
  ): Promise<EstimateFeeResponse> {
329
368
  return this.fetchEndpoint(
330
369
  'estimate_fee',
@@ -340,6 +379,45 @@ export class SequencerProvider implements ProviderInterface {
340
379
  ).then(this.responseParser.parseFeeEstimateResponse);
341
380
  }
342
381
 
382
+ public async getDeclareEstimateFee(
383
+ { senderAddress, contractDefinition, signature }: DeclareContractTransaction,
384
+ details: InvocationsDetailsWithNonce,
385
+ blockIdentifier: BlockIdentifier = 'pending'
386
+ ): Promise<EstimateFeeResponse> {
387
+ return this.fetchEndpoint(
388
+ 'estimate_fee',
389
+ { blockIdentifier },
390
+ {
391
+ type: 'DECLARE',
392
+ sender_address: senderAddress,
393
+ contract_class: contractDefinition,
394
+ signature: bigNumberishArrayToDecimalStringArray(signature || []),
395
+ version: toHex(toBN(details?.version || 1)),
396
+ nonce: toHex(toBN(details.nonce)),
397
+ }
398
+ ).then(this.responseParser.parseFeeEstimateResponse);
399
+ }
400
+
401
+ public async getDeployAccountEstimateFee(
402
+ { classHash, addressSalt, constructorCalldata, signature }: DeployAccountContractTransaction,
403
+ details: InvocationsDetailsWithNonce,
404
+ blockIdentifier: BlockIdentifier = 'pending'
405
+ ): Promise<EstimateFeeResponse> {
406
+ return this.fetchEndpoint(
407
+ 'estimate_fee',
408
+ { blockIdentifier },
409
+ {
410
+ type: 'DEPLOY_ACCOUNT',
411
+ class_hash: toHex(toBN(classHash)),
412
+ constructor_calldata: bigNumberishArrayToDecimalStringArray(constructorCalldata || []),
413
+ contract_address_salt: toHex(toBN(addressSalt || 0)),
414
+ signature: bigNumberishArrayToDecimalStringArray(signature || []),
415
+ version: toHex(toBN(details?.version || 0)),
416
+ nonce: toHex(toBN(details.nonce)),
417
+ }
418
+ ).then(this.responseParser.parseFeeEstimateResponse);
419
+ }
420
+
343
421
  public async getCode(
344
422
  contractAddress: string,
345
423
  blockIdentifier: BlockIdentifier = 'pending'
@@ -406,4 +484,18 @@ export class SequencerProvider implements ProviderInterface {
406
484
  const txHashHex = toHex(toBN(txHash));
407
485
  return this.fetchEndpoint('get_transaction_trace', { transactionHash: txHashHex });
408
486
  }
487
+
488
+ public async estimateMessageFee(
489
+ { from_address, to_address, entry_point_selector, payload }: CallL1Handler,
490
+ blockIdentifier: BlockIdentifier = 'pending'
491
+ ): Promise<Sequencer.EstimateFeeResponse> {
492
+ const validCallL1Handler = {
493
+ from_address: getDecimalString(from_address),
494
+ to_address: getHexString(to_address),
495
+ entry_point_selector: getSelector(entry_point_selector),
496
+ payload: getHexStringArray(payload),
497
+ };
498
+
499
+ return this.fetchEndpoint('estimate_message_fee', { blockIdentifier }, validCallL1Handler);
500
+ }
409
501
  }
@@ -1,6 +1,18 @@
1
- import { Abi, Call, InvocationsSignerDetails, KeyPair, Signature } from '../types';
1
+ import {
2
+ Abi,
3
+ Call,
4
+ DeclareSignerDetails,
5
+ InvocationsSignerDetails,
6
+ KeyPair,
7
+ Signature,
8
+ } from '../types';
9
+ import { DeployAccountSignerDetails } from '../types/signer';
2
10
  import { genKeyPair, getStarkKey, sign } from '../utils/ellipticCurve';
3
- import { calculateTransactionHash } from '../utils/hash';
11
+ import {
12
+ calculateDeclareTransactionHash,
13
+ calculateDeployAccountTransactionHash,
14
+ calculateTransactionHash,
15
+ } from '../utils/hash';
4
16
  import { fromCallsToExecuteCalldata } from '../utils/transaction';
5
17
  import { TypedData, getMessageHash } from '../utils/typedData';
6
18
  import { SignerInterface } from './interface';
@@ -40,6 +52,46 @@ export class Signer implements SignerInterface {
40
52
  return sign(this.keyPair, msgHash);
41
53
  }
42
54
 
55
+ public async signDeclareTransaction(
56
+ // contractClass: ContractClass, // Should be used once class hash is present in ContractClass
57
+ { classHash, senderAddress, chainId, maxFee, version, nonce }: DeclareSignerDetails
58
+ ) {
59
+ const msgHash = calculateDeclareTransactionHash(
60
+ classHash,
61
+ senderAddress,
62
+ version,
63
+ maxFee,
64
+ chainId,
65
+ nonce
66
+ );
67
+
68
+ return sign(this.keyPair, msgHash);
69
+ }
70
+
71
+ public async signDeployAccountTransaction({
72
+ classHash,
73
+ contractAddress,
74
+ constructorCalldata,
75
+ addressSalt,
76
+ maxFee,
77
+ version,
78
+ chainId,
79
+ nonce,
80
+ }: DeployAccountSignerDetails) {
81
+ const msgHash = calculateDeployAccountTransactionHash(
82
+ contractAddress,
83
+ classHash,
84
+ constructorCalldata,
85
+ addressSalt,
86
+ version,
87
+ maxFee,
88
+ chainId,
89
+ nonce
90
+ );
91
+
92
+ return sign(this.keyPair, msgHash);
93
+ }
94
+
43
95
  public async signMessage(typedData: TypedData, accountAddress: string): Promise<Signature> {
44
96
  const msgHash = getMessageHash(typedData, accountAddress);
45
97
  return sign(this.keyPair, msgHash);
@@ -1,4 +1,5 @@
1
- import { Abi, Call, InvocationsSignerDetails, Signature } from '../types';
1
+ import { Abi, Call, DeclareSignerDetails, InvocationsSignerDetails, Signature } from '../types';
2
+ import { DeployAccountSignerDetails } from '../types/signer';
2
3
  import { TypedData } from '../utils/typedData';
3
4
 
4
5
  export abstract class SignerInterface {
@@ -27,7 +28,6 @@ export abstract class SignerInterface {
27
28
  * - contractAddress - the address of the contract
28
29
  * - entrypoint - the entrypoint of the contract
29
30
  * - calldata - (defaults to []) the calldata
30
- * - signature - (defaults to []) the signature
31
31
  * @param abi (optional) the abi of the contract for better displaying
32
32
  *
33
33
  * @returns signature
@@ -37,4 +37,33 @@ export abstract class SignerInterface {
37
37
  transactionsDetail: InvocationsSignerDetails,
38
38
  abis?: Abi[]
39
39
  ): Promise<Signature>;
40
+
41
+ /**
42
+ * Signs a DEPLOY_ACCOUNT transaction with the starknet private key and returns the signature
43
+ * @param transaction
44
+ * - contractAddress - the computed address of the contract
45
+ * - constructorCalldata - calldata to be passed in deploy constructor
46
+ * - addressSalt - contract address salt
47
+ * - chainId - the chainId to declare contract on
48
+ * - maxFee - maxFee for the declare transaction
49
+ * - version - transaction version
50
+ * - nonce - Nonce of the declare transaction
51
+ * @returns signature
52
+ */
53
+ public abstract signDeployAccountTransaction(
54
+ transaction: DeployAccountSignerDetails
55
+ ): Promise<Signature>;
56
+
57
+ /**
58
+ * Signs a DECLARE transaction with the starknet private key and returns the signature
59
+ * @param transaction
60
+ * - classHash - computed class hash. Will be replaced by ContractClass in future once class hash is present in CompiledContract
61
+ * - senderAddress - the address of the sender
62
+ * - chainId - the chainId to declare contract on
63
+ * - maxFee - maxFee for the declare transaction
64
+ * - version - transaction version
65
+ * - nonce - Nonce of the declare transaction
66
+ * @returns signature
67
+ */
68
+ public abstract signDeclareTransaction(transaction: DeclareSignerDetails): Promise<Signature>;
40
69
  }
@@ -18,7 +18,7 @@ type BLOCK_HASH = FELT;
18
18
  type TXN_HASH = FELT;
19
19
  type PROTOCOL_VERSION = string;
20
20
  type TXN_STATUS = 'PENDING' | 'ACCEPTED_ON_L2' | 'ACCEPTED_ON_L1' | 'REJECTED';
21
- type TXN_TYPE = 'DECLARE' | 'DEPLOY' | 'INVOKE' | 'L1_HANDLER';
21
+ type TXN_TYPE = 'DECLARE' | 'DEPLOY' | 'DEPLOY_ACCOUNT' | 'INVOKE' | 'L1_HANDLER';
22
22
  type BLOCK_STATUS = 'PENDING' | 'ACCEPTED_ON_L2' | 'ACCEPTED_ON_L1' | 'REJECTED';
23
23
  enum BLOCK_TAG {
24
24
  'latest',
@@ -104,6 +104,15 @@ type DECLARE_TXN = COMMON_TXN_PROPERTIES & {
104
104
  class_hash: FELT;
105
105
  sender_address: ADDRESS;
106
106
  };
107
+ type DEPLOY_ACCOUNT_TXN_REQUEST = COMMON_TXN_PROPERTIES & {
108
+ class_hash: FELT;
109
+ contract_address_salt: FELT;
110
+ constructor_calldata: Array<FELT>;
111
+ };
112
+ type DECLARE_TXN_REQUEST = COMMON_TXN_PROPERTIES & {
113
+ contract_class: CONTRACT_CLASS;
114
+ sender_address: ADDRESS;
115
+ };
107
116
  type DEPLOY_TXN = {
108
117
  transaction_hash: TXN_HASH;
109
118
  class_hash: FELT;
@@ -328,7 +337,10 @@ export namespace OPENRPC {
328
337
  | Errors.INVALID_BLOCK_ID;
329
338
  };
330
339
  starknet_estimateFee: {
331
- params: { request: INVOKE_TXN; block_id: BLOCK_ID };
340
+ params: {
341
+ request: INVOKE_TXN | DECLARE_TXN_REQUEST | DEPLOY_ACCOUNT_TXN_REQUEST;
342
+ block_id: BLOCK_ID;
343
+ };
332
344
  result: FEE_ESTIMATE;
333
345
  errors:
334
346
  | Errors.CONTRACT_NOT_FOUND
@@ -384,7 +396,11 @@ export namespace OPENRPC {
384
396
  starknet_addDeclareTransaction: {
385
397
  params: {
386
398
  contract_class: CONTRACT_CLASS;
399
+ sender_address: ADDRESS;
400
+ signature: SIGNATURE;
401
+ max_fee: NUM_AS_HEX;
387
402
  version: NUM_AS_HEX;
403
+ nonce: FELT;
388
404
  };
389
405
  result: DeclaredTransaction;
390
406
  errors: Errors.INVALID_CONTRACT_CLASS;
@@ -399,6 +415,16 @@ export namespace OPENRPC {
399
415
  errors: Errors.INVALID_CONTRACT_CLASS;
400
416
  };
401
417
 
418
+ starknet_addDeployAccountTransaction: {
419
+ params: {
420
+ contract_address_salt: FELT;
421
+ constructor_calldata: Array<FELT>;
422
+ class_hash: FELT;
423
+ };
424
+ result: DeployedTransaction;
425
+ errors: Errors.INVALID_CONTRACT_CLASS;
426
+ };
427
+
402
428
  // Trace API
403
429
  starknet_traceTransaction: {
404
430
  params: { transaction_hash: TXN_HASH };