starknet 4.9.0 → 4.11.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 (81) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +1 -3
  3. package/__tests__/account.test.ts +5 -1
  4. package/__tests__/defaultProvider.test.ts +97 -210
  5. package/__tests__/fixtures.ts +2 -2
  6. package/__tests__/rpcProvider.test.ts +7 -4
  7. package/__tests__/udc.test.ts +41 -0
  8. package/account/default.d.ts +3 -1
  9. package/account/default.js +53 -3
  10. package/account/interface.d.ts +24 -7
  11. package/constants.d.ts +7 -1
  12. package/constants.js +7 -1
  13. package/contract/default.d.ts +11 -27
  14. package/contract/default.js +104 -120
  15. package/contract/interface.d.ts +5 -2
  16. package/dist/account/default.d.ts +3 -1
  17. package/dist/account/default.js +53 -3
  18. package/dist/account/interface.d.ts +24 -7
  19. package/dist/constants.d.ts +7 -1
  20. package/dist/constants.js +7 -1
  21. package/dist/contract/default.d.ts +11 -27
  22. package/dist/contract/default.js +104 -120
  23. package/dist/contract/interface.d.ts +5 -2
  24. package/dist/provider/default.d.ts +4 -2
  25. package/dist/provider/default.js +13 -2
  26. package/dist/provider/interface.d.ts +18 -3
  27. package/dist/provider/rpc.d.ts +15 -10
  28. package/dist/provider/rpc.js +71 -31
  29. package/dist/provider/sequencer.d.ts +6 -2
  30. package/dist/provider/sequencer.js +33 -5
  31. package/dist/signer/default.d.ts +2 -2
  32. package/dist/signer/default.js +15 -15
  33. package/dist/signer/interface.d.ts +2 -0
  34. package/dist/types/api/index.d.ts +0 -6
  35. package/dist/types/api/openrpc.d.ts +147 -98
  36. package/dist/types/api/openrpc.js +22 -4
  37. package/dist/types/index.d.ts +1 -1
  38. package/dist/types/lib.d.ts +22 -2
  39. package/dist/types/lib.js +6 -0
  40. package/dist/utils/number.d.ts +1 -0
  41. package/dist/utils/number.js +3 -1
  42. package/package.json +1 -1
  43. package/provider/default.d.ts +4 -2
  44. package/provider/default.js +13 -2
  45. package/provider/interface.d.ts +18 -3
  46. package/provider/rpc.d.ts +15 -10
  47. package/provider/rpc.js +71 -31
  48. package/provider/sequencer.d.ts +6 -2
  49. package/provider/sequencer.js +33 -5
  50. package/signer/default.d.ts +2 -2
  51. package/signer/default.js +15 -15
  52. package/signer/interface.d.ts +2 -0
  53. package/src/account/default.ts +51 -7
  54. package/src/account/interface.ts +34 -7
  55. package/src/constants.ts +7 -0
  56. package/src/contract/default.ts +123 -140
  57. package/src/contract/interface.ts +5 -2
  58. package/src/provider/default.ts +21 -3
  59. package/src/provider/interface.ts +26 -2
  60. package/src/provider/rpc.ts +73 -45
  61. package/src/provider/sequencer.ts +24 -4
  62. package/src/signer/default.ts +18 -18
  63. package/src/signer/interface.ts +2 -0
  64. package/src/types/api/index.ts +0 -4
  65. package/src/types/api/openrpc.ts +193 -105
  66. package/src/types/api/rpc.ts +0 -1
  67. package/src/types/index.ts +1 -1
  68. package/src/types/lib.ts +23 -2
  69. package/src/utils/number.ts +2 -0
  70. package/types/api/index.d.ts +0 -6
  71. package/types/api/openrpc.d.ts +147 -98
  72. package/types/api/openrpc.js +22 -4
  73. package/types/index.d.ts +1 -1
  74. package/types/lib.d.ts +22 -2
  75. package/types/lib.js +6 -0
  76. package/utils/number.d.ts +1 -0
  77. package/utils/number.js +3 -1
  78. package/www/docs/API/account.md +122 -22
  79. package/www/docs/API/contract.md +39 -3
  80. package/www/docs/API/provider.md +4 -0
  81. package/www/docs/API/signer.md +56 -2
@@ -8,7 +8,6 @@ import {
8
8
  EstimateFeeResponse,
9
9
  GetBlockResponse,
10
10
  GetCodeResponse,
11
- GetTransactionReceiptResponse,
12
11
  GetTransactionResponse,
13
12
  Invocation,
14
13
  InvocationsDetailsWithNonce,
@@ -17,8 +16,8 @@ import {
17
16
  import { RPC } from '../types/api';
18
17
  import {
19
18
  DeclareContractTransaction,
20
- DeployAccountContractPayload,
21
19
  DeployAccountContractTransaction,
20
+ InvocationsDetails,
22
21
  } from '../types/lib';
23
22
  import fetch from '../utils/fetchPonyfill';
24
23
  import { getSelectorFromName } from '../utils/hash';
@@ -38,6 +37,7 @@ import { Block, BlockIdentifier } from './utils';
38
37
  export type RpcProviderOptions = {
39
38
  nodeUrl: string;
40
39
  retries?: number;
40
+ headers?: object;
41
41
  };
42
42
 
43
43
  export class RpcProvider implements ProviderInterface {
@@ -46,14 +46,17 @@ export class RpcProvider implements ProviderInterface {
46
46
  // from interface
47
47
  public chainId!: StarknetChainId;
48
48
 
49
+ public headers: object;
50
+
49
51
  private responseParser = new RPCResponseParser();
50
52
 
51
53
  private retries: number;
52
54
 
53
55
  constructor(optionsOrProvider: RpcProviderOptions) {
54
- const { nodeUrl, retries } = optionsOrProvider;
56
+ const { nodeUrl, retries, headers } = optionsOrProvider;
55
57
  this.nodeUrl = nodeUrl;
56
58
  this.retries = retries || 200;
59
+ this.headers = { 'Content-Type': 'application/json', ...headers };
57
60
 
58
61
  this.getChainId().then((chainId) => {
59
62
  this.chainId = chainId;
@@ -61,10 +64,10 @@ export class RpcProvider implements ProviderInterface {
61
64
  }
62
65
 
63
66
  public fetch(method: any, params: any): Promise<any> {
64
- return fetch(this.nodeUrl, {
67
+ return fetch(`${this.nodeUrl}/rpc/v0.2`, {
65
68
  method: 'POST',
66
69
  body: stringify({ method, jsonrpc: '2.0', params, id: 0 }),
67
- headers: { 'Content-Type': 'application/json' },
70
+ headers: this.headers,
68
71
  });
69
72
  }
70
73
 
@@ -121,8 +124,8 @@ export class RpcProvider implements ProviderInterface {
121
124
  }
122
125
 
123
126
  public async getClassHashAt(
124
- blockIdentifier: BlockIdentifier,
125
- contractAddress: RPC.ContractAddress
127
+ contractAddress: RPC.ContractAddress,
128
+ blockIdentifier: BlockIdentifier = 'pending'
126
129
  ): Promise<RPC.Felt> {
127
130
  const block_id = new Block(blockIdentifier).identifier;
128
131
  return this.fetchEndpoint('starknet_getClassHashAt', {
@@ -150,7 +153,9 @@ export class RpcProvider implements ProviderInterface {
150
153
  throw new Error('Pathfinder does not implement this rpc 0.1.0 method');
151
154
  }
152
155
 
153
- public async getStateUpdate(blockIdentifier: BlockIdentifier): Promise<RPC.StateUpdate> {
156
+ public async getStateUpdate(
157
+ blockIdentifier: BlockIdentifier = 'pending'
158
+ ): Promise<RPC.StateUpdate> {
154
159
  const block_id = new Block(blockIdentifier).identifier;
155
160
  return this.fetchEndpoint('starknet_getStateUpdate', { block_id });
156
161
  }
@@ -186,17 +191,21 @@ export class RpcProvider implements ProviderInterface {
186
191
  return this.fetchEndpoint('starknet_getTransactionByBlockIdAndIndex', { block_id, index });
187
192
  }
188
193
 
189
- public async getTransactionReceipt(txHash: string): Promise<GetTransactionReceiptResponse> {
194
+ public async getTransactionReceipt(txHash: string): Promise<RPC.TransactionReceipt> {
190
195
  return this.fetchEndpoint('starknet_getTransactionReceipt', { transaction_hash: txHash });
191
196
  }
192
197
 
193
- public async getClass(classHash: RPC.Felt): Promise<RPC.ContractClass> {
194
- return this.fetchEndpoint('starknet_getClass', { class_hash: classHash });
198
+ public async getClass(
199
+ classHash: RPC.Felt,
200
+ blockIdentifier: BlockIdentifier = 'pending'
201
+ ): Promise<RPC.ContractClass> {
202
+ const block_id = new Block(blockIdentifier).identifier;
203
+ return this.fetchEndpoint('starknet_getClass', { class_hash: classHash, block_id });
195
204
  }
196
205
 
197
206
  public async getClassAt(
198
207
  contractAddress: string,
199
- blockIdentifier: BlockIdentifier
208
+ blockIdentifier: BlockIdentifier = 'pending'
200
209
  ): Promise<RPC.ContractClass> {
201
210
  const block_id = new Block(blockIdentifier).identifier;
202
211
  return this.fetchEndpoint('starknet_getClassAt', {
@@ -209,7 +218,7 @@ export class RpcProvider implements ProviderInterface {
209
218
  _contractAddress: string,
210
219
  _blockIdentifier?: BlockIdentifier
211
220
  ): Promise<GetCodeResponse> {
212
- throw new Error('RPC 0.1.0 does not implement getCode function');
221
+ throw new Error('RPC does not implement getCode function');
213
222
  }
214
223
 
215
224
  public async getEstimateFee(
@@ -293,46 +302,58 @@ export class RpcProvider implements ProviderInterface {
293
302
  details: InvocationsDetailsWithNonce
294
303
  ): Promise<DeclareContractResponse> {
295
304
  return this.fetchEndpoint('starknet_addDeclareTransaction', {
296
- contract_class: {
297
- program: contractDefinition.program,
298
- entry_points_by_type: contractDefinition.entry_points_by_type,
299
- abi: contractDefinition.abi, // rpc 2.0
305
+ declare_transaction: {
306
+ contract_class: {
307
+ program: contractDefinition.program,
308
+ entry_points_by_type: contractDefinition.entry_points_by_type,
309
+ abi: contractDefinition.abi, // rpc 2.0
310
+ },
311
+ type: 'DECLARE',
312
+ version: toHex(toBN(details.version || 0)),
313
+ max_fee: toHex(toBN(details.maxFee || 0)),
314
+ signature: bigNumberishArrayToHexadecimalStringArray(signature || []),
315
+ sender_address: senderAddress,
316
+ nonce: toHex(toBN(details.nonce)),
300
317
  },
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)),
306
318
  });
307
319
  }
308
320
 
309
- public async deployContract({
310
- contract,
311
- constructorCalldata,
312
- addressSalt,
313
- }: DeployContractPayload): Promise<DeployContractResponse> {
321
+ /**
322
+ * @deprecated This method wont be supported soon, use Account.deploy instead
323
+ */
324
+ public async deployContract(
325
+ { contract, constructorCalldata, addressSalt }: DeployContractPayload,
326
+ details?: InvocationsDetails
327
+ ): Promise<DeployContractResponse> {
314
328
  const contractDefinition = parseContract(contract);
315
-
316
329
  return this.fetchEndpoint('starknet_addDeployTransaction', {
317
- contract_address_salt: addressSalt ?? randomAddress(),
318
- constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata ?? []),
319
- contract_definition: {
320
- program: contractDefinition.program,
321
- entry_points_by_type: contractDefinition.entry_points_by_type,
322
- abi: contractDefinition.abi, // rpc 2.0
330
+ deploy_transaction: {
331
+ contract_address_salt: addressSalt ?? randomAddress(),
332
+ constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata ?? []),
333
+ contract_class: {
334
+ program: contractDefinition.program,
335
+ entry_points_by_type: contractDefinition.entry_points_by_type,
336
+ abi: contractDefinition.abi,
337
+ },
338
+ type: 'DEPLOY',
339
+ version: toHex(toBN(details?.version || 0)),
323
340
  },
324
341
  });
325
342
  }
326
343
 
327
- public async deployAccountContract({
328
- classHash,
329
- constructorCalldata,
330
- addressSalt,
331
- }: DeployAccountContractPayload): Promise<DeployContractResponse> {
344
+ public async deployAccountContract(
345
+ { classHash, constructorCalldata, addressSalt, signature }: DeployAccountContractTransaction,
346
+ details: InvocationsDetailsWithNonce
347
+ ): Promise<DeployContractResponse> {
332
348
  return this.fetchEndpoint('starknet_addDeployAccountTransaction', {
333
349
  constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata || []),
334
350
  class_hash: toHex(toBN(classHash)),
335
351
  contract_address_salt: toHex(toBN(addressSalt || 0)),
352
+ type: 'DEPLOY',
353
+ max_fee: toHex(toBN(details.maxFee || 0)),
354
+ version: toHex(toBN(details.version || 0)),
355
+ signature: bigNumberishArrayToHexadecimalStringArray(signature || []),
356
+ nonce: toHex(toBN(details.nonce)),
336
357
  });
337
358
  }
338
359
 
@@ -341,13 +362,15 @@ export class RpcProvider implements ProviderInterface {
341
362
  details: InvocationsDetailsWithNonce
342
363
  ): Promise<InvokeFunctionResponse> {
343
364
  return this.fetchEndpoint('starknet_addInvokeTransaction', {
344
- function_invocation: {
345
- contract_address: functionInvocation.contractAddress,
365
+ invoke_transaction: {
366
+ sender_address: functionInvocation.contractAddress,
346
367
  calldata: parseCalldata(functionInvocation.calldata),
368
+ type: 'INVOKE',
369
+ max_fee: toHex(toBN(details.maxFee || 0)),
370
+ version: toHex(toBN(details.version || 0)),
371
+ signature: bigNumberishArrayToHexadecimalStringArray(functionInvocation.signature || []),
372
+ nonce: toHex(toBN(details.nonce)),
347
373
  },
348
- signature: bigNumberishArrayToHexadecimalStringArray(functionInvocation.signature || []),
349
- max_fee: toHex(toBN(details.maxFee || 0)),
350
- version: toHex(toBN(details.version || 0)),
351
374
  });
352
375
  }
353
376
 
@@ -391,6 +414,11 @@ export class RpcProvider implements ProviderInterface {
391
414
  // eslint-disable-next-line no-await-in-loop
392
415
  const res = await this.getTransactionReceipt(txHash);
393
416
 
417
+ if (!('status' in res)) {
418
+ const error = new Error('pending transaction');
419
+ throw error;
420
+ }
421
+
394
422
  if (res.status && successStates.includes(res.status)) {
395
423
  onchain = true;
396
424
  } else if (res.status && errorStates.includes(res.status)) {
@@ -423,7 +451,7 @@ export class RpcProvider implements ProviderInterface {
423
451
  * @returns Number of transactions
424
452
  */
425
453
  public async getTransactionCount(
426
- blockIdentifier: BlockIdentifier
454
+ blockIdentifier: BlockIdentifier = 'pending'
427
455
  ): Promise<RPC.GetTransactionCountResponse> {
428
456
  const block_id = new Block(blockIdentifier).identifier;
429
457
  return this.fetchEndpoint('starknet_getBlockTransactionCount', { block_id });
@@ -44,7 +44,7 @@ import { GatewayError, HttpError } from './errors';
44
44
  import { ProviderInterface } from './interface';
45
45
  import { Block, BlockIdentifier } from './utils';
46
46
 
47
- type NetworkName = 'mainnet-alpha' | 'goerli-alpha';
47
+ type NetworkName = 'mainnet-alpha' | 'goerli-alpha' | 'goerli-alpha-2';
48
48
 
49
49
  function isEmptyQueryObject(obj?: Record<any, any>): obj is undefined {
50
50
  return (
@@ -62,6 +62,7 @@ export type SequencerProviderOptions =
62
62
  feederGatewayUrl?: string;
63
63
  gatewayUrl?: string;
64
64
  chainId?: StarknetChainId;
65
+ headers?: object;
65
66
  };
66
67
 
67
68
  export class SequencerProvider implements ProviderInterface {
@@ -73,9 +74,11 @@ export class SequencerProvider implements ProviderInterface {
73
74
 
74
75
  public chainId: StarknetChainId;
75
76
 
77
+ public headers: object | undefined;
78
+
76
79
  private responseParser = new SequencerAPIResponseParser();
77
80
 
78
- constructor(optionsOrProvider: SequencerProviderOptions = { network: 'goerli-alpha' }) {
81
+ constructor(optionsOrProvider: SequencerProviderOptions = { network: 'goerli-alpha-2' }) {
79
82
  if ('network' in optionsOrProvider) {
80
83
  this.baseUrl = SequencerProvider.getNetworkFromName(optionsOrProvider.network);
81
84
  this.chainId = SequencerProvider.getChainIdFromBaseUrl(this.baseUrl);
@@ -93,6 +96,8 @@ export class SequencerProvider implements ProviderInterface {
93
96
  this.chainId =
94
97
  optionsOrProvider.chainId ??
95
98
  SequencerProvider.getChainIdFromBaseUrl(optionsOrProvider.baseUrl);
99
+
100
+ this.headers = optionsOrProvider?.headers;
96
101
  }
97
102
  }
98
103
 
@@ -101,6 +106,9 @@ export class SequencerProvider implements ProviderInterface {
101
106
  case 'mainnet-alpha':
102
107
  return 'https://alpha-mainnet.starknet.io';
103
108
  case 'goerli-alpha':
109
+ return 'https://alpha4.starknet.io';
110
+ case 'goerli-alpha-2':
111
+ return 'https://alpha4-2.starknet.io';
104
112
  default:
105
113
  return 'https://alpha4.starknet.io';
106
114
  }
@@ -153,13 +161,14 @@ export class SequencerProvider implements ProviderInterface {
153
161
  return `?${queryString}`;
154
162
  }
155
163
 
156
- private getHeaders(method: 'POST' | 'GET'): Record<string, string> | undefined {
164
+ private getHeaders(method: 'POST' | 'GET'): object | undefined {
157
165
  if (method === 'POST') {
158
166
  return {
159
167
  'Content-Type': 'application/json',
168
+ ...this.headers,
160
169
  };
161
170
  }
162
- return undefined;
171
+ return this.headers;
163
172
  }
164
173
 
165
174
  // typesafe fetch
@@ -291,6 +300,17 @@ export class SequencerProvider implements ProviderInterface {
291
300
  );
292
301
  }
293
302
 
303
+ public async getClassHashAt(
304
+ contractAddress: string,
305
+ blockIdentifier: BlockIdentifier = 'pending'
306
+ ): Promise<string> {
307
+ return this.fetchEndpoint('get_class_hash_at', { blockIdentifier, contractAddress });
308
+ }
309
+
310
+ public async getClass(classHash: string): Promise<ContractClass> {
311
+ return this.fetchEndpoint('get_class_by_hash', { classHash }).then(parseContract);
312
+ }
313
+
294
314
  public async invokeFunction(
295
315
  functionInvocation: Invocation,
296
316
  details: InvocationsDetailsWithNonce
@@ -28,6 +28,11 @@ export class Signer implements SignerInterface {
28
28
  return getStarkKey(this.keyPair);
29
29
  }
30
30
 
31
+ public async signMessage(typedData: TypedData, accountAddress: string): Promise<Signature> {
32
+ const msgHash = getMessageHash(typedData, accountAddress);
33
+ return sign(this.keyPair, msgHash);
34
+ }
35
+
31
36
  public async signTransaction(
32
37
  transactions: Call[],
33
38
  transactionsDetail: InvocationsSignerDetails,
@@ -52,22 +57,6 @@ export class Signer implements SignerInterface {
52
57
  return sign(this.keyPair, msgHash);
53
58
  }
54
59
 
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
60
  public async signDeployAccountTransaction({
72
61
  classHash,
73
62
  contractAddress,
@@ -92,8 +81,19 @@ export class Signer implements SignerInterface {
92
81
  return sign(this.keyPair, msgHash);
93
82
  }
94
83
 
95
- public async signMessage(typedData: TypedData, accountAddress: string): Promise<Signature> {
96
- const msgHash = getMessageHash(typedData, accountAddress);
84
+ public async signDeclareTransaction(
85
+ // contractClass: ContractClass, // Should be used once class hash is present in ContractClass
86
+ { classHash, senderAddress, chainId, maxFee, version, nonce }: DeclareSignerDetails
87
+ ) {
88
+ const msgHash = calculateDeclareTransactionHash(
89
+ classHash,
90
+ senderAddress,
91
+ version,
92
+ maxFee,
93
+ chainId,
94
+ nonce
95
+ );
96
+
97
97
  return sign(this.keyPair, msgHash);
98
98
  }
99
99
  }
@@ -40,6 +40,7 @@ export abstract class SignerInterface {
40
40
 
41
41
  /**
42
42
  * Signs a DEPLOY_ACCOUNT transaction with the starknet private key and returns the signature
43
+ *
43
44
  * @param transaction
44
45
  * - contractAddress - the computed address of the contract
45
46
  * - constructorCalldata - calldata to be passed in deploy constructor
@@ -56,6 +57,7 @@ export abstract class SignerInterface {
56
57
 
57
58
  /**
58
59
  * Signs a DECLARE transaction with the starknet private key and returns the signature
60
+ *
59
61
  * @param transaction
60
62
  * - classHash - computed class hash. Will be replaced by ContractClass in future once class hash is present in CompiledContract
61
63
  * - senderAddress - the address of the sender
@@ -1,10 +1,6 @@
1
1
  import { BigNumberish } from '../../utils/number';
2
2
  import { Signature } from '../lib';
3
3
 
4
- export type RawArgs = {
5
- [inputName: string]: string | string[] | { type: 'struct'; [k: string]: BigNumberish };
6
- };
7
-
8
4
  export type Calldata = string[];
9
5
 
10
6
  export type Overrides = {