starknet 3.8.0 → 3.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [3.9.0](https://github.com/seanjameshan/starknet.js/compare/v3.8.0...v3.9.0) (2022-04-08)
2
+
3
+ ### Bug Fixes
4
+
5
+ - **account:** adding overhead on estimateFee for maxFee ([ec52f61](https://github.com/seanjameshan/starknet.js/commit/ec52f61aed9a8755491a4b7de73517b075785479))
6
+ - **contract:** override object when invoking a function ([c605151](https://github.com/seanjameshan/starknet.js/commit/c605151c03b544bf62ff9ab2e314e49de3cd562a))
7
+ - estimatedFeeToMaxFee with integers only ([71d19a7](https://github.com/seanjameshan/starknet.js/commit/71d19a7db01630ca0dba55011ff440243d7db992))
8
+ - rename txVersion to version ([2ae36b2](https://github.com/seanjameshan/starknet.js/commit/2ae36b2c075dbee4710abe47770af35478ceba4e))
9
+ - **utils:** remove check for the BN ([50a7951](https://github.com/seanjameshan/starknet.js/commit/50a79514343e303c397358efdba978fec5f93f48))
10
+
11
+ ### Features
12
+
13
+ - **account:** adding new transaction version for fee estimation ([2f7cb3f](https://github.com/seanjameshan/starknet.js/commit/2f7cb3fe85c973bcff3e39db333a9ed969c550b1))
14
+
1
15
  # [3.8.0](https://github.com/seanjameshan/starknet.js/compare/v3.7.0...v3.8.0) (2022-04-04)
2
16
 
3
17
  ### Bug Fixes
package/README.md CHANGED
@@ -40,62 +40,19 @@ Install starknet with `npm`
40
40
 
41
41
  ```bash
42
42
  $ npm install starknet
43
- # or
43
+ # or for pre-release features:
44
44
  $ npm install starknet@next
45
45
  ```
46
46
 
47
- Import `starknet` and use the [API](https://www.starknetjs.com/modules.html)
48
-
49
- The following code is used to build a [simple AMM example](https://starkfin.netlify.app/) from the [cairo docs](https://www.cairo-lang.org/docs/hello_starknet/amm.html)
50
-
51
- ```javascript
52
- import { defaultProvider, stark } from 'starknet';
53
- const { getSelectorFromName } = stark;
54
-
55
- const CONTRACT_ADDRESS =
56
- "0x03e19baa6cb2078631bcdb34844f3f7879449a544c9ce722681a54af08cff4b9";
57
-
58
- /**
59
- * invokeFunction() example
60
- **/
61
-
62
- /** Reset the liquidity pool **/
63
- const addTokenResponse = await defaultProvider.invokeFunction(
64
- {
65
- contractAddress: CONTRACT_ADDRESS,
66
- entrypoint: "init_pool",
67
- calldata: ["1000000", "1000000"],
68
- },
69
- abi // for displaying purposes only (default implementation has no display/ui)
70
- );
71
- console.log(addTokenResponse);
72
-
73
- /**
74
- * callContract() example
75
- **/
76
-
77
- /** Get the balance of the liquidity pool of token A **/
78
- const poolBalanceTokenA = await defaultProvider.callContract({
79
- contractAddress: CONTRACT_ADDRESS,
80
- entrypoint: "get_pool_token_balance",
81
- calldata: ["1"],
82
- });
83
- const balanceA = poolBalanceTokenA.result[0];
84
- console.log('token a liquidity pool balance: ', parseInt(balanceA, 16));
85
-
86
- /** Get the balance of the liquidity pool of token B **/
87
- const poolBalanceTokenB = await defaultProvider.callContract({
88
- contractAddress: CONTRACT_ADDRESS,
89
- entrypoint: "get_pool_token_balance",
90
- calldata: ["2"],
91
- });
92
- const balanceB = poolBalanceTokenB.result[0];
93
- console.log('token b liquidity pool balance: ', parseInt(balanceB, 16));
94
- ```
47
+ Import `starknet` and use the [API](https://www.starknetjs.com/docs/API/)
48
+
49
+ Please refer to the following code example [here](https://github.com/0xs34n/starknet.js-workshop/blob/main/index.js)
50
+
51
+ Guides can be found [here](https://www.starknetjs.com/guides/intro)
95
52
 
96
53
  ## 🌐 API
97
54
 
98
- [Click Here](https://www.starknetjs.com/modules.html)
55
+ [Click Here](https://www.starknetjs.com/docs/API/)
99
56
 
100
57
  ## 🚀 Powered by Starknet.js
101
58
 
@@ -105,11 +62,19 @@ console.log('token b liquidity pool balance: ', parseInt(balanceB, 16));
105
62
 
106
63
  ## ✏️ Contributing
107
64
 
108
- If you consider to contribute to this project please read [CONTRIBUTING.md](https://github.com/seanjameshan/starknet.js/blob/main/CONTRIBUTING.md) first.
65
+ If you consider to contribute to this project please read [CONTRIBUTING.md](https://github.com/0xs34n/starknet.js/blob/main/CONTRIBUTING.md) first.
109
66
 
110
67
  ## ❤️ Special Thanks
111
68
 
112
- Special thanks to all the [contributors](https://github.com/seanjameshan/starknet.js/graphs/contributors), especially to Janek ([@janek26](https://github.com/janek26)) from [Argent](https://github.com/argentlabs) for driving the development of Starknet.js.
69
+ Special thanks to all the [contributors](https://github.com/0xs34n/starknet.js/graphs/contributors), especially to:
70
+
71
+ Janek ([@janek26](https://github.com/janek26)) and Axel ([@delaaxe](https://github.com/delaaxe)) from [Argent](https://github.com/argentlabs)
72
+
73
+ Miljan ([@MilGard91](https://github.com/MilGard91)) from [Shard Labs](https://shardlabs.io/)
74
+
75
+ Dhruv ([@dhruvkelawala](https://github.com/dhruvkelawala)) from [Jedi Swap](https://twitter.com/jediswap)
76
+
77
+ and of course the [StarkWare](https://starkware.co/) team for their dedicated support!
113
78
 
114
79
  This library would not be possible without these rockstars.
115
80
 
@@ -117,4 +82,4 @@ This library would not be possible without these rockstars.
117
82
 
118
83
  Copyright (c) 2022 0xs34n
119
84
 
120
- Licensed under the [MIT license](https://github.com/seanjameshan/starknet.js/blob/main/LICENSE).
85
+ Licensed under the [MIT license](https://github.com/0xs34n/starknet.js/blob/main/LICENSE).
@@ -77,3 +77,13 @@ describe('computeHashOnElements()', () => {
77
77
  );
78
78
  });
79
79
  });
80
+ describe('estimatedFeeToMaxFee()', () => {
81
+ test('should return maxFee for 0', () => {
82
+ const res = stark.estimatedFeeToMaxFee(0, 0.15).toNumber();
83
+ expect(res).toBe(0);
84
+ });
85
+ test('should return maxFee for 10_000', () => {
86
+ const res = stark.estimatedFeeToMaxFee(10_000, 0.15).toNumber();
87
+ expect(res).toBe(11_500);
88
+ });
89
+ });
@@ -240,7 +240,7 @@ var Account = /** @class */ (function (_super) {
240
240
  _c = _b.blockIdentifier,
241
241
  blockIdentifier = _c === void 0 ? 'pending' : _c;
242
242
  return __awaiter(this, void 0, void 0, function () {
243
- var transactions, nonce, _d, signerDetails, signature, calldata;
243
+ var transactions, nonce, _d, version, signerDetails, signature, calldata;
244
244
  return __generator(this, function (_e) {
245
245
  switch (_e.label) {
246
246
  case 0:
@@ -255,10 +255,12 @@ var Account = /** @class */ (function (_super) {
255
255
  _e.label = 3;
256
256
  case 3:
257
257
  nonce = _d;
258
+ version = (0, number_1.toBN)(hash_1.feeTransactionVersion);
258
259
  signerDetails = {
259
260
  walletAddress: this.address,
260
261
  nonce: (0, number_1.toBN)(nonce),
261
262
  maxFee: (0, number_1.toBN)('0'),
263
+ version: version,
262
264
  };
263
265
  return [4 /*yield*/, this.signer.signTransaction(transactions, signerDetails)];
264
266
  case 4:
@@ -281,6 +283,7 @@ var Account = /** @class */ (function (_super) {
281
283
  contract_address: this.address,
282
284
  entry_point_selector: (0, hash_1.getSelectorFromName)('__execute__'),
283
285
  calldata: calldata,
286
+ version: (0, number_1.toHex)(version),
284
287
  signature: (0, number_1.bigNumberishArrayToDecimalStringArray)(signature),
285
288
  }
286
289
  ),
@@ -298,7 +301,7 @@ var Account = /** @class */ (function (_super) {
298
301
  * @returns a confirmation of invoking a function on the starknet contract
299
302
  */
300
303
  Account.prototype.execute = function (calls, abis, transactionsDetail) {
301
- var _a, _b;
304
+ var _a;
302
305
  if (abis === void 0) {
303
306
  abis = undefined;
304
307
  }
@@ -306,42 +309,43 @@ var Account = /** @class */ (function (_super) {
306
309
  transactionsDetail = {};
307
310
  }
308
311
  return __awaiter(this, void 0, void 0, function () {
309
- var transactions, nonce, _c, _d, maxFee, _e, signerDetails, signature, calldata;
310
- return __generator(this, function (_f) {
311
- switch (_f.label) {
312
+ var transactions, nonce, _b, _c, maxFee, estimatedFee, signerDetails, signature, calldata;
313
+ return __generator(this, function (_d) {
314
+ switch (_d.label) {
312
315
  case 0:
313
316
  transactions = Array.isArray(calls) ? calls : [calls];
314
- _c = number_1.toBN;
317
+ _b = number_1.toBN;
315
318
  if (!((_a = transactionsDetail.nonce) !== null && _a !== void 0))
316
319
  return [3 /*break*/, 1];
317
- _d = _a;
320
+ _c = _a;
318
321
  return [3 /*break*/, 3];
319
322
  case 1:
320
323
  return [4 /*yield*/, this.getNonce()];
321
324
  case 2:
322
- _d = _f.sent();
323
- _f.label = 3;
325
+ _c = _d.sent();
326
+ _d.label = 3;
324
327
  case 3:
325
- nonce = _c.apply(void 0, [_d]);
326
- if (!((_b = transactionsDetail.maxFee) !== null && _b !== void 0))
327
- return [3 /*break*/, 4];
328
- _e = _b;
328
+ nonce = _b.apply(void 0, [_c]);
329
+ maxFee = '0';
330
+ if (!transactionsDetail.maxFee) return [3 /*break*/, 4];
331
+ maxFee = transactionsDetail.maxFee;
329
332
  return [3 /*break*/, 6];
330
333
  case 4:
331
334
  return [4 /*yield*/, this.estimateFee(transactions, { nonce: nonce })];
332
335
  case 5:
333
- _e = _f.sent().amount;
334
- _f.label = 6;
336
+ estimatedFee = _d.sent().amount;
337
+ maxFee = (0, stark_1.estimatedFeeToMaxFee)(estimatedFee).toString();
338
+ _d.label = 6;
335
339
  case 6:
336
- maxFee = _e;
337
340
  signerDetails = {
338
341
  walletAddress: this.address,
339
342
  nonce: nonce,
340
343
  maxFee: maxFee,
344
+ version: (0, number_1.toBN)(hash_1.transactionVersion),
341
345
  };
342
346
  return [4 /*yield*/, this.signer.signTransaction(transactions, signerDetails, abis)];
343
347
  case 7:
344
- signature = _f.sent();
348
+ signature = _d.sent();
345
349
  calldata = __spreadArray(
346
350
  __spreadArray(
347
351
  [],
@@ -224,8 +224,20 @@ function buildInvoke(contract, functionAbi) {
224
224
  args[_i] = arguments[_i];
225
225
  }
226
226
  return __awaiter(this, void 0, void 0, function () {
227
+ var inputs, inputsLength, options;
227
228
  return __generator(this, function (_a) {
228
- return [2 /*return*/, contract.invoke(functionAbi.name, args)];
229
+ inputs = functionAbi.inputs;
230
+ inputsLength = inputs.reduce(function (acc, input) {
231
+ if (!/_len$/.test(input.name)) {
232
+ return acc + 1;
233
+ }
234
+ return acc;
235
+ }, 0);
236
+ options = {};
237
+ if (inputsLength + 1 === args.length && typeof args[args.length - 1] === 'object') {
238
+ Object.assign(options, args.pop());
239
+ }
240
+ return [2 /*return*/, contract.invoke(functionAbi.name, args, options)];
229
241
  });
230
242
  });
231
243
  };
@@ -117,7 +117,7 @@ var Account = /** @class */ (function (_super) {
117
117
  Account.prototype.estimateFee = function (calls, _a) {
118
118
  var _b = _a === void 0 ? {} : _a, providedNonce = _b.nonce, _c = _b.blockIdentifier, blockIdentifier = _c === void 0 ? 'pending' : _c;
119
119
  return __awaiter(this, void 0, void 0, function () {
120
- var transactions, nonce, _d, signerDetails, signature, calldata;
120
+ var transactions, nonce, _d, version, signerDetails, signature, calldata;
121
121
  return __generator(this, function (_e) {
122
122
  switch (_e.label) {
123
123
  case 0:
@@ -131,10 +131,12 @@ var Account = /** @class */ (function (_super) {
131
131
  _e.label = 3;
132
132
  case 3:
133
133
  nonce = _d;
134
+ version = (0, number_1.toBN)(hash_1.feeTransactionVersion);
134
135
  signerDetails = {
135
136
  walletAddress: this.address,
136
137
  nonce: (0, number_1.toBN)(nonce),
137
138
  maxFee: (0, number_1.toBN)('0'),
139
+ version: version,
138
140
  };
139
141
  return [4 /*yield*/, this.signer.signTransaction(transactions, signerDetails)];
140
142
  case 4:
@@ -144,6 +146,7 @@ var Account = /** @class */ (function (_super) {
144
146
  contract_address: this.address,
145
147
  entry_point_selector: (0, hash_1.getSelectorFromName)('__execute__'),
146
148
  calldata: calldata,
149
+ version: (0, number_1.toHex)(version),
147
150
  signature: (0, number_1.bigNumberishArrayToDecimalStringArray)(signature),
148
151
  })];
149
152
  }
@@ -159,42 +162,44 @@ var Account = /** @class */ (function (_super) {
159
162
  * @returns a confirmation of invoking a function on the starknet contract
160
163
  */
161
164
  Account.prototype.execute = function (calls, abis, transactionsDetail) {
162
- var _a, _b;
165
+ var _a;
163
166
  if (abis === void 0) { abis = undefined; }
164
167
  if (transactionsDetail === void 0) { transactionsDetail = {}; }
165
168
  return __awaiter(this, void 0, void 0, function () {
166
- var transactions, nonce, _c, _d, maxFee, _e, signerDetails, signature, calldata;
167
- return __generator(this, function (_f) {
168
- switch (_f.label) {
169
+ var transactions, nonce, _b, _c, maxFee, estimatedFee, signerDetails, signature, calldata;
170
+ return __generator(this, function (_d) {
171
+ switch (_d.label) {
169
172
  case 0:
170
173
  transactions = Array.isArray(calls) ? calls : [calls];
171
- _c = number_1.toBN;
174
+ _b = number_1.toBN;
172
175
  if (!((_a = transactionsDetail.nonce) !== null && _a !== void 0)) return [3 /*break*/, 1];
173
- _d = _a;
176
+ _c = _a;
174
177
  return [3 /*break*/, 3];
175
178
  case 1: return [4 /*yield*/, this.getNonce()];
176
179
  case 2:
177
- _d = (_f.sent());
178
- _f.label = 3;
180
+ _c = (_d.sent());
181
+ _d.label = 3;
179
182
  case 3:
180
- nonce = _c.apply(void 0, [_d]);
181
- if (!((_b = transactionsDetail.maxFee) !== null && _b !== void 0)) return [3 /*break*/, 4];
182
- _e = _b;
183
+ nonce = _b.apply(void 0, [_c]);
184
+ maxFee = '0';
185
+ if (!transactionsDetail.maxFee) return [3 /*break*/, 4];
186
+ maxFee = transactionsDetail.maxFee;
183
187
  return [3 /*break*/, 6];
184
188
  case 4: return [4 /*yield*/, this.estimateFee(transactions, { nonce: nonce })];
185
189
  case 5:
186
- _e = (_f.sent()).amount;
187
- _f.label = 6;
190
+ estimatedFee = (_d.sent()).amount;
191
+ maxFee = (0, stark_1.estimatedFeeToMaxFee)(estimatedFee).toString();
192
+ _d.label = 6;
188
193
  case 6:
189
- maxFee = _e;
190
194
  signerDetails = {
191
195
  walletAddress: this.address,
192
196
  nonce: nonce,
193
197
  maxFee: maxFee,
198
+ version: (0, number_1.toBN)(hash_1.transactionVersion),
194
199
  };
195
200
  return [4 /*yield*/, this.signer.signTransaction(transactions, signerDetails, abis)];
196
201
  case 7:
197
- signature = _f.sent();
202
+ signature = _d.sent();
198
203
  calldata = __spreadArray(__spreadArray([], __read((0, transaction_1.fromCallsToExecuteCalldata)(transactions)), false), [signerDetails.nonce.toString()], false);
199
204
  return [2 /*return*/, this.fetchEndpoint('add_transaction', undefined, {
200
205
  type: 'INVOKE_FUNCTION',
@@ -116,8 +116,20 @@ function buildInvoke(contract, functionAbi) {
116
116
  args[_i] = arguments[_i];
117
117
  }
118
118
  return __awaiter(this, void 0, void 0, function () {
119
+ var inputs, inputsLength, options;
119
120
  return __generator(this, function (_a) {
120
- return [2 /*return*/, contract.invoke(functionAbi.name, args)];
121
+ inputs = functionAbi.inputs;
122
+ inputsLength = inputs.reduce(function (acc, input) {
123
+ if (!/_len$/.test(input.name)) {
124
+ return acc + 1;
125
+ }
126
+ return acc;
127
+ }, 0);
128
+ options = {};
129
+ if (inputsLength + 1 === args.length && typeof args[args.length - 1] === 'object') {
130
+ Object.assign(options, args.pop());
131
+ }
132
+ return [2 /*return*/, contract.invoke(functionAbi.name, args, options)];
121
133
  });
122
134
  });
123
135
  };
@@ -58,7 +58,7 @@ var Signer = /** @class */ (function () {
58
58
  if (abis && abis.length !== transactions.length) {
59
59
  throw new Error('ABI must be provided for each transaction or no transaction');
60
60
  }
61
- msgHash = (0, hash_1.hashMulticall)(transactionsDetail.walletAddress, transactions, transactionsDetail.nonce.toString(), transactionsDetail.maxFee.toString());
61
+ msgHash = (0, hash_1.hashMulticall)(transactionsDetail.walletAddress, transactions, transactionsDetail.nonce.toString(), transactionsDetail.maxFee.toString(), transactionsDetail.version.toString());
62
62
  return [2 /*return*/, (0, ellipticCurve_1.sign)(this.keyPair, msgHash)];
63
63
  });
64
64
  });
@@ -92,6 +92,7 @@ export declare type InvokeFunctionTransaction = {
92
92
  calldata?: RawCalldata;
93
93
  nonce?: BigNumberish;
94
94
  max_fee?: BigNumberish;
95
+ version?: BigNumberish;
95
96
  };
96
97
  export declare type InvokeFunctionTrace = {
97
98
  caller_address: string;
@@ -18,6 +18,7 @@ export declare type Call = Omit<Invocation, 'signature'>;
18
18
  export declare type InvocationsDetails = {
19
19
  nonce?: BigNumberish;
20
20
  maxFee?: BigNumberish;
21
+ version?: BigNumberish;
21
22
  };
22
23
  export declare type Status = 'NOT_RECEIVED' | 'RECEIVED' | 'PENDING' | 'ACCEPTED_ON_L2' | 'ACCEPTED_ON_L1' | 'REJECTED';
23
24
  export declare type TransactionStatus = 'TRANSACTION_RECEIVED';
@@ -3,6 +3,7 @@ import { Call } from '../types';
3
3
  import { BigNumberish } from './number';
4
4
  export declare const transactionPrefix: string;
5
5
  export declare const transactionVersion = 0;
6
+ export declare const feeTransactionVersion: BN;
6
7
  /**
7
8
  * Function to get the starknet keccak hash from a string
8
9
  *
@@ -21,4 +22,4 @@ export declare function starknetKeccak(value: string): BN;
21
22
  export declare function getSelectorFromName(funcName: string): string;
22
23
  export declare function pedersen(input: [BigNumberish, BigNumberish]): string;
23
24
  export declare function computeHashOnElements(data: BigNumberish[]): string;
24
- export declare function hashMulticall(account: string, transactions: Call[], nonce: string, maxFee: string): string;
25
+ export declare function hashMulticall(account: string, transactions: Call[], nonce: string, maxFee: string, version?: string | number): string;
@@ -28,7 +28,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  return (mod && mod.__esModule) ? mod : { "default": mod };
29
29
  };
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.hashMulticall = exports.computeHashOnElements = exports.pedersen = exports.getSelectorFromName = exports.starknetKeccak = exports.transactionVersion = exports.transactionPrefix = void 0;
31
+ exports.hashMulticall = exports.computeHashOnElements = exports.pedersen = exports.getSelectorFromName = exports.starknetKeccak = exports.feeTransactionVersion = exports.transactionVersion = exports.transactionPrefix = void 0;
32
32
  var keccak_1 = require("ethereum-cryptography/keccak");
33
33
  var minimalistic_assert_1 = __importDefault(require("minimalistic-assert"));
34
34
  var constants_1 = require("../constants");
@@ -38,6 +38,7 @@ var number_1 = require("./number");
38
38
  var shortString_1 = require("./shortString");
39
39
  exports.transactionPrefix = (0, shortString_1.encodeShortString)('StarkNet Transaction');
40
40
  exports.transactionVersion = 0;
41
+ exports.feeTransactionVersion = (0, number_1.toBN)(2).pow((0, number_1.toBN)(128)).add((0, number_1.toBN)(exports.transactionVersion));
41
42
  function keccakHex(value) {
42
43
  return (0, encode_1.addHexPrefix)((0, encode_1.buf2hex)((0, keccak_1.keccak256)((0, encode_1.utf8ToArray)(value))));
43
44
  }
@@ -88,7 +89,8 @@ function computeHashOnElements(data) {
88
89
  return __spreadArray(__spreadArray([], __read(data), false), [data.length], false).reduce(function (x, y) { return pedersen([x, y]); }, 0).toString();
89
90
  }
90
91
  exports.computeHashOnElements = computeHashOnElements;
91
- function hashMulticall(account, transactions, nonce, maxFee) {
92
+ function hashMulticall(account, transactions, nonce, maxFee, version) {
93
+ if (version === void 0) { version = exports.transactionVersion; }
92
94
  var hashArray = transactions
93
95
  .map(function (_a) {
94
96
  var contractAddress = _a.contractAddress, entrypoint = _a.entrypoint, calldata = _a.calldata;
@@ -106,7 +108,7 @@ function hashMulticall(account, transactions, nonce, maxFee) {
106
108
  computeHashOnElements(hashArray),
107
109
  nonce,
108
110
  maxFee,
109
- exports.transactionVersion,
111
+ version,
110
112
  ]);
111
113
  }
112
114
  exports.hashMulticall = hashMulticall;
@@ -1,4 +1,6 @@
1
+ import BN from 'bn.js';
1
2
  import { Calldata, CompressedProgram, Program, RawArgs, Signature } from '../types';
3
+ import { BigNumberish } from './number';
2
4
  /**
3
5
  * Function to compress compiled cairo program
4
6
  *
@@ -11,3 +13,4 @@ export declare function randomAddress(): string;
11
13
  export declare function makeAddress(input: string): string;
12
14
  export declare function formatSignature(sig?: Signature): string[];
13
15
  export declare function compileCalldata(args: RawArgs): Calldata;
16
+ export declare function estimatedFeeToMaxFee(estimatedFee: BigNumberish, overhead?: number): BN;
@@ -25,7 +25,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
25
25
  return to.concat(ar || Array.prototype.slice.call(from));
26
26
  };
27
27
  Object.defineProperty(exports, "__esModule", { value: true });
28
- exports.compileCalldata = exports.formatSignature = exports.makeAddress = exports.randomAddress = exports.compressProgram = void 0;
28
+ exports.estimatedFeeToMaxFee = exports.compileCalldata = exports.formatSignature = exports.makeAddress = exports.randomAddress = exports.compressProgram = void 0;
29
29
  var pako_1 = require("pako");
30
30
  var ellipticCurve_1 = require("./ellipticCurve");
31
31
  var encode_1 = require("./encode");
@@ -82,3 +82,10 @@ function compileCalldata(args) {
82
82
  });
83
83
  }
84
84
  exports.compileCalldata = compileCalldata;
85
+ function estimatedFeeToMaxFee(estimatedFee, overhead) {
86
+ if (overhead === void 0) { overhead = 0.15; }
87
+ // BN can only handle Integers, so we need to do all calulations with integers
88
+ var overHeadPercent = Math.round((1 + overhead) * 100);
89
+ return (0, number_1.toBN)(estimatedFee).mul((0, number_1.toBN)(overHeadPercent)).div((0, number_1.toBN)(100));
90
+ }
91
+ exports.estimatedFeeToMaxFee = estimatedFeeToMaxFee;
@@ -47,8 +47,8 @@ export declare const encodeData: <T extends {
47
47
  }[]>;
48
48
  primaryType: string;
49
49
  domain: {
50
- name?: string | undefined;
51
50
  version?: string | undefined;
51
+ name?: string | undefined;
52
52
  chainId?: string | number | undefined;
53
53
  };
54
54
  message: Record<string, unknown>;
@@ -74,8 +74,8 @@ export declare const getStructHash: <T extends {
74
74
  }[]>;
75
75
  primaryType: string;
76
76
  domain: {
77
- name?: string | undefined;
78
77
  version?: string | undefined;
78
+ name?: string | undefined;
79
79
  chainId?: string | number | undefined;
80
80
  };
81
81
  message: Record<string, unknown>;
@@ -25,8 +25,8 @@ export declare const STARKNET_TYPE: import("superstruct").Struct<{
25
25
  */
26
26
  export declare type StarkNetType = Infer<typeof STARKNET_TYPE>;
27
27
  export declare const STARKNET_DOMAIN_TYPE: import("superstruct").Struct<{
28
- name?: string | undefined;
29
28
  version?: string | undefined;
29
+ name?: string | undefined;
30
30
  chainId?: string | number | undefined;
31
31
  }, {
32
32
  name: import("superstruct").Struct<string | undefined, null>;
@@ -49,8 +49,8 @@ export declare const STARKNET_TYPED_DATA_TYPE: import("superstruct").Struct<{
49
49
  }[]>;
50
50
  primaryType: string;
51
51
  domain: {
52
- name?: string | undefined;
53
52
  version?: string | undefined;
53
+ name?: string | undefined;
54
54
  chainId?: string | number | undefined;
55
55
  };
56
56
  message: Record<string, unknown>;
@@ -66,8 +66,8 @@ export declare const STARKNET_TYPED_DATA_TYPE: import("superstruct").Struct<{
66
66
  }[]>, null>;
67
67
  primaryType: import("superstruct").Struct<string, null>;
68
68
  domain: import("superstruct").Struct<{
69
- name?: string | undefined;
70
69
  version?: string | undefined;
70
+ name?: string | undefined;
71
71
  chainId?: string | number | undefined;
72
72
  }, {
73
73
  name: import("superstruct").Struct<string | undefined, null>;
@@ -16,8 +16,8 @@ export declare const validateTypedData: (data: unknown) => data is {
16
16
  }[]>;
17
17
  primaryType: string;
18
18
  domain: {
19
- name?: string | undefined;
20
19
  version?: string | undefined;
20
+ name?: string | undefined;
21
21
  chainId?: string | number | undefined;
22
22
  };
23
23
  message: Record<string, unknown>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starknet",
3
- "version": "3.8.0",
3
+ "version": "3.9.0",
4
4
  "description": "JavaScript library for StarkNet",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/signer/default.js CHANGED
@@ -157,7 +157,8 @@ var Signer = /** @class */ (function () {
157
157
  transactionsDetail.walletAddress,
158
158
  transactions,
159
159
  transactionsDetail.nonce.toString(),
160
- transactionsDetail.maxFee.toString()
160
+ transactionsDetail.maxFee.toString(),
161
+ transactionsDetail.version.toString()
161
162
  );
162
163
  return [2 /*return*/, (0, ellipticCurve_1.sign)(this.keyPair, msgHash)];
163
164
  });
@@ -17,12 +17,13 @@ import {
17
17
  import { sign } from '../utils/ellipticCurve';
18
18
  import {
19
19
  computeHashOnElements,
20
+ feeTransactionVersion,
20
21
  getSelectorFromName,
21
22
  transactionPrefix,
22
23
  transactionVersion,
23
24
  } from '../utils/hash';
24
25
  import { BigNumberish, bigNumberishArrayToDecimalStringArray, toBN, toHex } from '../utils/number';
25
- import { compileCalldata } from '../utils/stark';
26
+ import { compileCalldata, estimatedFeeToMaxFee } from '../utils/stark';
26
27
  import { fromCallsToExecuteCalldata } from '../utils/transaction';
27
28
  import { TypedData, getMessageHash } from '../utils/typedData';
28
29
  import { AccountInterface } from './interface';
@@ -56,10 +57,12 @@ export class Account extends Provider implements AccountInterface {
56
57
  ): Promise<EstimateFeeResponse> {
57
58
  const transactions = Array.isArray(calls) ? calls : [calls];
58
59
  const nonce = providedNonce ?? (await this.getNonce());
60
+ const version = toBN(feeTransactionVersion);
59
61
  const signerDetails = {
60
62
  walletAddress: this.address,
61
63
  nonce: toBN(nonce),
62
64
  maxFee: toBN('0'),
65
+ version,
63
66
  };
64
67
  const signature = await this.signer.signTransaction(transactions, signerDetails);
65
68
 
@@ -71,6 +74,7 @@ export class Account extends Provider implements AccountInterface {
71
74
  contract_address: this.address,
72
75
  entry_point_selector: getSelectorFromName('__execute__'),
73
76
  calldata,
77
+ version: toHex(version),
74
78
  signature: bigNumberishArrayToDecimalStringArray(signature),
75
79
  }
76
80
  );
@@ -91,12 +95,18 @@ export class Account extends Provider implements AccountInterface {
91
95
  ): Promise<AddTransactionResponse> {
92
96
  const transactions = Array.isArray(calls) ? calls : [calls];
93
97
  const nonce = toBN(transactionsDetail.nonce ?? (await this.getNonce()));
94
- const maxFee =
95
- transactionsDetail.maxFee ?? (await this.estimateFee(transactions, { nonce })).amount;
98
+ let maxFee: BigNumberish = '0';
99
+ if (transactionsDetail.maxFee) {
100
+ maxFee = transactionsDetail.maxFee;
101
+ } else {
102
+ const estimatedFee = (await this.estimateFee(transactions, { nonce })).amount;
103
+ maxFee = estimatedFeeToMaxFee(estimatedFee).toString();
104
+ }
96
105
  const signerDetails = {
97
106
  walletAddress: this.address,
98
107
  nonce,
99
108
  maxFee,
109
+ version: toBN(transactionVersion),
100
110
  };
101
111
 
102
112
  const signature = await this.signer.signTransaction(transactions, signerDetails, abis);
@@ -46,7 +46,18 @@ function buildCall(contract: Contract, functionAbi: FunctionAbi): AsyncContractF
46
46
  */
47
47
  function buildInvoke(contract: Contract, functionAbi: FunctionAbi): AsyncContractFunction {
48
48
  return async function (...args: Array<any>): Promise<any> {
49
- return contract.invoke(functionAbi.name, args);
49
+ const { inputs } = functionAbi;
50
+ const inputsLength = inputs.reduce((acc, input) => {
51
+ if (!/_len$/.test(input.name)) {
52
+ return acc + 1;
53
+ }
54
+ return acc;
55
+ }, 0);
56
+ const options = {};
57
+ if (inputsLength + 1 === args.length && typeof args[args.length - 1] === 'object') {
58
+ Object.assign(options, args.pop());
59
+ }
60
+ return contract.invoke(functionAbi.name, args, options);
50
61
  };
51
62
  }
52
63
 
@@ -29,7 +29,8 @@ export class Signer implements SignerInterface {
29
29
  transactionsDetail.walletAddress,
30
30
  transactions,
31
31
  transactionsDetail.nonce.toString(),
32
- transactionsDetail.maxFee.toString()
32
+ transactionsDetail.maxFee.toString(),
33
+ transactionsDetail.version.toString()
33
34
  );
34
35
 
35
36
  return sign(this.keyPair, msgHash);
package/src/types/api.ts CHANGED
@@ -105,6 +105,7 @@ export type InvokeFunctionTransaction = {
105
105
  calldata?: RawCalldata;
106
106
  nonce?: BigNumberish;
107
107
  max_fee?: BigNumberish;
108
+ version?: BigNumberish;
108
109
  };
109
110
 
110
111
  export type InvokeFunctionTrace = {
package/src/types/lib.ts CHANGED
@@ -24,6 +24,7 @@ export type Call = Omit<Invocation, 'signature'>;
24
24
  export type InvocationsDetails = {
25
25
  nonce?: BigNumberish;
26
26
  maxFee?: BigNumberish;
27
+ version?: BigNumberish;
27
28
  };
28
29
 
29
30
  export type Status =
package/src/utils/hash.ts CHANGED
@@ -11,6 +11,7 @@ import { encodeShortString } from './shortString';
11
11
 
12
12
  export const transactionPrefix = encodeShortString('StarkNet Transaction');
13
13
  export const transactionVersion = 0;
14
+ export const feeTransactionVersion = toBN(2).pow(toBN(128)).add(toBN(transactionVersion));
14
15
 
15
16
  function keccakHex(value: string): string {
16
17
  return addHexPrefix(buf2hex(keccak256(utf8ToArray(value))));
@@ -68,7 +69,8 @@ export function hashMulticall(
68
69
  account: string,
69
70
  transactions: Call[],
70
71
  nonce: string,
71
- maxFee: string
72
+ maxFee: string,
73
+ version: string | number = transactionVersion
72
74
  ) {
73
75
  const hashArray = transactions
74
76
  .map(({ contractAddress, entrypoint, calldata }) => [
@@ -85,6 +87,6 @@ export function hashMulticall(
85
87
  computeHashOnElements(hashArray),
86
88
  nonce,
87
89
  maxFee,
88
- transactionVersion,
90
+ version,
89
91
  ]);
90
92
  }
@@ -1,10 +1,11 @@
1
+ import BN from 'bn.js';
1
2
  import { gzip } from 'pako';
2
3
 
3
4
  import { Calldata, CompressedProgram, Program, RawArgs, Signature } from '../types';
4
5
  import { genKeyPair, getStarkKey } from './ellipticCurve';
5
6
  import { addHexPrefix, btoaUniversal } from './encode';
6
7
  import { stringify } from './json';
7
- import { toBN } from './number';
8
+ import { BigNumberish, toBN } from './number';
8
9
 
9
10
  /**
10
11
  * Function to compress compiled cairo program
@@ -48,3 +49,9 @@ export function compileCalldata(args: RawArgs): Calldata {
48
49
  return toBN(value).toString();
49
50
  });
50
51
  }
52
+
53
+ export function estimatedFeeToMaxFee(estimatedFee: BigNumberish, overhead: number = 0.15): BN {
54
+ // BN can only handle Integers, so we need to do all calulations with integers
55
+ const overHeadPercent = Math.round((1 + overhead) * 100);
56
+ return toBN(estimatedFee).mul(toBN(overHeadPercent)).div(toBN(100));
57
+ }
package/types/api.d.ts CHANGED
@@ -101,6 +101,7 @@ export declare type InvokeFunctionTransaction = {
101
101
  calldata?: RawCalldata;
102
102
  nonce?: BigNumberish;
103
103
  max_fee?: BigNumberish;
104
+ version?: BigNumberish;
104
105
  };
105
106
  export declare type InvokeFunctionTrace = {
106
107
  caller_address: string;
package/types/lib.d.ts CHANGED
@@ -19,6 +19,7 @@ export declare type Call = Omit<Invocation, 'signature'>;
19
19
  export declare type InvocationsDetails = {
20
20
  nonce?: BigNumberish;
21
21
  maxFee?: BigNumberish;
22
+ version?: BigNumberish;
22
23
  };
23
24
  export declare type Status =
24
25
  | 'NOT_RECEIVED'
package/utils/hash.d.ts CHANGED
@@ -4,6 +4,7 @@ import { Call } from '../types';
4
4
  import { BigNumberish } from './number';
5
5
  export declare const transactionPrefix: string;
6
6
  export declare const transactionVersion = 0;
7
+ export declare const feeTransactionVersion: BN;
7
8
  /**
8
9
  * Function to get the starknet keccak hash from a string
9
10
  *
@@ -26,5 +27,6 @@ export declare function hashMulticall(
26
27
  account: string,
27
28
  transactions: Call[],
28
29
  nonce: string,
29
- maxFee: string
30
+ maxFee: string,
31
+ version?: string | number
30
32
  ): string;
package/utils/hash.js CHANGED
@@ -44,6 +44,7 @@ exports.hashMulticall =
44
44
  exports.pedersen =
45
45
  exports.getSelectorFromName =
46
46
  exports.starknetKeccak =
47
+ exports.feeTransactionVersion =
47
48
  exports.transactionVersion =
48
49
  exports.transactionPrefix =
49
50
  void 0;
@@ -56,6 +57,9 @@ var number_1 = require('./number');
56
57
  var shortString_1 = require('./shortString');
57
58
  exports.transactionPrefix = (0, shortString_1.encodeShortString)('StarkNet Transaction');
58
59
  exports.transactionVersion = 0;
60
+ exports.feeTransactionVersion = (0, number_1.toBN)(2)
61
+ .pow((0, number_1.toBN)(128))
62
+ .add((0, number_1.toBN)(exports.transactionVersion));
59
63
  function keccakHex(value) {
60
64
  return (0, encode_1.addHexPrefix)(
61
65
  (0, encode_1.buf2hex)((0, keccak_1.keccak256)((0, encode_1.utf8ToArray)(value)))
@@ -116,7 +120,10 @@ function computeHashOnElements(data) {
116
120
  .toString();
117
121
  }
118
122
  exports.computeHashOnElements = computeHashOnElements;
119
- function hashMulticall(account, transactions, nonce, maxFee) {
123
+ function hashMulticall(account, transactions, nonce, maxFee, version) {
124
+ if (version === void 0) {
125
+ version = exports.transactionVersion;
126
+ }
120
127
  var hashArray = transactions
121
128
  .map(function (_a) {
122
129
  var contractAddress = _a.contractAddress,
@@ -136,7 +143,7 @@ function hashMulticall(account, transactions, nonce, maxFee) {
136
143
  computeHashOnElements(hashArray),
137
144
  nonce,
138
145
  maxFee,
139
- exports.transactionVersion,
146
+ version,
140
147
  ]);
141
148
  }
142
149
  exports.hashMulticall = hashMulticall;
package/utils/stark.d.ts CHANGED
@@ -1,4 +1,7 @@
1
+ import BN from 'bn.js';
2
+
1
3
  import { Calldata, CompressedProgram, Program, RawArgs, Signature } from '../types';
4
+ import { BigNumberish } from './number';
2
5
  /**
3
6
  * Function to compress compiled cairo program
4
7
  *
@@ -11,3 +14,4 @@ export declare function randomAddress(): string;
11
14
  export declare function makeAddress(input: string): string;
12
15
  export declare function formatSignature(sig?: Signature): string[];
13
16
  export declare function compileCalldata(args: RawArgs): Calldata;
17
+ export declare function estimatedFeeToMaxFee(estimatedFee: BigNumberish, overhead?: number): BN;
package/utils/stark.js CHANGED
@@ -34,7 +34,8 @@ var __spreadArray =
34
34
  return to.concat(ar || Array.prototype.slice.call(from));
35
35
  };
36
36
  Object.defineProperty(exports, '__esModule', { value: true });
37
- exports.compileCalldata =
37
+ exports.estimatedFeeToMaxFee =
38
+ exports.compileCalldata =
38
39
  exports.formatSignature =
39
40
  exports.makeAddress =
40
41
  exports.randomAddress =
@@ -111,3 +112,14 @@ function compileCalldata(args) {
111
112
  });
112
113
  }
113
114
  exports.compileCalldata = compileCalldata;
115
+ function estimatedFeeToMaxFee(estimatedFee, overhead) {
116
+ if (overhead === void 0) {
117
+ overhead = 0.15;
118
+ }
119
+ // BN can only handle Integers, so we need to do all calulations with integers
120
+ var overHeadPercent = Math.round((1 + overhead) * 100);
121
+ return (0, number_1.toBN)(estimatedFee)
122
+ .mul((0, number_1.toBN)(overHeadPercent))
123
+ .div((0, number_1.toBN)(100));
124
+ }
125
+ exports.estimatedFeeToMaxFee = estimatedFeeToMaxFee;
@@ -55,8 +55,8 @@ export declare const encodeData: <
55
55
  >;
56
56
  primaryType: string;
57
57
  domain: {
58
- name?: string | undefined;
59
58
  version?: string | undefined;
59
+ name?: string | undefined;
60
60
  chainId?: string | number | undefined;
61
61
  };
62
62
  message: Record<string, unknown>;
@@ -91,8 +91,8 @@ export declare const getStructHash: <
91
91
  >;
92
92
  primaryType: string;
93
93
  domain: {
94
- name?: string | undefined;
95
94
  version?: string | undefined;
95
+ name?: string | undefined;
96
96
  chainId?: string | number | undefined;
97
97
  };
98
98
  message: Record<string, unknown>;
@@ -29,8 +29,8 @@ export declare const STARKNET_TYPE: import('superstruct').Struct<
29
29
  export declare type StarkNetType = Infer<typeof STARKNET_TYPE>;
30
30
  export declare const STARKNET_DOMAIN_TYPE: import('superstruct').Struct<
31
31
  {
32
- name?: string | undefined;
33
32
  version?: string | undefined;
33
+ name?: string | undefined;
34
34
  chainId?: string | number | undefined;
35
35
  },
36
36
  {
@@ -59,8 +59,8 @@ export declare const STARKNET_TYPED_DATA_TYPE: import('superstruct').Struct<
59
59
  >;
60
60
  primaryType: string;
61
61
  domain: {
62
- name?: string | undefined;
63
62
  version?: string | undefined;
63
+ name?: string | undefined;
64
64
  chainId?: string | number | undefined;
65
65
  };
66
66
  message: Record<string, unknown>;
@@ -84,8 +84,8 @@ export declare const STARKNET_TYPED_DATA_TYPE: import('superstruct').Struct<
84
84
  primaryType: import('superstruct').Struct<string, null>;
85
85
  domain: import('superstruct').Struct<
86
86
  {
87
- name?: string | undefined;
88
87
  version?: string | undefined;
88
+ name?: string | undefined;
89
89
  chainId?: string | number | undefined;
90
90
  },
91
91
  {
@@ -19,8 +19,8 @@ export declare const validateTypedData: (data: unknown) => data is {
19
19
  >;
20
20
  primaryType: string;
21
21
  domain: {
22
- name?: string | undefined;
23
22
  version?: string | undefined;
23
+ name?: string | undefined;
24
24
  chainId?: string | number | undefined;
25
25
  };
26
26
  message: Record<string, unknown>;