starknet 2.4.0 → 2.5.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 (55) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/__tests__/account.test.ts +3 -3
  3. package/__tests__/utils/ellipticalCurve.test.ts +1 -1
  4. package/__tests__/utils/typedData.test.ts +72 -0
  5. package/contract.d.ts +2 -2
  6. package/dist/contract.d.ts +2 -2
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +2 -1
  9. package/dist/provider/default.d.ts +2 -2
  10. package/dist/provider/default.js +10 -9
  11. package/dist/provider/interface.d.ts +2 -2
  12. package/dist/signer/default.d.ts +18 -1
  13. package/dist/signer/default.js +43 -7
  14. package/dist/signer/interface.d.ts +20 -1
  15. package/dist/types.d.ts +3 -3
  16. package/dist/utils/ellipticCurve.d.ts +8 -1
  17. package/dist/utils/ellipticCurve.js +48 -9
  18. package/dist/utils/stark.d.ts +2 -3
  19. package/dist/utils/typedData/index.d.ts +91 -0
  20. package/dist/utils/typedData/index.js +183 -0
  21. package/dist/utils/typedData/types.d.ts +82 -0
  22. package/dist/utils/typedData/types.js +47 -0
  23. package/dist/utils/typedData/utils.d.ts +24 -0
  24. package/dist/utils/typedData/utils.js +15 -0
  25. package/index.d.ts +1 -0
  26. package/index.js +3 -1
  27. package/package.json +2 -1
  28. package/provider/default.d.ts +2 -1
  29. package/provider/default.js +10 -10
  30. package/provider/interface.d.ts +2 -1
  31. package/signer/default.d.ts +18 -1
  32. package/signer/default.js +44 -7
  33. package/signer/interface.d.ts +20 -1
  34. package/src/contract.ts +2 -2
  35. package/src/index.ts +1 -0
  36. package/src/provider/default.ts +5 -5
  37. package/src/provider/interface.ts +2 -1
  38. package/src/signer/default.ts +26 -3
  39. package/src/signer/interface.ts +22 -1
  40. package/src/types.ts +9 -3
  41. package/src/utils/ellipticCurve.ts +31 -9
  42. package/src/utils/stark.ts +4 -4
  43. package/src/utils/typedData/index.ts +176 -0
  44. package/src/utils/typedData/types.ts +82 -0
  45. package/src/utils/typedData/utils.ts +13 -0
  46. package/types.d.ts +5 -4
  47. package/utils/ellipticCurve.d.ts +12 -1
  48. package/utils/ellipticCurve.js +72 -23
  49. package/utils/stark.d.ts +2 -3
  50. package/utils/typedData/index.d.ts +113 -0
  51. package/utils/typedData/index.js +247 -0
  52. package/utils/typedData/types.d.ts +103 -0
  53. package/utils/typedData/types.js +57 -0
  54. package/utils/typedData/utils.d.ts +27 -0
  55. package/utils/typedData/utils.js +15 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ # [2.5.0](https://github.com/seanjameshan/starknet.js/compare/v2.4.0...v2.5.0) (2021-12-13)
2
+
3
+ ### Bug Fixes
4
+
5
+ - add jsdoc comment ([4cd969f](https://github.com/seanjameshan/starknet.js/commit/4cd969f82eb4a5d8c08feb59c42fb3e7195af50e))
6
+ - remove eip712 reference ([039a360](https://github.com/seanjameshan/starknet.js/commit/039a360873f9a1cdedc7a498b6e1732183957143))
7
+ - remove unused types ([e528f7d](https://github.com/seanjameshan/starknet.js/commit/e528f7d75f4560d2affe3ca99426e01fbee6dfb5))
8
+ - review ([a3813c9](https://github.com/seanjameshan/starknet.js/commit/a3813c9931c178d58c2521b926fb3fdff6944635))
9
+
10
+ ### Features
11
+
12
+ - add `getKeyPairFromPublicKey` method ([66d543d](https://github.com/seanjameshan/starknet.js/commit/66d543dca1bb302654f0f1588a27f7794bfa49be))
13
+ - add tests ([b414a83](https://github.com/seanjameshan/starknet.js/commit/b414a839a1fdd56084a58d6efb4747e8f5455628))
14
+ - allow multi sig ([fc1e086](https://github.com/seanjameshan/starknet.js/commit/fc1e0866154d2bf29f26374639a34fec438bae5e))
15
+ - support eip712 for starknet ([d597082](https://github.com/seanjameshan/starknet.js/commit/d59708211fc497d801699a7168dad1a5cc9648fd))
16
+
1
17
  # [2.4.0](https://github.com/seanjameshan/starknet.js/compare/v2.3.1...v2.4.0) (2021-12-09)
2
18
 
3
19
  ### Features
@@ -104,7 +104,7 @@ describe('deploy and test Wallet', () => {
104
104
  )
105
105
  );
106
106
 
107
- const { r, s } = ec.sign(starkKeyPair, msgHash);
107
+ const signature = ec.sign(starkKeyPair, msgHash);
108
108
  const { code, transaction_hash } = await wallet.invoke(
109
109
  'execute',
110
110
  {
@@ -113,7 +113,7 @@ describe('deploy and test Wallet', () => {
113
113
  calldata: [erc20Address, '10'],
114
114
  nonce: nonce.toString(),
115
115
  },
116
- [number.toHex(r), number.toHex(s)]
116
+ signature
117
117
  );
118
118
 
119
119
  expect(code).toBe('TRANSACTION_RECEIVED');
@@ -151,7 +151,7 @@ test('build tx', async () => {
151
151
  .toString()
152
152
  );
153
153
 
154
- const { r, s } = ec.sign(keyPair, msgHash);
154
+ const [r, s] = ec.sign(keyPair, msgHash);
155
155
  expect(r.toString()).toBe(
156
156
  '706800951915233622090196542158919402159816118214143837213294331713137614072'
157
157
  );
@@ -40,7 +40,7 @@ test('hashMessage()', () => {
40
40
  );
41
41
  expect(hashMsg).toBe('0x7f15c38ea577a26f4f553282fcfe4f1feeb8ecfaad8f221ae41abf8224cbddd');
42
42
  const keyPair = getKeyPair(privateKey);
43
- const { r, s } = sign(keyPair, removeHexPrefix(hashMsg));
43
+ const [r, s] = sign(keyPair, removeHexPrefix(hashMsg));
44
44
  expect(r.toString()).toStrictEqual(
45
45
  toBN('2458502865976494910213617956670505342647705497324144349552978333078363662855').toString()
46
46
  );
@@ -0,0 +1,72 @@
1
+ import { encodeType, getMessageHash, getStructHash, getTypeHash } from '../../src/utils/typedData';
2
+
3
+ const typedDataExample = {
4
+ types: {
5
+ StarkNetDomain: [
6
+ { name: 'name', type: 'felt' },
7
+ { name: 'version', type: 'felt' },
8
+ { name: 'chainId', type: 'felt' },
9
+ ],
10
+ Person: [
11
+ { name: 'name', type: 'felt' },
12
+ { name: 'wallet', type: 'felt' },
13
+ ],
14
+ Mail: [
15
+ { name: 'from', type: 'Person' },
16
+ { name: 'to', type: 'Person' },
17
+ { name: 'contents', type: 'felt' },
18
+ ],
19
+ },
20
+ primaryType: 'Mail',
21
+ domain: {
22
+ name: 'StarkNet Mail',
23
+ version: '1',
24
+ chainId: 1,
25
+ },
26
+ message: {
27
+ from: {
28
+ name: 'Cow',
29
+ wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
30
+ },
31
+ to: {
32
+ name: 'Bob',
33
+ wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
34
+ },
35
+ contents: 'Hello, Bob!',
36
+ },
37
+ };
38
+
39
+ describe('typedData', () => {
40
+ test('should get right type encoding', () => {
41
+ const typeEncoding = encodeType(typedDataExample, 'Mail');
42
+ expect(typeEncoding).toMatchInlineSnapshot(
43
+ `"Mail(from:Person,to:Person,contents:felt)Person(name:felt,wallet:felt)"`
44
+ );
45
+ });
46
+ test('should get right type hash', () => {
47
+ const typeHashDomain = getTypeHash(typedDataExample, 'StarkNetDomain');
48
+ expect(typeHashDomain).toMatchInlineSnapshot(
49
+ `"0x1bfc207425a47a5dfa1a50a4f5241203f50624ca5fdf5e18755765416b8e288"`
50
+ );
51
+ const typeHashPerson = getTypeHash(typedDataExample, 'Person');
52
+ expect(typeHashPerson).toMatchInlineSnapshot(
53
+ `"0x2896dbe4b96a67110f454c01e5336edc5bbc3635537efd690f122f4809cc855"`
54
+ );
55
+ const typeHashMail = getTypeHash(typedDataExample, 'Mail');
56
+ expect(typeHashMail).toMatchInlineSnapshot(
57
+ `"0x13d89452df9512bf750f539ba3001b945576243288137ddb6c788457d4b2f79"`
58
+ );
59
+ });
60
+ test('should get right hash for StarkNetDomain', () => {
61
+ const hash = getStructHash(typedDataExample, 'StarkNetDomain', typedDataExample.domain as any);
62
+ expect(hash).toMatchInlineSnapshot(
63
+ `"0x54833b121883a3e3aebff48ec08a962f5742e5f7b973469c1f8f4f55d470b07"`
64
+ );
65
+ });
66
+ test('should get right hash for entire message', () => {
67
+ const hash = getMessageHash(typedDataExample, '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826');
68
+ expect(hash).toMatchInlineSnapshot(
69
+ `"0x6fcff244f63e38b9d88b9e3378d44757710d1b244282b435cb472053c8d78d0"`
70
+ );
71
+ });
72
+ });
package/contract.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Provider } from './provider';
2
- import { Abi, StructAbi } from './types';
2
+ import { Abi, Signature, StructAbi } from './types';
3
3
  import { BigNumberish } from './utils/number';
4
4
  export declare type Args = {
5
5
  [inputName: string]:
@@ -33,7 +33,7 @@ export declare class Contract {
33
33
  invoke(
34
34
  method: string,
35
35
  args?: Args,
36
- signature?: [BigNumberish, BigNumberish]
36
+ signature?: Signature
37
37
  ): Promise<import('./types').AddTransactionResponse>;
38
38
  call(method: string, args?: Args): Promise<Args>;
39
39
  }
@@ -1,5 +1,5 @@
1
1
  import { Provider } from './provider';
2
- import { Abi, StructAbi } from './types';
2
+ import { Abi, Signature, StructAbi } from './types';
3
3
  import { BigNumberish } from './utils/number';
4
4
  export declare type Args = {
5
5
  [inputName: string]: string | string[] | {
@@ -27,6 +27,6 @@ export declare class Contract {
27
27
  private validateMethodAndArgs;
28
28
  private parseResponseField;
29
29
  private parseResponse;
30
- invoke(method: string, args?: Args, signature?: [BigNumberish, BigNumberish]): Promise<import("./types").AddTransactionResponse>;
30
+ invoke(method: string, args?: Args, signature?: Signature): Promise<import("./types").AddTransactionResponse>;
31
31
  call(method: string, args?: Args): Promise<Args>;
32
32
  }
package/dist/index.d.ts CHANGED
@@ -17,3 +17,4 @@ export * as stark from './utils/stark';
17
17
  export * as ec from './utils/ellipticCurve';
18
18
  export * as uint256 from './utils/uint256';
19
19
  export * as shortString from './utils/shortString';
20
+ export * as typedData from './utils/typedData';
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  return result;
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.shortString = exports.uint256 = exports.ec = exports.stark = exports.number = exports.json = exports.hash = exports.encode = exports.constants = void 0;
25
+ exports.typedData = exports.shortString = exports.uint256 = exports.ec = exports.stark = exports.number = exports.json = exports.hash = exports.encode = exports.constants = void 0;
26
26
  /**
27
27
  * Main
28
28
  */
@@ -42,3 +42,4 @@ exports.stark = __importStar(require("./utils/stark"));
42
42
  exports.ec = __importStar(require("./utils/ellipticCurve"));
43
43
  exports.uint256 = __importStar(require("./utils/uint256"));
44
44
  exports.shortString = __importStar(require("./utils/shortString"));
45
+ exports.typedData = __importStar(require("./utils/typedData"));
@@ -1,4 +1,4 @@
1
- import { AddTransactionResponse, CallContractResponse, CallContractTransaction, CompiledContract, GetBlockResponse, GetCodeResponse, GetContractAddressesResponse, GetTransactionResponse, GetTransactionStatusResponse, Transaction } from '../types';
1
+ import { AddTransactionResponse, CallContractResponse, CallContractTransaction, CompiledContract, GetBlockResponse, GetCodeResponse, GetContractAddressesResponse, GetTransactionResponse, GetTransactionStatusResponse, Signature, Transaction } from '../types';
2
2
  import { BigNumberish } from '../utils/number';
3
3
  import { ProviderInterface } from './interface';
4
4
  declare type NetworkName = 'mainnet-alpha' | 'georli-alpha';
@@ -104,7 +104,7 @@ export declare class Provider implements ProviderInterface {
104
104
  * @param signature - (optional) signature to send along
105
105
  * @returns response from addTransaction
106
106
  */
107
- invokeFunction(contractAddress: string, entrypointSelector: string, calldata?: string[], signature?: [BigNumberish, BigNumberish]): Promise<AddTransactionResponse>;
107
+ invokeFunction(contractAddress: string, entrypointSelector: string, calldata?: string[], signature?: Signature): Promise<AddTransactionResponse>;
108
108
  waitForTx(txHash: BigNumberish, retryInterval?: number): Promise<void>;
109
109
  }
110
110
  export {};
@@ -308,20 +308,21 @@ var Provider = /** @class */ (function () {
308
308
  switch (_a.label) {
309
309
  case 0:
310
310
  onchain = false;
311
- _a.label = 1;
311
+ return [4 /*yield*/, wait(retryInterval)];
312
312
  case 1:
313
- if (!!onchain) return [3 /*break*/, 4];
313
+ _a.sent();
314
+ _a.label = 2;
315
+ case 2:
316
+ if (!!onchain) return [3 /*break*/, 5];
314
317
  // eslint-disable-next-line no-await-in-loop
315
318
  return [4 /*yield*/, wait(retryInterval)];
316
- case 2:
319
+ case 3:
317
320
  // eslint-disable-next-line no-await-in-loop
318
321
  _a.sent();
319
322
  return [4 /*yield*/, this.getTransactionStatus(txHash)];
320
- case 3:
323
+ case 4:
321
324
  res = _a.sent();
322
- if (res.tx_status === 'ACCEPTED_ONCHAIN' ||
323
- (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.
324
- ) {
325
+ if (res.tx_status === 'ACCEPTED_ON_L1' || res.tx_status === 'ACCEPTED_ON_L2') {
325
326
  onchain = true;
326
327
  }
327
328
  else if (res.tx_status === 'REJECTED') {
@@ -330,8 +331,8 @@ var Provider = /** @class */ (function () {
330
331
  else if (res.tx_status === 'NOT_RECEIVED') {
331
332
  throw Error('NOT_RECEIVED');
332
333
  }
333
- return [3 /*break*/, 1];
334
- case 4: return [2 /*return*/];
334
+ return [3 /*break*/, 2];
335
+ case 5: return [2 /*return*/];
335
336
  }
336
337
  });
337
338
  });
@@ -1,4 +1,4 @@
1
- import type { AddTransactionResponse, CallContractResponse, CallContractTransaction, CompiledContract, GetBlockResponse, GetCodeResponse, GetContractAddressesResponse, GetTransactionResponse, GetTransactionStatusResponse, Transaction } from '../types';
1
+ import type { AddTransactionResponse, CallContractResponse, CallContractTransaction, CompiledContract, GetBlockResponse, GetCodeResponse, GetContractAddressesResponse, GetTransactionResponse, GetTransactionStatusResponse, Signature, Transaction } from '../types';
2
2
  import type { BigNumberish } from '../utils/number';
3
3
  export declare abstract class ProviderInterface {
4
4
  abstract baseUrl: string;
@@ -95,6 +95,6 @@ export declare abstract class ProviderInterface {
95
95
  * @param signature - (optional) signature to send along
96
96
  * @returns response from addTransaction
97
97
  */
98
- abstract invokeFunction(contractAddress: string, entrypointSelector: string, calldata?: string[], signature?: [BigNumberish, BigNumberish]): Promise<AddTransactionResponse>;
98
+ abstract invokeFunction(contractAddress: string, entrypointSelector: string, calldata?: string[], signature?: Signature): Promise<AddTransactionResponse>;
99
99
  abstract waitForTx(txHash: BigNumberish, retryInterval?: number): Promise<void>;
100
100
  }
@@ -1,5 +1,6 @@
1
1
  import { Provider } from '../provider';
2
- import { AddTransactionResponse, KeyPair, Transaction } from '../types';
2
+ import { AddTransactionResponse, KeyPair, Signature, Transaction } from '../types';
3
+ import { TypedData } from '../utils/typedData';
3
4
  import { SignerInterface } from './interface';
4
5
  export declare class Signer extends Provider implements SignerInterface {
5
6
  address: string;
@@ -14,4 +15,20 @@ export declare class Signer extends Provider implements SignerInterface {
14
15
  * @returns a confirmation of invoking a function on the starknet contract
15
16
  */
16
17
  addTransaction(transaction: Transaction): Promise<AddTransactionResponse>;
18
+ /**
19
+ * Sign an JSON object with the starknet private key and return the signature
20
+ *
21
+ * @param json - JSON object to be signed
22
+ * @returns the signature of the JSON object
23
+ * @throws {Error} if the JSON object is not a valid JSON
24
+ */
25
+ signMessage(typedData: TypedData): Promise<Signature>;
26
+ /**
27
+ * Hash a JSON object with pederson hash and return the hash
28
+ *
29
+ * @param json - JSON object to be hashed
30
+ * @returns the hash of the JSON object
31
+ * @throws {Error} if the JSON object is not a valid JSON
32
+ */
33
+ hashMessage(typedData: TypedData): Promise<string>;
17
34
  }
@@ -87,6 +87,7 @@ var encode_1 = require("../utils/encode");
87
87
  var hash_1 = require("../utils/hash");
88
88
  var number_1 = require("../utils/number");
89
89
  var stark_1 = require("../utils/stark");
90
+ var typedData_1 = require("../utils/typedData");
90
91
  var Signer = /** @class */ (function (_super) {
91
92
  __extends(Signer, _super);
92
93
  function Signer(provider, address, keyPair) {
@@ -105,9 +106,9 @@ var Signer = /** @class */ (function (_super) {
105
106
  */
106
107
  Signer.prototype.addTransaction = function (transaction) {
107
108
  return __awaiter(this, void 0, void 0, function () {
108
- var nonceBn, result, calldataDecimal, msgHash, _a, r, s;
109
- return __generator(this, function (_b) {
110
- switch (_b.label) {
109
+ var nonceBn, result, calldataDecimal, msgHash, signature;
110
+ return __generator(this, function (_a) {
111
+ switch (_a.label) {
111
112
  case 0:
112
113
  if (transaction.type === 'DEPLOY')
113
114
  return [2 /*return*/, _super.prototype.addTransaction.call(this, transaction)];
@@ -120,13 +121,13 @@ var Signer = /** @class */ (function (_super) {
120
121
  entry_point_selector: (0, stark_1.getSelectorFromName)('get_nonce'),
121
122
  })];
122
123
  case 2:
123
- result = (_b.sent()).result;
124
+ result = (_a.sent()).result;
124
125
  nonceBn = (0, number_1.toBN)(result[0]);
125
- _b.label = 3;
126
+ _a.label = 3;
126
127
  case 3:
127
128
  calldataDecimal = (transaction.calldata || []).map(function (x) { return (0, number_1.toBN)(x).toString(); });
128
129
  msgHash = (0, encode_1.addHexPrefix)((0, hash_1.hashMessage)(this.address, transaction.contract_address, transaction.entry_point_selector, calldataDecimal, nonceBn.toString()));
129
- _a = (0, ellipticCurve_1.sign)(this.keyPair, msgHash), r = _a.r, s = _a.s;
130
+ signature = (0, ellipticCurve_1.sign)(this.keyPair, msgHash);
130
131
  return [2 /*return*/, _super.prototype.addTransaction.call(this, {
131
132
  type: 'INVOKE_FUNCTION',
132
133
  entry_point_selector: (0, stark_1.getSelectorFromName)('execute'),
@@ -138,12 +139,47 @@ var Signer = /** @class */ (function (_super) {
138
139
  nonceBn.toString(),
139
140
  ], false).map(function (x) { return (0, number_1.toBN)(x).toString(); }),
140
141
  contract_address: this.address,
141
- signature: [r, s],
142
+ signature: signature,
142
143
  })];
143
144
  }
144
145
  });
145
146
  });
146
147
  };
148
+ /**
149
+ * Sign an JSON object with the starknet private key and return the signature
150
+ *
151
+ * @param json - JSON object to be signed
152
+ * @returns the signature of the JSON object
153
+ * @throws {Error} if the JSON object is not a valid JSON
154
+ */
155
+ Signer.prototype.signMessage = function (typedData) {
156
+ return __awaiter(this, void 0, void 0, function () {
157
+ var _a, _b;
158
+ return __generator(this, function (_c) {
159
+ switch (_c.label) {
160
+ case 0:
161
+ _a = ellipticCurve_1.sign;
162
+ _b = [this.keyPair];
163
+ return [4 /*yield*/, this.hashMessage(typedData)];
164
+ case 1: return [2 /*return*/, _a.apply(void 0, _b.concat([_c.sent()]))];
165
+ }
166
+ });
167
+ });
168
+ };
169
+ /**
170
+ * Hash a JSON object with pederson hash and return the hash
171
+ *
172
+ * @param json - JSON object to be hashed
173
+ * @returns the hash of the JSON object
174
+ * @throws {Error} if the JSON object is not a valid JSON
175
+ */
176
+ Signer.prototype.hashMessage = function (typedData) {
177
+ return __awaiter(this, void 0, void 0, function () {
178
+ return __generator(this, function (_a) {
179
+ return [2 /*return*/, (0, typedData_1.getMessageHash)(typedData, this.address)];
180
+ });
181
+ });
182
+ };
147
183
  return Signer;
148
184
  }(provider_1.Provider));
149
185
  exports.Signer = Signer;
@@ -1,5 +1,6 @@
1
1
  import { Provider } from '../provider';
2
- import { AddTransactionResponse, Transaction } from '../types';
2
+ import { AddTransactionResponse, Signature, Transaction } from '../types';
3
+ import { TypedData } from '../utils/typedData/types';
3
4
  export declare abstract class SignerInterface extends Provider {
4
5
  abstract address: string;
5
6
  /**
@@ -11,4 +12,22 @@ export declare abstract class SignerInterface extends Provider {
11
12
  * @returns a confirmation of invoking a function on the starknet contract
12
13
  */
13
14
  abstract addTransaction(transaction: Transaction): Promise<AddTransactionResponse>;
15
+ /**
16
+ * Sign an JSON object for off-chain usage with the starknet private key and return the signature
17
+ * This adds a message prefix so it cant be interchanged with transactions
18
+ *
19
+ * @param json - JSON object to be signed
20
+ * @returns the signature of the JSON object
21
+ * @throws {Error} if the JSON object is not a valid JSON
22
+ */
23
+ abstract signMessage(typedData: TypedData): Promise<Signature>;
24
+ /**
25
+ * Hash a JSON object with pederson hash and return the hash
26
+ * This adds a message prefix so it cant be interchanged with transactions
27
+ *
28
+ * @param json - JSON object to be hashed
29
+ * @returns the hash of the JSON object
30
+ * @throws {Error} if the JSON object is not a valid JSON
31
+ */
32
+ abstract hashMessage(typedData: TypedData): Promise<string>;
14
33
  }
package/dist/types.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import type { ec as EC } from 'elliptic';
2
2
  import type { BigNumberish } from './utils/number';
3
3
  export declare type KeyPair = EC.KeyPair;
4
- export declare type Signature = EC.Signature;
4
+ export declare type Signature = BigNumberish[];
5
5
  export declare type GetContractAddressesResponse = {
6
6
  Starknet: string;
7
7
  GpsStatementVerifier: string;
8
8
  };
9
- export declare type Status = 'NOT_RECEIVED' | 'RECEIVED' | 'PENDING' | 'REJECTED' | 'ACCEPTED_ONCHAIN';
9
+ export declare type Status = 'NOT_RECEIVED' | 'RECEIVED' | 'PENDING' | 'ACCEPTED_ON_L2' | 'ACCEPTED_ON_L1' | 'REJECTED';
10
10
  export declare type TransactionStatus = 'TRANSACTION_RECEIVED';
11
11
  export declare type Type = 'DEPLOY' | 'INVOKE_FUNCTION';
12
12
  export declare type EntryPointType = 'EXTERNAL';
@@ -49,7 +49,7 @@ export declare type DeployTransaction = {
49
49
  export declare type InvokeFunctionTransaction = {
50
50
  type: 'INVOKE_FUNCTION';
51
51
  contract_address: string;
52
- signature?: [BigNumberish, BigNumberish];
52
+ signature?: Signature;
53
53
  entry_point_type?: EntryPointType;
54
54
  entry_point_selector: string;
55
55
  calldata?: string[];
@@ -5,5 +5,12 @@ export declare const ec: EC;
5
5
  export declare const genKeyPair: (options?: EC.GenKeyPairOptions | undefined) => EC.KeyPair;
6
6
  export declare function getKeyPair(pk: BigNumberish): KeyPair;
7
7
  export declare function getStarkKey(keyPair: KeyPair): string;
8
+ /**
9
+ * Takes a public key and casts it into `elliptic` KeyPair format.
10
+ *
11
+ * @param publicKey - public key which should get casted to a KeyPair
12
+ * @returns keyPair with public key only, which can be used to verify signatures, but cant sign anything
13
+ */
14
+ export declare function getKeyPairFromPublicKey(publicKey: BigNumberish): KeyPair;
8
15
  export declare function sign(keyPair: KeyPair, msgHash: string): Signature;
9
- export declare function verify(keyPair: KeyPair, msgHash: string, sig: Signature): boolean;
16
+ export declare function verify(keyPair: KeyPair | KeyPair[], msgHash: string, sig: Signature): boolean;
@@ -1,9 +1,25 @@
1
1
  "use strict";
2
+ var __read = (this && this.__read) || function (o, n) {
3
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
4
+ if (!m) return o;
5
+ var i = m.call(o), r, ar = [], e;
6
+ try {
7
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
+ }
9
+ catch (error) { e = { error: error }; }
10
+ finally {
11
+ try {
12
+ if (r && !r.done && (m = i["return"])) m.call(i);
13
+ }
14
+ finally { if (e) throw e.error; }
15
+ }
16
+ return ar;
17
+ };
2
18
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
19
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
20
  };
5
21
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.verify = exports.sign = exports.getStarkKey = exports.getKeyPair = exports.genKeyPair = exports.ec = void 0;
22
+ exports.verify = exports.sign = exports.getKeyPairFromPublicKey = exports.getStarkKey = exports.getKeyPair = exports.genKeyPair = exports.ec = void 0;
7
23
  var elliptic_1 = require("elliptic");
8
24
  var hash_js_1 = __importDefault(require("hash.js"));
9
25
  var minimalistic_assert_1 = __importDefault(require("minimalistic-assert"));
@@ -50,6 +66,17 @@ function getStarkKey(keyPair) {
50
66
  return (0, encode_1.addHexPrefix)((0, encode_1.sanitizeBytes)(keyPair.pub.getX().toString(16), 2));
51
67
  }
52
68
  exports.getStarkKey = getStarkKey;
69
+ /**
70
+ * Takes a public key and casts it into `elliptic` KeyPair format.
71
+ *
72
+ * @param publicKey - public key which should get casted to a KeyPair
73
+ * @returns keyPair with public key only, which can be used to verify signatures, but cant sign anything
74
+ */
75
+ function getKeyPairFromPublicKey(publicKey) {
76
+ var publicKeyBn = (0, number_1.toBN)(publicKey);
77
+ return exports.ec.keyFromPublic((0, encode_1.removeHexPrefix)((0, number_1.toHex)(publicKeyBn)), 'hex');
78
+ }
79
+ exports.getKeyPairFromPublicKey = getKeyPairFromPublicKey;
53
80
  /*
54
81
  Signs a message using the provided key.
55
82
  key should be an KeyPair with a valid private key.
@@ -66,9 +93,14 @@ function sign(keyPair, msgHash) {
66
93
  (0, number_1.assertInRange)(r, constants_1.ONE, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.MAX_ECDSA_VAL)), 'r');
67
94
  (0, number_1.assertInRange)(s, constants_1.ONE, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.EC_ORDER)), 's');
68
95
  (0, number_1.assertInRange)(w, constants_1.ONE, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.MAX_ECDSA_VAL)), 'w');
69
- return msgSignature;
96
+ return [r, s];
70
97
  }
71
98
  exports.sign = sign;
99
+ function chunkArray(arr, n) {
100
+ return Array(Math.ceil(arr.length / n))
101
+ .fill('')
102
+ .map(function (_, i) { return arr.slice(i * n, i * n + n); });
103
+ }
72
104
  /*
73
105
  Verifies a message using the provided key.
74
106
  key should be an KeyPair with a valid public key.
@@ -76,14 +108,21 @@ exports.sign = sign;
76
108
  Returns a boolean true if the verification succeeds.
77
109
  */
78
110
  function verify(keyPair, msgHash, sig) {
111
+ var keyPairArray = Array.isArray(keyPair) ? keyPair : [keyPair];
79
112
  var msgHashBN = (0, number_1.toBN)((0, encode_1.addHexPrefix)(msgHash));
113
+ (0, minimalistic_assert_1.default)(sig.length % 2 === 0, 'Signature must be an array of length dividable by 2');
80
114
  (0, number_1.assertInRange)(msgHashBN, constants_1.ZERO, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.MAX_ECDSA_VAL)), 'msgHash');
81
- var r = sig.r, s = sig.s;
82
- var w = s.invm(exports.ec.n);
83
- // Verify signature has valid length.
84
- (0, number_1.assertInRange)(r, constants_1.ONE, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.MAX_ECDSA_VAL)), 'r');
85
- (0, number_1.assertInRange)(s, constants_1.ONE, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.EC_ORDER)), 's');
86
- (0, number_1.assertInRange)(w, constants_1.ONE, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.MAX_ECDSA_VAL)), 'w');
87
- return keyPair.verify(fixMessage(msgHash), sig);
115
+ (0, minimalistic_assert_1.default)(keyPairArray.length === sig.length / 2, 'Signature and keyPair length must be equal');
116
+ return chunkArray(sig, 2).every(function (_a, i) {
117
+ var _b;
118
+ var _c = __read(_a, 2), r = _c[0], s = _c[1];
119
+ var rBN = (0, number_1.toBN)(r);
120
+ var sBN = (0, number_1.toBN)(s);
121
+ var w = sBN.invm(exports.ec.n);
122
+ (0, number_1.assertInRange)(rBN, constants_1.ONE, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.MAX_ECDSA_VAL)), 'r');
123
+ (0, number_1.assertInRange)(sBN, constants_1.ONE, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.EC_ORDER)), 's');
124
+ (0, number_1.assertInRange)(w, constants_1.ONE, (0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.MAX_ECDSA_VAL)), 'w');
125
+ return (_b = exports.ec.verify(fixMessage(msgHash), { r: rBN, s: sBN }, keyPairArray[i])) !== null && _b !== void 0 ? _b : false;
126
+ });
88
127
  }
89
128
  exports.verify = verify;
@@ -1,5 +1,4 @@
1
- import { CompressedProgram, Program } from '../types';
2
- import { BigNumberish } from './number';
1
+ import { CompressedProgram, Program, Signature } from '../types';
3
2
  /**
4
3
  * Function to compress compiled cairo program
5
4
  *
@@ -18,4 +17,4 @@ export declare function compressProgram(jsonProgram: Program | string): Compress
18
17
  export declare function getSelectorFromName(funcName: string): string;
19
18
  export declare function randomAddress(): string;
20
19
  export declare function makeAddress(input: string): string;
21
- export declare function formatSignature(sig?: [BigNumberish, BigNumberish]): [string, string] | [];
20
+ export declare function formatSignature(sig?: Signature): string[];
@@ -0,0 +1,91 @@
1
+ import { BigNumberish } from '../number';
2
+ import { TypedData } from './types';
3
+ export * from './types';
4
+ /**
5
+ * Get the dependencies of a struct type. If a struct has the same dependency multiple times, it's only included once
6
+ * in the resulting array.
7
+ *
8
+ * @param {TypedData} typedData
9
+ * @param {string} type
10
+ * @param {string[]} [dependencies]
11
+ * @return {string[]}
12
+ */
13
+ export declare const getDependencies: (typedData: TypedData, type: string, dependencies?: string[]) => string[];
14
+ /**
15
+ * Encode a type to a string. All dependant types are alphabetically sorted.
16
+ *
17
+ * @param {TypedData} typedData
18
+ * @param {string} type
19
+ * @return {string}
20
+ */
21
+ export declare const encodeType: (typedData: TypedData, type: string) => string;
22
+ /**
23
+ * Get a type string as hash.
24
+ *
25
+ * @param {TypedData} typedData
26
+ * @param {string} type
27
+ * @return {string}
28
+ */
29
+ export declare const getTypeHash: (typedData: TypedData, type: string) => string;
30
+ /**
31
+ * Encode the data to an ABI encoded Buffer. The data should be a key -> value object with all the required values. All
32
+ * dependant types are automatically encoded.
33
+ *
34
+ * @param {TypedData} typedData
35
+ * @param {string} type
36
+ * @param {Record<string, any>} data
37
+ */
38
+ export declare const encodeData: <T extends {
39
+ types: {
40
+ StarkNetDomain: {
41
+ type: string;
42
+ name: string;
43
+ }[];
44
+ } & Record<string, {
45
+ type: string;
46
+ name: string;
47
+ }[]>;
48
+ primaryType: string;
49
+ domain: {
50
+ name?: string | undefined;
51
+ version?: string | undefined;
52
+ chainId?: string | number | undefined;
53
+ };
54
+ message: Record<string, unknown>;
55
+ }>(typedData: T, type: string, data: T["message"]) => string[][];
56
+ /**
57
+ * Get encoded data as a hash. The data should be a key -> value object with all the required values. All dependant
58
+ * types are automatically encoded.
59
+ *
60
+ * @param {TypedData} typedData
61
+ * @param {string} type
62
+ * @param {Record<string, any>} data
63
+ * @return {Buffer}
64
+ */
65
+ export declare const getStructHash: <T extends {
66
+ types: {
67
+ StarkNetDomain: {
68
+ type: string;
69
+ name: string;
70
+ }[];
71
+ } & Record<string, {
72
+ type: string;
73
+ name: string;
74
+ }[]>;
75
+ primaryType: string;
76
+ domain: {
77
+ name?: string | undefined;
78
+ version?: string | undefined;
79
+ chainId?: string | number | undefined;
80
+ };
81
+ message: Record<string, unknown>;
82
+ }>(typedData: T, type: string, data: T["message"]) => string;
83
+ /**
84
+ * Get the EIP-191 encoded message to sign, from the typedData object. If `hash` is enabled, the message will be hashed
85
+ * with Keccak256.
86
+ *
87
+ * @param {TypedData} typedData
88
+ * @param {boolean} hash
89
+ * @return {string}
90
+ */
91
+ export declare const getMessageHash: (typedData: TypedData, account: BigNumberish) => string;