starknet 2.0.2 → 2.1.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,9 +1,13 @@
1
- ## [2.0.2](https://github.com/seanjameshan/starknet.js/compare/v2.0.1...v2.0.2) (2021-11-22)
1
+ # [2.1.0](https://github.com/seanjameshan/starknet.js/compare/v2.0.1...v2.1.0) (2021-11-30)
2
2
 
3
3
  ### Bug Fixes
4
4
 
5
- - correctly parse structs in Starknet return types ([5a4a318](https://github.com/seanjameshan/starknet.js/commit/5a4a318dad4c78fe84540ad92063fc1879317ac1))
6
- - make Typescript compiler happy with constant types ([aedd895](https://github.com/seanjameshan/starknet.js/commit/aedd895a62e6018dd1d7330b004d54360007967f))
5
+ - deps ([020ba39](https://github.com/seanjameshan/starknet.js/commit/020ba3948f03e41fc96c7c002b613250d73fbda6))
6
+ - transaction status pending ([198d82b](https://github.com/seanjameshan/starknet.js/commit/198d82b30dd8c0c978cfdd2d56cb5a7e5131cb6a))
7
+
8
+ ### Features
9
+
10
+ - support mainnet ([de07149](https://github.com/seanjameshan/starknet.js/commit/de07149ad6521edc9f79e2b0e9c82bf40f32fe02))
7
11
 
8
12
  ## [2.0.1](https://github.com/seanjameshan/starknet.js/compare/v2.0.0...v2.0.1) (2021-11-18)
9
13
 
package/README.md CHANGED
@@ -44,14 +44,53 @@ $ npm install starknet
44
44
 
45
45
  Import `starknet` and use the [API](https://www.starknetjs.com/modules.html)
46
46
 
47
+ 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)
48
+
47
49
  ```javascript
48
- import { defaultProvider } from 'starknet';
50
+ import { defaultProvider, stark } from 'starknet';
51
+ const { getSelectorFromName } = stark;
52
+
53
+ const CONTRACT_ADDRESS =
54
+ "0x03e19baa6cb2078631bcdb34844f3f7879449a544c9ce722681a54af08cff4b9";
55
+
56
+ /**
57
+ * addTransaction() example
58
+ **/
59
+
60
+ /** Reset the liquidity pool **/
61
+ const addTokenResponse = await provider.addTransaction({
62
+ type: "INVOKE_FUNCTION",
63
+ contract_address: CONTRACT_ADDRESS,
64
+ entry_point_selector: getSelectorFromName("init_pool"),
65
+ calldata: ["1000000", "1000000"],
66
+ });
67
+ console.log(addTokenResponse);
68
+
69
+ /**
70
+ * callContract() example
71
+ **/
49
72
 
50
- defaultProvider.getContractAddresses().then((data) => {
51
- console.log(data);
73
+ /** Get the balance of the liquidity pool of token A **/
74
+ const poolBalanceTokenA = await callContract({
75
+ contract_address: CONTRACT_ADDRESS,
76
+ entry_point_selector: getSelectorFromName("get_pool_token_balance"),
77
+ calldata: ["1"],
52
78
  });
79
+ const balanceA = poolBalanceTokenA.result[0];
80
+ console.log('token a liquidity pool balance: ', parseInt(balanceA, 16));
81
+
82
+ /** Get the balance of the liquidity pool of token B **/
83
+ const poolBalanceTokenB = await callContract({
84
+ contract_address: CONTRACT_ADDRESS,
85
+ entry_point_selector: getSelectorFromName("get_pool_token_balance"),
86
+ calldata: ["2"],
87
+ });
88
+ const balanceB = poolBalanceTokenB.result[0];
89
+ console.log('token b liquidity pool balance: ', parseInt(balanceB, 16));
53
90
  ```
54
91
 
92
+ For more information about **signing transactions**, please take a look at this [pull request](https://github.com/seanjameshan/starknet.js/pull/51)
93
+
55
94
  ## 🌐 API
56
95
 
57
96
  [Click Here](https://www.starknetjs.com/modules.html)
@@ -60,6 +99,7 @@ defaultProvider.getContractAddresses().then((data) => {
60
99
 
61
100
  - [Argent X - the first StarkNet wallet](https://github.com/argentlabs/argent-x)
62
101
  - [React + Starknet.js boilerplate](https://github.com/fracek/starknet-react-example)
102
+ - [AMM Demo](https://www.starknetswap.com/)
63
103
 
64
104
  ## ✏️ Contributing
65
105
 
@@ -67,7 +107,7 @@ If you consider to contribute to this project please read [CONTRIBUTING.md](http
67
107
 
68
108
  ## ❤️ Special Thanks
69
109
 
70
- Special thanks to all the [contributors](https://github.com/seanjameshan/starknet.js/graphs/contributors), and especially Janek ([@janek26](https://github.com/janek26)) from [Argent](https://github.com/argentlabs) for driving the development of Starknet.js.
110
+ 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.
71
111
 
72
112
  This library would not be possible without these rockstars.
73
113
 
@@ -49,17 +49,17 @@ describe('defaultProvider', () => {
49
49
  )
50
50
  ).resolves.not.toThrow();
51
51
  });
52
- test('getTransactionStatus()', () => {
52
+ test('getTransactionStatus()', async () => {
53
53
  return expect(
54
54
  defaultProvider.getTransactionStatus(
55
- '0x774f7856b1ce6d5ce023a18cd5a06ab67e3a6d81c7bfcd01f99f32243c2d2ef'
55
+ '0x72add9621ecdcb07405a4f943fe410bf57003ca250400f01ce70f8a6fc72147'
56
56
  )
57
57
  ).resolves.not.toThrow();
58
58
  });
59
59
  test('getTransaction()', async () => {
60
60
  return expect(
61
61
  defaultProvider.getTransaction(
62
- '0x774f7856b1ce6d5ce023a18cd5a06ab67e3a6d81c7bfcd01f99f32243c2d2ef'
62
+ '0x72add9621ecdcb07405a4f943fe410bf57003ca250400f01ce70f8a6fc72147'
63
63
  )
64
64
  ).resolves.not.toThrow();
65
65
  });
@@ -1,4 +1,4 @@
1
- import { getKeyPair, getStarkKey, sign, verify, ec } from '../../src/utils/ellipticCurve';
1
+ import { ec, getKeyPair, getStarkKey, sign, verify } from '../../src/utils/ellipticCurve';
2
2
  import { removeHexPrefix } from '../../src/utils/encode';
3
3
  import { hashCalldata, hashMessage, pedersen } from '../../src/utils/hash';
4
4
  import { toBN, toHex } from '../../src/utils/number';
package/constants.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import BN from 'bn.js';
1
+ /// <reference types="bn.js" />
2
2
  export { IS_BROWSER } from './utils/encode';
3
- export declare const ZERO: BN;
4
- export declare const ONE: BN;
5
- export declare const TWO: BN;
6
- export declare const MASK_250: BN;
3
+ export declare const ZERO: import('bn.js');
4
+ export declare const ONE: import('bn.js');
5
+ export declare const TWO: import('bn.js');
6
+ export declare const MASK_250: import('bn.js');
7
7
  /**
8
8
  * The following is taken from https://github.com/starkware-libs/starkex-resources/blob/master/crypto/starkware/crypto/signature/pedersen_params.json but converted to hex, because JS is very bad handling big integers by default
9
9
  * Please do not edit until the JSON changes.
package/contract.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Provider } from './provider';
2
- import { Abi, StructAbi } from './types';
2
+ import { Abi } from './types';
3
3
  import { BigNumberish } from './utils/number';
4
4
  export declare type Args = {
5
5
  [inputName: string]: string | string[];
@@ -9,9 +9,6 @@ export declare function compileCalldata(args: Args): Calldata;
9
9
  export declare class Contract {
10
10
  connectedTo: string | null;
11
11
  abi: Abi[];
12
- structs: {
13
- [name: string]: StructAbi;
14
- };
15
12
  provider: Provider;
16
13
  /**
17
14
  * Contract class to handle contract methods
@@ -22,7 +19,6 @@ export declare class Contract {
22
19
  constructor(abi: Abi[], address?: string | null, provider?: Provider);
23
20
  connect(address: string): Contract;
24
21
  private validateMethodAndArgs;
25
- private parseResponseField;
26
22
  private parseResponse;
27
23
  invoke(
28
24
  method: string,
package/contract.js CHANGED
@@ -238,14 +238,6 @@ var Contract = /** @class */ (function () {
238
238
  this.connectedTo = address;
239
239
  this.provider = provider;
240
240
  this.abi = abi;
241
- this.structs = abi
242
- .filter(function (abiEntry) {
243
- return abiEntry.type === 'struct';
244
- })
245
- .reduce(function (acc, abiEntry) {
246
- var _a;
247
- return __assign(__assign({}, acc), ((_a = {}), (_a[abiEntry.name] = abiEntry), _a));
248
- }, {});
249
241
  }
250
242
  Contract.prototype.connect = function (address) {
251
243
  this.connectedTo = address;
@@ -258,9 +250,9 @@ var Contract = /** @class */ (function () {
258
250
  // ensure provided method exists
259
251
  var invokeableFunctionNames = this.abi
260
252
  .filter(function (abi) {
261
- if (abi.type !== 'function') return false;
262
253
  var isView = abi.stateMutability === 'view';
263
- return type === 'INVOKE' ? !isView : isView;
254
+ var isFunction = abi.type === 'function';
255
+ return isFunction && type === 'INVOKE' ? !isView : isView;
264
256
  })
265
257
  .map(function (abi) {
266
258
  return abi.name;
@@ -271,7 +263,7 @@ var Contract = /** @class */ (function () {
271
263
  );
272
264
  // ensure args match abi type
273
265
  var methodAbi = this.abi.find(function (abi) {
274
- return abi.name === method && abi.type === 'function';
266
+ return abi.name === method;
275
267
  });
276
268
  methodAbi.inputs.forEach(function (input) {
277
269
  if (args[input.name] !== undefined) {
@@ -299,31 +291,14 @@ var Contract = /** @class */ (function () {
299
291
  }
300
292
  });
301
293
  };
302
- Contract.prototype.parseResponseField = function (element, responseIterator) {
303
- var _this = this;
304
- var entries = [];
305
- if (['felt', 'felt*'].includes(element.type)) {
306
- return responseIterator.next().value;
307
- }
308
- if (element.type in this.structs) {
309
- entries = this.structs[element.type].members;
310
- } else if ('outputs' in element) {
311
- entries = element.outputs;
312
- }
313
- return entries.reduce(function (acc, member) {
314
- var _a;
315
- return __assign(
316
- __assign({}, acc),
317
- ((_a = {}), (_a[member.name] = _this.parseResponseField(member, responseIterator)), _a)
318
- );
319
- }, {});
320
- };
321
294
  Contract.prototype.parseResponse = function (method, response) {
322
295
  var methodAbi = this.abi.find(function (abi) {
323
296
  return abi.name === method;
324
297
  });
325
- var responseIterator = response.flat()[Symbol.iterator]();
326
- return this.parseResponseField(methodAbi, responseIterator);
298
+ return methodAbi.outputs.reduce(function (acc, output, i) {
299
+ var _a;
300
+ return __assign(__assign({}, acc), ((_a = {}), (_a[output.name] = response[i]), _a));
301
+ }, {});
327
302
  };
328
303
  Contract.prototype.invoke = function (method, args, signature) {
329
304
  if (args === void 0) {
@@ -1,9 +1,9 @@
1
- import BN from 'bn.js';
1
+ /// <reference types="bn.js" />
2
2
  export { IS_BROWSER } from './utils/encode';
3
- export declare const ZERO: BN;
4
- export declare const ONE: BN;
5
- export declare const TWO: BN;
6
- export declare const MASK_250: BN;
3
+ export declare const ZERO: import("bn.js");
4
+ export declare const ONE: import("bn.js");
5
+ export declare const TWO: import("bn.js");
6
+ export declare const MASK_250: import("bn.js");
7
7
  /**
8
8
  * The following is taken from https://github.com/starkware-libs/starkex-resources/blob/master/crypto/starkware/crypto/signature/pedersen_params.json but converted to hex, because JS is very bad handling big integers by default
9
9
  * Please do not edit until the JSON changes.
@@ -1,5 +1,5 @@
1
1
  import { Provider } from './provider';
2
- import { Abi, StructAbi } from './types';
2
+ import { Abi } from './types';
3
3
  import { BigNumberish } from './utils/number';
4
4
  export declare type Args = {
5
5
  [inputName: string]: string | string[];
@@ -9,9 +9,6 @@ export declare function compileCalldata(args: Args): Calldata;
9
9
  export declare class Contract {
10
10
  connectedTo: string | null;
11
11
  abi: Abi[];
12
- structs: {
13
- [name: string]: StructAbi;
14
- };
15
12
  provider: Provider;
16
13
  /**
17
14
  * Contract class to handle contract methods
@@ -22,7 +19,6 @@ export declare class Contract {
22
19
  constructor(abi: Abi[], address?: string | null, provider?: Provider);
23
20
  connect(address: string): Contract;
24
21
  private validateMethodAndArgs;
25
- private parseResponseField;
26
22
  private parseResponse;
27
23
  invoke(method: string, args?: Args, signature?: [BigNumberish, BigNumberish]): Promise<import("./types").AddTransactionResponse>;
28
24
  call(method: string, args?: Args): Promise<Args>;
package/dist/contract.js CHANGED
@@ -119,12 +119,6 @@ var Contract = /** @class */ (function () {
119
119
  this.connectedTo = address;
120
120
  this.provider = provider;
121
121
  this.abi = abi;
122
- this.structs = abi
123
- .filter(function (abiEntry) { return abiEntry.type === 'struct'; })
124
- .reduce(function (acc, abiEntry) {
125
- var _a;
126
- return (__assign(__assign({}, acc), (_a = {}, _a[abiEntry.name] = abiEntry, _a)));
127
- }, {});
128
122
  }
129
123
  Contract.prototype.connect = function (address) {
130
124
  this.connectedTo = address;
@@ -135,15 +129,14 @@ var Contract = /** @class */ (function () {
135
129
  // ensure provided method exists
136
130
  var invokeableFunctionNames = this.abi
137
131
  .filter(function (abi) {
138
- if (abi.type !== 'function')
139
- return false;
140
132
  var isView = abi.stateMutability === 'view';
141
- return type === 'INVOKE' ? !isView : isView;
133
+ var isFunction = abi.type === 'function';
134
+ return isFunction && type === 'INVOKE' ? !isView : isView;
142
135
  })
143
136
  .map(function (abi) { return abi.name; });
144
137
  (0, minimalistic_assert_1.default)(invokeableFunctionNames.includes(method), (type === 'INVOKE' ? 'invokeable' : 'viewable') + " method not found in abi");
145
138
  // ensure args match abi type
146
- var methodAbi = this.abi.find(function (abi) { return abi.name === method && abi.type === 'function'; });
139
+ var methodAbi = this.abi.find(function (abi) { return abi.name === method; });
147
140
  methodAbi.inputs.forEach(function (input) {
148
141
  if (args[input.name] !== undefined) {
149
142
  if (input.type === 'felt') {
@@ -160,27 +153,12 @@ var Contract = /** @class */ (function () {
160
153
  }
161
154
  });
162
155
  };
163
- Contract.prototype.parseResponseField = function (element, responseIterator) {
164
- var _this = this;
165
- var entries = [];
166
- if (['felt', 'felt*'].includes(element.type)) {
167
- return responseIterator.next().value;
168
- }
169
- if (element.type in this.structs) {
170
- entries = this.structs[element.type].members;
171
- }
172
- else if ('outputs' in element) {
173
- entries = element.outputs;
174
- }
175
- return entries.reduce(function (acc, member) {
176
- var _a;
177
- return (__assign(__assign({}, acc), (_a = {}, _a[member.name] = _this.parseResponseField(member, responseIterator), _a)));
178
- }, {});
179
- };
180
156
  Contract.prototype.parseResponse = function (method, response) {
181
157
  var methodAbi = this.abi.find(function (abi) { return abi.name === method; });
182
- var responseIterator = response.flat()[Symbol.iterator]();
183
- return this.parseResponseField(methodAbi, responseIterator);
158
+ return methodAbi.outputs.reduce(function (acc, output, i) {
159
+ var _a;
160
+ return __assign(__assign({}, acc), (_a = {}, _a[output.name] = response[i], _a));
161
+ }, {});
184
162
  };
185
163
  Contract.prototype.invoke = function (method, args, signature) {
186
164
  if (args === void 0) { args = {}; }
@@ -1,16 +1,18 @@
1
1
  import { AddTransactionResponse, CallContractResponse, CallContractTransaction, CompiledContract, GetBlockResponse, GetCodeResponse, GetContractAddressesResponse, GetTransactionResponse, GetTransactionStatusResponse, Transaction } from '../types';
2
2
  import { BigNumberish } from '../utils/number';
3
3
  import { ProviderInterface } from './interface';
4
- declare type NetworkName = 'alpha';
5
- interface ProviderOptions {
6
- network?: NetworkName;
7
- }
4
+ declare type NetworkName = 'mainnet-alpha' | 'georli-alpha';
5
+ declare type ProviderOptions = {
6
+ network: NetworkName;
7
+ } | {
8
+ baseUrl: string;
9
+ };
8
10
  export declare class Provider implements ProviderInterface {
9
11
  baseUrl: string;
10
12
  feederGatewayUrl: string;
11
13
  gatewayUrl: string;
12
14
  constructor(optionsOrProvider?: ProviderOptions | Provider);
13
- protected static getNetworkFromName(name: NetworkName): string;
15
+ protected static getNetworkFromName(name: NetworkName): "http://alpha-mainnet.starknet.io/" | "https://alpha4.starknet.io";
14
16
  /**
15
17
  * Gets the smart contract address on the goerli testnet.
16
18
  *
@@ -60,14 +60,16 @@ function wait(delay) {
60
60
  }
61
61
  var Provider = /** @class */ (function () {
62
62
  function Provider(optionsOrProvider) {
63
+ if (optionsOrProvider === void 0) { optionsOrProvider = { network: 'georli-alpha' }; }
63
64
  if (optionsOrProvider instanceof Provider) {
64
65
  this.baseUrl = optionsOrProvider.baseUrl;
65
66
  this.feederGatewayUrl = optionsOrProvider.feederGatewayUrl;
66
67
  this.gatewayUrl = optionsOrProvider.gatewayUrl;
67
68
  }
68
69
  else {
69
- var _a = (optionsOrProvider || {}).network, network = _a === void 0 ? 'alpha' : _a;
70
- var baseUrl = Provider.getNetworkFromName(network);
70
+ var baseUrl = 'baseUrl' in optionsOrProvider
71
+ ? optionsOrProvider.baseUrl
72
+ : Provider.getNetworkFromName(optionsOrProvider.network);
71
73
  this.baseUrl = baseUrl;
72
74
  this.feederGatewayUrl = baseUrl + "/feeder_gateway";
73
75
  this.gatewayUrl = baseUrl + "/gateway";
@@ -75,7 +77,9 @@ var Provider = /** @class */ (function () {
75
77
  }
76
78
  Provider.getNetworkFromName = function (name) {
77
79
  switch (name) {
78
- case 'alpha':
80
+ case 'mainnet-alpha':
81
+ return 'http://alpha-mainnet.starknet.io/';
82
+ case 'georli-alpha':
79
83
  default:
80
84
  return 'https://alpha4.starknet.io';
81
85
  }
@@ -296,14 +300,13 @@ var Provider = /** @class */ (function () {
296
300
  });
297
301
  };
298
302
  Provider.prototype.waitForTx = function (txHash, retryInterval) {
299
- if (retryInterval === void 0) { retryInterval = 5000; }
303
+ if (retryInterval === void 0) { retryInterval = 8000; }
300
304
  return __awaiter(this, void 0, void 0, function () {
301
- var onchain, firstRun, res;
305
+ var onchain, res;
302
306
  return __generator(this, function (_a) {
303
307
  switch (_a.label) {
304
308
  case 0:
305
309
  onchain = false;
306
- firstRun = true;
307
310
  _a.label = 1;
308
311
  case 1:
309
312
  if (!!onchain) return [3 /*break*/, 4];
@@ -315,16 +318,17 @@ var Provider = /** @class */ (function () {
315
318
  return [4 /*yield*/, this.getTransactionStatus(txHash)];
316
319
  case 3:
317
320
  res = _a.sent();
318
- if (res.tx_status === 'ACCEPTED_ONCHAIN' || res.tx_status === 'PENDING') {
321
+ if (res.tx_status === 'ACCEPTED_ONCHAIN' ||
322
+ (res.tx_status === 'PENDING' && res.block_hash !== 'pending') // This is needed as of today. In the future there will be a different status for pending transactions.
323
+ ) {
319
324
  onchain = true;
320
325
  }
321
326
  else if (res.tx_status === 'REJECTED') {
322
327
  throw Error('REJECTED');
323
328
  }
324
- else if (res.tx_status === 'NOT_RECEIVED' && !firstRun) {
329
+ else if (res.tx_status === 'NOT_RECEIVED') {
325
330
  throw Error('NOT_RECEIVED');
326
331
  }
327
- firstRun = false;
328
332
  return [3 /*break*/, 1];
329
333
  case 4: return [2 /*return*/];
330
334
  }
package/dist/types.d.ts CHANGED
@@ -11,26 +11,19 @@ export declare type TxStatus = 'TRANSACTION_RECEIVED';
11
11
  export declare type Type = 'DEPLOY' | 'INVOKE_FUNCTION';
12
12
  export declare type EntryPointType = 'EXTERNAL';
13
13
  export declare type CompressedProgram = string;
14
- export declare type AbiEntry = {
14
+ export declare type Abi = {
15
+ inputs: {
16
+ name: string;
17
+ type: 'felt' | 'felt*';
18
+ }[];
15
19
  name: string;
16
- type: 'felt' | 'felt*' | string;
17
- };
18
- export declare type FunctionAbi = {
19
- inputs: AbiEntry[];
20
- name: string;
21
- outputs: AbiEntry[];
20
+ outputs: {
21
+ name: string;
22
+ type: 'felt' | 'felt*';
23
+ }[];
22
24
  stateMutability?: 'view';
23
25
  type: 'function';
24
26
  };
25
- export declare type StructAbi = {
26
- members: (AbiEntry & {
27
- offset: number;
28
- })[];
29
- name: string;
30
- size: number;
31
- type: 'struct';
32
- };
33
- export declare type Abi = FunctionAbi | StructAbi;
34
27
  export declare type EntryPointsByType = object;
35
28
  export declare type Program = object;
36
29
  export declare type CompiledContract = {
@@ -61,14 +54,14 @@ export declare type CallContractResponse = {
61
54
  export declare type GetBlockResponse = {
62
55
  sequence_number: number;
63
56
  state_root: string;
64
- block_id: number;
57
+ block_hash: string;
65
58
  transactions: {
66
59
  [txHash: string]: Transaction;
67
60
  };
68
61
  timestamp: number;
69
62
  transaction_receipts: {
70
63
  [txHash: string]: {
71
- block_id: number;
64
+ block_hash: string;
72
65
  transaction_hash: string;
73
66
  l2_to_l1_messages: {
74
67
  to_address: string;
@@ -80,7 +73,7 @@ export declare type GetBlockResponse = {
80
73
  transaction_index: number;
81
74
  };
82
75
  };
83
- previous_block_id: number;
76
+ previous_block_hash: string;
84
77
  status: Status;
85
78
  };
86
79
  export declare type GetCodeResponse = {
@@ -89,12 +82,12 @@ export declare type GetCodeResponse = {
89
82
  };
90
83
  export declare type GetTransactionStatusResponse = {
91
84
  tx_status: Status;
92
- block_id: number;
85
+ block_hash: string;
93
86
  };
94
87
  export declare type GetTransactionResponse = {
95
88
  status: Status;
96
89
  transaction: Transaction;
97
- block_id: number;
90
+ block_hash: string;
98
91
  block_number: number;
99
92
  transaction_index: number;
100
93
  transaction_hash: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starknet",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "JavaScript library for StarkNet",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,16 +12,22 @@ import {
12
12
  } from '../types';
13
13
  import { BigNumberish } from '../utils/number';
14
14
  import { ProviderInterface } from './interface';
15
- declare type NetworkName = 'alpha';
16
- interface ProviderOptions {
17
- network?: NetworkName;
18
- }
15
+ declare type NetworkName = 'mainnet-alpha' | 'georli-alpha';
16
+ declare type ProviderOptions =
17
+ | {
18
+ network: NetworkName;
19
+ }
20
+ | {
21
+ baseUrl: string;
22
+ };
19
23
  export declare class Provider implements ProviderInterface {
20
24
  baseUrl: string;
21
25
  feederGatewayUrl: string;
22
26
  gatewayUrl: string;
23
27
  constructor(optionsOrProvider?: ProviderOptions | Provider);
24
- protected static getNetworkFromName(name: NetworkName): string;
28
+ protected static getNetworkFromName(
29
+ name: NetworkName
30
+ ): 'http://alpha-mainnet.starknet.io/' | 'https://alpha4.starknet.io';
25
31
  /**
26
32
  * Gets the smart contract address on the goerli testnet.
27
33
  *
@@ -162,14 +162,18 @@ function wait(delay) {
162
162
  }
163
163
  var Provider = /** @class */ (function () {
164
164
  function Provider(optionsOrProvider) {
165
+ if (optionsOrProvider === void 0) {
166
+ optionsOrProvider = { network: 'georli-alpha' };
167
+ }
165
168
  if (optionsOrProvider instanceof Provider) {
166
169
  this.baseUrl = optionsOrProvider.baseUrl;
167
170
  this.feederGatewayUrl = optionsOrProvider.feederGatewayUrl;
168
171
  this.gatewayUrl = optionsOrProvider.gatewayUrl;
169
172
  } else {
170
- var _a = (optionsOrProvider || {}).network,
171
- network = _a === void 0 ? 'alpha' : _a;
172
- var baseUrl = Provider.getNetworkFromName(network);
173
+ var baseUrl =
174
+ 'baseUrl' in optionsOrProvider
175
+ ? optionsOrProvider.baseUrl
176
+ : Provider.getNetworkFromName(optionsOrProvider.network);
173
177
  this.baseUrl = baseUrl;
174
178
  this.feederGatewayUrl = baseUrl + '/feeder_gateway';
175
179
  this.gatewayUrl = baseUrl + '/gateway';
@@ -177,7 +181,9 @@ var Provider = /** @class */ (function () {
177
181
  }
178
182
  Provider.getNetworkFromName = function (name) {
179
183
  switch (name) {
180
- case 'alpha':
184
+ case 'mainnet-alpha':
185
+ return 'http://alpha-mainnet.starknet.io/';
186
+ case 'georli-alpha':
181
187
  default:
182
188
  return 'https://alpha4.starknet.io';
183
189
  }
@@ -484,15 +490,14 @@ var Provider = /** @class */ (function () {
484
490
  };
485
491
  Provider.prototype.waitForTx = function (txHash, retryInterval) {
486
492
  if (retryInterval === void 0) {
487
- retryInterval = 5000;
493
+ retryInterval = 8000;
488
494
  }
489
495
  return __awaiter(this, void 0, void 0, function () {
490
- var onchain, firstRun, res;
496
+ var onchain, res;
491
497
  return __generator(this, function (_a) {
492
498
  switch (_a.label) {
493
499
  case 0:
494
500
  onchain = false;
495
- firstRun = true;
496
501
  _a.label = 1;
497
502
  case 1:
498
503
  if (!!onchain) return [3 /*break*/, 4];
@@ -504,14 +509,16 @@ var Provider = /** @class */ (function () {
504
509
  return [4 /*yield*/, this.getTransactionStatus(txHash)];
505
510
  case 3:
506
511
  res = _a.sent();
507
- if (res.tx_status === 'ACCEPTED_ONCHAIN' || res.tx_status === 'PENDING') {
512
+ if (
513
+ res.tx_status === 'ACCEPTED_ONCHAIN' ||
514
+ (res.tx_status === 'PENDING' && res.block_hash !== 'pending') // This is needed as of today. In the future there will be a different status for pending transactions.
515
+ ) {
508
516
  onchain = true;
509
517
  } else if (res.tx_status === 'REJECTED') {
510
518
  throw Error('REJECTED');
511
- } else if (res.tx_status === 'NOT_RECEIVED' && !firstRun) {
519
+ } else if (res.tx_status === 'NOT_RECEIVED') {
512
520
  throw Error('NOT_RECEIVED');
513
521
  }
514
- firstRun = false;
515
522
  return [3 /*break*/, 1];
516
523
  case 4:
517
524
  return [2 /*return*/];
package/src/constants.ts CHANGED
@@ -1,13 +1,11 @@
1
- import BN from 'bn.js';
2
-
3
1
  import { toBN } from './utils/number';
4
2
 
5
3
  export { IS_BROWSER } from './utils/encode';
6
4
 
7
- export const ZERO: BN = toBN(0);
8
- export const ONE: BN = toBN(1);
9
- export const TWO: BN = toBN(2);
10
- export const MASK_250: BN = TWO.pow(toBN(250)).sub(ONE); // 2 ** 250 - 1
5
+ export const ZERO = toBN(0);
6
+ export const ONE = toBN(1);
7
+ export const TWO = toBN(2);
8
+ export const MASK_250 = TWO.pow(toBN(250)).sub(ONE); // 2 ** 250 - 1
11
9
 
12
10
  /**
13
11
  * The following is taken from https://github.com/starkware-libs/starkex-resources/blob/master/crypto/starkware/crypto/signature/pedersen_params.json but converted to hex, because JS is very bad handling big integers by default
package/src/contract.ts CHANGED
@@ -2,7 +2,7 @@ import BN from 'bn.js';
2
2
  import assert from 'minimalistic-assert';
3
3
 
4
4
  import { Provider, defaultProvider } from './provider';
5
- import { Abi, AbiEntry, FunctionAbi, StructAbi } from './types';
5
+ import { Abi } from './types';
6
6
  import { BigNumberish, toBN } from './utils/number';
7
7
  import { getSelectorFromName } from './utils/stark';
8
8
 
@@ -39,8 +39,6 @@ export class Contract {
39
39
 
40
40
  abi: Abi[];
41
41
 
42
- structs: { [name: string]: StructAbi };
43
-
44
42
  provider: Provider;
45
43
 
46
44
  /**
@@ -53,15 +51,6 @@ export class Contract {
53
51
  this.connectedTo = address;
54
52
  this.provider = provider;
55
53
  this.abi = abi;
56
- this.structs = abi
57
- .filter((abiEntry) => abiEntry.type === 'struct')
58
- .reduce(
59
- (acc, abiEntry) => ({
60
- ...acc,
61
- [abiEntry.name]: abiEntry,
62
- }),
63
- {}
64
- );
65
54
  }
66
55
 
67
56
  public connect(address: string): Contract {
@@ -73,9 +62,9 @@ export class Contract {
73
62
  // ensure provided method exists
74
63
  const invokeableFunctionNames = this.abi
75
64
  .filter((abi) => {
76
- if (abi.type !== 'function') return false;
77
65
  const isView = abi.stateMutability === 'view';
78
- return type === 'INVOKE' ? !isView : isView;
66
+ const isFunction = abi.type === 'function';
67
+ return isFunction && type === 'INVOKE' ? !isView : isView;
79
68
  })
80
69
  .map((abi) => abi.name);
81
70
  assert(
@@ -84,9 +73,7 @@ export class Contract {
84
73
  );
85
74
 
86
75
  // ensure args match abi type
87
- const methodAbi = this.abi.find(
88
- (abi) => abi.name === method && abi.type === 'function'
89
- ) as FunctionAbi;
76
+ const methodAbi = this.abi.find((abi) => abi.name === method)!;
90
77
  methodAbi.inputs.forEach((input) => {
91
78
  if (args[input.name] !== undefined) {
92
79
  if (input.type === 'felt') {
@@ -115,32 +102,14 @@ export class Contract {
115
102
  });
116
103
  }
117
104
 
118
- private parseResponseField(
119
- element: AbiEntry | FunctionAbi,
120
- responseIterator: Iterator<string>
121
- ): Args {
122
- let entries: AbiEntry[] = [];
123
- if (['felt', 'felt*'].includes(element.type)) {
124
- return responseIterator.next().value;
125
- }
126
- if (element.type in this.structs) {
127
- entries = this.structs[element.type].members;
128
- } else if ('outputs' in element) {
129
- entries = element.outputs;
130
- }
131
- return entries.reduce(
132
- (acc, member) => ({
105
+ private parseResponse(method: string, response: (string | string[])[]): Args {
106
+ const methodAbi = this.abi.find((abi) => abi.name === method)!;
107
+ return methodAbi.outputs.reduce((acc, output, i) => {
108
+ return {
133
109
  ...acc,
134
- [member.name]: this.parseResponseField(member, responseIterator),
135
- }),
136
- {}
137
- );
138
- }
139
-
140
- private parseResponse(method: string, response: string[]): Args {
141
- const methodAbi = this.abi.find((abi) => abi.name === method) as FunctionAbi;
142
- const responseIterator = response.flat()[Symbol.iterator]();
143
- return this.parseResponseField(methodAbi, responseIterator);
110
+ [output.name]: response[i],
111
+ };
112
+ }, {} as Args);
144
113
  }
145
114
 
146
115
  public invoke(method: string, args: Args = {}, signature?: [BigNumberish, BigNumberish]) {
@@ -17,11 +17,15 @@ import { BigNumberish, toBN, toHex } from '../utils/number';
17
17
  import { compressProgram, formatSignature, randomAddress } from '../utils/stark';
18
18
  import { ProviderInterface } from './interface';
19
19
 
20
- type NetworkName = 'alpha';
20
+ type NetworkName = 'mainnet-alpha' | 'georli-alpha';
21
21
 
22
- interface ProviderOptions {
23
- network?: NetworkName;
24
- }
22
+ type ProviderOptions =
23
+ | {
24
+ network: NetworkName;
25
+ }
26
+ | {
27
+ baseUrl: string;
28
+ };
25
29
 
26
30
  function wait(delay: number) {
27
31
  return new Promise((res) => setTimeout(res, delay));
@@ -34,14 +38,16 @@ export class Provider implements ProviderInterface {
34
38
 
35
39
  public gatewayUrl: string;
36
40
 
37
- constructor(optionsOrProvider?: ProviderOptions | Provider) {
41
+ constructor(optionsOrProvider: ProviderOptions | Provider = { network: 'georli-alpha' }) {
38
42
  if (optionsOrProvider instanceof Provider) {
39
43
  this.baseUrl = optionsOrProvider.baseUrl;
40
44
  this.feederGatewayUrl = optionsOrProvider.feederGatewayUrl;
41
45
  this.gatewayUrl = optionsOrProvider.gatewayUrl;
42
46
  } else {
43
- const { network = 'alpha' } = optionsOrProvider || {};
44
- const baseUrl = Provider.getNetworkFromName(network);
47
+ const baseUrl =
48
+ 'baseUrl' in optionsOrProvider
49
+ ? optionsOrProvider.baseUrl
50
+ : Provider.getNetworkFromName(optionsOrProvider.network);
45
51
  this.baseUrl = baseUrl;
46
52
  this.feederGatewayUrl = `${baseUrl}/feeder_gateway`;
47
53
  this.gatewayUrl = `${baseUrl}/gateway`;
@@ -50,7 +56,9 @@ export class Provider implements ProviderInterface {
50
56
 
51
57
  protected static getNetworkFromName(name: NetworkName) {
52
58
  switch (name) {
53
- case 'alpha':
59
+ case 'mainnet-alpha':
60
+ return 'http://alpha-mainnet.starknet.io/';
61
+ case 'georli-alpha':
54
62
  default:
55
63
  return 'https://alpha4.starknet.io';
56
64
  }
@@ -257,23 +265,24 @@ export class Provider implements ProviderInterface {
257
265
  });
258
266
  }
259
267
 
260
- public async waitForTx(txHash: BigNumberish, retryInterval: number = 5000) {
268
+ public async waitForTx(txHash: BigNumberish, retryInterval: number = 8000) {
261
269
  let onchain = false;
262
- let firstRun = true;
263
270
  while (!onchain) {
264
271
  // eslint-disable-next-line no-await-in-loop
265
272
  await wait(retryInterval);
266
273
  // eslint-disable-next-line no-await-in-loop
267
274
  const res = await this.getTransactionStatus(txHash);
268
275
 
269
- if (res.tx_status === 'ACCEPTED_ONCHAIN' || res.tx_status === 'PENDING') {
276
+ if (
277
+ res.tx_status === 'ACCEPTED_ONCHAIN' ||
278
+ (res.tx_status === 'PENDING' && res.block_hash !== 'pending') // This is needed as of today. In the future there will be a different status for pending transactions.
279
+ ) {
270
280
  onchain = true;
271
281
  } else if (res.tx_status === 'REJECTED') {
272
282
  throw Error('REJECTED');
273
- } else if (res.tx_status === 'NOT_RECEIVED' && !firstRun) {
283
+ } else if (res.tx_status === 'NOT_RECEIVED') {
274
284
  throw Error('NOT_RECEIVED');
275
285
  }
276
- firstRun = false;
277
286
  }
278
287
  }
279
288
  }
package/src/types.ts CHANGED
@@ -16,25 +16,13 @@ export type Type = 'DEPLOY' | 'INVOKE_FUNCTION';
16
16
  export type EntryPointType = 'EXTERNAL';
17
17
  export type CompressedProgram = string;
18
18
 
19
- export type AbiEntry = { name: string; type: 'felt' | 'felt*' | string };
20
-
21
- export type FunctionAbi = {
22
- inputs: AbiEntry[];
19
+ export type Abi = {
20
+ inputs: { name: string; type: 'felt' | 'felt*' }[];
23
21
  name: string;
24
- outputs: AbiEntry[];
22
+ outputs: { name: string; type: 'felt' | 'felt*' }[];
25
23
  stateMutability?: 'view';
26
24
  type: 'function';
27
25
  };
28
-
29
- export type StructAbi = {
30
- members: (AbiEntry & { offset: number })[];
31
- name: string;
32
- size: number;
33
- type: 'struct';
34
- };
35
-
36
- export type Abi = FunctionAbi | StructAbi;
37
-
38
26
  export type EntryPointsByType = object;
39
27
  export type Program = object;
40
28
 
@@ -73,14 +61,14 @@ export type CallContractResponse = {
73
61
  export type GetBlockResponse = {
74
62
  sequence_number: number;
75
63
  state_root: string;
76
- block_id: number;
64
+ block_hash: string;
77
65
  transactions: {
78
66
  [txHash: string]: Transaction;
79
67
  };
80
68
  timestamp: number;
81
69
  transaction_receipts: {
82
70
  [txHash: string]: {
83
- block_id: number;
71
+ block_hash: string;
84
72
  transaction_hash: string;
85
73
  l2_to_l1_messages: {
86
74
  to_address: string;
@@ -92,7 +80,7 @@ export type GetBlockResponse = {
92
80
  transaction_index: number;
93
81
  };
94
82
  };
95
- previous_block_id: number;
83
+ previous_block_hash: string;
96
84
  status: Status;
97
85
  };
98
86
 
@@ -103,13 +91,13 @@ export type GetCodeResponse = {
103
91
 
104
92
  export type GetTransactionStatusResponse = {
105
93
  tx_status: Status;
106
- block_id: number;
94
+ block_hash: string;
107
95
  };
108
96
 
109
97
  export type GetTransactionResponse = {
110
98
  status: Status;
111
99
  transaction: Transaction;
112
- block_id: number;
100
+ block_hash: string;
113
101
  block_number: number;
114
102
  transaction_index: number;
115
103
  transaction_hash: string;
package/types.d.ts CHANGED
@@ -17,26 +17,19 @@ export declare type TxStatus = 'TRANSACTION_RECEIVED';
17
17
  export declare type Type = 'DEPLOY' | 'INVOKE_FUNCTION';
18
18
  export declare type EntryPointType = 'EXTERNAL';
19
19
  export declare type CompressedProgram = string;
20
- export declare type AbiEntry = {
20
+ export declare type Abi = {
21
+ inputs: {
22
+ name: string;
23
+ type: 'felt' | 'felt*';
24
+ }[];
21
25
  name: string;
22
- type: 'felt' | 'felt*' | string;
23
- };
24
- export declare type FunctionAbi = {
25
- inputs: AbiEntry[];
26
- name: string;
27
- outputs: AbiEntry[];
26
+ outputs: {
27
+ name: string;
28
+ type: 'felt' | 'felt*';
29
+ }[];
28
30
  stateMutability?: 'view';
29
31
  type: 'function';
30
32
  };
31
- export declare type StructAbi = {
32
- members: (AbiEntry & {
33
- offset: number;
34
- })[];
35
- name: string;
36
- size: number;
37
- type: 'struct';
38
- };
39
- export declare type Abi = FunctionAbi | StructAbi;
40
33
  export declare type EntryPointsByType = object;
41
34
  export declare type Program = object;
42
35
  export declare type CompiledContract = {
@@ -67,14 +60,14 @@ export declare type CallContractResponse = {
67
60
  export declare type GetBlockResponse = {
68
61
  sequence_number: number;
69
62
  state_root: string;
70
- block_id: number;
63
+ block_hash: string;
71
64
  transactions: {
72
65
  [txHash: string]: Transaction;
73
66
  };
74
67
  timestamp: number;
75
68
  transaction_receipts: {
76
69
  [txHash: string]: {
77
- block_id: number;
70
+ block_hash: string;
78
71
  transaction_hash: string;
79
72
  l2_to_l1_messages: {
80
73
  to_address: string;
@@ -86,7 +79,7 @@ export declare type GetBlockResponse = {
86
79
  transaction_index: number;
87
80
  };
88
81
  };
89
- previous_block_id: number;
82
+ previous_block_hash: string;
90
83
  status: Status;
91
84
  };
92
85
  export declare type GetCodeResponse = {
@@ -95,12 +88,12 @@ export declare type GetCodeResponse = {
95
88
  };
96
89
  export declare type GetTransactionStatusResponse = {
97
90
  tx_status: Status;
98
- block_id: number;
91
+ block_hash: string;
99
92
  };
100
93
  export declare type GetTransactionResponse = {
101
94
  status: Status;
102
95
  transaction: Transaction;
103
- block_id: number;
96
+ block_hash: string;
104
97
  block_number: number;
105
98
  transaction_index: number;
106
99
  transaction_hash: string;