starknet 4.8.0 → 4.10.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 +46 -0
- package/README.md +1 -3
- 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 +91 -240
- package/__tests__/fixtures.ts +10 -2
- package/__tests__/rpcProvider.test.ts +8 -16
- package/__tests__/sequencerProvider.test.ts +17 -10
- package/__tests__/udc.test.ts +41 -0
- package/__tests__/utils/merkle.test.ts +98 -3
- package/__tests__/utils/typedData.test.ts +3 -3
- package/account/default.d.ts +12 -44
- package/account/default.js +305 -61
- package/account/interface.d.ts +96 -8
- package/constants.d.ts +8 -1
- package/constants.js +8 -1
- package/contract/default.d.ts +11 -27
- package/contract/default.js +105 -121
- package/contract/interface.d.ts +5 -2
- package/dist/account/default.d.ts +12 -44
- package/dist/account/default.js +305 -61
- package/dist/account/interface.d.ts +96 -8
- package/dist/constants.d.ts +8 -1
- package/dist/constants.js +8 -1
- package/dist/contract/default.d.ts +11 -27
- package/dist/contract/default.js +105 -121
- package/dist/contract/interface.d.ts +5 -2
- 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 +10 -3
- package/dist/provider/rpc.js +98 -10
- package/dist/provider/sequencer.d.ts +11 -4
- package/dist/provider/sequencer.js +89 -18
- package/dist/signer/default.d.ts +5 -2
- package/dist/signer/default.js +25 -3
- package/dist/signer/interface.d.ts +29 -2
- package/dist/types/api/index.d.ts +0 -6
- package/dist/types/api/openrpc.d.ts +24 -2
- package/dist/types/api/sequencer.d.ts +22 -7
- package/dist/types/index.d.ts +1 -1
- package/dist/types/lib.d.ts +36 -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/number.d.ts +1 -0
- package/dist/utils/number.js +3 -1
- 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 +10 -3
- package/provider/rpc.js +98 -10
- package/provider/sequencer.d.ts +11 -4
- package/provider/sequencer.js +89 -18
- package/signer/default.d.ts +5 -2
- package/signer/default.js +25 -3
- package/signer/interface.d.ts +29 -2
- package/src/account/default.ts +243 -55
- package/src/account/interface.ts +132 -7
- package/src/constants.ts +8 -0
- package/src/contract/default.ts +124 -141
- package/src/contract/interface.ts +5 -2
- package/src/provider/default.ts +43 -5
- package/src/provider/interface.ts +92 -7
- package/src/provider/rpc.ts +93 -15
- package/src/provider/sequencer.ts +87 -14
- package/src/signer/default.ts +56 -4
- package/src/signer/interface.ts +33 -2
- package/src/types/api/index.ts +0 -4
- package/src/types/api/openrpc.ts +28 -2
- package/src/types/api/sequencer.ts +32 -9
- package/src/types/index.ts +1 -1
- package/src/types/lib.ts +43 -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/number.ts +2 -0
- package/src/utils/responseParser/rpc.ts +4 -20
- package/src/utils/responseParser/sequencer.ts +2 -0
- package/types/api/index.d.ts +0 -6
- package/types/api/openrpc.d.ts +24 -2
- package/types/api/sequencer.d.ts +22 -7
- package/types/index.d.ts +1 -1
- package/types/lib.d.ts +36 -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/number.d.ts +1 -0
- package/utils/number.js +3 -1
- 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 +170 -11
- package/www/docs/API/contract.md +39 -3
- package/www/docs/API/provider.md +310 -17
- package/www/docs/API/signer.md +56 -2
- package/www/guides/erc20.md +13 -7
package/src/provider/rpc.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { StarknetChainId } from '../constants';
|
|
|
2
2
|
import {
|
|
3
3
|
Call,
|
|
4
4
|
CallContractResponse,
|
|
5
|
-
DeclareContractPayload,
|
|
6
5
|
DeclareContractResponse,
|
|
7
6
|
DeployContractPayload,
|
|
8
7
|
DeployContractResponse,
|
|
@@ -16,6 +15,11 @@ import {
|
|
|
16
15
|
InvokeFunctionResponse,
|
|
17
16
|
} from '../types';
|
|
18
17
|
import { RPC } from '../types/api';
|
|
18
|
+
import {
|
|
19
|
+
DeclareContractTransaction,
|
|
20
|
+
DeployAccountContractPayload,
|
|
21
|
+
DeployAccountContractTransaction,
|
|
22
|
+
} from '../types/lib';
|
|
19
23
|
import fetch from '../utils/fetchPonyfill';
|
|
20
24
|
import { getSelectorFromName } from '../utils/hash';
|
|
21
25
|
import { stringify } from '../utils/json';
|
|
@@ -34,6 +38,7 @@ import { Block, BlockIdentifier } from './utils';
|
|
|
34
38
|
export type RpcProviderOptions = {
|
|
35
39
|
nodeUrl: string;
|
|
36
40
|
retries?: number;
|
|
41
|
+
headers?: object;
|
|
37
42
|
};
|
|
38
43
|
|
|
39
44
|
export class RpcProvider implements ProviderInterface {
|
|
@@ -42,14 +47,17 @@ export class RpcProvider implements ProviderInterface {
|
|
|
42
47
|
// from interface
|
|
43
48
|
public chainId!: StarknetChainId;
|
|
44
49
|
|
|
50
|
+
public headers: object;
|
|
51
|
+
|
|
45
52
|
private responseParser = new RPCResponseParser();
|
|
46
53
|
|
|
47
54
|
private retries: number;
|
|
48
55
|
|
|
49
56
|
constructor(optionsOrProvider: RpcProviderOptions) {
|
|
50
|
-
const { nodeUrl, retries } = optionsOrProvider;
|
|
57
|
+
const { nodeUrl, retries, headers } = optionsOrProvider;
|
|
51
58
|
this.nodeUrl = nodeUrl;
|
|
52
59
|
this.retries = retries || 200;
|
|
60
|
+
this.headers = { 'Content-Type': 'application/json', ...headers };
|
|
53
61
|
|
|
54
62
|
this.getChainId().then((chainId) => {
|
|
55
63
|
this.chainId = chainId;
|
|
@@ -60,7 +68,7 @@ export class RpcProvider implements ProviderInterface {
|
|
|
60
68
|
return fetch(this.nodeUrl, {
|
|
61
69
|
method: 'POST',
|
|
62
70
|
body: stringify({ method, jsonrpc: '2.0', params, id: 0 }),
|
|
63
|
-
headers:
|
|
71
|
+
headers: this.headers,
|
|
64
72
|
});
|
|
65
73
|
}
|
|
66
74
|
|
|
@@ -183,9 +191,7 @@ export class RpcProvider implements ProviderInterface {
|
|
|
183
191
|
}
|
|
184
192
|
|
|
185
193
|
public async getTransactionReceipt(txHash: string): Promise<GetTransactionReceiptResponse> {
|
|
186
|
-
return this.fetchEndpoint('starknet_getTransactionReceipt', { transaction_hash: txHash })
|
|
187
|
-
this.responseParser.parseGetTransactionReceiptResponse
|
|
188
|
-
);
|
|
194
|
+
return this.fetchEndpoint('starknet_getTransactionReceipt', { transaction_hash: txHash });
|
|
189
195
|
}
|
|
190
196
|
|
|
191
197
|
public async getClass(classHash: RPC.Felt): Promise<RPC.ContractClass> {
|
|
@@ -194,7 +200,7 @@ export class RpcProvider implements ProviderInterface {
|
|
|
194
200
|
|
|
195
201
|
public async getClassAt(
|
|
196
202
|
contractAddress: string,
|
|
197
|
-
blockIdentifier: BlockIdentifier
|
|
203
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
198
204
|
): Promise<RPC.ContractClass> {
|
|
199
205
|
const block_id = new Block(blockIdentifier).identifier;
|
|
200
206
|
return this.fetchEndpoint('starknet_getClassAt', {
|
|
@@ -214,33 +220,93 @@ export class RpcProvider implements ProviderInterface {
|
|
|
214
220
|
invocation: Invocation,
|
|
215
221
|
invocationDetails: InvocationsDetailsWithNonce,
|
|
216
222
|
blockIdentifier: BlockIdentifier = 'pending'
|
|
223
|
+
): Promise<EstimateFeeResponse> {
|
|
224
|
+
return this.getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
public async getInvokeEstimateFee(
|
|
228
|
+
invocation: Invocation,
|
|
229
|
+
invocationDetails: InvocationsDetailsWithNonce,
|
|
230
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
217
231
|
): Promise<EstimateFeeResponse> {
|
|
218
232
|
const block_id = new Block(blockIdentifier).identifier;
|
|
219
233
|
return this.fetchEndpoint('starknet_estimateFee', {
|
|
220
234
|
request: {
|
|
235
|
+
type: 'INVOKE',
|
|
221
236
|
contract_address: invocation.contractAddress,
|
|
222
237
|
calldata: parseCalldata(invocation.calldata),
|
|
223
238
|
signature: bigNumberishArrayToHexadecimalStringArray(invocation.signature || []),
|
|
224
239
|
version: toHex(toBN(invocationDetails?.version || 0)),
|
|
240
|
+
nonce: toHex(toBN(invocationDetails.nonce)),
|
|
225
241
|
max_fee: toHex(toBN(invocationDetails?.maxFee || 0)),
|
|
226
242
|
},
|
|
227
243
|
block_id,
|
|
228
244
|
}).then(this.responseParser.parseFeeEstimateResponse);
|
|
229
245
|
}
|
|
230
246
|
|
|
231
|
-
|
|
232
|
-
contract,
|
|
233
|
-
version,
|
|
234
|
-
}: DeclareContractPayload): Promise<DeclareContractResponse> {
|
|
235
|
-
const contractDefinition = parseContract(contract);
|
|
247
|
+
// TODO: Revisit after Pathfinder release with JSON-RPC v0.2.1 RPC Spec
|
|
236
248
|
|
|
249
|
+
public async getDeclareEstimateFee(
|
|
250
|
+
{ senderAddress, contractDefinition, signature }: DeclareContractTransaction,
|
|
251
|
+
details: InvocationsDetailsWithNonce,
|
|
252
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
253
|
+
): Promise<EstimateFeeResponse> {
|
|
254
|
+
const block_id = new Block(blockIdentifier).identifier;
|
|
255
|
+
return this.fetchEndpoint('starknet_estimateFee', {
|
|
256
|
+
request: {
|
|
257
|
+
type: 'DECLARE',
|
|
258
|
+
contract_class: {
|
|
259
|
+
program: contractDefinition.program,
|
|
260
|
+
entry_points_by_type: contractDefinition.entry_points_by_type,
|
|
261
|
+
abi: contractDefinition.abi, // rpc 2.0
|
|
262
|
+
},
|
|
263
|
+
sender_address: senderAddress,
|
|
264
|
+
signature: bigNumberishArrayToHexadecimalStringArray(signature || []),
|
|
265
|
+
version: toHex(toBN(details?.version || 0)),
|
|
266
|
+
nonce: toHex(toBN(details.nonce)),
|
|
267
|
+
max_fee: toHex(toBN(details?.maxFee || 0)),
|
|
268
|
+
},
|
|
269
|
+
block_id,
|
|
270
|
+
}).then(this.responseParser.parseFeeEstimateResponse);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
public async getDeployAccountEstimateFee(
|
|
274
|
+
{ classHash, constructorCalldata, addressSalt, signature }: DeployAccountContractTransaction,
|
|
275
|
+
details: InvocationsDetailsWithNonce,
|
|
276
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
277
|
+
): Promise<EstimateFeeResponse> {
|
|
278
|
+
const block_id = new Block(blockIdentifier).identifier;
|
|
279
|
+
return this.fetchEndpoint('starknet_estimateFee', {
|
|
280
|
+
request: {
|
|
281
|
+
type: 'DEPLOY_ACCOUNT',
|
|
282
|
+
constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata || []),
|
|
283
|
+
class_hash: toHex(toBN(classHash)),
|
|
284
|
+
contract_address_salt: toHex(toBN(addressSalt || 0)),
|
|
285
|
+
signature: bigNumberishArrayToHexadecimalStringArray(signature || []),
|
|
286
|
+
version: toHex(toBN(details?.version || 0)),
|
|
287
|
+
nonce: toHex(toBN(details.nonce)),
|
|
288
|
+
max_fee: toHex(toBN(details?.maxFee || 0)),
|
|
289
|
+
},
|
|
290
|
+
block_id,
|
|
291
|
+
}).then(this.responseParser.parseFeeEstimateResponse);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// TODO: Revisit after Pathfinder release with JSON-RPC v0.2.1 RPC Spec
|
|
295
|
+
public async declareContract(
|
|
296
|
+
{ contractDefinition, signature, senderAddress }: DeclareContractTransaction,
|
|
297
|
+
details: InvocationsDetailsWithNonce
|
|
298
|
+
): Promise<DeclareContractResponse> {
|
|
237
299
|
return this.fetchEndpoint('starknet_addDeclareTransaction', {
|
|
238
300
|
contract_class: {
|
|
239
301
|
program: contractDefinition.program,
|
|
240
302
|
entry_points_by_type: contractDefinition.entry_points_by_type,
|
|
241
303
|
abi: contractDefinition.abi, // rpc 2.0
|
|
242
304
|
},
|
|
243
|
-
version: toHex(toBN(version || 0)),
|
|
305
|
+
version: toHex(toBN(details.version || 0)),
|
|
306
|
+
max_fee: toHex(toBN(details.maxFee || 0)),
|
|
307
|
+
signature: bigNumberishArrayToHexadecimalStringArray(signature || []),
|
|
308
|
+
sender_address: senderAddress,
|
|
309
|
+
nonce: toHex(toBN(details.nonce)),
|
|
244
310
|
});
|
|
245
311
|
}
|
|
246
312
|
|
|
@@ -262,6 +328,18 @@ export class RpcProvider implements ProviderInterface {
|
|
|
262
328
|
});
|
|
263
329
|
}
|
|
264
330
|
|
|
331
|
+
public async deployAccountContract({
|
|
332
|
+
classHash,
|
|
333
|
+
constructorCalldata,
|
|
334
|
+
addressSalt,
|
|
335
|
+
}: DeployAccountContractPayload): Promise<DeployContractResponse> {
|
|
336
|
+
return this.fetchEndpoint('starknet_addDeployAccountTransaction', {
|
|
337
|
+
constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata || []),
|
|
338
|
+
class_hash: toHex(toBN(classHash)),
|
|
339
|
+
contract_address_salt: toHex(toBN(addressSalt || 0)),
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
|
|
265
343
|
public async invokeFunction(
|
|
266
344
|
functionInvocation: Invocation,
|
|
267
345
|
details: InvocationsDetailsWithNonce
|
|
@@ -317,9 +395,9 @@ export class RpcProvider implements ProviderInterface {
|
|
|
317
395
|
// eslint-disable-next-line no-await-in-loop
|
|
318
396
|
const res = await this.getTransactionReceipt(txHash);
|
|
319
397
|
|
|
320
|
-
if (successStates.includes(res.status)) {
|
|
398
|
+
if (res.status && successStates.includes(res.status)) {
|
|
321
399
|
onchain = true;
|
|
322
|
-
} else if (errorStates.includes(res.status)) {
|
|
400
|
+
} else if (res.status && errorStates.includes(res.status)) {
|
|
323
401
|
const message = res.status;
|
|
324
402
|
const error = new Error(message) as Error & { response: any };
|
|
325
403
|
error.response = res;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import urljoin from 'url-join';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { StarknetChainId } from '../constants';
|
|
4
4
|
import {
|
|
5
5
|
Call,
|
|
6
6
|
CallContractResponse,
|
|
7
7
|
ContractClass,
|
|
8
|
-
DeclareContractPayload,
|
|
9
8
|
DeclareContractResponse,
|
|
10
9
|
DeployContractPayload,
|
|
11
10
|
DeployContractResponse,
|
|
@@ -24,6 +23,7 @@ import {
|
|
|
24
23
|
GetTransactionTraceResponse,
|
|
25
24
|
Sequencer,
|
|
26
25
|
} from '../types/api';
|
|
26
|
+
import { DeclareContractTransaction, DeployAccountContractTransaction } from '../types/lib';
|
|
27
27
|
import fetch from '../utils/fetchPonyfill';
|
|
28
28
|
import { getSelector, getSelectorFromName } from '../utils/hash';
|
|
29
29
|
import { parse, parseAlwaysAsBig, stringify } from '../utils/json';
|
|
@@ -44,7 +44,7 @@ import { GatewayError, HttpError } from './errors';
|
|
|
44
44
|
import { ProviderInterface } from './interface';
|
|
45
45
|
import { Block, BlockIdentifier } from './utils';
|
|
46
46
|
|
|
47
|
-
type NetworkName = 'mainnet-alpha' | 'goerli-alpha';
|
|
47
|
+
type NetworkName = 'mainnet-alpha' | 'goerli-alpha' | 'goerli-alpha-2';
|
|
48
48
|
|
|
49
49
|
function isEmptyQueryObject(obj?: Record<any, any>): obj is undefined {
|
|
50
50
|
return (
|
|
@@ -62,6 +62,7 @@ export type SequencerProviderOptions =
|
|
|
62
62
|
feederGatewayUrl?: string;
|
|
63
63
|
gatewayUrl?: string;
|
|
64
64
|
chainId?: StarknetChainId;
|
|
65
|
+
headers?: object;
|
|
65
66
|
};
|
|
66
67
|
|
|
67
68
|
export class SequencerProvider implements ProviderInterface {
|
|
@@ -73,9 +74,11 @@ export class SequencerProvider implements ProviderInterface {
|
|
|
73
74
|
|
|
74
75
|
public chainId: StarknetChainId;
|
|
75
76
|
|
|
77
|
+
public headers: object | undefined;
|
|
78
|
+
|
|
76
79
|
private responseParser = new SequencerAPIResponseParser();
|
|
77
80
|
|
|
78
|
-
constructor(optionsOrProvider: SequencerProviderOptions = { network: 'goerli-alpha' }) {
|
|
81
|
+
constructor(optionsOrProvider: SequencerProviderOptions = { network: 'goerli-alpha-2' }) {
|
|
79
82
|
if ('network' in optionsOrProvider) {
|
|
80
83
|
this.baseUrl = SequencerProvider.getNetworkFromName(optionsOrProvider.network);
|
|
81
84
|
this.chainId = SequencerProvider.getChainIdFromBaseUrl(this.baseUrl);
|
|
@@ -93,6 +96,8 @@ export class SequencerProvider implements ProviderInterface {
|
|
|
93
96
|
this.chainId =
|
|
94
97
|
optionsOrProvider.chainId ??
|
|
95
98
|
SequencerProvider.getChainIdFromBaseUrl(optionsOrProvider.baseUrl);
|
|
99
|
+
|
|
100
|
+
this.headers = optionsOrProvider?.headers;
|
|
96
101
|
}
|
|
97
102
|
}
|
|
98
103
|
|
|
@@ -101,6 +106,9 @@ export class SequencerProvider implements ProviderInterface {
|
|
|
101
106
|
case 'mainnet-alpha':
|
|
102
107
|
return 'https://alpha-mainnet.starknet.io';
|
|
103
108
|
case 'goerli-alpha':
|
|
109
|
+
return 'https://alpha4.starknet.io';
|
|
110
|
+
case 'goerli-alpha-2':
|
|
111
|
+
return 'https://alpha4-2.starknet.io';
|
|
104
112
|
default:
|
|
105
113
|
return 'https://alpha4.starknet.io';
|
|
106
114
|
}
|
|
@@ -153,19 +161,20 @@ export class SequencerProvider implements ProviderInterface {
|
|
|
153
161
|
return `?${queryString}`;
|
|
154
162
|
}
|
|
155
163
|
|
|
156
|
-
private getHeaders(method: 'POST' | 'GET'):
|
|
164
|
+
private getHeaders(method: 'POST' | 'GET'): object | undefined {
|
|
157
165
|
if (method === 'POST') {
|
|
158
166
|
return {
|
|
159
167
|
'Content-Type': 'application/json',
|
|
168
|
+
...this.headers,
|
|
160
169
|
};
|
|
161
170
|
}
|
|
162
|
-
return
|
|
171
|
+
return this.headers;
|
|
163
172
|
}
|
|
164
173
|
|
|
165
174
|
// typesafe fetch
|
|
166
175
|
protected async fetchEndpoint<T extends keyof Sequencer.Endpoints>(
|
|
167
176
|
endpoint: T,
|
|
168
|
-
// typescript type
|
|
177
|
+
// typescript type magic to create a nice fitting function interface
|
|
169
178
|
...[query, request]: Sequencer.Endpoints[T]['QUERY'] extends never
|
|
170
179
|
? Sequencer.Endpoints[T]['REQUEST'] extends never
|
|
171
180
|
? [] // when no query and no request is needed, we can omit the query and request parameters
|
|
@@ -321,17 +330,34 @@ export class SequencerProvider implements ProviderInterface {
|
|
|
321
330
|
}).then(this.responseParser.parseDeployContractResponse);
|
|
322
331
|
}
|
|
323
332
|
|
|
324
|
-
public async
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
333
|
+
public async deployAccountContract(
|
|
334
|
+
{ classHash, constructorCalldata, addressSalt, signature }: DeployAccountContractTransaction,
|
|
335
|
+
details: InvocationsDetailsWithNonce
|
|
336
|
+
): Promise<DeployContractResponse> {
|
|
337
|
+
return this.fetchEndpoint('add_transaction', undefined, {
|
|
338
|
+
type: 'DEPLOY_ACCOUNT',
|
|
339
|
+
contract_address_salt: addressSalt ?? randomAddress(),
|
|
340
|
+
constructor_calldata: bigNumberishArrayToDecimalStringArray(constructorCalldata ?? []),
|
|
341
|
+
class_hash: toHex(toBN(classHash)),
|
|
342
|
+
max_fee: toHex(toBN(details.maxFee || 0)),
|
|
343
|
+
version: toHex(toBN(details.version || 0)),
|
|
344
|
+
nonce: toHex(toBN(details.nonce)),
|
|
345
|
+
signature: bigNumberishArrayToDecimalStringArray(signature || []),
|
|
346
|
+
}).then(this.responseParser.parseDeployContractResponse);
|
|
347
|
+
}
|
|
328
348
|
|
|
349
|
+
public async declareContract(
|
|
350
|
+
{ senderAddress, contractDefinition, signature }: DeclareContractTransaction,
|
|
351
|
+
details: InvocationsDetailsWithNonce
|
|
352
|
+
): Promise<DeclareContractResponse> {
|
|
329
353
|
return this.fetchEndpoint('add_transaction', undefined, {
|
|
330
354
|
type: 'DECLARE',
|
|
331
355
|
contract_class: contractDefinition,
|
|
332
|
-
nonce: toHex(
|
|
333
|
-
signature: [],
|
|
334
|
-
sender_address:
|
|
356
|
+
nonce: toHex(toBN(details.nonce)),
|
|
357
|
+
signature: bigNumberishArrayToDecimalStringArray(signature || []),
|
|
358
|
+
sender_address: senderAddress,
|
|
359
|
+
max_fee: toHex(toBN(details.maxFee || 0)),
|
|
360
|
+
version: toHex(toBN(details.version || 1)),
|
|
335
361
|
}).then(this.responseParser.parseDeclareContractResponse);
|
|
336
362
|
}
|
|
337
363
|
|
|
@@ -339,6 +365,14 @@ export class SequencerProvider implements ProviderInterface {
|
|
|
339
365
|
invocation: Invocation,
|
|
340
366
|
invocationDetails: InvocationsDetailsWithNonce,
|
|
341
367
|
blockIdentifier: BlockIdentifier = 'pending'
|
|
368
|
+
): Promise<EstimateFeeResponse> {
|
|
369
|
+
return this.getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
public async getInvokeEstimateFee(
|
|
373
|
+
invocation: Invocation,
|
|
374
|
+
invocationDetails: InvocationsDetailsWithNonce,
|
|
375
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
342
376
|
): Promise<EstimateFeeResponse> {
|
|
343
377
|
return this.fetchEndpoint(
|
|
344
378
|
'estimate_fee',
|
|
@@ -354,6 +388,45 @@ export class SequencerProvider implements ProviderInterface {
|
|
|
354
388
|
).then(this.responseParser.parseFeeEstimateResponse);
|
|
355
389
|
}
|
|
356
390
|
|
|
391
|
+
public async getDeclareEstimateFee(
|
|
392
|
+
{ senderAddress, contractDefinition, signature }: DeclareContractTransaction,
|
|
393
|
+
details: InvocationsDetailsWithNonce,
|
|
394
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
395
|
+
): Promise<EstimateFeeResponse> {
|
|
396
|
+
return this.fetchEndpoint(
|
|
397
|
+
'estimate_fee',
|
|
398
|
+
{ blockIdentifier },
|
|
399
|
+
{
|
|
400
|
+
type: 'DECLARE',
|
|
401
|
+
sender_address: senderAddress,
|
|
402
|
+
contract_class: contractDefinition,
|
|
403
|
+
signature: bigNumberishArrayToDecimalStringArray(signature || []),
|
|
404
|
+
version: toHex(toBN(details?.version || 1)),
|
|
405
|
+
nonce: toHex(toBN(details.nonce)),
|
|
406
|
+
}
|
|
407
|
+
).then(this.responseParser.parseFeeEstimateResponse);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
public async getDeployAccountEstimateFee(
|
|
411
|
+
{ classHash, addressSalt, constructorCalldata, signature }: DeployAccountContractTransaction,
|
|
412
|
+
details: InvocationsDetailsWithNonce,
|
|
413
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
414
|
+
): Promise<EstimateFeeResponse> {
|
|
415
|
+
return this.fetchEndpoint(
|
|
416
|
+
'estimate_fee',
|
|
417
|
+
{ blockIdentifier },
|
|
418
|
+
{
|
|
419
|
+
type: 'DEPLOY_ACCOUNT',
|
|
420
|
+
class_hash: toHex(toBN(classHash)),
|
|
421
|
+
constructor_calldata: bigNumberishArrayToDecimalStringArray(constructorCalldata || []),
|
|
422
|
+
contract_address_salt: toHex(toBN(addressSalt || 0)),
|
|
423
|
+
signature: bigNumberishArrayToDecimalStringArray(signature || []),
|
|
424
|
+
version: toHex(toBN(details?.version || 0)),
|
|
425
|
+
nonce: toHex(toBN(details.nonce)),
|
|
426
|
+
}
|
|
427
|
+
).then(this.responseParser.parseFeeEstimateResponse);
|
|
428
|
+
}
|
|
429
|
+
|
|
357
430
|
public async getCode(
|
|
358
431
|
contractAddress: string,
|
|
359
432
|
blockIdentifier: BlockIdentifier = 'pending'
|
package/src/signer/default.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Abi,
|
|
3
|
+
Call,
|
|
4
|
+
DeclareSignerDetails,
|
|
5
|
+
InvocationsSignerDetails,
|
|
6
|
+
KeyPair,
|
|
7
|
+
Signature,
|
|
8
|
+
} from '../types';
|
|
9
|
+
import { DeployAccountSignerDetails } from '../types/signer';
|
|
2
10
|
import { genKeyPair, getStarkKey, sign } from '../utils/ellipticCurve';
|
|
3
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
calculateDeclareTransactionHash,
|
|
13
|
+
calculateDeployAccountTransactionHash,
|
|
14
|
+
calculateTransactionHash,
|
|
15
|
+
} from '../utils/hash';
|
|
4
16
|
import { fromCallsToExecuteCalldata } from '../utils/transaction';
|
|
5
17
|
import { TypedData, getMessageHash } from '../utils/typedData';
|
|
6
18
|
import { SignerInterface } from './interface';
|
|
@@ -16,6 +28,11 @@ export class Signer implements SignerInterface {
|
|
|
16
28
|
return getStarkKey(this.keyPair);
|
|
17
29
|
}
|
|
18
30
|
|
|
31
|
+
public async signMessage(typedData: TypedData, accountAddress: string): Promise<Signature> {
|
|
32
|
+
const msgHash = getMessageHash(typedData, accountAddress);
|
|
33
|
+
return sign(this.keyPair, msgHash);
|
|
34
|
+
}
|
|
35
|
+
|
|
19
36
|
public async signTransaction(
|
|
20
37
|
transactions: Call[],
|
|
21
38
|
transactionsDetail: InvocationsSignerDetails,
|
|
@@ -40,8 +57,43 @@ export class Signer implements SignerInterface {
|
|
|
40
57
|
return sign(this.keyPair, msgHash);
|
|
41
58
|
}
|
|
42
59
|
|
|
43
|
-
public async
|
|
44
|
-
|
|
60
|
+
public async signDeployAccountTransaction({
|
|
61
|
+
classHash,
|
|
62
|
+
contractAddress,
|
|
63
|
+
constructorCalldata,
|
|
64
|
+
addressSalt,
|
|
65
|
+
maxFee,
|
|
66
|
+
version,
|
|
67
|
+
chainId,
|
|
68
|
+
nonce,
|
|
69
|
+
}: DeployAccountSignerDetails) {
|
|
70
|
+
const msgHash = calculateDeployAccountTransactionHash(
|
|
71
|
+
contractAddress,
|
|
72
|
+
classHash,
|
|
73
|
+
constructorCalldata,
|
|
74
|
+
addressSalt,
|
|
75
|
+
version,
|
|
76
|
+
maxFee,
|
|
77
|
+
chainId,
|
|
78
|
+
nonce
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
return sign(this.keyPair, msgHash);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public async signDeclareTransaction(
|
|
85
|
+
// contractClass: ContractClass, // Should be used once class hash is present in ContractClass
|
|
86
|
+
{ classHash, senderAddress, chainId, maxFee, version, nonce }: DeclareSignerDetails
|
|
87
|
+
) {
|
|
88
|
+
const msgHash = calculateDeclareTransactionHash(
|
|
89
|
+
classHash,
|
|
90
|
+
senderAddress,
|
|
91
|
+
version,
|
|
92
|
+
maxFee,
|
|
93
|
+
chainId,
|
|
94
|
+
nonce
|
|
95
|
+
);
|
|
96
|
+
|
|
45
97
|
return sign(this.keyPair, msgHash);
|
|
46
98
|
}
|
|
47
99
|
}
|
package/src/signer/interface.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Abi, Call, InvocationsSignerDetails, Signature } from '../types';
|
|
1
|
+
import { Abi, Call, DeclareSignerDetails, InvocationsSignerDetails, Signature } from '../types';
|
|
2
|
+
import { DeployAccountSignerDetails } from '../types/signer';
|
|
2
3
|
import { TypedData } from '../utils/typedData';
|
|
3
4
|
|
|
4
5
|
export abstract class SignerInterface {
|
|
@@ -27,7 +28,6 @@ export abstract class SignerInterface {
|
|
|
27
28
|
* - contractAddress - the address of the contract
|
|
28
29
|
* - entrypoint - the entrypoint of the contract
|
|
29
30
|
* - calldata - (defaults to []) the calldata
|
|
30
|
-
* - signature - (defaults to []) the signature
|
|
31
31
|
* @param abi (optional) the abi of the contract for better displaying
|
|
32
32
|
*
|
|
33
33
|
* @returns signature
|
|
@@ -37,4 +37,35 @@ export abstract class SignerInterface {
|
|
|
37
37
|
transactionsDetail: InvocationsSignerDetails,
|
|
38
38
|
abis?: Abi[]
|
|
39
39
|
): Promise<Signature>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Signs a DEPLOY_ACCOUNT transaction with the starknet private key and returns the signature
|
|
43
|
+
*
|
|
44
|
+
* @param transaction
|
|
45
|
+
* - contractAddress - the computed address of the contract
|
|
46
|
+
* - constructorCalldata - calldata to be passed in deploy constructor
|
|
47
|
+
* - addressSalt - contract address salt
|
|
48
|
+
* - chainId - the chainId to declare contract on
|
|
49
|
+
* - maxFee - maxFee for the declare transaction
|
|
50
|
+
* - version - transaction version
|
|
51
|
+
* - nonce - Nonce of the declare transaction
|
|
52
|
+
* @returns signature
|
|
53
|
+
*/
|
|
54
|
+
public abstract signDeployAccountTransaction(
|
|
55
|
+
transaction: DeployAccountSignerDetails
|
|
56
|
+
): Promise<Signature>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Signs a DECLARE transaction with the starknet private key and returns the signature
|
|
60
|
+
*
|
|
61
|
+
* @param transaction
|
|
62
|
+
* - classHash - computed class hash. Will be replaced by ContractClass in future once class hash is present in CompiledContract
|
|
63
|
+
* - senderAddress - the address of the sender
|
|
64
|
+
* - chainId - the chainId to declare contract on
|
|
65
|
+
* - maxFee - maxFee for the declare transaction
|
|
66
|
+
* - version - transaction version
|
|
67
|
+
* - nonce - Nonce of the declare transaction
|
|
68
|
+
* @returns signature
|
|
69
|
+
*/
|
|
70
|
+
public abstract signDeclareTransaction(transaction: DeclareSignerDetails): Promise<Signature>;
|
|
40
71
|
}
|
package/src/types/api/index.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { BigNumberish } from '../../utils/number';
|
|
2
2
|
import { Signature } from '../lib';
|
|
3
3
|
|
|
4
|
-
export type RawArgs = {
|
|
5
|
-
[inputName: string]: string | string[] | { type: 'struct'; [k: string]: BigNumberish };
|
|
6
|
-
};
|
|
7
|
-
|
|
8
4
|
export type Calldata = string[];
|
|
9
5
|
|
|
10
6
|
export type Overrides = {
|
package/src/types/api/openrpc.ts
CHANGED
|
@@ -18,7 +18,7 @@ type BLOCK_HASH = FELT;
|
|
|
18
18
|
type TXN_HASH = FELT;
|
|
19
19
|
type PROTOCOL_VERSION = string;
|
|
20
20
|
type TXN_STATUS = 'PENDING' | 'ACCEPTED_ON_L2' | 'ACCEPTED_ON_L1' | 'REJECTED';
|
|
21
|
-
type TXN_TYPE = 'DECLARE' | 'DEPLOY' | 'INVOKE' | 'L1_HANDLER';
|
|
21
|
+
type TXN_TYPE = 'DECLARE' | 'DEPLOY' | 'DEPLOY_ACCOUNT' | 'INVOKE' | 'L1_HANDLER';
|
|
22
22
|
type BLOCK_STATUS = 'PENDING' | 'ACCEPTED_ON_L2' | 'ACCEPTED_ON_L1' | 'REJECTED';
|
|
23
23
|
enum BLOCK_TAG {
|
|
24
24
|
'latest',
|
|
@@ -104,6 +104,15 @@ type DECLARE_TXN = COMMON_TXN_PROPERTIES & {
|
|
|
104
104
|
class_hash: FELT;
|
|
105
105
|
sender_address: ADDRESS;
|
|
106
106
|
};
|
|
107
|
+
type DEPLOY_ACCOUNT_TXN_REQUEST = COMMON_TXN_PROPERTIES & {
|
|
108
|
+
class_hash: FELT;
|
|
109
|
+
contract_address_salt: FELT;
|
|
110
|
+
constructor_calldata: Array<FELT>;
|
|
111
|
+
};
|
|
112
|
+
type DECLARE_TXN_REQUEST = COMMON_TXN_PROPERTIES & {
|
|
113
|
+
contract_class: CONTRACT_CLASS;
|
|
114
|
+
sender_address: ADDRESS;
|
|
115
|
+
};
|
|
107
116
|
type DEPLOY_TXN = {
|
|
108
117
|
transaction_hash: TXN_HASH;
|
|
109
118
|
class_hash: FELT;
|
|
@@ -328,7 +337,10 @@ export namespace OPENRPC {
|
|
|
328
337
|
| Errors.INVALID_BLOCK_ID;
|
|
329
338
|
};
|
|
330
339
|
starknet_estimateFee: {
|
|
331
|
-
params: {
|
|
340
|
+
params: {
|
|
341
|
+
request: INVOKE_TXN | DECLARE_TXN_REQUEST | DEPLOY_ACCOUNT_TXN_REQUEST;
|
|
342
|
+
block_id: BLOCK_ID;
|
|
343
|
+
};
|
|
332
344
|
result: FEE_ESTIMATE;
|
|
333
345
|
errors:
|
|
334
346
|
| Errors.CONTRACT_NOT_FOUND
|
|
@@ -384,7 +396,11 @@ export namespace OPENRPC {
|
|
|
384
396
|
starknet_addDeclareTransaction: {
|
|
385
397
|
params: {
|
|
386
398
|
contract_class: CONTRACT_CLASS;
|
|
399
|
+
sender_address: ADDRESS;
|
|
400
|
+
signature: SIGNATURE;
|
|
401
|
+
max_fee: NUM_AS_HEX;
|
|
387
402
|
version: NUM_AS_HEX;
|
|
403
|
+
nonce: FELT;
|
|
388
404
|
};
|
|
389
405
|
result: DeclaredTransaction;
|
|
390
406
|
errors: Errors.INVALID_CONTRACT_CLASS;
|
|
@@ -399,6 +415,16 @@ export namespace OPENRPC {
|
|
|
399
415
|
errors: Errors.INVALID_CONTRACT_CLASS;
|
|
400
416
|
};
|
|
401
417
|
|
|
418
|
+
starknet_addDeployAccountTransaction: {
|
|
419
|
+
params: {
|
|
420
|
+
contract_address_salt: FELT;
|
|
421
|
+
constructor_calldata: Array<FELT>;
|
|
422
|
+
class_hash: FELT;
|
|
423
|
+
};
|
|
424
|
+
result: DeployedTransaction;
|
|
425
|
+
errors: Errors.INVALID_CONTRACT_CLASS;
|
|
426
|
+
};
|
|
427
|
+
|
|
402
428
|
// Trace API
|
|
403
429
|
starknet_traceTransaction: {
|
|
404
430
|
params: { transaction_hash: TXN_HASH };
|
|
@@ -5,13 +5,13 @@ import { BigNumberish } from '../../utils/number';
|
|
|
5
5
|
import {
|
|
6
6
|
Abi,
|
|
7
7
|
BlockNumber,
|
|
8
|
+
ContractClass,
|
|
8
9
|
EntryPointType,
|
|
9
10
|
RawCalldata,
|
|
10
11
|
Signature,
|
|
11
12
|
Status,
|
|
12
13
|
TransactionStatus,
|
|
13
14
|
} from '../lib';
|
|
14
|
-
import { ContractClass } from '../provider';
|
|
15
15
|
|
|
16
16
|
export type GetTransactionStatusResponse = {
|
|
17
17
|
tx_status: Status;
|
|
@@ -76,10 +76,12 @@ export type CallL1Handler = {
|
|
|
76
76
|
export namespace Sequencer {
|
|
77
77
|
export type DeclareTransaction = {
|
|
78
78
|
type: 'DECLARE';
|
|
79
|
+
sender_address: string;
|
|
79
80
|
contract_class: ContractClass;
|
|
81
|
+
signature?: Signature;
|
|
80
82
|
nonce: BigNumberish;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
max_fee?: BigNumberish;
|
|
84
|
+
version?: BigNumberish;
|
|
83
85
|
};
|
|
84
86
|
|
|
85
87
|
export type DeployTransaction = {
|
|
@@ -90,6 +92,17 @@ export namespace Sequencer {
|
|
|
90
92
|
nonce?: BigNumberish;
|
|
91
93
|
};
|
|
92
94
|
|
|
95
|
+
export type DeployAccountTransaction = {
|
|
96
|
+
type: 'DEPLOY_ACCOUNT';
|
|
97
|
+
class_hash: string;
|
|
98
|
+
contract_address_salt: BigNumberish;
|
|
99
|
+
constructor_calldata: string[];
|
|
100
|
+
signature?: Signature;
|
|
101
|
+
max_fee?: BigNumberish;
|
|
102
|
+
version?: BigNumberish;
|
|
103
|
+
nonce?: BigNumberish;
|
|
104
|
+
};
|
|
105
|
+
|
|
93
106
|
export type InvokeFunctionTransaction = {
|
|
94
107
|
type: 'INVOKE_FUNCTION';
|
|
95
108
|
contract_address: string;
|
|
@@ -101,7 +114,11 @@ export namespace Sequencer {
|
|
|
101
114
|
version?: BigNumberish;
|
|
102
115
|
};
|
|
103
116
|
|
|
104
|
-
export type Transaction =
|
|
117
|
+
export type Transaction =
|
|
118
|
+
| DeclareTransaction
|
|
119
|
+
| DeployTransaction
|
|
120
|
+
| InvokeFunctionTransaction
|
|
121
|
+
| DeployAccountTransaction;
|
|
105
122
|
|
|
106
123
|
export type AddTransactionResponse = {
|
|
107
124
|
transaction_hash: string;
|
|
@@ -209,10 +226,16 @@ export namespace Sequencer {
|
|
|
209
226
|
result: string[];
|
|
210
227
|
};
|
|
211
228
|
|
|
212
|
-
export type
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
229
|
+
export type InvokeEstimateFee = Omit<InvokeFunctionTransaction, 'max_fee' | 'entry_point_type'>;
|
|
230
|
+
export type DeclareEstimateFee = Omit<DeclareTransaction, 'max_fee'>;
|
|
231
|
+
export type DeployAccountEstimateFee = Omit<DeployAccountTransaction, 'max_fee'>;
|
|
232
|
+
export type DeployEstimateFee = DeployTransaction;
|
|
233
|
+
|
|
234
|
+
export type EstimateFeeRequest =
|
|
235
|
+
| InvokeEstimateFee
|
|
236
|
+
| DeclareEstimateFee
|
|
237
|
+
| DeployEstimateFee
|
|
238
|
+
| DeployAccountEstimateFee;
|
|
216
239
|
|
|
217
240
|
// Support 0.9.1 changes in a backward-compatible way
|
|
218
241
|
export type EstimateFeeResponse =
|
|
@@ -308,7 +331,7 @@ export namespace Sequencer {
|
|
|
308
331
|
QUERY: {
|
|
309
332
|
blockIdentifier: BlockIdentifier;
|
|
310
333
|
};
|
|
311
|
-
REQUEST:
|
|
334
|
+
REQUEST: EstimateFeeRequest;
|
|
312
335
|
RESPONSE: EstimateFeeResponse;
|
|
313
336
|
};
|
|
314
337
|
get_class_by_hash: {
|