starknet 3.5.1 → 3.8.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 (84) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/__tests__/account.test.ts +38 -20
  3. package/__tests__/accountContract.test.ts +0 -31
  4. package/__tests__/constancts.ts +2 -0
  5. package/__tests__/contract.test.ts +14 -21
  6. package/__tests__/provider.test.ts +8 -0
  7. package/account/default.d.ts +14 -1
  8. package/account/default.js +78 -14
  9. package/account/interface.d.ts +14 -0
  10. package/contract/default.d.ts +13 -3
  11. package/contract/default.js +36 -25
  12. package/contract/interface.d.ts +21 -3
  13. package/dist/account/default.d.ts +8 -2
  14. package/dist/account/default.js +57 -11
  15. package/dist/account/interface.d.ts +13 -1
  16. package/dist/contract/default.d.ts +7 -4
  17. package/dist/contract/default.js +27 -24
  18. package/dist/contract/interface.d.ts +9 -4
  19. package/dist/provider/default.d.ts +11 -4
  20. package/dist/provider/default.js +34 -30
  21. package/dist/provider/utils.d.ts +1 -2
  22. package/dist/provider/utils.js +7 -8
  23. package/dist/signer/index.d.ts +1 -0
  24. package/dist/signer/index.js +1 -0
  25. package/dist/signer/ledger.d.ts +12 -0
  26. package/dist/signer/ledger.js +138 -0
  27. package/dist/types/api.d.ts +60 -3
  28. package/package.json +5 -2
  29. package/provider/default.d.ts +13 -3
  30. package/provider/default.js +49 -42
  31. package/provider/utils.d.ts +1 -2
  32. package/provider/utils.js +7 -8
  33. package/signer/index.d.ts +1 -0
  34. package/signer/index.js +1 -0
  35. package/signer/ledger.d.ts +15 -0
  36. package/signer/ledger.js +243 -0
  37. package/src/account/default.ts +40 -6
  38. package/src/account/interface.ts +15 -0
  39. package/src/contract/default.ts +37 -34
  40. package/src/contract/interface.ts +21 -3
  41. package/src/provider/default.ts +31 -23
  42. package/src/provider/utils.ts +7 -8
  43. package/src/signer/index.ts +1 -0
  44. package/src/signer/ledger.ts +81 -0
  45. package/src/types/api.ts +65 -4
  46. package/tsconfig.json +1 -10
  47. package/types/api.d.ts +60 -3
  48. package/www/README.md +41 -0
  49. package/www/babel.config.js +3 -0
  50. package/www/code-examples/account.js +62 -0
  51. package/www/code-examples/amm.js +49 -0
  52. package/www/code-examples/erc20.js +10 -0
  53. package/www/code-examples/package-lock.json +336 -0
  54. package/www/code-examples/package.json +15 -0
  55. package/www/docs/API/_category_.json +5 -0
  56. package/www/docs/API/account.md +11 -0
  57. package/www/docs/API/contract.md +14 -0
  58. package/www/docs/API/index.md +4 -0
  59. package/www/docs/API/provider.md +10 -0
  60. package/www/docs/API/signer.md +8 -0
  61. package/www/docusaurus.config.js +131 -0
  62. package/www/guides/account.md +60 -0
  63. package/www/guides/cra.md +3 -0
  64. package/www/guides/erc20.md +88 -0
  65. package/www/guides/intro.md +20 -0
  66. package/www/package-lock.json +22285 -0
  67. package/www/package.json +43 -0
  68. package/www/sidebars.js +31 -0
  69. package/www/src/components/HomepageFeatures/index.tsx +67 -0
  70. package/www/src/components/HomepageFeatures/styles.module.css +10 -0
  71. package/www/src/css/custom.css +39 -0
  72. package/www/src/pages/index.module.css +23 -0
  73. package/www/src/pages/index.tsx +40 -0
  74. package/www/src/pages/markdown-page.md +7 -0
  75. package/www/static/.nojekyll +0 -0
  76. package/www/static/img/docusaurus.png +0 -0
  77. package/www/static/img/favicon.ico +0 -0
  78. package/www/static/img/logo.svg +17 -0
  79. package/www/static/img/starknet-1.png +0 -0
  80. package/www/static/img/starknet-2.png +0 -0
  81. package/www/static/img/starknet-3.png +0 -0
  82. package/www/static/img/tutorial/docsVersionDropdown.png +0 -0
  83. package/www/static/img/tutorial/localeDropdown.png +0 -0
  84. package/www/tsconfig.json +8 -0
@@ -0,0 +1,243 @@
1
+ 'use strict';
2
+ var __awaiter =
3
+ (this && this.__awaiter) ||
4
+ function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) {
6
+ return value instanceof P
7
+ ? value
8
+ : new P(function (resolve) {
9
+ resolve(value);
10
+ });
11
+ }
12
+ return new (P || (P = Promise))(function (resolve, reject) {
13
+ function fulfilled(value) {
14
+ try {
15
+ step(generator.next(value));
16
+ } catch (e) {
17
+ reject(e);
18
+ }
19
+ }
20
+ function rejected(value) {
21
+ try {
22
+ step(generator['throw'](value));
23
+ } catch (e) {
24
+ reject(e);
25
+ }
26
+ }
27
+ function step(result) {
28
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
29
+ }
30
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
31
+ });
32
+ };
33
+ var __generator =
34
+ (this && this.__generator) ||
35
+ function (thisArg, body) {
36
+ var _ = {
37
+ label: 0,
38
+ sent: function () {
39
+ if (t[0] & 1) throw t[1];
40
+ return t[1];
41
+ },
42
+ trys: [],
43
+ ops: [],
44
+ },
45
+ f,
46
+ y,
47
+ t,
48
+ g;
49
+ return (
50
+ (g = { next: verb(0), throw: verb(1), return: verb(2) }),
51
+ typeof Symbol === 'function' &&
52
+ (g[Symbol.iterator] = function () {
53
+ return this;
54
+ }),
55
+ g
56
+ );
57
+ function verb(n) {
58
+ return function (v) {
59
+ return step([n, v]);
60
+ };
61
+ }
62
+ function step(op) {
63
+ if (f) throw new TypeError('Generator is already executing.');
64
+ while (_)
65
+ try {
66
+ if (
67
+ ((f = 1),
68
+ y &&
69
+ (t =
70
+ op[0] & 2
71
+ ? y['return']
72
+ : op[0]
73
+ ? y['throw'] || ((t = y['return']) && t.call(y), 0)
74
+ : y.next) &&
75
+ !(t = t.call(y, op[1])).done)
76
+ )
77
+ return t;
78
+ if (((y = 0), t)) op = [op[0] & 2, t.value];
79
+ switch (op[0]) {
80
+ case 0:
81
+ case 1:
82
+ t = op;
83
+ break;
84
+ case 4:
85
+ _.label++;
86
+ return { value: op[1], done: false };
87
+ case 5:
88
+ _.label++;
89
+ y = op[1];
90
+ op = [0];
91
+ continue;
92
+ case 7:
93
+ op = _.ops.pop();
94
+ _.trys.pop();
95
+ continue;
96
+ default:
97
+ if (
98
+ !((t = _.trys), (t = t.length > 0 && t[t.length - 1])) &&
99
+ (op[0] === 6 || op[0] === 2)
100
+ ) {
101
+ _ = 0;
102
+ continue;
103
+ }
104
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
105
+ _.label = op[1];
106
+ break;
107
+ }
108
+ if (op[0] === 6 && _.label < t[1]) {
109
+ _.label = t[1];
110
+ t = op;
111
+ break;
112
+ }
113
+ if (t && _.label < t[2]) {
114
+ _.label = t[2];
115
+ _.ops.push(op);
116
+ break;
117
+ }
118
+ if (t[2]) _.ops.pop();
119
+ _.trys.pop();
120
+ continue;
121
+ }
122
+ op = body.call(thisArg, _);
123
+ } catch (e) {
124
+ op = [6, e];
125
+ y = 0;
126
+ } finally {
127
+ f = t = 0;
128
+ }
129
+ if (op[0] & 5) throw op[1];
130
+ return { value: op[0] ? op[1] : void 0, done: true };
131
+ }
132
+ };
133
+ var __importDefault =
134
+ (this && this.__importDefault) ||
135
+ function (mod) {
136
+ return mod && mod.__esModule ? mod : { default: mod };
137
+ };
138
+ Object.defineProperty(exports, '__esModule', { value: true });
139
+ exports.LedgerBlindSigner = void 0;
140
+ var hw_app_eth_1 = __importDefault(require('@ledgerhq/hw-app-eth'));
141
+ var hw_transport_webhid_1 = __importDefault(require('@ledgerhq/hw-transport-webhid'));
142
+ var encode_1 = require('../utils/encode');
143
+ var hash_1 = require('../utils/hash');
144
+ var typedData_1 = require('../utils/typedData');
145
+ function hexZeroPad(hash, length) {
146
+ var value = hash;
147
+ if (value.length > 2 * length + 2) {
148
+ throw new Error('value out of range');
149
+ }
150
+ while (value.length < 2 * length + 2) {
151
+ value = '0x0' + value.substring(2);
152
+ }
153
+ return value;
154
+ }
155
+ var LedgerBlindSigner = /** @class */ (function () {
156
+ function LedgerBlindSigner() {
157
+ this.derivationPath = "/2645'/579218131'/1148870696'/0'/0'/0";
158
+ }
159
+ LedgerBlindSigner.prototype.getEthApp = function () {
160
+ return __awaiter(this, void 0, void 0, function () {
161
+ var _a, _b;
162
+ return __generator(this, function (_c) {
163
+ switch (_c.label) {
164
+ case 0:
165
+ if (!!this.transport) return [3 /*break*/, 4];
166
+ _c.label = 1;
167
+ case 1:
168
+ _c.trys.push([1, 3, , 4]);
169
+ _a = this;
170
+ return [4 /*yield*/, hw_transport_webhid_1.default.create()];
171
+ case 2:
172
+ _a.transport = _c.sent();
173
+ return [3 /*break*/, 4];
174
+ case 3:
175
+ _b = _c.sent();
176
+ throw new Error('Device connection error');
177
+ case 4:
178
+ return [2 /*return*/, new hw_app_eth_1.default(this.transport)];
179
+ }
180
+ });
181
+ });
182
+ };
183
+ LedgerBlindSigner.prototype.getPubKey = function () {
184
+ return __awaiter(this, void 0, void 0, function () {
185
+ var eth, response, starkPub;
186
+ return __generator(this, function (_a) {
187
+ switch (_a.label) {
188
+ case 0:
189
+ return [4 /*yield*/, this.getEthApp()];
190
+ case 1:
191
+ eth = _a.sent();
192
+ return [4 /*yield*/, eth.starkGetPublicKey(this.derivationPath)];
193
+ case 2:
194
+ response = _a.sent();
195
+ starkPub = '0x' + response.slice(1, 1 + 32).toString('hex');
196
+ return [2 /*return*/, starkPub];
197
+ }
198
+ });
199
+ });
200
+ };
201
+ LedgerBlindSigner.prototype.signTransaction = function (transactions, transactionsDetail) {
202
+ return __awaiter(this, void 0, void 0, function () {
203
+ var msgHash;
204
+ return __generator(this, function (_a) {
205
+ msgHash = (0, hash_1.hashMulticall)(
206
+ transactionsDetail.walletAddress,
207
+ transactions,
208
+ transactionsDetail.nonce.toString(),
209
+ transactionsDetail.maxFee.toString()
210
+ );
211
+ return [2 /*return*/, this.sign(msgHash)];
212
+ });
213
+ });
214
+ };
215
+ LedgerBlindSigner.prototype.signMessage = function (typedData, accountAddress) {
216
+ return __awaiter(this, void 0, void 0, function () {
217
+ var msgHash;
218
+ return __generator(this, function (_a) {
219
+ msgHash = (0, typedData_1.getMessageHash)(typedData, accountAddress);
220
+ return [2 /*return*/, this.sign(msgHash)];
221
+ });
222
+ });
223
+ };
224
+ LedgerBlindSigner.prototype.sign = function (msgHash) {
225
+ return __awaiter(this, void 0, void 0, function () {
226
+ var eth, _a, r, s;
227
+ return __generator(this, function (_b) {
228
+ switch (_b.label) {
229
+ case 0:
230
+ return [4 /*yield*/, this.getEthApp()];
231
+ case 1:
232
+ eth = _b.sent();
233
+ return [4 /*yield*/, eth.starkUnsafeSign(this.derivationPath, hexZeroPad(msgHash, 32))];
234
+ case 2:
235
+ (_a = _b.sent()), (r = _a.r), (s = _a.s);
236
+ return [2 /*return*/, [(0, encode_1.addHexPrefix)(r), (0, encode_1.addHexPrefix)(s)]];
237
+ }
238
+ });
239
+ });
240
+ };
241
+ return LedgerBlindSigner;
242
+ })();
243
+ exports.LedgerBlindSigner = LedgerBlindSigner;
@@ -1,11 +1,13 @@
1
1
  import assert from 'minimalistic-assert';
2
2
 
3
3
  import { Provider } from '../provider';
4
+ import { BlockIdentifier } from '../provider/utils';
4
5
  import { Signer, SignerInterface } from '../signer';
5
6
  import {
6
7
  Abi,
7
8
  AddTransactionResponse,
8
9
  Call,
10
+ EstimateFeeResponse,
9
11
  InvocationsDetails,
10
12
  InvokeFunctionTransaction,
11
13
  KeyPair,
@@ -30,9 +32,10 @@ export class Account extends Provider implements AccountInterface {
30
32
 
31
33
  private signer: SignerInterface;
32
34
 
33
- constructor(provider: Provider, address: string, keyPair: KeyPair) {
35
+ constructor(provider: Provider, address: string, keyPairOrSigner: KeyPair | SignerInterface) {
34
36
  super(provider);
35
- this.signer = new Signer(keyPair);
37
+ this.signer =
38
+ 'getPubKey' in keyPairOrSigner ? keyPairOrSigner : new Signer(keyPairOrSigner as KeyPair);
36
39
  this.address = address;
37
40
  }
38
41
 
@@ -44,6 +47,35 @@ export class Account extends Provider implements AccountInterface {
44
47
  return toHex(toBN(result[0]));
45
48
  }
46
49
 
50
+ public async estimateFee(
51
+ calls: Call | Call[],
52
+ {
53
+ nonce: providedNonce,
54
+ blockIdentifier = 'pending',
55
+ }: { nonce?: BigNumberish; blockIdentifier?: BlockIdentifier } = {}
56
+ ): Promise<EstimateFeeResponse> {
57
+ const transactions = Array.isArray(calls) ? calls : [calls];
58
+ const nonce = providedNonce ?? (await this.getNonce());
59
+ const signerDetails = {
60
+ walletAddress: this.address,
61
+ nonce: toBN(nonce),
62
+ maxFee: toBN('0'),
63
+ };
64
+ const signature = await this.signer.signTransaction(transactions, signerDetails);
65
+
66
+ const calldata = [...fromCallsToExecuteCalldata(transactions), signerDetails.nonce.toString()];
67
+ return this.fetchEndpoint(
68
+ 'estimate_fee',
69
+ { blockIdentifier },
70
+ {
71
+ contract_address: this.address,
72
+ entry_point_selector: getSelectorFromName('__execute__'),
73
+ calldata,
74
+ signature: bigNumberishArrayToDecimalStringArray(signature),
75
+ }
76
+ );
77
+ }
78
+
47
79
  /**
48
80
  * Invoke execute function in account contract
49
81
  *
@@ -58,23 +90,25 @@ export class Account extends Provider implements AccountInterface {
58
90
  transactionsDetail: InvocationsDetails = {}
59
91
  ): Promise<AddTransactionResponse> {
60
92
  const transactions = Array.isArray(calls) ? calls : [calls];
61
-
93
+ const nonce = toBN(transactionsDetail.nonce ?? (await this.getNonce()));
94
+ const maxFee =
95
+ transactionsDetail.maxFee ?? (await this.estimateFee(transactions, { nonce })).amount;
62
96
  const signerDetails = {
63
97
  walletAddress: this.address,
64
- nonce: toBN(transactionsDetail.nonce ?? (await this.getNonce())),
65
- maxFee: toBN(transactionsDetail.maxFee ?? '0'),
98
+ nonce,
99
+ maxFee,
66
100
  };
67
101
 
68
102
  const signature = await this.signer.signTransaction(transactions, signerDetails, abis);
69
103
 
70
104
  const calldata = [...fromCallsToExecuteCalldata(transactions), signerDetails.nonce.toString()];
71
-
72
105
  return this.fetchEndpoint('add_transaction', undefined, {
73
106
  type: 'INVOKE_FUNCTION',
74
107
  contract_address: this.address,
75
108
  entry_point_selector: getSelectorFromName('__execute__'),
76
109
  calldata,
77
110
  signature: bigNumberishArrayToDecimalStringArray(signature),
111
+ max_fee: toHex(toBN(maxFee)),
78
112
  });
79
113
  }
80
114
 
@@ -4,6 +4,8 @@ import {
4
4
  AddTransactionResponse,
5
5
  Call,
6
6
  DeployContractPayload,
7
+ EstimateFeeResponse,
8
+ Invocation,
7
9
  InvocationsDetails,
8
10
  Signature,
9
11
  } from '../types';
@@ -28,6 +30,19 @@ export abstract class AccountInterface extends ProviderInterface {
28
30
  abi?: Abi
29
31
  ): Promise<AddTransactionResponse>;
30
32
 
33
+ /**
34
+ * Estimate Fee for a method on starknet
35
+ *
36
+ * @param invocation the invocation object containing:
37
+ * - contractAddress - the address of the contract
38
+ * - entrypoint - the entrypoint of the contract
39
+ * - calldata - (defaults to []) the calldata
40
+ * - signature - (defaults to []) the signature
41
+ *
42
+ * @returns response from addTransaction
43
+ */
44
+ public abstract estimateFee(invocation: Invocation): Promise<EstimateFeeResponse>;
45
+
31
46
  /**
32
47
  * Invoke execute function in account contract
33
48
  *
@@ -3,6 +3,7 @@ import assert from 'minimalistic-assert';
3
3
 
4
4
  import { AccountInterface } from '../account';
5
5
  import { ProviderInterface, defaultProvider } from '../provider';
6
+ import { BlockIdentifier } from '../provider/utils';
6
7
  import {
7
8
  Abi,
8
9
  AbiEntry,
@@ -13,11 +14,11 @@ import {
13
14
  ContractFunction,
14
15
  FunctionAbi,
15
16
  Invocation,
17
+ Overrides,
16
18
  ParsedStruct,
17
19
  Result,
18
20
  StructAbi,
19
21
  } from '../types';
20
- import { getSelectorFromName } from '../utils/hash';
21
22
  import { BigNumberish, toBN, toFelt } from '../utils/number';
22
23
  import { ContractInterface } from './interface';
23
24
 
@@ -528,7 +529,11 @@ export class Contract implements ContractInterface {
528
529
  }, [] as Result);
529
530
  }
530
531
 
531
- public invoke(method: string, args: Array<any> = []): Promise<AddTransactionResponse> {
532
+ public invoke(
533
+ method: string,
534
+ args: Array<any> = [],
535
+ options: Overrides = {}
536
+ ): Promise<AddTransactionResponse> {
532
537
  // ensure contract is connected
533
538
  assert(this.address !== null, 'contract isnt connected to an address');
534
539
  // validate method and args
@@ -541,10 +546,7 @@ export class Contract implements ContractInterface {
541
546
  }
542
547
  return acc;
543
548
  }, 0);
544
- const signature = [];
545
- if (args.length === inputsLength + 1 && Array.isArray(args[args.length - 1])) {
546
- signature.push(...args.pop());
547
- }
549
+
548
550
  if (args.length !== inputsLength) {
549
551
  throw Error(
550
552
  `Invalid number of arguments, expected ${inputsLength} arguments, but got ${args.length}`
@@ -559,28 +561,34 @@ export class Contract implements ContractInterface {
559
561
  entrypoint: method,
560
562
  };
561
563
  if ('execute' in this.providerOrAccount) {
562
- return this.providerOrAccount.execute(invocation);
564
+ return this.providerOrAccount.execute(invocation, undefined, {
565
+ maxFee: options.maxFee,
566
+ nonce: options.nonce,
567
+ });
563
568
  }
569
+
564
570
  return this.providerOrAccount.invokeFunction({
565
571
  ...invocation,
566
- signature,
572
+ signature: options.signature || [],
567
573
  });
568
574
  }
569
575
 
570
- public async call(method: string, args: Array<any> = []): Promise<Result> {
576
+ public async call(
577
+ method: string,
578
+ args: Array<any> = [],
579
+ {
580
+ blockIdentifier = 'pending',
581
+ }: {
582
+ blockIdentifier?: BlockIdentifier;
583
+ } = {}
584
+ ): Promise<Result> {
571
585
  // ensure contract is connected
572
586
  assert(this.address !== null, 'contract isnt connected to an address');
573
587
 
574
588
  // validate method and args
575
589
  this.validateMethodAndArgs('CALL', method, args);
576
590
  const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
577
- const inputsLength = inputs.length;
578
- const options = {
579
- blockIdentifier: null,
580
- };
581
- if (args.length === inputsLength + 1 && typeof args[args.length - 1] === 'object') {
582
- Object.assign(options, args.pop());
583
- }
591
+
584
592
  // compile calldata
585
593
  const calldata = this.compileCalldata(args, inputs);
586
594
  return this.providerOrAccount
@@ -590,35 +598,30 @@ export class Contract implements ContractInterface {
590
598
  calldata,
591
599
  entrypoint: method,
592
600
  },
593
- options
601
+ { blockIdentifier }
594
602
  )
595
603
  .then((x) => this.parseResponse(method, x.result));
596
604
  }
597
605
 
598
- public async estimate(_method: string, _args: Array<any> = []) {
606
+ public async estimate(method: string, args: Array<any> = []) {
599
607
  // TODO; remove error as soon as estimate fees are supported
600
- throw Error('Estimation of the fees are not yet supported');
601
- // // ensure contract is connected
602
- // assert(this.address !== null, 'contract isnt connected to an address');
603
-
604
- // // validate method and args
605
- // // this.validateMethodAndArgs('CALL', method, args);
606
- // const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
607
-
608
- // // compile calldata
609
- // const calldata = this.compileCalldata(args, inputs);
610
- // return this.providerOrAccount.estimateFee({
611
- // contractAddress: this.address as string,
612
- // calldata,
613
- // entrypoint: method,
614
- // });
608
+ // ensure contract is connected
609
+ assert(this.address !== null, 'contract isnt connected to an address');
610
+
611
+ // validate method and args
612
+ this.validateMethodAndArgs('INVOKE', method, args);
613
+ const invocation = this.populateTransaction[method](...args);
614
+ if ('estimateFee' in this.providerOrAccount) {
615
+ return this.providerOrAccount.estimateFee(invocation);
616
+ }
617
+ throw Error('Contract must be connected to the account contract to estimate');
615
618
  }
616
619
 
617
620
  public populate(method: string, args: Array<any> = []): Invocation {
618
621
  const { inputs } = this.abi.find((abi) => abi.name === method) as FunctionAbi;
619
622
  return {
620
623
  contractAddress: this.address,
621
- entrypoint: getSelectorFromName(method),
624
+ entrypoint: method,
622
625
  calldata: this.compileCalldata(args, inputs),
623
626
  signature: [],
624
627
  };
@@ -1,11 +1,13 @@
1
1
  import { AccountInterface } from '../account';
2
2
  import { ProviderInterface } from '../provider';
3
+ import { BlockIdentifier } from '../provider/utils';
3
4
  import {
4
5
  Abi,
5
6
  AddTransactionResponse,
6
7
  AsyncContractFunction,
7
8
  ContractFunction,
8
9
  Invocation,
10
+ Overrides,
9
11
  Result,
10
12
  } from '../types';
11
13
 
@@ -57,7 +59,13 @@ export abstract class ContractInterface {
57
59
  * @param args Array of the arguments for the call
58
60
  * @returns Result of the call as an array with key value pars
59
61
  */
60
- public abstract call(method: string, args?: Array<any>): Promise<Result>;
62
+ public abstract call(
63
+ method: string,
64
+ args?: Array<any>,
65
+ options?: {
66
+ blockIdentifier?: BlockIdentifier;
67
+ }
68
+ ): Promise<Result>;
61
69
 
62
70
  /**
63
71
  * Invokes a method on a contract
@@ -66,7 +74,11 @@ export abstract class ContractInterface {
66
74
  * @param args Array of the arguments for the invoke
67
75
  * @returns Add Transaction Response
68
76
  */
69
- public abstract invoke(method: string, args?: Array<any>): Promise<AddTransactionResponse>;
77
+ public abstract invoke(
78
+ method: string,
79
+ args?: Array<any>,
80
+ options?: Overrides
81
+ ): Promise<AddTransactionResponse>;
70
82
 
71
83
  /**
72
84
  * Calls a method on a contract
@@ -74,7 +86,13 @@ export abstract class ContractInterface {
74
86
  * @param method name of the method
75
87
  * @param args Array of the arguments for the call
76
88
  */
77
- public abstract estimate(method: string, args?: Array<any>): Promise<any>;
89
+ public abstract estimate(
90
+ method: string,
91
+ args?: Array<any>,
92
+ options?: {
93
+ blockIdentifier?: BlockIdentifier;
94
+ }
95
+ ): Promise<any>;
78
96
 
79
97
  /**
80
98
  * Calls a method on a contract
@@ -14,6 +14,7 @@ import {
14
14
  GetContractAddressesResponse,
15
15
  GetTransactionResponse,
16
16
  GetTransactionStatusResponse,
17
+ GetTransactionTraceResponse,
17
18
  Invocation,
18
19
  TransactionReceipt,
19
20
  } from '../types';
@@ -167,14 +168,18 @@ export class Provider implements ProviderInterface {
167
168
  */
168
169
  public async callContract(
169
170
  { contractAddress, entrypoint, calldata = [] }: Call,
170
- options: { blockIdentifier: BlockIdentifier } = { blockIdentifier: null }
171
+ { blockIdentifier = 'pending' }: { blockIdentifier?: BlockIdentifier } = {}
171
172
  ): Promise<CallContractResponse> {
172
- return this.fetchEndpoint('call_contract', options, {
173
- signature: [],
174
- contract_address: contractAddress,
175
- entry_point_selector: getSelectorFromName(entrypoint),
176
- calldata,
177
- });
173
+ return this.fetchEndpoint(
174
+ 'call_contract',
175
+ { blockIdentifier },
176
+ {
177
+ signature: [],
178
+ contract_address: contractAddress,
179
+ entry_point_selector: getSelectorFromName(entrypoint),
180
+ calldata,
181
+ }
182
+ );
178
183
  }
179
184
 
180
185
  /**
@@ -202,7 +207,7 @@ export class Provider implements ProviderInterface {
202
207
  */
203
208
  public async getCode(
204
209
  contractAddress: string,
205
- blockIdentifier: BlockIdentifier = null
210
+ blockIdentifier: BlockIdentifier = 'pending'
206
211
  ): Promise<GetCodeResponse> {
207
212
  return this.fetchEndpoint('get_code', { blockIdentifier, contractAddress });
208
213
  }
@@ -222,7 +227,7 @@ export class Provider implements ProviderInterface {
222
227
  public async getStorageAt(
223
228
  contractAddress: string,
224
229
  key: number,
225
- blockIdentifier: BlockIdentifier = null
230
+ blockIdentifier: BlockIdentifier = 'pending'
226
231
  ): Promise<object> {
227
232
  return this.fetchEndpoint('get_storage_at', { blockIdentifier, contractAddress, key });
228
233
  }
@@ -277,6 +282,18 @@ export class Provider implements ProviderInterface {
277
282
  return this.fetchEndpoint('get_transaction', { transactionHash: txHashHex });
278
283
  }
279
284
 
285
+ /**
286
+ * Gets the transaction trace from a tx id.
287
+ *
288
+ *
289
+ * @param txHash
290
+ * @returns the transaction trace
291
+ */
292
+ public async getTransactionTrace(txHash: BigNumberish): Promise<GetTransactionTraceResponse> {
293
+ const txHashHex = toHex(toBN(txHash));
294
+ return this.fetchEndpoint('get_transaction_trace', { transactionHash: txHashHex });
295
+ }
296
+
280
297
  /**
281
298
  * Deploys a given compiled contract (json) to starknet
282
299
  *
@@ -325,20 +342,8 @@ export class Provider implements ProviderInterface {
325
342
  });
326
343
  }
327
344
 
328
- public estimateFee(invocation: Invocation): Promise<any> {
329
- return this.fetchEndpoint('estimate_fee', undefined, {
330
- // TODO: change the TYPE of the call
331
- type: 'INVOKE_FUNCTION',
332
- contract_address: invocation.contractAddress,
333
- entry_point_selector: getSelectorFromName(invocation.entrypoint),
334
- calldata: bigNumberishArrayToDecimalStringArray(invocation.calldata ?? []),
335
- signature: bigNumberishArrayToDecimalStringArray(invocation.signature ?? []),
336
- });
337
- }
338
-
339
345
  public async waitForTransaction(txHash: BigNumberish, retryInterval: number = 8000) {
340
346
  let onchain = false;
341
- await wait(retryInterval);
342
347
 
343
348
  while (!onchain) {
344
349
  // eslint-disable-next-line no-await-in-loop
@@ -346,9 +351,12 @@ export class Provider implements ProviderInterface {
346
351
  // eslint-disable-next-line no-await-in-loop
347
352
  const res = await this.getTransactionStatus(txHash);
348
353
 
349
- if (res.tx_status === 'ACCEPTED_ON_L1' || res.tx_status === 'ACCEPTED_ON_L2') {
354
+ const successStates = ['ACCEPTED_ON_L1', 'ACCEPTED_ON_L2', 'PENDING'];
355
+ const errorStates = ['REJECTED', 'NOT_RECEIVED'];
356
+
357
+ if (successStates.includes(res.tx_status)) {
350
358
  onchain = true;
351
- } else if (res.tx_status === 'REJECTED' || res.tx_status === 'NOT_RECEIVED') {
359
+ } else if (errorStates.includes(res.tx_status)) {
352
360
  const message = res.tx_failure_reason
353
361
  ? `${res.tx_status}: ${res.tx_failure_reason.code}\n${res.tx_failure_reason.error_message}`
354
362
  : res.tx_status;