starknet 4.3.1 → 4.4.2

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 (46) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/__mocks__/typedDataSessionExample.json +42 -0
  3. package/__tests__/rpcProvider.test.ts +29 -2
  4. package/__tests__/utils/__snapshots__/ellipticalCurve.test.ts.snap +2 -0
  5. package/__tests__/utils/ellipticalCurve.test.ts +5 -0
  6. package/__tests__/utils/merkle.test.ts +146 -0
  7. package/__tests__/utils/typedData.test.ts +107 -9
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +2 -1
  10. package/dist/provider/rpc.js +3 -3
  11. package/dist/signer/default.d.ts +1 -1
  12. package/dist/signer/default.js +1 -0
  13. package/dist/utils/hash.js +8 -6
  14. package/dist/utils/merkle.d.ts +10 -0
  15. package/dist/utils/merkle.js +90 -0
  16. package/dist/utils/number.d.ts +1 -0
  17. package/dist/utils/number.js +6 -2
  18. package/dist/utils/typedData/index.d.ts +23 -8
  19. package/dist/utils/typedData/index.js +70 -31
  20. package/dist/utils/typedData/types.d.ts +8 -3
  21. package/index.d.ts +1 -0
  22. package/index.js +2 -1
  23. package/package.json +1 -1
  24. package/provider/rpc.js +3 -3
  25. package/signer/default.d.ts +1 -1
  26. package/signer/default.js +1 -0
  27. package/src/index.ts +1 -0
  28. package/src/provider/rpc.ts +9 -4
  29. package/src/signer/default.ts +2 -2
  30. package/src/utils/hash.ts +8 -6
  31. package/src/utils/merkle.ts +70 -0
  32. package/src/utils/number.ts +5 -1
  33. package/src/utils/typedData/index.ts +88 -34
  34. package/src/utils/typedData/types.ts +12 -4
  35. package/utils/hash.js +8 -6
  36. package/utils/merkle.d.ts +10 -0
  37. package/utils/merkle.js +90 -0
  38. package/utils/number.d.ts +1 -0
  39. package/utils/number.js +6 -2
  40. package/utils/typedData/index.d.ts +23 -8
  41. package/utils/typedData/index.js +70 -31
  42. package/utils/typedData/types.d.ts +8 -3
  43. package/www/docs/API/utils.md +6 -0
  44. package/www/guides/account.md +8 -8
  45. package/www/guides/erc20.md +4 -5
  46. package/www/package-lock.json +4731 -6611
package/CHANGELOG.md CHANGED
@@ -1,3 +1,35 @@
1
+ ## [4.4.2](https://github.com/0xs34n/starknet.js/compare/v4.4.1...v4.4.2) (2022-09-07)
2
+
3
+ ### Bug Fixes
4
+
5
+ - dont import fetch from crosshatch ([a3ef41c](https://github.com/0xs34n/starknet.js/commit/a3ef41cac0e818f7429e6dd7654722ede1dc3796))
6
+ - use custom fetch ponyfill ([78f904a](https://github.com/0xs34n/starknet.js/commit/78f904a1d5aeb5efaba7fbdd853802529c80594b))
7
+ - use isomorphic-unfetch ([c63b6a1](https://github.com/0xs34n/starknet.js/commit/c63b6a138616936cf7a70f9098af5df290983c74))
8
+
9
+ ## [4.4.1](https://github.com/0xs34n/starknet.js/compare/v4.4.0...v4.4.1) (2022-09-01)
10
+
11
+ ### Bug Fixes
12
+
13
+ - supply calldata as hexadecimal string array ([44cb4c5](https://github.com/0xs34n/starknet.js/commit/44cb4c5f108a2ea8fcd77147f053e068189d4f33))
14
+
15
+ # [4.4.0](https://github.com/0xs34n/starknet.js/compare/v4.3.1...v4.4.0) (2022-09-01)
16
+
17
+ ### Bug Fixes
18
+
19
+ - delete premature session account file ([ca3e70b](https://github.com/0xs34n/starknet.js/commit/ca3e70b06d21dba8b2074512251cf232ed8be46b))
20
+ - session ([00269bf](https://github.com/0xs34n/starknet.js/commit/00269bfd23ed647270a1efd699af7c36978965c7))
21
+ - session account prooving ([0b56833](https://github.com/0xs34n/starknet.js/commit/0b56833f6eb7557d55725a505a01185bbc9756db))
22
+ - tests ([4586e93](https://github.com/0xs34n/starknet.js/commit/4586e93f10a2a43c375a23d851a9778bab412fcc))
23
+ - typo ([1c60a4d](https://github.com/0xs34n/starknet.js/commit/1c60a4d4b306879422769a6c2afc4fd6c39c4c07))
24
+
25
+ ### Features
26
+
27
+ - add merkle trees ([e9b8674](https://github.com/0xs34n/starknet.js/commit/e9b8674f51c6d6fe57772a4c88b162c5132cfbdd))
28
+ - add visibility modifiers ([cd1a23d](https://github.com/0xs34n/starknet.js/commit/cd1a23d74b49407c27314a12d5bc149ed40209f3))
29
+ - allow merkle trees as native type in eip712 like messages ([65b7766](https://github.com/0xs34n/starknet.js/commit/65b7766c29eca4f4d0e89f6ad1368fedd5e0e18e))
30
+ - session ([9ac48cc](https://github.com/0xs34n/starknet.js/commit/9ac48cc15c1c7b0e504adfc79a7f382f5d0b55d0))
31
+ - session needs to be aware of the whole tree ([11e10bd](https://github.com/0xs34n/starknet.js/commit/11e10bda0f020a670854d941a54142d55936fc18))
32
+
1
33
  ## [4.3.1](https://github.com/0xs34n/starknet.js/compare/v4.3.0...v4.3.1) (2022-08-31)
2
34
 
3
35
  ### Bug Fixes
@@ -0,0 +1,42 @@
1
+ {
2
+ "primaryType": "Session",
3
+ "types": {
4
+ "Policy": [
5
+ { "name": "contractAddress", "type": "felt" },
6
+ { "name": "selector", "type": "selector" }
7
+ ],
8
+ "Session": [
9
+ { "name": "key", "type": "felt" },
10
+ { "name": "expires", "type": "felt" },
11
+ { "name": "root", "type": "merkletree", "contains": "Policy" }
12
+ ],
13
+ "StarkNetDomain": [
14
+ { "name": "name", "type": "felt" },
15
+ { "name": "version", "type": "felt" },
16
+ { "name": "chain_id", "type": "felt" }
17
+ ]
18
+ },
19
+ "domain": {
20
+ "name": "StarkNet Mail",
21
+ "version": "1",
22
+ "chain_id": 1
23
+ },
24
+ "message": {
25
+ "key": "0x0000000000000000000000000000000000000000000000000000000000000000",
26
+ "expires": "0x0000000000000000000000000000000000000000000000000000000000000000",
27
+ "root": [
28
+ {
29
+ "contractAddress": "0x1",
30
+ "selector": "transfer"
31
+ },
32
+ {
33
+ "contractAddress": "0x2",
34
+ "selector": "transfer"
35
+ },
36
+ {
37
+ "contractAddress": "0x3",
38
+ "selector": "transfer"
39
+ }
40
+ ]
41
+ }
42
+ }
@@ -1,11 +1,23 @@
1
- import { RpcProvider } from '../src';
2
- import { describeIfRpc, getTestProvider } from './fixtures';
1
+ import { Account, RpcProvider, ec } from '../src';
2
+ import {
3
+ compiledOpenZeppelinAccount,
4
+ describeIfRpc,
5
+ getTestAccount,
6
+ getTestProvider,
7
+ } from './fixtures';
3
8
 
4
9
  describeIfRpc('RPCProvider', () => {
5
10
  let rpcProvider: RpcProvider;
11
+ let accountPublicKey: string;
6
12
 
7
13
  beforeAll(async () => {
8
14
  rpcProvider = getTestProvider() as RpcProvider;
15
+ const account = getTestAccount(rpcProvider);
16
+
17
+ expect(account).toBeInstanceOf(Account);
18
+
19
+ const accountKeyPair = ec.genKeyPair();
20
+ accountPublicKey = ec.getStarkKey(accountKeyPair);
9
21
  });
10
22
 
11
23
  describe('RPC methods', () => {
@@ -13,5 +25,20 @@ describeIfRpc('RPCProvider', () => {
13
25
  const chainId = await rpcProvider.getChainId();
14
26
  expect(chainId).toBe('0x534e5f474f45524c49');
15
27
  });
28
+
29
+ test('deployContract', async () => {
30
+ const { contract_address, transaction_hash } = await rpcProvider.deployContract({
31
+ contract: compiledOpenZeppelinAccount,
32
+ constructorCalldata: [accountPublicKey],
33
+ addressSalt: accountPublicKey,
34
+ });
35
+ await rpcProvider.waitForTransaction(transaction_hash);
36
+ expect(contract_address).toBeTruthy();
37
+ expect(transaction_hash).toBeTruthy();
38
+ });
39
+
40
+ test.todo('getEstimateFee');
41
+
42
+ test.todo('invokeFunction');
16
43
  });
17
44
  });
@@ -1,3 +1,5 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`pedersen() 1`] = `"0x5ed2703dfdb505c587700ce2ebfcab5b3515cd7e6114817e6026ec9d4b364ca"`;
4
+
5
+ exports[`pedersen() with 0 1`] = `"0x1a5c561f97b52c17a19f34c4499a745cd4e8412e29e4ed5e91e4481c7d53935"`;
@@ -25,6 +25,11 @@ test('pedersen()', () => {
25
25
  expect(own).toMatchSnapshot();
26
26
  });
27
27
 
28
+ test('pedersen() with 0', () => {
29
+ const own = pedersen(['0x12773', '0x0']);
30
+ expect(own).toMatchSnapshot();
31
+ });
32
+
28
33
  test('computeHashOnElements()', () => {
29
34
  const array = ['1', '2', '3', '4'];
30
35
  expect(computeHashOnElements(array)).toBe(
@@ -0,0 +1,146 @@
1
+ import { MerkleTree, proofMerklePath } from '../../src/utils/merkle';
2
+
3
+ describe('MerkleTree class', () => {
4
+ describe('generate roots', () => {
5
+ test('should generate valid root for 1 elements', async () => {
6
+ const leaves = ['0x1'];
7
+ const tree = new MerkleTree(leaves);
8
+
9
+ const manualMerkle = leaves[0];
10
+
11
+ expect(tree.root).toBe(manualMerkle);
12
+ });
13
+ test('should generate valid root for 2 elements', async () => {
14
+ const leaves = ['0x1', '0x2'];
15
+ const tree = new MerkleTree(leaves);
16
+
17
+ const manualMerkle = MerkleTree.hash(leaves[0], leaves[1]);
18
+
19
+ expect(tree.root).toBe(manualMerkle);
20
+ });
21
+ test('should generate valid root for 4 elements', async () => {
22
+ const leaves = ['0x1', '0x2', '0x3', '0x4'];
23
+ const tree = new MerkleTree(leaves);
24
+
25
+ const manualMerkle = MerkleTree.hash(
26
+ MerkleTree.hash(leaves[0], leaves[1]),
27
+ MerkleTree.hash(leaves[2], leaves[3])
28
+ );
29
+
30
+ expect(tree.root).toBe(manualMerkle);
31
+ });
32
+ test('should generate valid root for 6 elements', async () => {
33
+ const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6'];
34
+ const tree = new MerkleTree(leaves);
35
+
36
+ const manualMerkle = MerkleTree.hash(
37
+ MerkleTree.hash(
38
+ MerkleTree.hash(leaves[0], leaves[1]),
39
+ MerkleTree.hash(leaves[2], leaves[3])
40
+ ),
41
+ MerkleTree.hash(leaves[4], leaves[5])
42
+ );
43
+
44
+ expect(tree.root).toBe(manualMerkle);
45
+ });
46
+ test('should generate valid root for 7 elements', async () => {
47
+ const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7'];
48
+ const tree = new MerkleTree(leaves);
49
+
50
+ const manualMerkle = MerkleTree.hash(
51
+ MerkleTree.hash(
52
+ MerkleTree.hash(leaves[0], leaves[1]),
53
+ MerkleTree.hash(leaves[2], leaves[3])
54
+ ),
55
+ MerkleTree.hash(MerkleTree.hash(leaves[4], leaves[5]), leaves[6])
56
+ );
57
+
58
+ expect(tree.root).toBe(manualMerkle);
59
+ });
60
+ });
61
+ describe('generate proofs', () => {
62
+ let tree: MerkleTree;
63
+ beforeAll(() => {
64
+ const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7'];
65
+ tree = new MerkleTree(leaves);
66
+ });
67
+ test('should return proof path for valid child', async () => {
68
+ const proof = tree.getProof('0x3');
69
+
70
+ const manualProof = [
71
+ '0x4',
72
+ MerkleTree.hash('0x1', '0x2'),
73
+ MerkleTree.hash(MerkleTree.hash('0x5', '0x6'), '0x7'),
74
+ ];
75
+
76
+ expect(proof).toEqual(manualProof);
77
+ });
78
+ test('should return proof path for valid child', async () => {
79
+ const proof = tree.getProof('0x7');
80
+
81
+ const manualProof = [
82
+ '0x0', // proofs should always be as long as the tree is deep
83
+ MerkleTree.hash('0x5', '0x6'),
84
+ MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
85
+ ];
86
+
87
+ expect(proof).toEqual(manualProof);
88
+ });
89
+ test('should throw for invalid child', () => {
90
+ expect(() => tree.getProof('0x8')).toThrow('leaf not found');
91
+ });
92
+ });
93
+ describe('verify proofs', () => {
94
+ let tree: MerkleTree;
95
+ beforeAll(() => {
96
+ const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7'];
97
+ tree = new MerkleTree(leaves);
98
+ });
99
+
100
+ test('should return true for valid manual proof', async () => {
101
+ const manualProof = [
102
+ MerkleTree.hash('0x5', '0x6'),
103
+ MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
104
+ ];
105
+ const leaf = '0x7';
106
+ const { root } = tree;
107
+
108
+ expect(proofMerklePath(root, leaf, manualProof)).toBe(true);
109
+ });
110
+ test('should return true for valid proof', async () => {
111
+ const proof = tree.getProof('0x3');
112
+ const leaf = '0x3';
113
+ const { root } = tree;
114
+
115
+ expect(proofMerklePath(root, leaf, proof)).toBe(true);
116
+ });
117
+ test('should return false for invalid proof (root)', async () => {
118
+ const proof = tree.getProof('0x3');
119
+ const leaf = '0x3';
120
+ const root = '0x4';
121
+
122
+ expect(proofMerklePath(root, leaf, proof)).toBe(false);
123
+ });
124
+ test('should return false for invalid proof (proof[0])', async () => {
125
+ const proof = tree.getProof('0x3');
126
+ const leaf = '0x3';
127
+ const { root } = tree;
128
+ proof[0] = '0x7';
129
+ expect(proofMerklePath(root, leaf, proof)).toBe(false);
130
+ });
131
+ test('should return false for invalid proof (proof[1])', async () => {
132
+ const proof = tree.getProof('0x3');
133
+ const leaf = '0x3';
134
+ const { root } = tree;
135
+ proof[1] = '0x4';
136
+ expect(proofMerklePath(root, leaf, proof)).toBe(false);
137
+ });
138
+ test('should return false for invalid proof (proof[2])', async () => {
139
+ const proof = tree.getProof('0x3');
140
+ const leaf = '0x3';
141
+ const { root } = tree;
142
+ proof[2] = '0x4';
143
+ expect(proofMerklePath(root, leaf, proof)).toBe(false);
144
+ });
145
+ });
146
+ });
@@ -1,46 +1,134 @@
1
1
  import typedDataExample from '../../__mocks__/typedDataExample.json';
2
+ import typedDataSessionExample from '../../__mocks__/typedDataSessionExample.json';
2
3
  import typedDataStructArrayExample from '../../__mocks__/typedDataStructArrayExample.json';
3
4
  import { number } from '../../src';
5
+ import { getSelectorFromName } from '../../src/utils/hash';
6
+ import { MerkleTree } from '../../src/utils/merkle';
4
7
  import { BigNumberish } from '../../src/utils/number';
5
- import { encodeType, getMessageHash, getStructHash, getTypeHash } from '../../src/utils/typedData';
8
+ import {
9
+ StarkNetDomain,
10
+ encodeType,
11
+ encodeValue,
12
+ getMessageHash,
13
+ getStructHash,
14
+ getTypeHash,
15
+ } from '../../src/utils/typedData';
6
16
 
7
17
  describe('typedData', () => {
8
18
  test('should get right type encoding', () => {
9
- const typeEncoding = encodeType(typedDataExample, 'Mail');
19
+ const typeEncoding = encodeType(typedDataExample.types, 'Mail');
10
20
  expect(typeEncoding).toMatchInlineSnapshot(
11
21
  `"Mail(from:Person,to:Person,contents:felt)Person(name:felt,wallet:felt)"`
12
22
  );
13
- const typeEncodingStructArr = encodeType(typedDataStructArrayExample, 'Mail');
23
+ const typeEncodingStructArr = encodeType(typedDataStructArrayExample.types, 'Mail');
14
24
  expect(typeEncodingStructArr).toMatchInlineSnapshot(
15
25
  `"Mail(from:Person,to:Person,posts_len:felt,posts:Post*)Person(name:felt,wallet:felt)Post(title:felt,content:felt)"`
16
26
  );
17
27
  });
18
28
 
19
29
  test('should get right type hash', () => {
20
- const typeHashDomain = getTypeHash(typedDataExample, 'StarkNetDomain');
30
+ const typeHashDomain = getTypeHash(typedDataExample.types, 'StarkNetDomain');
21
31
  expect(typeHashDomain).toMatchInlineSnapshot(
22
32
  `"0x1bfc207425a47a5dfa1a50a4f5241203f50624ca5fdf5e18755765416b8e288"`
23
33
  );
24
- const typeHashPerson = getTypeHash(typedDataExample, 'Person');
34
+ const typeHashPerson = getTypeHash(typedDataExample.types, 'Person');
25
35
  expect(typeHashPerson).toMatchInlineSnapshot(
26
36
  `"0x2896dbe4b96a67110f454c01e5336edc5bbc3635537efd690f122f4809cc855"`
27
37
  );
28
- const typeHashMail = getTypeHash(typedDataExample, 'Mail');
38
+ const typeHashMail = getTypeHash(typedDataExample.types, 'Mail');
29
39
  expect(typeHashMail).toMatchInlineSnapshot(
30
40
  `"0x13d89452df9512bf750f539ba3001b945576243288137ddb6c788457d4b2f79"`
31
41
  );
32
- const typeHashPost = getTypeHash(typedDataStructArrayExample, 'Post');
42
+ const typeHashPost = getTypeHash(typedDataStructArrayExample.types, 'Post');
33
43
  expect(typeHashPost).toMatchInlineSnapshot(
34
44
  `"0x1d71e69bf476486b43cdcfaf5a85c00bb2d954c042b281040e513080388356d"`
35
45
  );
36
- const typeHashMailWithStructArray = getTypeHash(typedDataStructArrayExample, 'Mail');
46
+ const typeHashMailWithStructArray = getTypeHash(typedDataStructArrayExample.types, 'Mail');
37
47
  expect(typeHashMailWithStructArray).toMatchInlineSnapshot(
38
48
  `"0x873b878e35e258fc99e3085d5aaad3a81a0c821f189c08b30def2cde55ff27"`
39
49
  );
50
+ const selectorTypeHash = getTypeHash({}, 'selector');
51
+ expect(selectorTypeHash).toMatchInlineSnapshot(
52
+ `"0x1d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"`
53
+ );
54
+ });
55
+
56
+ test('should transform type selector', () => {
57
+ const selector = 'transfer';
58
+ const selectorHash = getSelectorFromName(selector);
59
+ const rawSelectorValueHash = encodeValue({}, 'felt', selectorHash);
60
+ const selectorValueHash = encodeValue({}, 'selector', selector);
61
+ expect(selectorValueHash).toEqual(rawSelectorValueHash);
62
+ expect(selectorValueHash).toMatchInlineSnapshot(`
63
+ Array [
64
+ "felt",
65
+ "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e",
66
+ ]
67
+ `);
68
+ });
69
+
70
+ test('should transform merkle tree', () => {
71
+ const tree = new MerkleTree(['0x1', '0x2', '0x3']);
72
+ const [, merkleTreeHash] = encodeValue({}, 'merkletree', tree.leaves);
73
+ expect(merkleTreeHash).toBe(tree.root);
74
+ expect(merkleTreeHash).toMatchInlineSnapshot(
75
+ `"0x551b4adb6c35d49c686a00b9192da9332b18c9b262507cad0ece37f3b6918d2"`
76
+ );
77
+ });
78
+
79
+ test('should transform merkle tree with custom types', () => {
80
+ const leaves = [
81
+ {
82
+ contractAddress: '0x1',
83
+ selector: 'transfer',
84
+ },
85
+ {
86
+ contractAddress: '0x2',
87
+ selector: 'transfer',
88
+ },
89
+ {
90
+ contractAddress: '0x3',
91
+ selector: 'transfer',
92
+ },
93
+ ];
94
+ const hashedLeaves = leaves.map(
95
+ (leaf) =>
96
+ encodeValue(
97
+ {
98
+ Policy: [
99
+ { name: 'contractAddress', type: 'felt' },
100
+ { name: 'selector', type: 'selector' },
101
+ ],
102
+ },
103
+ 'Policy',
104
+ leaf
105
+ )[1]
106
+ );
107
+ const tree = new MerkleTree(hashedLeaves);
108
+ const [, merkleTreeHash] = encodeValue(
109
+ {
110
+ Parent: [{ name: 'root', type: 'merkletree', contains: 'Policy' }],
111
+ Policy: [
112
+ { name: 'contractAddress', type: 'felt' },
113
+ { name: 'selector', type: 'selector' },
114
+ ],
115
+ },
116
+ 'merkletree',
117
+ leaves,
118
+ { key: 'root', parent: 'Parent' }
119
+ );
120
+ expect(merkleTreeHash).toBe(tree.root);
121
+ expect(merkleTreeHash).toMatchInlineSnapshot(
122
+ `"0x75c4f467f4527a5348f3e302007228a6b0057fc4c015f981ffb5b3ace475727"`
123
+ );
40
124
  });
41
125
 
42
126
  test('should get right hash for StarkNetDomain', () => {
43
- const hash = getStructHash(typedDataExample, 'StarkNetDomain', typedDataExample.domain as any);
127
+ const hash = getStructHash(
128
+ typedDataExample.types,
129
+ 'StarkNetDomain',
130
+ typedDataExample.domain as StarkNetDomain
131
+ );
44
132
  expect(hash).toMatchInlineSnapshot(
45
133
  `"0x54833b121883a3e3aebff48ec08a962f5742e5f7b973469c1f8f4f55d470b07"`
46
134
  );
@@ -122,4 +210,14 @@ describe('typedData', () => {
122
210
  `"0x70338fb11b8f70b68b261de8a322bcb004bd85e88ac47d9147982c7f5ac66fd"`
123
211
  );
124
212
  });
213
+
214
+ test('should transform session message correctly', () => {
215
+ const hash = getMessageHash(
216
+ typedDataSessionExample,
217
+ '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
218
+ );
219
+ expect(hash).toMatchInlineSnapshot(
220
+ `"0x1ad0330a62a4a94eae5ea1a7ad96388179d2e4d33e6f909d17421d315110653"`
221
+ );
222
+ });
125
223
  });
package/dist/index.d.ts CHANGED
@@ -16,6 +16,7 @@ export * as json from './utils/json';
16
16
  export * as number from './utils/number';
17
17
  export * as transaction from './utils/transaction';
18
18
  export * as stark from './utils/stark';
19
+ export * as merkle from './utils/merkle';
19
20
  export * as ec from './utils/ellipticCurve';
20
21
  export * as uint256 from './utils/uint256';
21
22
  export * as shortString from './utils/shortString';
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
26
26
  return result;
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.typedData = exports.shortString = exports.uint256 = exports.ec = exports.stark = exports.transaction = exports.number = exports.json = exports.hash = exports.encode = exports.constants = void 0;
29
+ exports.typedData = exports.shortString = exports.uint256 = exports.ec = exports.merkle = exports.stark = exports.transaction = exports.number = exports.json = exports.hash = exports.encode = exports.constants = void 0;
30
30
  /**
31
31
  * Main
32
32
  */
@@ -45,6 +45,7 @@ exports.json = __importStar(require("./utils/json"));
45
45
  exports.number = __importStar(require("./utils/number"));
46
46
  exports.transaction = __importStar(require("./utils/transaction"));
47
47
  exports.stark = __importStar(require("./utils/stark"));
48
+ exports.merkle = __importStar(require("./utils/merkle"));
48
49
  exports.ec = __importStar(require("./utils/ellipticCurve"));
49
50
  exports.uint256 = __importStar(require("./utils/uint256"));
50
51
  exports.shortString = __importStar(require("./utils/shortString"));
@@ -217,7 +217,7 @@ var RpcProvider = /** @class */ (function () {
217
217
  contract_address: invocation.contractAddress,
218
218
  entry_point_selector: (0, hash_1.getSelectorFromName)(invocation.entrypoint),
219
219
  calldata: (0, provider_1.parseCalldata)(invocation.calldata),
220
- signature: (0, number_1.bigNumberishArrayToDecimalStringArray)(invocation.signature || []),
220
+ signature: (0, number_1.bigNumberishArrayToHexadecimalStringArray)(invocation.signature || []),
221
221
  version: (0, number_1.toHex)((0, number_1.toBN)((invocationDetails === null || invocationDetails === void 0 ? void 0 : invocationDetails.version) || 0)),
222
222
  },
223
223
  blockIdentifier,
@@ -249,7 +249,7 @@ var RpcProvider = /** @class */ (function () {
249
249
  contractDefinition = (0, provider_1.parseContract)(contract);
250
250
  return [2 /*return*/, this.fetchEndpoint('starknet_addDeployTransaction', [
251
251
  addressSalt !== null && addressSalt !== void 0 ? addressSalt : (0, stark_1.randomAddress)(),
252
- (0, number_1.bigNumberishArrayToDecimalStringArray)(constructorCalldata !== null && constructorCalldata !== void 0 ? constructorCalldata : []),
252
+ (0, number_1.bigNumberishArrayToHexadecimalStringArray)(constructorCalldata !== null && constructorCalldata !== void 0 ? constructorCalldata : []),
253
253
  {
254
254
  program: contractDefinition.program,
255
255
  entry_points_by_type: contractDefinition.entry_points_by_type,
@@ -267,7 +267,7 @@ var RpcProvider = /** @class */ (function () {
267
267
  entry_point_selector: (0, hash_1.getSelectorFromName)(functionInvocation.entrypoint),
268
268
  calldata: (0, provider_1.parseCalldata)(functionInvocation.calldata),
269
269
  },
270
- (0, number_1.bigNumberishArrayToDecimalStringArray)(functionInvocation.signature || []),
270
+ (0, number_1.bigNumberishArrayToHexadecimalStringArray)(functionInvocation.signature || []),
271
271
  (0, number_1.toHex)((0, number_1.toBN)(details.maxFee || 0)),
272
272
  (0, number_1.toHex)((0, number_1.toBN)(details.version || 0)),
273
273
  ]).then(this.responseParser.parseInvokeFunctionResponse)];
@@ -3,7 +3,7 @@ import { TypedData } from '../utils/typedData';
3
3
  import { SignerInterface } from './interface';
4
4
  export declare class Signer implements SignerInterface {
5
5
  protected keyPair: KeyPair;
6
- constructor(keyPair: KeyPair);
6
+ constructor(keyPair?: KeyPair);
7
7
  getPubKey(): Promise<string>;
8
8
  signTransaction(transactions: Invocation[], transactionsDetail: InvocationsSignerDetails, abis?: Abi[]): Promise<Signature>;
9
9
  signMessage(typedData: TypedData, accountAddress: string): Promise<Signature>;
@@ -43,6 +43,7 @@ var transaction_1 = require("../utils/transaction");
43
43
  var typedData_1 = require("../utils/typedData");
44
44
  var Signer = /** @class */ (function () {
45
45
  function Signer(keyPair) {
46
+ if (keyPair === void 0) { keyPair = (0, ellipticCurve_1.genKeyPair)(); }
46
47
  this.keyPair = keyPair;
47
48
  }
48
49
  Signer.prototype.getPubKey = function () {
@@ -78,13 +78,15 @@ function pedersen(input) {
78
78
  for (var i = 0; i < input.length; i += 1) {
79
79
  var x = (0, number_1.toBN)(input[i]);
80
80
  (0, minimalistic_assert_1.default)(x.gte(constants_1.ZERO) && x.lt((0, number_1.toBN)((0, encode_1.addHexPrefix)(constants_1.FIELD_PRIME))), "Invalid input: ".concat(input[i]));
81
- for (var j = 0; j < 252; j += 1) {
82
- var pt = constantPoints[2 + i * 252 + j];
83
- (0, minimalistic_assert_1.default)(!point.getX().eq(pt.getX()));
84
- if (x.and(constants_1.ONE).toNumber() !== 0) {
85
- point = point.add(pt);
81
+ if (!x.isZero()) {
82
+ for (var j = 0; j < 252; j += 1) {
83
+ var pt = constantPoints[2 + i * 252 + j];
84
+ (0, minimalistic_assert_1.default)(!point.getX().eq(pt.getX()));
85
+ if (x.and(constants_1.ONE).toNumber() !== 0) {
86
+ point = point.add(pt);
87
+ }
88
+ x = x.shrn(1);
86
89
  }
87
- x = x.shrn(1);
88
90
  }
89
91
  }
90
92
  return (0, encode_1.addHexPrefix)(point.getX().toString(16));
@@ -0,0 +1,10 @@
1
+ export declare class MerkleTree {
2
+ leaves: string[];
3
+ branches: string[][];
4
+ root: string;
5
+ constructor(leafHashes: string[]);
6
+ private build;
7
+ static hash(a: string, b: string): string;
8
+ getProof(leaf: string, branch?: string[], hashPath?: string[]): string[];
9
+ }
10
+ export declare function proofMerklePath(root: string, leaf: string, path: string[]): boolean;
@@ -0,0 +1,90 @@
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
+ };
18
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
20
+ if (ar || !(i in from)) {
21
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
22
+ ar[i] = from[i];
23
+ }
24
+ }
25
+ return to.concat(ar || Array.prototype.slice.call(from));
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.proofMerklePath = exports.MerkleTree = void 0;
29
+ var hash_1 = require("./hash");
30
+ var MerkleTree = /** @class */ (function () {
31
+ function MerkleTree(leafHashes) {
32
+ this.branches = [];
33
+ this.leaves = leafHashes;
34
+ this.root = this.build(leafHashes);
35
+ }
36
+ MerkleTree.prototype.build = function (leaves) {
37
+ if (leaves.length === 1) {
38
+ return leaves[0];
39
+ }
40
+ if (leaves.length !== this.leaves.length) {
41
+ this.branches.push(leaves);
42
+ }
43
+ var newLeaves = [];
44
+ for (var i = 0; i < leaves.length; i += 2) {
45
+ if (i + 1 === leaves.length) {
46
+ newLeaves.push(leaves[i]);
47
+ }
48
+ else {
49
+ newLeaves.push(MerkleTree.hash(leaves[i], leaves[i + 1]));
50
+ }
51
+ }
52
+ return this.build(newLeaves);
53
+ };
54
+ MerkleTree.hash = function (a, b) {
55
+ var _a = __read([a, b].sort(), 2), aSorted = _a[0], bSorted = _a[1];
56
+ return (0, hash_1.pedersen)([aSorted, bSorted]);
57
+ };
58
+ MerkleTree.prototype.getProof = function (leaf, branch, hashPath) {
59
+ var _a, _b;
60
+ if (branch === void 0) { branch = this.leaves; }
61
+ if (hashPath === void 0) { hashPath = []; }
62
+ var index = branch.indexOf(leaf);
63
+ if (index === -1) {
64
+ throw new Error('leaf not found');
65
+ }
66
+ if (branch.length === 1) {
67
+ return hashPath;
68
+ }
69
+ var isLeft = index % 2 === 0;
70
+ var neededBranch = (_a = (isLeft ? branch[index + 1] : branch[index - 1])) !== null && _a !== void 0 ? _a : '0x0';
71
+ var newHashPath = __spreadArray(__spreadArray([], __read(hashPath), false), [neededBranch], false);
72
+ var currentBranchLevelIndex = this.leaves.length === branch.length
73
+ ? -1
74
+ : this.branches.findIndex(function (b) { return b.length === branch.length; });
75
+ var nextBranch = (_b = this.branches[currentBranchLevelIndex + 1]) !== null && _b !== void 0 ? _b : [this.root];
76
+ return this.getProof(neededBranch === '0x0'
77
+ ? leaf
78
+ : MerkleTree.hash(isLeft ? leaf : neededBranch, isLeft ? neededBranch : leaf), nextBranch, newHashPath);
79
+ };
80
+ return MerkleTree;
81
+ }());
82
+ exports.MerkleTree = MerkleTree;
83
+ function proofMerklePath(root, leaf, path) {
84
+ if (path.length === 0) {
85
+ return root === leaf;
86
+ }
87
+ var _a = __read(path), next = _a[0], rest = _a.slice(1);
88
+ return proofMerklePath(root, MerkleTree.hash(leaf, next), rest);
89
+ }
90
+ exports.proofMerklePath = proofMerklePath;
@@ -7,3 +7,4 @@ export declare function hexToDecimalString(hex: string): string;
7
7
  export declare function toFelt(num: BigNumberish): string;
8
8
  export declare function assertInRange(input: BigNumberish, lowerBound: BigNumberish, upperBound: BigNumberish, inputName?: string): void;
9
9
  export declare function bigNumberishArrayToDecimalStringArray(rawCalldata: BigNumberish[]): string[];
10
+ export declare function bigNumberishArrayToHexadecimalStringArray(rawCalldata: BigNumberish[]): string[];