starknet 4.17.0 → 4.18.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 +20 -0
- package/README.md +2 -10
- package/dist/index.d.ts +27 -9
- package/dist/index.global.js +30 -13
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +30 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +30 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -1
- package/.babelrc +0 -6
- package/.commitlintrc +0 -22
- package/.eslintignore +0 -2
- package/.eslintrc +0 -28
- package/.prettierrc +0 -6
- package/.releaserc +0 -28
- package/CODE_OF_CONDUCT.md +0 -128
- package/CONTRIBUTING.md +0 -52
- package/__mocks__/Account.json +0 -25486
- package/__mocks__/ERC20.json +0 -40027
- package/__mocks__/TestDapp.json +0 -12962
- package/__mocks__/contract.json +0 -33191
- package/__mocks__/l1l2_compiled.json +0 -10107
- package/__mocks__/multicall.json +0 -8139
- package/__mocks__/naming_compiled.json +0 -53283
- package/__mocks__/starknetId_compiled.json +0 -44703
- package/__mocks__/typedDataExample.json +0 -35
- package/__mocks__/typedDataSessionExample.json +0 -42
- package/__mocks__/typedDataStructArrayExample.json +0 -44
- package/__tests__/account.test.ts +0 -345
- package/__tests__/contract.test.ts +0 -249
- package/__tests__/defaultProvider.test.ts +0 -177
- package/__tests__/fixtures.ts +0 -84
- package/__tests__/jest.setup.ts +0 -30
- package/__tests__/rpcProvider.test.ts +0 -132
- package/__tests__/sequencerProvider.test.ts +0 -123
- package/__tests__/utils/__snapshots__/ellipticalCurve.test.ts.snap +0 -5
- package/__tests__/utils/__snapshots__/utils.browser.test.ts.snap +0 -5
- package/__tests__/utils/__snapshots__/utils.test.ts.snap +0 -5
- package/__tests__/utils/address.test.ts +0 -45
- package/__tests__/utils/ellipticalCurve.test.ts +0 -91
- package/__tests__/utils/merkle.test.ts +0 -256
- package/__tests__/utils/shortString.test.ts +0 -22
- package/__tests__/utils/starknetId.test.ts +0 -53
- package/__tests__/utils/transactionHash.test.ts +0 -17
- package/__tests__/utils/typedData.test.ts +0 -223
- package/__tests__/utils/uint256.test.ts +0 -32
- package/__tests__/utils/utils.browser.test.ts +0 -29
- package/__tests__/utils/utils.test.ts +0 -141
- package/img/logo.svg +0 -17
- package/index.d.ts +0 -2683
- package/index.global.js +0 -23192
- package/index.global.js.map +0 -1
- package/index.js +0 -4910
- package/index.js.map +0 -1
- package/index.mjs +0 -4852
- package/index.mjs.map +0 -1
- package/src/account/default.ts +0 -501
- package/src/account/index.ts +0 -2
- package/src/account/interface.ts +0 -309
- package/src/constants.ts +0 -2065
- package/src/contract/contractFactory.ts +0 -88
- package/src/contract/default.ts +0 -425
- package/src/contract/index.ts +0 -3
- package/src/contract/interface.ts +0 -106
- package/src/index.ts +0 -26
- package/src/provider/default.ts +0 -187
- package/src/provider/errors.ts +0 -14
- package/src/provider/index.ts +0 -9
- package/src/provider/interface.ts +0 -281
- package/src/provider/rpc.ts +0 -482
- package/src/provider/sequencer.ts +0 -523
- package/src/provider/utils.ts +0 -100
- package/src/signer/default.ts +0 -99
- package/src/signer/index.ts +0 -2
- package/src/signer/interface.ts +0 -77
- package/src/types/account.ts +0 -43
- package/src/types/api/index.ts +0 -10
- package/src/types/api/openrpc.ts +0 -607
- package/src/types/api/rpc.ts +0 -45
- package/src/types/api/sequencer.ts +0 -369
- package/src/types/contract.ts +0 -5
- package/src/types/index.ts +0 -8
- package/src/types/lib.ts +0 -143
- package/src/types/provider.ts +0 -134
- package/src/types/signer.ts +0 -24
- package/src/utils/address.ts +0 -44
- package/src/utils/calldata.ts +0 -250
- package/src/utils/ellipticCurve.ts +0 -120
- package/src/utils/encode.ts +0 -66
- package/src/utils/events.ts +0 -32
- package/src/utils/fetchPonyfill.ts +0 -5
- package/src/utils/hash.ts +0 -235
- package/src/utils/json.ts +0 -15
- package/src/utils/merkle.ts +0 -69
- package/src/utils/number.ts +0 -98
- package/src/utils/provider.ts +0 -28
- package/src/utils/responseParser/index.ts +0 -28
- package/src/utils/responseParser/rpc.ts +0 -70
- package/src/utils/responseParser/sequencer.ts +0 -135
- package/src/utils/shortString.ts +0 -21
- package/src/utils/stark.ts +0 -57
- package/src/utils/starknetId.ts +0 -116
- package/src/utils/transaction.ts +0 -56
- package/src/utils/typedData/index.ts +0 -247
- package/src/utils/typedData/types.ts +0 -37
- package/src/utils/typedData/utils.ts +0 -16
- package/src/utils/uint256.ts +0 -32
- package/src/utils/url.ts +0 -53
- package/tsconfig.eslint.json +0 -4
- package/tsup.config.ts +0 -9
- package/www/README.md +0 -41
- package/www/babel.config.js +0 -3
- package/www/code-examples/account.js +0 -65
- package/www/code-examples/amm.js +0 -44
- package/www/code-examples/erc20.js +0 -13
- package/www/code-examples/package-lock.json +0 -336
- package/www/code-examples/package.json +0 -15
- package/www/docs/API/_category_.json +0 -5
- package/www/docs/API/account.md +0 -463
- package/www/docs/API/changelog.md +0 -15
- package/www/docs/API/contract.md +0 -135
- package/www/docs/API/contractFactory.md +0 -45
- package/www/docs/API/index.md +0 -3
- package/www/docs/API/provider.md +0 -725
- package/www/docs/API/signer.md +0 -105
- package/www/docs/API/utils.md +0 -374
- package/www/docusaurus.config.js +0 -130
- package/www/guides/account.md +0 -140
- package/www/guides/cra.md +0 -3
- package/www/guides/erc20.md +0 -163
- package/www/guides/intro.md +0 -63
- package/www/package-lock.json +0 -20405
- package/www/package.json +0 -43
- package/www/sidebars.js +0 -31
- package/www/src/components/HomepageFeatures/index.tsx +0 -67
- package/www/src/components/HomepageFeatures/styles.module.css +0 -10
- package/www/src/css/custom.css +0 -39
- package/www/src/pages/index.module.css +0 -23
- package/www/src/pages/index.tsx +0 -40
- package/www/src/pages/markdown-page.md +0 -7
- package/www/static/.nojekyll +0 -0
- package/www/static/img/docusaurus.png +0 -0
- package/www/static/img/favicon.ico +0 -0
- package/www/static/img/logo.svg +0 -17
- package/www/static/img/starknet-1.png +0 -0
- package/www/static/img/starknet-2.png +0 -0
- package/www/static/img/starknet-3.png +0 -0
- package/www/static/img/tutorial/docsVersionDropdown.png +0 -0
- package/www/static/img/tutorial/localeDropdown.png +0 -0
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { StarknetChainId } from '../../src/constants';
|
|
2
|
-
import { ec, getKeyPair, getStarkKey, sign, verify } from '../../src/utils/ellipticCurve';
|
|
3
|
-
import { removeHexPrefix } from '../../src/utils/encode';
|
|
4
|
-
import {
|
|
5
|
-
calculateTransactionHash,
|
|
6
|
-
computeHashOnElements,
|
|
7
|
-
pedersen,
|
|
8
|
-
transactionVersion,
|
|
9
|
-
} from '../../src/utils/hash';
|
|
10
|
-
import { toBN, toHex } from '../../src/utils/number';
|
|
11
|
-
import { fromCallsToExecuteCalldataWithNonce } from '../../src/utils/transaction';
|
|
12
|
-
|
|
13
|
-
test('getKeyPair()', () => {
|
|
14
|
-
const privateKey = '0x019800ea6a9a73f94aee6a3d2edf018fc770443e90c7ba121e8303ec6b349279';
|
|
15
|
-
const pair = getKeyPair(privateKey);
|
|
16
|
-
// somehow needed, returns error else
|
|
17
|
-
expect(toHex(toBN(getStarkKey(pair)))).toBe(
|
|
18
|
-
'0x33f45f07e1bd1a51b45fc24ec8c8c9908db9e42191be9e169bfcac0c0d99745'
|
|
19
|
-
);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test('pedersen()', () => {
|
|
23
|
-
const own = pedersen(['0x12773', '0x872362']);
|
|
24
|
-
expect(own).toMatchSnapshot();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test('pedersen() with 0', () => {
|
|
28
|
-
const own = pedersen(['0x12773', '0x0']);
|
|
29
|
-
expect(own).toMatchSnapshot();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test('computeHashOnElements()', () => {
|
|
33
|
-
const array = ['1', '2', '3', '4'];
|
|
34
|
-
expect(computeHashOnElements(array)).toBe(
|
|
35
|
-
'0x66bd4335902683054d08a0572747ea78ebd9e531536fb43125424ca9f902084'
|
|
36
|
-
);
|
|
37
|
-
expect(array).toStrictEqual(['1', '2', '3', '4']);
|
|
38
|
-
|
|
39
|
-
expect(computeHashOnElements(['1', '2'])).toBe(
|
|
40
|
-
'0x501a3a8e6cd4f5241c639c74052aaa34557aafa84dd4ba983d6443c590ab7df'
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('hashMessage()', () => {
|
|
45
|
-
const privateKey = '0x019800ea6a9a73f94aee6a3d2edf018fc770443e90c7ba121e8303ec6b349279';
|
|
46
|
-
const account = '2007067565103695475819120104515800035851923905855118399071773059478896040938';
|
|
47
|
-
const transactions = [
|
|
48
|
-
{
|
|
49
|
-
contractAddress:
|
|
50
|
-
'3290661298119599979891444342541795905081168856323302956721669397616389152866',
|
|
51
|
-
entrypoint: 'set_number',
|
|
52
|
-
calldata: ['47'],
|
|
53
|
-
},
|
|
54
|
-
];
|
|
55
|
-
const nonce = '3';
|
|
56
|
-
const maxFee = '0';
|
|
57
|
-
const calldata = fromCallsToExecuteCalldataWithNonce(transactions, nonce);
|
|
58
|
-
|
|
59
|
-
const hashMsg = calculateTransactionHash(
|
|
60
|
-
account,
|
|
61
|
-
transactionVersion,
|
|
62
|
-
calldata,
|
|
63
|
-
maxFee,
|
|
64
|
-
StarknetChainId.TESTNET,
|
|
65
|
-
nonce
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
expect(hashMsg).toMatchInlineSnapshot(
|
|
69
|
-
`"0x6d1706bd3d1ba7c517be2a2a335996f63d4738e2f182144d078a1dd9997062e"`
|
|
70
|
-
);
|
|
71
|
-
const keyPair = getKeyPair(privateKey);
|
|
72
|
-
const [r, s] = sign(keyPair, removeHexPrefix(hashMsg));
|
|
73
|
-
expect(r.toString()).toMatchInlineSnapshot(
|
|
74
|
-
`"1427981024487605678086498726488552139932400435436186597196374630267616399345"`
|
|
75
|
-
);
|
|
76
|
-
expect(s.toString()).toMatchInlineSnapshot(
|
|
77
|
-
`"1853664302719670721837677288395394946745467311923401353018029119631574115563"`
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('verify signed message()', () => {
|
|
82
|
-
const pk = '0x019800ea6a9a73f94aee6a3d2edf018fc770443e90c7ba121e8303ec6b349279';
|
|
83
|
-
const account = '0x33f45f07e1bd1a51b45fc24ec8c8c9908db9e42191be9e169bfcac0c0d99745';
|
|
84
|
-
const price = '1';
|
|
85
|
-
const hashMsg = pedersen([account, price]);
|
|
86
|
-
const keyPair = getKeyPair(pk);
|
|
87
|
-
const signature = sign(keyPair, removeHexPrefix(hashMsg));
|
|
88
|
-
const pubKey = keyPair.getPublic('hex');
|
|
89
|
-
const pubKeyPair = ec.keyFromPublic(pubKey, 'hex');
|
|
90
|
-
expect(verify(pubKeyPair, removeHexPrefix(hashMsg), signature)).toBe(true);
|
|
91
|
-
});
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { pedersen } from '../../src/utils/hash';
|
|
2
|
-
import { MerkleTree, proofMerklePath } from '../../src/utils/merkle';
|
|
3
|
-
import { toBN } from '../../src/utils/number';
|
|
4
|
-
|
|
5
|
-
describe('MerkleTree class', () => {
|
|
6
|
-
describe('calculate hashes', () => {
|
|
7
|
-
test('should generate hash with sorted arguments', async () => {
|
|
8
|
-
let leaves = ['0x12', '0xa']; // 18, 10
|
|
9
|
-
let merkleHash = MerkleTree.hash(leaves[0], leaves[1]);
|
|
10
|
-
let rawHash = pedersen([toBN(leaves[1]), toBN(leaves[0])]);
|
|
11
|
-
expect(merkleHash).toBe(rawHash);
|
|
12
|
-
|
|
13
|
-
leaves = ['0x5bb9440e27889a364bcb678b1f679ecd1347acdedcbf36e83494f857cc58026', '0x3'];
|
|
14
|
-
merkleHash = MerkleTree.hash(leaves[0], leaves[1]);
|
|
15
|
-
rawHash = pedersen([toBN(leaves[1]), toBN(leaves[0])]);
|
|
16
|
-
expect(merkleHash).toBe(rawHash);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
describe('generate roots', () => {
|
|
20
|
-
test('should generate valid root for 1 elements', async () => {
|
|
21
|
-
const leaves = ['0x1'];
|
|
22
|
-
const tree = new MerkleTree(leaves);
|
|
23
|
-
|
|
24
|
-
const manualMerkle = leaves[0];
|
|
25
|
-
|
|
26
|
-
expect(tree.root).toBe(manualMerkle);
|
|
27
|
-
});
|
|
28
|
-
test('should generate valid root for 2 elements', async () => {
|
|
29
|
-
const leaves = ['0x1', '0x2'];
|
|
30
|
-
const tree = new MerkleTree(leaves);
|
|
31
|
-
|
|
32
|
-
const manualMerkle = MerkleTree.hash(leaves[0], leaves[1]);
|
|
33
|
-
|
|
34
|
-
expect(tree.root).toBe(manualMerkle);
|
|
35
|
-
});
|
|
36
|
-
test('should generate valid root for 4 elements', async () => {
|
|
37
|
-
const leaves = ['0x1', '0x2', '0x3', '0x4'];
|
|
38
|
-
const tree = new MerkleTree(leaves);
|
|
39
|
-
|
|
40
|
-
const manualMerkle = MerkleTree.hash(
|
|
41
|
-
MerkleTree.hash(leaves[0], leaves[1]),
|
|
42
|
-
MerkleTree.hash(leaves[2], leaves[3])
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
expect(tree.root).toBe(manualMerkle);
|
|
46
|
-
});
|
|
47
|
-
test('should generate valid root for 6 elements', async () => {
|
|
48
|
-
const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6'];
|
|
49
|
-
const tree = new MerkleTree(leaves);
|
|
50
|
-
|
|
51
|
-
const manualMerkle = MerkleTree.hash(
|
|
52
|
-
MerkleTree.hash(
|
|
53
|
-
MerkleTree.hash(leaves[0], leaves[1]),
|
|
54
|
-
MerkleTree.hash(leaves[2], leaves[3])
|
|
55
|
-
),
|
|
56
|
-
MerkleTree.hash(MerkleTree.hash(leaves[4], leaves[5]), '0x0')
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
expect(tree.root).toBe(manualMerkle);
|
|
60
|
-
});
|
|
61
|
-
test('should generate valid root for 7 elements', async () => {
|
|
62
|
-
const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7'];
|
|
63
|
-
const tree = new MerkleTree(leaves);
|
|
64
|
-
|
|
65
|
-
const manualMerkle = MerkleTree.hash(
|
|
66
|
-
MerkleTree.hash(
|
|
67
|
-
MerkleTree.hash(leaves[0], leaves[1]),
|
|
68
|
-
MerkleTree.hash(leaves[2], leaves[3])
|
|
69
|
-
),
|
|
70
|
-
MerkleTree.hash(MerkleTree.hash(leaves[4], leaves[5]), MerkleTree.hash(leaves[6], '0x0'))
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
expect(tree.root).toBe(manualMerkle);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
describe('generate proofs', () => {
|
|
77
|
-
let tree: MerkleTree;
|
|
78
|
-
beforeAll(() => {
|
|
79
|
-
const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7'];
|
|
80
|
-
tree = new MerkleTree(leaves);
|
|
81
|
-
});
|
|
82
|
-
test('should return proof path for valid child', async () => {
|
|
83
|
-
const proof = tree.getProof('0x3');
|
|
84
|
-
|
|
85
|
-
const manualProof = [
|
|
86
|
-
'0x4',
|
|
87
|
-
MerkleTree.hash('0x1', '0x2'),
|
|
88
|
-
MerkleTree.hash(MerkleTree.hash('0x5', '0x6'), MerkleTree.hash('0x7', '0x0')),
|
|
89
|
-
];
|
|
90
|
-
|
|
91
|
-
expect(proof).toEqual(manualProof);
|
|
92
|
-
});
|
|
93
|
-
test('should return proof path for valid child', async () => {
|
|
94
|
-
const proof = tree.getProof('0x7');
|
|
95
|
-
|
|
96
|
-
const manualProof = [
|
|
97
|
-
'0x0', // proofs should always be as long as the tree is deep
|
|
98
|
-
MerkleTree.hash('0x5', '0x6'),
|
|
99
|
-
MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
|
|
100
|
-
];
|
|
101
|
-
|
|
102
|
-
expect(proof).toEqual(manualProof);
|
|
103
|
-
});
|
|
104
|
-
test('should return proof path for valid child', async () => {
|
|
105
|
-
const proof = tree.getProof('0x5');
|
|
106
|
-
|
|
107
|
-
const manualProof = [
|
|
108
|
-
'0x6',
|
|
109
|
-
MerkleTree.hash('0x7', '0x0'), // tree should be padded with 0x0 so that all proofs are equals in size
|
|
110
|
-
MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
|
|
111
|
-
];
|
|
112
|
-
|
|
113
|
-
expect(proof).toEqual(manualProof);
|
|
114
|
-
});
|
|
115
|
-
test('should throw for invalid child', () => {
|
|
116
|
-
expect(() => tree.getProof('0x8')).toThrow('leaf not found');
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
describe('verify proofs', () => {
|
|
120
|
-
let tree: MerkleTree;
|
|
121
|
-
beforeAll(() => {
|
|
122
|
-
const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7'];
|
|
123
|
-
tree = new MerkleTree(leaves);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
test('should return true for valid manual proof', async () => {
|
|
127
|
-
const manualProof = [
|
|
128
|
-
'0x0', // tree should be padded with 0x0 so that all proofs are equals in size
|
|
129
|
-
MerkleTree.hash('0x5', '0x6'),
|
|
130
|
-
MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
|
|
131
|
-
];
|
|
132
|
-
const leaf = '0x7';
|
|
133
|
-
const { root } = tree;
|
|
134
|
-
|
|
135
|
-
expect(proofMerklePath(root, leaf, manualProof)).toBe(true);
|
|
136
|
-
});
|
|
137
|
-
test('should return true for valid manual proof', async () => {
|
|
138
|
-
const manualProof = [
|
|
139
|
-
'0x6',
|
|
140
|
-
MerkleTree.hash('0x7', '0x0'), // tree should be padded with 0x0 so that all proofs are equals in size
|
|
141
|
-
MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
|
|
142
|
-
];
|
|
143
|
-
const leaf = '0x5';
|
|
144
|
-
const { root } = tree;
|
|
145
|
-
|
|
146
|
-
expect(proofMerklePath(root, leaf, manualProof)).toBe(true);
|
|
147
|
-
});
|
|
148
|
-
test('should return true for valid proof', async () => {
|
|
149
|
-
const proof = tree.getProof('0x3');
|
|
150
|
-
const leaf = '0x3';
|
|
151
|
-
const { root } = tree;
|
|
152
|
-
|
|
153
|
-
expect(proofMerklePath(root, leaf, proof)).toBe(true);
|
|
154
|
-
});
|
|
155
|
-
test('should return false for invalid proof (root)', async () => {
|
|
156
|
-
const proof = tree.getProof('0x3');
|
|
157
|
-
const leaf = '0x3';
|
|
158
|
-
const root = '0x4';
|
|
159
|
-
|
|
160
|
-
expect(proofMerklePath(root, leaf, proof)).toBe(false);
|
|
161
|
-
});
|
|
162
|
-
test('should return false for invalid proof (proof[0])', async () => {
|
|
163
|
-
const proof = tree.getProof('0x3');
|
|
164
|
-
const leaf = '0x3';
|
|
165
|
-
const { root } = tree;
|
|
166
|
-
proof[0] = '0x7';
|
|
167
|
-
expect(proofMerklePath(root, leaf, proof)).toBe(false);
|
|
168
|
-
});
|
|
169
|
-
test('should return false for invalid proof (proof[1])', async () => {
|
|
170
|
-
const proof = tree.getProof('0x3');
|
|
171
|
-
const leaf = '0x3';
|
|
172
|
-
const { root } = tree;
|
|
173
|
-
proof[1] = '0x4';
|
|
174
|
-
expect(proofMerklePath(root, leaf, proof)).toBe(false);
|
|
175
|
-
});
|
|
176
|
-
test('should return false for invalid proof (proof[2])', async () => {
|
|
177
|
-
const proof = tree.getProof('0x3');
|
|
178
|
-
const leaf = '0x3';
|
|
179
|
-
const { root } = tree;
|
|
180
|
-
proof[2] = '0x4';
|
|
181
|
-
expect(proofMerklePath(root, leaf, proof)).toBe(false);
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
describe('verify 2-deep tree with empty data on the right', () => {
|
|
185
|
-
let tree: MerkleTree;
|
|
186
|
-
beforeAll(() => {
|
|
187
|
-
const leaves = ['0x1', '0x2', '0x3'];
|
|
188
|
-
tree = new MerkleTree(leaves);
|
|
189
|
-
});
|
|
190
|
-
test('should return 1-length proof in a 2-length tree', async () => {
|
|
191
|
-
const proof = tree.getProof('0x3');
|
|
192
|
-
const manualProof = ['0x0', MerkleTree.hash('0x1', '0x2')];
|
|
193
|
-
expect(proof).toEqual(manualProof);
|
|
194
|
-
});
|
|
195
|
-
test('should check the previous proof works fine', async () => {
|
|
196
|
-
const manualMerkle = MerkleTree.hash(
|
|
197
|
-
MerkleTree.hash('0x3', '0x0'),
|
|
198
|
-
MerkleTree.hash('0x1', '0x2')
|
|
199
|
-
);
|
|
200
|
-
expect(tree.root).toBe(manualMerkle);
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
describe('verify 3-deep tree with empty data on the right', () => {
|
|
204
|
-
let tree: MerkleTree;
|
|
205
|
-
beforeAll(() => {
|
|
206
|
-
const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6'];
|
|
207
|
-
tree = new MerkleTree(leaves);
|
|
208
|
-
});
|
|
209
|
-
test('should return 2-length proof with the 2nd place skipped', async () => {
|
|
210
|
-
const proof = tree.getProof('0x5');
|
|
211
|
-
const manualProof = [
|
|
212
|
-
'0x6',
|
|
213
|
-
'0x0',
|
|
214
|
-
MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
|
|
215
|
-
];
|
|
216
|
-
expect(proof).toEqual(manualProof);
|
|
217
|
-
});
|
|
218
|
-
test('should check the previous proof works fine', async () => {
|
|
219
|
-
const manualMerkle = MerkleTree.hash(
|
|
220
|
-
MerkleTree.hash(MerkleTree.hash('0x5', '0x6'), '0x0'),
|
|
221
|
-
MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4'))
|
|
222
|
-
);
|
|
223
|
-
expect(tree.root).toBe(manualMerkle);
|
|
224
|
-
});
|
|
225
|
-
});
|
|
226
|
-
describe('verify 4-deep tree with empty data on the right', () => {
|
|
227
|
-
let tree: MerkleTree;
|
|
228
|
-
beforeAll(() => {
|
|
229
|
-
const leaves = ['0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7', '0x8', '0x9'];
|
|
230
|
-
tree = new MerkleTree(leaves);
|
|
231
|
-
});
|
|
232
|
-
test('should return 2-length proof with the 2nd place skipped', async () => {
|
|
233
|
-
const proof = tree.getProof('0x9');
|
|
234
|
-
const manualProof = [
|
|
235
|
-
'0x0',
|
|
236
|
-
'0x0',
|
|
237
|
-
'0x0',
|
|
238
|
-
MerkleTree.hash(
|
|
239
|
-
MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
|
|
240
|
-
MerkleTree.hash(MerkleTree.hash('0x5', '0x6'), MerkleTree.hash('0x7', '0x8'))
|
|
241
|
-
),
|
|
242
|
-
];
|
|
243
|
-
expect(proof).toEqual(manualProof);
|
|
244
|
-
});
|
|
245
|
-
test('should check the previous proof works fine', async () => {
|
|
246
|
-
const manualMerkle = MerkleTree.hash(
|
|
247
|
-
MerkleTree.hash(MerkleTree.hash(MerkleTree.hash('0x9', '0x0'), '0x0'), '0x0'),
|
|
248
|
-
MerkleTree.hash(
|
|
249
|
-
MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
|
|
250
|
-
MerkleTree.hash(MerkleTree.hash('0x5', '0x6'), MerkleTree.hash('0x7', '0x8'))
|
|
251
|
-
)
|
|
252
|
-
);
|
|
253
|
-
expect(tree.root).toBe(manualMerkle);
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { decodeShortString, encodeShortString } from '../../src/utils/shortString';
|
|
2
|
-
|
|
3
|
-
describe('shortString', () => {
|
|
4
|
-
test('should convert string to number', () => {
|
|
5
|
-
expect(encodeShortString('hello')).toMatchInlineSnapshot(`"0x68656c6c6f"`);
|
|
6
|
-
});
|
|
7
|
-
test('should convert number to string', () => {
|
|
8
|
-
expect(decodeShortString('0x68656c6c6f')).toMatchInlineSnapshot(`"hello"`);
|
|
9
|
-
});
|
|
10
|
-
test('should throw if string is too long', () => {
|
|
11
|
-
expect(() =>
|
|
12
|
-
encodeShortString('hello world hello world hello world hello world hello world hello world')
|
|
13
|
-
).toThrowErrorMatchingInlineSnapshot(
|
|
14
|
-
`"hello world hello world hello world hello world hello world hello world is too long"`
|
|
15
|
-
);
|
|
16
|
-
});
|
|
17
|
-
test('should throw if string contains non ascii chars', () => {
|
|
18
|
-
expect(() => encodeShortString('hello\uD83D\uDE00')).toThrowErrorMatchingInlineSnapshot(
|
|
19
|
-
`"hello😀 is not an ASCII string"`
|
|
20
|
-
);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { BN } from 'bn.js';
|
|
2
|
-
|
|
3
|
-
import { StarknetChainId } from '../../src/constants';
|
|
4
|
-
import { getStarknetIdContract, useDecoded, useEncoded } from '../../src/utils/starknetId';
|
|
5
|
-
|
|
6
|
-
function randomWithSeed(seed: number) {
|
|
7
|
-
const x = Math.sin(seed) * 10000;
|
|
8
|
-
return x - Math.floor(x);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function generateString(length: number, seed: number): string {
|
|
12
|
-
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789-这来';
|
|
13
|
-
|
|
14
|
-
let result = '';
|
|
15
|
-
const charactersLength = characters.length;
|
|
16
|
-
for (let i = 0; i < length; i += 1) {
|
|
17
|
-
result += characters.charAt(Math.floor(randomWithSeed(seed + i) * charactersLength));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return result;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
describe('Should tets StarknetId utils', () => {
|
|
24
|
-
test('Should test useEncoded and useDecoded hook with a random string', () => {
|
|
25
|
-
for (let index = 0; index < 2500; index += 1) {
|
|
26
|
-
const randomString = generateString(10, index);
|
|
27
|
-
expect(useDecoded([useEncoded(randomString)])).toBe(randomString.concat('.stark'));
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('Should test useDecoded and useEncoded hook with an encoded number', () => {
|
|
32
|
-
for (let index = 0; index < 2500; index += 1) {
|
|
33
|
-
const decoded = useDecoded([new BN(index)]);
|
|
34
|
-
expect(useEncoded(decoded.substring(0, decoded.length - 6)).toString()).toBe(
|
|
35
|
-
index.toString()
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test('Should test getStarknetIdContract', () => {
|
|
41
|
-
expect(getStarknetIdContract(StarknetChainId.TESTNET)).toBe(
|
|
42
|
-
'0x05cf267a0af6101667013fc6bd3f6c11116a14cda9b8c4b1198520d59f900b17'
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
expect(() => {
|
|
46
|
-
getStarknetIdContract(StarknetChainId.TESTNET2);
|
|
47
|
-
}).toThrow();
|
|
48
|
-
|
|
49
|
-
expect(getStarknetIdContract(StarknetChainId.MAINNET)).toBe(
|
|
50
|
-
'0x6ac597f8116f886fa1c97a23fa4e08299975ecaf6b598873ca6792b9bbfb678'
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { StarknetChainId, TransactionHashPrefix } from '../../src/constants';
|
|
2
|
-
import { calculateTransactionHashCommon } from '../../src/utils/hash';
|
|
3
|
-
|
|
4
|
-
describe('calculateTransactionHashCommon()', () => {
|
|
5
|
-
test('should match most simple python output', () => {
|
|
6
|
-
const result = calculateTransactionHashCommon(
|
|
7
|
-
TransactionHashPrefix.INVOKE,
|
|
8
|
-
'0x0',
|
|
9
|
-
'0x2a',
|
|
10
|
-
'0x64',
|
|
11
|
-
[],
|
|
12
|
-
'0x0',
|
|
13
|
-
StarknetChainId.TESTNET
|
|
14
|
-
);
|
|
15
|
-
expect(result).toBe('0x7d260744de9d8c55e7675a34512d1951a7b262c79e685d26599edd2948de959');
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import typedDataExample from '../../__mocks__/typedDataExample.json';
|
|
2
|
-
import typedDataSessionExample from '../../__mocks__/typedDataSessionExample.json';
|
|
3
|
-
import typedDataStructArrayExample from '../../__mocks__/typedDataStructArrayExample.json';
|
|
4
|
-
import { number } from '../../src';
|
|
5
|
-
import { getSelectorFromName } from '../../src/utils/hash';
|
|
6
|
-
import { MerkleTree } from '../../src/utils/merkle';
|
|
7
|
-
import { BigNumberish } from '../../src/utils/number';
|
|
8
|
-
import {
|
|
9
|
-
StarkNetDomain,
|
|
10
|
-
encodeType,
|
|
11
|
-
encodeValue,
|
|
12
|
-
getMessageHash,
|
|
13
|
-
getStructHash,
|
|
14
|
-
getTypeHash,
|
|
15
|
-
} from '../../src/utils/typedData';
|
|
16
|
-
|
|
17
|
-
describe('typedData', () => {
|
|
18
|
-
test('should get right type encoding', () => {
|
|
19
|
-
const typeEncoding = encodeType(typedDataExample.types, 'Mail');
|
|
20
|
-
expect(typeEncoding).toMatchInlineSnapshot(
|
|
21
|
-
`"Mail(from:Person,to:Person,contents:felt)Person(name:felt,wallet:felt)"`
|
|
22
|
-
);
|
|
23
|
-
const typeEncodingStructArr = encodeType(typedDataStructArrayExample.types, 'Mail');
|
|
24
|
-
expect(typeEncodingStructArr).toMatchInlineSnapshot(
|
|
25
|
-
`"Mail(from:Person,to:Person,posts_len:felt,posts:Post*)Person(name:felt,wallet:felt)Post(title:felt,content:felt)"`
|
|
26
|
-
);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test('should get right type hash', () => {
|
|
30
|
-
const typeHashDomain = getTypeHash(typedDataExample.types, 'StarkNetDomain');
|
|
31
|
-
expect(typeHashDomain).toMatchInlineSnapshot(
|
|
32
|
-
`"0x1bfc207425a47a5dfa1a50a4f5241203f50624ca5fdf5e18755765416b8e288"`
|
|
33
|
-
);
|
|
34
|
-
const typeHashPerson = getTypeHash(typedDataExample.types, 'Person');
|
|
35
|
-
expect(typeHashPerson).toMatchInlineSnapshot(
|
|
36
|
-
`"0x2896dbe4b96a67110f454c01e5336edc5bbc3635537efd690f122f4809cc855"`
|
|
37
|
-
);
|
|
38
|
-
const typeHashMail = getTypeHash(typedDataExample.types, 'Mail');
|
|
39
|
-
expect(typeHashMail).toMatchInlineSnapshot(
|
|
40
|
-
`"0x13d89452df9512bf750f539ba3001b945576243288137ddb6c788457d4b2f79"`
|
|
41
|
-
);
|
|
42
|
-
const typeHashPost = getTypeHash(typedDataStructArrayExample.types, 'Post');
|
|
43
|
-
expect(typeHashPost).toMatchInlineSnapshot(
|
|
44
|
-
`"0x1d71e69bf476486b43cdcfaf5a85c00bb2d954c042b281040e513080388356d"`
|
|
45
|
-
);
|
|
46
|
-
const typeHashMailWithStructArray = getTypeHash(typedDataStructArrayExample.types, 'Mail');
|
|
47
|
-
expect(typeHashMailWithStructArray).toMatchInlineSnapshot(
|
|
48
|
-
`"0x873b878e35e258fc99e3085d5aaad3a81a0c821f189c08b30def2cde55ff27"`
|
|
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
|
-
`"0x15ac9e457789ef0c56e5d559809e7336a909c14ee2511503fa7af69be1ba639"`
|
|
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
|
-
`"0x12354b159e3799dc0ebe86d62dde4ce7b300538d471e5a7fef23dcbac076011"`
|
|
123
|
-
);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
test('should get right hash for StarkNetDomain', () => {
|
|
127
|
-
const hash = getStructHash(
|
|
128
|
-
typedDataExample.types,
|
|
129
|
-
'StarkNetDomain',
|
|
130
|
-
typedDataExample.domain as StarkNetDomain
|
|
131
|
-
);
|
|
132
|
-
expect(hash).toMatchInlineSnapshot(
|
|
133
|
-
`"0x54833b121883a3e3aebff48ec08a962f5742e5f7b973469c1f8f4f55d470b07"`
|
|
134
|
-
);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
test('should get right hash for entire message', () => {
|
|
138
|
-
const hash = getMessageHash(typedDataExample, '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826');
|
|
139
|
-
expect(hash).toMatchInlineSnapshot(
|
|
140
|
-
`"0x6fcff244f63e38b9d88b9e3378d44757710d1b244282b435cb472053c8d78d0"`
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
const hashStructArr = getMessageHash(
|
|
144
|
-
typedDataStructArrayExample,
|
|
145
|
-
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
|
|
146
|
-
);
|
|
147
|
-
expect(hashStructArr).toMatchInlineSnapshot(
|
|
148
|
-
`"0x5914ed2764eca2e6a41eb037feefd3d2e33d9af6225a9e7fe31ac943ff712c"`
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
interface StringStruct {
|
|
153
|
-
len: BigNumberish;
|
|
154
|
-
data: BigNumberish[];
|
|
155
|
-
}
|
|
156
|
-
function stringToStringStruct(str: string): StringStruct {
|
|
157
|
-
const len = str.length;
|
|
158
|
-
const data = str.split('').map((char) => number.toHex(number.toBN(char.charCodeAt(0))));
|
|
159
|
-
return { len, data };
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const typedDataStringExample = {
|
|
163
|
-
types: {
|
|
164
|
-
StarkNetDomain: [
|
|
165
|
-
{ name: 'name', type: 'felt' },
|
|
166
|
-
{ name: 'version', type: 'felt' },
|
|
167
|
-
{ name: 'chainId', type: 'felt' },
|
|
168
|
-
],
|
|
169
|
-
Person: [
|
|
170
|
-
{ name: 'name', type: 'felt' },
|
|
171
|
-
{ name: 'wallet', type: 'felt' },
|
|
172
|
-
],
|
|
173
|
-
String: [
|
|
174
|
-
{ name: 'len', type: 'felt' },
|
|
175
|
-
{ name: 'data', type: 'felt*' },
|
|
176
|
-
],
|
|
177
|
-
Mail: [
|
|
178
|
-
{ name: 'from', type: 'Person' },
|
|
179
|
-
{ name: 'to', type: 'Person' },
|
|
180
|
-
{ name: 'contents', type: 'String' },
|
|
181
|
-
],
|
|
182
|
-
},
|
|
183
|
-
primaryType: 'Mail',
|
|
184
|
-
domain: {
|
|
185
|
-
name: 'StarkNet Mail',
|
|
186
|
-
version: '1',
|
|
187
|
-
chainId: 1,
|
|
188
|
-
},
|
|
189
|
-
message: {
|
|
190
|
-
from: {
|
|
191
|
-
name: 'Cow',
|
|
192
|
-
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
|
|
193
|
-
},
|
|
194
|
-
to: {
|
|
195
|
-
name: 'Bob',
|
|
196
|
-
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
|
197
|
-
},
|
|
198
|
-
contents: stringToStringStruct(
|
|
199
|
-
'this is way longer than just 32 characters, to test if that is possible within a typedData struct.'
|
|
200
|
-
),
|
|
201
|
-
},
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
test('should transform strings correctly', () => {
|
|
205
|
-
const hash = getMessageHash(
|
|
206
|
-
typedDataStringExample,
|
|
207
|
-
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
|
|
208
|
-
);
|
|
209
|
-
expect(hash).toMatchInlineSnapshot(
|
|
210
|
-
`"0x70338fb11b8f70b68b261de8a322bcb004bd85e88ac47d9147982c7f5ac66fd"`
|
|
211
|
-
);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
test('should transform session message correctly', () => {
|
|
215
|
-
const hash = getMessageHash(
|
|
216
|
-
typedDataSessionExample,
|
|
217
|
-
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
|
|
218
|
-
);
|
|
219
|
-
expect(hash).toMatchInlineSnapshot(
|
|
220
|
-
`"0x751fb7d98545f7649d0d0eadc80d770fcd88d8cfaa55590b284f4e1b701ef0a"`
|
|
221
|
-
);
|
|
222
|
-
});
|
|
223
|
-
});
|