starknet 4.8.0 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/__mocks__/ERC20.json +32561 -29055
- package/__tests__/account.test.ts +32 -24
- package/__tests__/contract.test.ts +25 -14
- package/__tests__/defaultProvider.test.ts +19 -43
- package/__tests__/fixtures.ts +9 -1
- package/__tests__/rpcProvider.test.ts +6 -15
- package/__tests__/sequencerProvider.test.ts +17 -10
- package/__tests__/utils/merkle.test.ts +98 -3
- package/__tests__/utils/typedData.test.ts +3 -3
- package/account/default.d.ts +10 -44
- package/account/default.js +255 -61
- package/account/interface.d.ts +78 -7
- package/constants.d.ts +1 -0
- package/constants.js +1 -0
- package/contract/default.js +6 -6
- package/dist/account/default.d.ts +10 -44
- package/dist/account/default.js +255 -61
- package/dist/account/interface.d.ts +78 -7
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/contract/default.js +6 -6
- package/dist/provider/default.d.ts +8 -3
- package/dist/provider/default.js +31 -4
- package/dist/provider/interface.d.ts +67 -5
- package/dist/provider/rpc.d.ts +7 -2
- package/dist/provider/rpc.js +83 -8
- package/dist/provider/sequencer.d.ts +7 -2
- package/dist/provider/sequencer.js +71 -13
- package/dist/signer/default.d.ts +4 -1
- package/dist/signer/default.js +22 -0
- package/dist/signer/interface.d.ts +27 -2
- package/dist/types/api/openrpc.d.ts +24 -2
- package/dist/types/api/sequencer.d.ts +22 -7
- package/dist/types/lib.d.ts +23 -2
- package/dist/types/provider.d.ts +15 -10
- package/dist/types/signer.d.ts +14 -1
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +13 -2
- package/dist/utils/merkle.js +2 -4
- package/dist/utils/responseParser/rpc.d.ts +2 -6
- package/dist/utils/responseParser/rpc.js +0 -11
- package/dist/utils/responseParser/sequencer.js +4 -14
- package/package.json +1 -1
- package/provider/default.d.ts +8 -3
- package/provider/default.js +31 -4
- package/provider/interface.d.ts +67 -5
- package/provider/rpc.d.ts +7 -2
- package/provider/rpc.js +83 -8
- package/provider/sequencer.d.ts +7 -2
- package/provider/sequencer.js +71 -13
- package/signer/default.d.ts +4 -1
- package/signer/default.js +22 -0
- package/signer/interface.d.ts +27 -2
- package/src/account/default.ts +201 -53
- package/src/account/interface.ts +104 -6
- package/src/constants.ts +1 -0
- package/src/contract/default.ts +6 -6
- package/src/provider/default.ts +43 -5
- package/src/provider/interface.ts +92 -7
- package/src/provider/rpc.ts +86 -12
- package/src/provider/sequencer.ts +74 -10
- package/src/signer/default.ts +54 -2
- package/src/signer/interface.ts +31 -2
- package/src/types/api/openrpc.ts +28 -2
- package/src/types/api/sequencer.ts +32 -9
- package/src/types/lib.ts +30 -2
- package/src/types/provider.ts +27 -11
- package/src/types/signer.ts +18 -1
- package/src/utils/hash.ts +46 -1
- package/src/utils/merkle.ts +2 -4
- package/src/utils/responseParser/rpc.ts +4 -20
- package/src/utils/responseParser/sequencer.ts +2 -0
- package/types/api/openrpc.d.ts +24 -2
- package/types/api/sequencer.d.ts +22 -7
- package/types/lib.d.ts +23 -2
- package/types/provider.d.ts +15 -10
- package/types/signer.d.ts +14 -1
- package/utils/hash.d.ts +2 -0
- package/utils/hash.js +13 -2
- package/utils/merkle.js +2 -4
- package/utils/responseParser/rpc.d.ts +2 -6
- package/utils/responseParser/rpc.js +0 -11
- package/utils/responseParser/sequencer.js +4 -14
- package/www/docs/API/account.md +60 -1
- package/www/docs/API/provider.md +306 -17
- package/www/guides/erc20.md +13 -7
|
@@ -3,7 +3,13 @@ import { isBN } from 'bn.js';
|
|
|
3
3
|
import typedDataExample from '../__mocks__/typedDataExample.json';
|
|
4
4
|
import { Account, Contract, Provider, number, stark } from '../src';
|
|
5
5
|
import { toBN } from '../src/utils/number';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
compiledErc20,
|
|
8
|
+
compiledTestDapp,
|
|
9
|
+
getERC20DeployPayload,
|
|
10
|
+
getTestAccount,
|
|
11
|
+
getTestProvider,
|
|
12
|
+
} from './fixtures';
|
|
7
13
|
|
|
8
14
|
describe('deploy and test Wallet', () => {
|
|
9
15
|
const provider = getTestProvider();
|
|
@@ -15,26 +21,18 @@ describe('deploy and test Wallet', () => {
|
|
|
15
21
|
beforeAll(async () => {
|
|
16
22
|
expect(account).toBeInstanceOf(Account);
|
|
17
23
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
const erc20DeployPayload = getERC20DeployPayload(account.address);
|
|
25
|
+
|
|
26
|
+
const erc20Response = await provider.deployContract(erc20DeployPayload);
|
|
21
27
|
|
|
22
28
|
erc20Address = erc20Response.contract_address;
|
|
23
29
|
erc20 = new Contract(compiledErc20.abi, erc20Address, provider);
|
|
24
30
|
|
|
25
31
|
await provider.waitForTransaction(erc20Response.transaction_hash);
|
|
26
32
|
|
|
27
|
-
const
|
|
28
|
-
contractAddress: erc20Address,
|
|
29
|
-
entrypoint: 'mint',
|
|
30
|
-
calldata: [account.address, '1000'],
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
await provider.waitForTransaction(mintResponse.transaction_hash);
|
|
33
|
+
const x = await erc20.balanceOf(account.address);
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
expect(number.toBN(x.res as string).toString()).toStrictEqual(number.toBN(1000).toString());
|
|
35
|
+
expect(number.toBN(x[0].low).toString()).toStrictEqual(number.toBN(1000).toString());
|
|
38
36
|
|
|
39
37
|
const dappResponse = await provider.deployContract({
|
|
40
38
|
contract: compiledTestDapp,
|
|
@@ -45,34 +43,34 @@ describe('deploy and test Wallet', () => {
|
|
|
45
43
|
});
|
|
46
44
|
|
|
47
45
|
test('estimate fee', async () => {
|
|
48
|
-
const { overall_fee } = await account.
|
|
46
|
+
const { overall_fee } = await account.estimateInvokeFee({
|
|
49
47
|
contractAddress: erc20Address,
|
|
50
48
|
entrypoint: 'transfer',
|
|
51
|
-
calldata: [erc20.address, '10'],
|
|
49
|
+
calldata: [erc20.address, '10', '0'],
|
|
52
50
|
});
|
|
53
51
|
expect(isBN(overall_fee)).toBe(true);
|
|
54
52
|
});
|
|
55
53
|
|
|
56
54
|
test('read balance of wallet', async () => {
|
|
57
|
-
const x = await erc20.
|
|
55
|
+
const x = await erc20.balanceOf(account.address);
|
|
58
56
|
|
|
59
|
-
expect(number.toBN(x.
|
|
57
|
+
expect(number.toBN(x[0].low).toString()).toStrictEqual(number.toBN(1000).toString());
|
|
60
58
|
});
|
|
61
59
|
|
|
62
60
|
test('execute by wallet owner', async () => {
|
|
63
61
|
const { transaction_hash } = await account.execute({
|
|
64
62
|
contractAddress: erc20Address,
|
|
65
63
|
entrypoint: 'transfer',
|
|
66
|
-
calldata: [erc20.address, '10'],
|
|
64
|
+
calldata: [erc20.address, '10', '0'],
|
|
67
65
|
});
|
|
68
66
|
|
|
69
67
|
await provider.waitForTransaction(transaction_hash);
|
|
70
68
|
});
|
|
71
69
|
|
|
72
70
|
test('read balance of wallet after transfer', async () => {
|
|
73
|
-
const {
|
|
71
|
+
const { balance } = await erc20.balanceOf(account.address);
|
|
74
72
|
|
|
75
|
-
expect(
|
|
73
|
+
expect(balance.low).toStrictEqual(toBN(990));
|
|
76
74
|
});
|
|
77
75
|
|
|
78
76
|
test('execute with custom nonce', async () => {
|
|
@@ -82,7 +80,7 @@ describe('deploy and test Wallet', () => {
|
|
|
82
80
|
{
|
|
83
81
|
contractAddress: erc20Address,
|
|
84
82
|
entrypoint: 'transfer',
|
|
85
|
-
calldata: [account.address, '10'],
|
|
83
|
+
calldata: [account.address, '10', '0'],
|
|
86
84
|
},
|
|
87
85
|
undefined,
|
|
88
86
|
{ nonce }
|
|
@@ -130,7 +128,7 @@ describe('deploy and test Wallet', () => {
|
|
|
130
128
|
const mintResponse = await account.execute({
|
|
131
129
|
contractAddress: erc20Address,
|
|
132
130
|
entrypoint: 'mint',
|
|
133
|
-
calldata: [wallet, '1000'],
|
|
131
|
+
calldata: [wallet, '1000', '0'],
|
|
134
132
|
});
|
|
135
133
|
|
|
136
134
|
await provider.waitForTransaction(mintResponse.transaction_hash);
|
|
@@ -143,8 +141,18 @@ describe('deploy and test Wallet', () => {
|
|
|
143
141
|
});
|
|
144
142
|
|
|
145
143
|
test('estimate gas fee for `mint`', async () => {
|
|
146
|
-
const res = await erc20.estimateFee.mint(wallet, '10');
|
|
144
|
+
const res = await erc20.estimateFee.mint(wallet, ['10', '0']);
|
|
147
145
|
expect(res).toHaveProperty('overall_fee');
|
|
148
146
|
});
|
|
147
|
+
|
|
148
|
+
test('Declare Account contract', async () => {
|
|
149
|
+
const declareTx = await account.declare({
|
|
150
|
+
contract: compiledErc20,
|
|
151
|
+
classHash: '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a',
|
|
152
|
+
});
|
|
153
|
+
await provider.waitForTransaction(declareTx.transaction_hash);
|
|
154
|
+
|
|
155
|
+
expect(declareTx.class_hash).toBeDefined();
|
|
156
|
+
});
|
|
149
157
|
});
|
|
150
158
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isBN } from 'bn.js';
|
|
2
2
|
|
|
3
3
|
import { Contract, ContractFactory, stark } from '../src';
|
|
4
|
+
import { DeployContractPayload } from '../src/types/lib';
|
|
4
5
|
import { getSelectorFromName } from '../src/utils/hash';
|
|
5
6
|
import { BigNumberish, toBN } from '../src/utils/number';
|
|
6
7
|
import { compileCalldata } from '../src/utils/stark';
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
compiledErc20,
|
|
9
10
|
compiledMulticall,
|
|
10
11
|
compiledTypeTransformation,
|
|
12
|
+
getERC20DeployPayload,
|
|
11
13
|
getTestProvider,
|
|
12
14
|
} from './fixtures';
|
|
13
15
|
|
|
@@ -21,9 +23,12 @@ describe('class Contract {}', () => {
|
|
|
21
23
|
let contract: Contract;
|
|
22
24
|
|
|
23
25
|
beforeAll(async () => {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
}
|
|
26
|
+
const erc20DeployPayload = getERC20DeployPayload(wallet);
|
|
27
|
+
|
|
28
|
+
const { contract_address, transaction_hash } = await provider.deployContract(
|
|
29
|
+
erc20DeployPayload
|
|
30
|
+
);
|
|
31
|
+
|
|
27
32
|
erc20 = new Contract(compiledErc20.abi, contract_address!, provider);
|
|
28
33
|
await provider.waitForTransaction(transaction_hash);
|
|
29
34
|
// Deploy Multicall
|
|
@@ -39,21 +44,21 @@ describe('class Contract {}', () => {
|
|
|
39
44
|
});
|
|
40
45
|
|
|
41
46
|
test('populate transaction for initial balance of that account', async () => {
|
|
42
|
-
const res = await erc20.populateTransaction.
|
|
47
|
+
const res = await erc20.populateTransaction.balanceOf(wallet);
|
|
43
48
|
expect(res).toHaveProperty('contractAddress');
|
|
44
49
|
expect(res).toHaveProperty('entrypoint');
|
|
45
50
|
expect(res).toHaveProperty('calldata');
|
|
46
51
|
});
|
|
47
52
|
|
|
48
53
|
test('estimate gas fee for `mint` should fail when connected to the provider', async () => {
|
|
49
|
-
expect(erc20.estimateFee.mint(wallet, '10')).rejects.toThrow();
|
|
54
|
+
expect(erc20.estimateFee.mint(wallet, ['10', '0'])).rejects.toThrow();
|
|
50
55
|
});
|
|
51
56
|
|
|
52
57
|
test('read initial balance of that account', async () => {
|
|
53
|
-
const result = await erc20.
|
|
58
|
+
const result = await erc20.balanceOf(wallet);
|
|
54
59
|
const [res] = result;
|
|
55
|
-
expect(res).toStrictEqual(toBN(
|
|
56
|
-
expect(res).toStrictEqual(result.
|
|
60
|
+
expect(res.low).toStrictEqual(toBN(1000));
|
|
61
|
+
expect(res).toStrictEqual(result.balance);
|
|
57
62
|
});
|
|
58
63
|
|
|
59
64
|
test('read balance in a multicall', async () => {
|
|
@@ -61,7 +66,7 @@ describe('class Contract {}', () => {
|
|
|
61
66
|
const args2 = {};
|
|
62
67
|
const calls = [
|
|
63
68
|
erc20.address,
|
|
64
|
-
getSelectorFromName('
|
|
69
|
+
getSelectorFromName('balanceOf'),
|
|
65
70
|
Object.keys(args1).length,
|
|
66
71
|
...compileCalldata(args1),
|
|
67
72
|
|
|
@@ -190,21 +195,27 @@ describe('class Contract {}', () => {
|
|
|
190
195
|
|
|
191
196
|
describe('class ContractFactory {}', () => {
|
|
192
197
|
let erc20Address: string;
|
|
198
|
+
const wallet = stark.randomAddress();
|
|
199
|
+
let erc20DeployPayload: DeployContractPayload;
|
|
200
|
+
|
|
193
201
|
beforeAll(async () => {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
202
|
+
erc20DeployPayload = getERC20DeployPayload(wallet);
|
|
203
|
+
|
|
204
|
+
const { contract_address, transaction_hash } = await provider.deployContract(
|
|
205
|
+
erc20DeployPayload
|
|
206
|
+
);
|
|
207
|
+
|
|
197
208
|
await provider.waitForTransaction(transaction_hash);
|
|
198
209
|
erc20Address = contract_address;
|
|
199
210
|
});
|
|
200
211
|
test('deployment of new contract', async () => {
|
|
201
212
|
const factory = new ContractFactory(compiledErc20, provider);
|
|
202
|
-
const erc20 = await factory.deploy();
|
|
213
|
+
const erc20 = await factory.deploy(erc20DeployPayload.constructorCalldata);
|
|
203
214
|
expect(erc20 instanceof Contract);
|
|
204
215
|
});
|
|
205
216
|
test('wait for deployment transaction', async () => {
|
|
206
217
|
const factory = new ContractFactory(compiledErc20, provider);
|
|
207
|
-
const contract = await factory.deploy();
|
|
218
|
+
const contract = await factory.deploy(erc20DeployPayload.constructorCalldata);
|
|
208
219
|
expect(contract.deployed()).resolves.not.toThrow();
|
|
209
220
|
});
|
|
210
221
|
test('attach new contract', async () => {
|
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BlockNumber,
|
|
3
|
-
DeclareContractResponse,
|
|
4
|
-
DeployContractResponse,
|
|
5
|
-
GetBlockResponse,
|
|
6
|
-
stark,
|
|
7
|
-
} from '../src';
|
|
1
|
+
import { BlockNumber, DeployContractResponse, GetBlockResponse, stark } from '../src';
|
|
8
2
|
import { toBN } from '../src/utils/number';
|
|
9
3
|
import {
|
|
10
|
-
compiledErc20,
|
|
11
4
|
compiledOpenZeppelinAccount,
|
|
12
5
|
describeIfNotDevnet,
|
|
6
|
+
getERC20DeployPayload,
|
|
13
7
|
getTestProvider,
|
|
14
8
|
} from './fixtures';
|
|
15
9
|
|
|
@@ -24,11 +18,14 @@ describe('defaultProvider', () => {
|
|
|
24
18
|
let exampleBlock: GetBlockResponse;
|
|
25
19
|
let exampleBlockNumber: BlockNumber;
|
|
26
20
|
let exampleBlockHash: string;
|
|
21
|
+
const wallet = stark.randomAddress();
|
|
27
22
|
|
|
28
23
|
beforeAll(async () => {
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
}
|
|
24
|
+
const erc20DeployPayload = getERC20DeployPayload(wallet);
|
|
25
|
+
|
|
26
|
+
const { contract_address, transaction_hash } = await testProvider.deployContract(
|
|
27
|
+
erc20DeployPayload
|
|
28
|
+
);
|
|
32
29
|
await testProvider.waitForTransaction(transaction_hash);
|
|
33
30
|
exampleTransactionHash = transaction_hash;
|
|
34
31
|
exampleContractAddress = contract_address;
|
|
@@ -58,7 +55,7 @@ describe('defaultProvider', () => {
|
|
|
58
55
|
});
|
|
59
56
|
|
|
60
57
|
test('getBlock() -> { blockNumber }', async () => {
|
|
61
|
-
const block = await testProvider.getBlock();
|
|
58
|
+
const block = await testProvider.getBlock('latest');
|
|
62
59
|
return expect(block).toHaveProperty('block_number');
|
|
63
60
|
});
|
|
64
61
|
|
|
@@ -101,7 +98,7 @@ describe('defaultProvider', () => {
|
|
|
101
98
|
return expect(
|
|
102
99
|
testProvider.callContract({
|
|
103
100
|
contractAddress: exampleContractAddress,
|
|
104
|
-
entrypoint: '
|
|
101
|
+
entrypoint: 'balanceOf',
|
|
105
102
|
calldata: compileCalldata({
|
|
106
103
|
user: '0x9ff64f4ab0e1fe88df4465ade98d1ea99d5732761c39279b8e1374fa943e9b',
|
|
107
104
|
}),
|
|
@@ -123,15 +120,6 @@ describe('defaultProvider', () => {
|
|
|
123
120
|
});
|
|
124
121
|
|
|
125
122
|
describe('addTransaction()', () => {
|
|
126
|
-
test('declareContract()', async () => {
|
|
127
|
-
const response = await testProvider.declareContract({
|
|
128
|
-
contract: compiledErc20,
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
expect(response.transaction_hash).toBeDefined();
|
|
132
|
-
expect(response.class_hash).toBeDefined();
|
|
133
|
-
});
|
|
134
|
-
|
|
135
123
|
test('deployContract()', async () => {
|
|
136
124
|
const response = await testProvider.deployContract({
|
|
137
125
|
contract: compiledOpenZeppelinAccount,
|
|
@@ -147,8 +135,8 @@ describe('defaultProvider', () => {
|
|
|
147
135
|
let latestBlock;
|
|
148
136
|
describe(`Provider methods if not devnet`, () => {
|
|
149
137
|
describe('getBlock', () => {
|
|
150
|
-
test('getBlock by tag
|
|
151
|
-
latestBlock = await provider.getBlock();
|
|
138
|
+
test('getBlock by tag latest', async () => {
|
|
139
|
+
latestBlock = await provider.getBlock('latest');
|
|
152
140
|
expect(latestBlock).toHaveProperty('block_hash');
|
|
153
141
|
expect(latestBlock).toHaveProperty('parent_hash');
|
|
154
142
|
expect(latestBlock).toHaveProperty('block_number');
|
|
@@ -221,6 +209,7 @@ describe('defaultProvider', () => {
|
|
|
221
209
|
expect(transaction.transaction_hash).toBeTruthy();
|
|
222
210
|
expect(transaction.contract_address).toBeTruthy();
|
|
223
211
|
expect(Array.isArray(transaction.calldata)).toBe(true);
|
|
212
|
+
// expect(transaction.entry_point_selector).toBeTruthy();
|
|
224
213
|
expect(Array.isArray(transaction.signature)).toBe(true);
|
|
225
214
|
expect(transaction.max_fee).toBeTruthy();
|
|
226
215
|
});
|
|
@@ -242,28 +231,22 @@ describe('defaultProvider', () => {
|
|
|
242
231
|
const receipt = await provider.getTransactionReceipt(
|
|
243
232
|
'0x37013e1cb9c133e6fe51b4b371b76b317a480f56d80576730754c1662582348'
|
|
244
233
|
);
|
|
245
|
-
|
|
246
234
|
expect(receipt).toHaveProperty('transaction_hash');
|
|
247
235
|
expect(receipt).toHaveProperty('status');
|
|
248
|
-
expect(receipt).toHaveProperty('
|
|
249
|
-
expect(receipt).toHaveProperty('events');
|
|
236
|
+
expect(receipt).toHaveProperty('actual_fee');
|
|
250
237
|
});
|
|
251
238
|
});
|
|
252
239
|
|
|
253
240
|
describe('Contract methods', () => {
|
|
254
241
|
let contractAddress: string;
|
|
255
242
|
let deployResponse: DeployContractResponse;
|
|
256
|
-
let declareResponse: DeclareContractResponse;
|
|
257
243
|
let blockNumber: BlockNumber;
|
|
258
244
|
|
|
259
245
|
beforeAll(async () => {
|
|
260
|
-
|
|
246
|
+
const erc20DeployPayload = getERC20DeployPayload(wallet);
|
|
247
|
+
deployResponse = await provider.deployContract(erc20DeployPayload);
|
|
261
248
|
contractAddress = deployResponse.contract_address;
|
|
262
|
-
|
|
263
|
-
await Promise.all([
|
|
264
|
-
provider.waitForTransaction(deployResponse.transaction_hash),
|
|
265
|
-
provider.waitForTransaction(declareResponse.transaction_hash),
|
|
266
|
-
]);
|
|
249
|
+
await provider.waitForTransaction(deployResponse.transaction_hash);
|
|
267
250
|
({ block_number: blockNumber } = await provider.getBlock('latest'));
|
|
268
251
|
});
|
|
269
252
|
|
|
@@ -274,13 +257,6 @@ describe('defaultProvider', () => {
|
|
|
274
257
|
});
|
|
275
258
|
});
|
|
276
259
|
|
|
277
|
-
describe('declareContract', () => {
|
|
278
|
-
test('response', async () => {
|
|
279
|
-
expect(declareResponse.class_hash).toBeTruthy();
|
|
280
|
-
expect(declareResponse.transaction_hash).toBeTruthy();
|
|
281
|
-
});
|
|
282
|
-
});
|
|
283
|
-
|
|
284
260
|
describe('getClassAt', () => {
|
|
285
261
|
test('response', async () => {
|
|
286
262
|
const classResponse = await provider.getClassAt(contractAddress, blockNumber);
|
|
@@ -296,9 +272,9 @@ describe('defaultProvider', () => {
|
|
|
296
272
|
provider
|
|
297
273
|
.callContract({
|
|
298
274
|
contractAddress: deployResponse.contract_address,
|
|
299
|
-
entrypoint: '
|
|
275
|
+
entrypoint: 'balanceOf',
|
|
300
276
|
calldata: compileCalldata({
|
|
301
|
-
user:
|
|
277
|
+
user: wallet,
|
|
302
278
|
}),
|
|
303
279
|
})
|
|
304
280
|
.then((res) => {
|
package/__tests__/fixtures.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
|
|
3
3
|
import { Account, ProviderInterface, RpcProvider, SequencerProvider, ec, json } from '../src';
|
|
4
|
-
import { CompiledContract } from '../src/types';
|
|
4
|
+
import { CompiledContract, DeployContractPayload } from '../src/types';
|
|
5
|
+
import { encodeShortString } from '../src/utils/shortString';
|
|
5
6
|
|
|
6
7
|
const readContract = (name: string): CompiledContract =>
|
|
7
8
|
json.parse(fs.readFileSync(`./__mocks__/${name}.json`).toString('ascii'));
|
|
@@ -71,3 +72,10 @@ const describeIf = (condition: boolean) => (condition ? describe : describe.skip
|
|
|
71
72
|
export const describeIfSequencer = describeIf(IS_DEVNET);
|
|
72
73
|
export const describeIfRpc = describeIf(IS_RPC);
|
|
73
74
|
export const describeIfNotDevnet = describeIf(!IS_DEVNET);
|
|
75
|
+
|
|
76
|
+
export const getERC20DeployPayload = (recipient: string): DeployContractPayload => {
|
|
77
|
+
return {
|
|
78
|
+
contract: compiledErc20,
|
|
79
|
+
constructorCalldata: [encodeShortString('Token'), encodeShortString('ERC20'), recipient],
|
|
80
|
+
};
|
|
81
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Account, GetBlockResponse, RpcProvider, ec } from '../src';
|
|
2
2
|
import {
|
|
3
|
-
compiledErc20,
|
|
4
3
|
compiledOpenZeppelinAccount,
|
|
5
4
|
describeIfRpc,
|
|
6
5
|
getTestAccount,
|
|
@@ -116,20 +115,12 @@ describeIfRpc('RPCProvider', () => {
|
|
|
116
115
|
});
|
|
117
116
|
});
|
|
118
117
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}));
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
test('getClass', async () => {
|
|
129
|
-
const contractClass = await rpcProvider.getClass(class_hash);
|
|
130
|
-
expect(contractClass).toHaveProperty('program');
|
|
131
|
-
expect(contractClass).toHaveProperty('entry_points_by_type');
|
|
132
|
-
});
|
|
118
|
+
test('getClass classHash 0x0733734fa0dab1158bccdfe0df7b0becf3827f908971fac8d39cc73d99ad8645', async () => {
|
|
119
|
+
const contractClass = await rpcProvider.getClass(
|
|
120
|
+
'0x0733734fa0dab1158bccdfe0df7b0becf3827f908971fac8d39cc73d99ad8645'
|
|
121
|
+
);
|
|
122
|
+
expect(contractClass).toHaveProperty('program');
|
|
123
|
+
expect(contractClass).toHaveProperty('entry_points_by_type');
|
|
133
124
|
});
|
|
134
125
|
|
|
135
126
|
test.todo('getEstimateFee');
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
compiledL1L2,
|
|
7
7
|
describeIfNotDevnet,
|
|
8
8
|
describeIfSequencer,
|
|
9
|
+
getERC20DeployPayload,
|
|
9
10
|
getTestProvider,
|
|
10
11
|
} from './fixtures';
|
|
11
12
|
|
|
@@ -19,7 +20,7 @@ describeIfSequencer('SequencerProvider', () => {
|
|
|
19
20
|
sequencerProvider = getTestProvider() as SequencerProvider;
|
|
20
21
|
customSequencerProvider = new Provider({
|
|
21
22
|
sequencer: {
|
|
22
|
-
baseUrl: '
|
|
23
|
+
baseUrl: 'http://127.0.0.1:5050/',
|
|
23
24
|
feederGatewayUrl: 'feeder_gateway',
|
|
24
25
|
gatewayUrl: 'gateway',
|
|
25
26
|
}, // Similar to arguements used in docs
|
|
@@ -28,11 +29,15 @@ describeIfSequencer('SequencerProvider', () => {
|
|
|
28
29
|
|
|
29
30
|
describe('Gateway specific methods', () => {
|
|
30
31
|
let exampleTransactionHash: string;
|
|
32
|
+
const wallet = stark.randomAddress();
|
|
31
33
|
|
|
32
34
|
beforeAll(async () => {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
}
|
|
35
|
+
const erc20DeployPayload = getERC20DeployPayload(wallet);
|
|
36
|
+
|
|
37
|
+
const { contract_address, transaction_hash } = await sequencerProvider.deployContract(
|
|
38
|
+
erc20DeployPayload
|
|
39
|
+
);
|
|
40
|
+
|
|
36
41
|
await sequencerProvider.waitForTransaction(transaction_hash);
|
|
37
42
|
exampleTransactionHash = transaction_hash;
|
|
38
43
|
exampleContractAddress = contract_address;
|
|
@@ -69,19 +74,21 @@ describeIfSequencer('SequencerProvider', () => {
|
|
|
69
74
|
const wallet = stark.randomAddress();
|
|
70
75
|
|
|
71
76
|
beforeAll(async () => {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
}
|
|
77
|
+
const erc20DeployPayload = getERC20DeployPayload(wallet);
|
|
78
|
+
|
|
79
|
+
const { contract_address, transaction_hash } = await customSequencerProvider.deployContract(
|
|
80
|
+
erc20DeployPayload
|
|
81
|
+
);
|
|
75
82
|
|
|
76
83
|
await customSequencerProvider.waitForTransaction(transaction_hash);
|
|
77
84
|
erc20 = new Contract(compiledErc20.abi, contract_address, customSequencerProvider);
|
|
78
85
|
});
|
|
79
86
|
|
|
80
87
|
test('Check ERC20 balance using Custom Sequencer Provider', async () => {
|
|
81
|
-
const result = await erc20.
|
|
88
|
+
const result = await erc20.balanceOf(wallet);
|
|
82
89
|
const [res] = result;
|
|
83
|
-
expect(res).toStrictEqual(toBN(
|
|
84
|
-
expect(res).toStrictEqual(result.
|
|
90
|
+
expect(res.low).toStrictEqual(toBN(1000));
|
|
91
|
+
expect(res).toStrictEqual(result.balance);
|
|
85
92
|
});
|
|
86
93
|
});
|
|
87
94
|
|
|
@@ -53,7 +53,7 @@ describe('MerkleTree class', () => {
|
|
|
53
53
|
MerkleTree.hash(leaves[0], leaves[1]),
|
|
54
54
|
MerkleTree.hash(leaves[2], leaves[3])
|
|
55
55
|
),
|
|
56
|
-
MerkleTree.hash(leaves[4], leaves[5])
|
|
56
|
+
MerkleTree.hash(MerkleTree.hash(leaves[4], leaves[5]), '0x0')
|
|
57
57
|
);
|
|
58
58
|
|
|
59
59
|
expect(tree.root).toBe(manualMerkle);
|
|
@@ -67,7 +67,7 @@ describe('MerkleTree class', () => {
|
|
|
67
67
|
MerkleTree.hash(leaves[0], leaves[1]),
|
|
68
68
|
MerkleTree.hash(leaves[2], leaves[3])
|
|
69
69
|
),
|
|
70
|
-
MerkleTree.hash(MerkleTree.hash(leaves[4], leaves[5]), leaves[6])
|
|
70
|
+
MerkleTree.hash(MerkleTree.hash(leaves[4], leaves[5]), MerkleTree.hash(leaves[6], '0x0'))
|
|
71
71
|
);
|
|
72
72
|
|
|
73
73
|
expect(tree.root).toBe(manualMerkle);
|
|
@@ -85,7 +85,7 @@ describe('MerkleTree class', () => {
|
|
|
85
85
|
const manualProof = [
|
|
86
86
|
'0x4',
|
|
87
87
|
MerkleTree.hash('0x1', '0x2'),
|
|
88
|
-
MerkleTree.hash(MerkleTree.hash('0x5', '0x6'), '0x7'),
|
|
88
|
+
MerkleTree.hash(MerkleTree.hash('0x5', '0x6'), MerkleTree.hash('0x7', '0x0')),
|
|
89
89
|
];
|
|
90
90
|
|
|
91
91
|
expect(proof).toEqual(manualProof);
|
|
@@ -101,6 +101,17 @@ describe('MerkleTree class', () => {
|
|
|
101
101
|
|
|
102
102
|
expect(proof).toEqual(manualProof);
|
|
103
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
|
+
});
|
|
104
115
|
test('should throw for invalid child', () => {
|
|
105
116
|
expect(() => tree.getProof('0x8')).toThrow('leaf not found');
|
|
106
117
|
});
|
|
@@ -114,6 +125,7 @@ describe('MerkleTree class', () => {
|
|
|
114
125
|
|
|
115
126
|
test('should return true for valid manual proof', async () => {
|
|
116
127
|
const manualProof = [
|
|
128
|
+
'0x0', // tree should be padded with 0x0 so that all proofs are equals in size
|
|
117
129
|
MerkleTree.hash('0x5', '0x6'),
|
|
118
130
|
MerkleTree.hash(MerkleTree.hash('0x1', '0x2'), MerkleTree.hash('0x3', '0x4')),
|
|
119
131
|
];
|
|
@@ -122,6 +134,17 @@ describe('MerkleTree class', () => {
|
|
|
122
134
|
|
|
123
135
|
expect(proofMerklePath(root, leaf, manualProof)).toBe(true);
|
|
124
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
|
+
});
|
|
125
148
|
test('should return true for valid proof', async () => {
|
|
126
149
|
const proof = tree.getProof('0x3');
|
|
127
150
|
const leaf = '0x3';
|
|
@@ -158,4 +181,76 @@ describe('MerkleTree class', () => {
|
|
|
158
181
|
expect(proofMerklePath(root, leaf, proof)).toBe(false);
|
|
159
182
|
});
|
|
160
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
|
+
});
|
|
161
256
|
});
|
|
@@ -72,7 +72,7 @@ describe('typedData', () => {
|
|
|
72
72
|
const [, merkleTreeHash] = encodeValue({}, 'merkletree', tree.leaves);
|
|
73
73
|
expect(merkleTreeHash).toBe(tree.root);
|
|
74
74
|
expect(merkleTreeHash).toMatchInlineSnapshot(
|
|
75
|
-
`"
|
|
75
|
+
`"0x15ac9e457789ef0c56e5d559809e7336a909c14ee2511503fa7af69be1ba639"`
|
|
76
76
|
);
|
|
77
77
|
});
|
|
78
78
|
|
|
@@ -119,7 +119,7 @@ describe('typedData', () => {
|
|
|
119
119
|
);
|
|
120
120
|
expect(merkleTreeHash).toBe(tree.root);
|
|
121
121
|
expect(merkleTreeHash).toMatchInlineSnapshot(
|
|
122
|
-
`"
|
|
122
|
+
`"0x12354b159e3799dc0ebe86d62dde4ce7b300538d471e5a7fef23dcbac076011"`
|
|
123
123
|
);
|
|
124
124
|
});
|
|
125
125
|
|
|
@@ -217,7 +217,7 @@ describe('typedData', () => {
|
|
|
217
217
|
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
|
|
218
218
|
);
|
|
219
219
|
expect(hash).toMatchInlineSnapshot(
|
|
220
|
-
`"
|
|
220
|
+
`"0x751fb7d98545f7649d0d0eadc80d770fcd88d8cfaa55590b284f4e1b701ef0a"`
|
|
221
221
|
);
|
|
222
222
|
});
|
|
223
223
|
});
|