starknet 4.6.0 → 4.7.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 +25 -0
- package/__tests__/account.test.ts +2 -5
- package/__tests__/contract.test.ts +0 -1
- package/__tests__/defaultProvider.test.ts +9 -1
- package/__tests__/sequencerProvider.test.ts +10 -8
- package/__tests__/utils/ellipticalCurve.test.ts +7 -8
- package/account/default.d.ts +3 -2
- package/account/default.js +22 -29
- package/account/interface.d.ts +2 -1
- package/contract/contractFactory.d.ts +1 -2
- package/contract/default.d.ts +2 -2
- package/contract/default.js +7 -3
- package/dist/account/default.d.ts +3 -2
- package/dist/account/default.js +22 -29
- package/dist/account/interface.d.ts +2 -1
- package/dist/contract/contractFactory.d.ts +1 -2
- package/dist/contract/default.d.ts +2 -2
- package/dist/contract/default.js +7 -3
- package/dist/provider/default.d.ts +4 -3
- package/dist/provider/default.js +9 -3
- package/dist/provider/interface.d.ts +10 -3
- package/dist/provider/rpc.d.ts +12 -10
- package/dist/provider/rpc.js +80 -72
- package/dist/provider/sequencer.d.ts +4 -3
- package/dist/provider/sequencer.js +14 -6
- package/dist/signer/default.d.ts +2 -2
- package/dist/signer/default.js +2 -2
- package/dist/signer/interface.d.ts +2 -2
- package/dist/types/api/openrpc.d.ts +17 -27
- package/dist/types/api/rpc.d.ts +4 -128
- package/dist/types/api/sequencer.d.ts +15 -4
- package/dist/types/lib.d.ts +10 -4
- package/dist/types/provider.d.ts +3 -2
- package/dist/utils/hash.d.ts +2 -2
- package/dist/utils/hash.js +5 -5
- package/dist/utils/responseParser/rpc.d.ts +2 -5
- package/dist/utils/responseParser/rpc.js +2 -38
- package/package.json +1 -1
- package/provider/default.d.ts +4 -3
- package/provider/default.js +9 -3
- package/provider/interface.d.ts +10 -3
- package/provider/rpc.d.ts +12 -10
- package/provider/rpc.js +80 -72
- package/provider/sequencer.d.ts +4 -3
- package/provider/sequencer.js +14 -6
- package/signer/default.d.ts +2 -2
- package/signer/default.js +2 -2
- package/signer/interface.d.ts +2 -2
- package/src/account/default.ts +21 -20
- package/src/account/interface.ts +2 -1
- package/src/contract/contractFactory.ts +1 -2
- package/src/contract/default.ts +16 -8
- package/src/provider/default.ts +12 -5
- package/src/provider/interface.ts +15 -4
- package/src/provider/rpc.ts +89 -73
- package/src/provider/sequencer.ts +16 -8
- package/src/signer/default.ts +8 -8
- package/src/signer/interface.ts +2 -2
- package/src/types/api/openrpc.ts +20 -25
- package/src/types/api/rpc.ts +4 -128
- package/src/types/api/sequencer.ts +17 -4
- package/src/types/lib.ts +7 -5
- package/src/types/provider.ts +3 -2
- package/src/utils/hash.ts +7 -6
- package/src/utils/responseParser/rpc.ts +7 -25
- package/types/api/openrpc.d.ts +17 -27
- package/types/api/rpc.d.ts +4 -128
- package/types/api/sequencer.d.ts +15 -4
- package/types/lib.d.ts +10 -4
- package/types/provider.d.ts +3 -2
- package/utils/hash.d.ts +2 -2
- package/utils/hash.js +5 -5
- package/utils/responseParser/rpc.d.ts +2 -5
- package/utils/responseParser/rpc.js +2 -38
- package/www/docs/API/account.md +3 -3
- package/www/docs/API/contract.md +2 -2
- package/www/docs/API/provider.md +6 -0
- package/www/docs/API/utils.md +2 -2
package/provider/rpc.d.ts
CHANGED
|
@@ -1,46 +1,48 @@
|
|
|
1
1
|
import { StarknetChainId } from '../constants';
|
|
2
|
-
import { Call, CallContractResponse, DeclareContractPayload, DeclareContractResponse, DeployContractPayload, DeployContractResponse, EstimateFeeResponse, GetBlockResponse, GetCodeResponse, GetTransactionReceiptResponse, GetTransactionResponse, Invocation,
|
|
2
|
+
import { Call, CallContractResponse, DeclareContractPayload, DeclareContractResponse, DeployContractPayload, DeployContractResponse, EstimateFeeResponse, GetBlockResponse, GetCodeResponse, GetTransactionReceiptResponse, GetTransactionResponse, Invocation, InvocationsDetailsWithNonce, InvokeFunctionResponse } from '../types';
|
|
3
3
|
import { RPC } from '../types/api';
|
|
4
4
|
import { BigNumberish } from '../utils/number';
|
|
5
5
|
import { ProviderInterface } from './interface';
|
|
6
6
|
import { BlockIdentifier } from './utils';
|
|
7
7
|
export declare type RpcProviderOptions = {
|
|
8
8
|
nodeUrl: string;
|
|
9
|
+
retries?: number;
|
|
9
10
|
};
|
|
10
11
|
export declare class RpcProvider implements ProviderInterface {
|
|
11
12
|
nodeUrl: string;
|
|
12
13
|
chainId: StarknetChainId;
|
|
13
14
|
private responseParser;
|
|
15
|
+
private retries;
|
|
14
16
|
constructor(optionsOrProvider: RpcProviderOptions);
|
|
15
17
|
fetch(method: any, params: any): Promise<any>;
|
|
16
18
|
protected errorHandler(error: any): void;
|
|
17
|
-
protected fetchEndpoint<T extends keyof RPC.Methods>(method: T,
|
|
19
|
+
protected fetchEndpoint<T extends keyof RPC.Methods>(method: T, params?: RPC.Methods[T]['params']): Promise<RPC.Methods[T]['result']>;
|
|
18
20
|
getChainId(): Promise<any>;
|
|
19
21
|
getBlock(blockIdentifier?: BlockIdentifier): Promise<GetBlockResponse>;
|
|
20
22
|
getBlockHashAndNumber(): Promise<RPC.BlockHashAndNumber>;
|
|
21
23
|
getBlockWithTxHashes(blockIdentifier?: BlockIdentifier): Promise<RPC.GetBlockWithTxHashesResponse>;
|
|
22
24
|
getBlockWithTxs(blockIdentifier?: BlockIdentifier): Promise<RPC.GetBlockWithTxs>;
|
|
23
25
|
getClassHashAt(blockIdentifier: BlockIdentifier, contractAddress: RPC.ContractAddress): Promise<RPC.Felt>;
|
|
24
|
-
getNonce(contractAddress: string): Promise<
|
|
26
|
+
getNonce(contractAddress: string, blockIdentifier?: BlockIdentifier): Promise<RPC.Nonce>;
|
|
25
27
|
getPendingTransactions(): Promise<RPC.PendingTransactions>;
|
|
26
28
|
getProtocolVersion(): Promise<Error>;
|
|
27
29
|
getStateUpdate(blockIdentifier: BlockIdentifier): Promise<RPC.StateUpdate>;
|
|
28
30
|
getStorageAt(contractAddress: string, key: BigNumberish, blockIdentifier?: BlockIdentifier): Promise<BigNumberish>;
|
|
29
|
-
getTransaction(txHash:
|
|
30
|
-
getTransactionByHash(txHash:
|
|
31
|
+
getTransaction(txHash: string): Promise<GetTransactionResponse>;
|
|
32
|
+
getTransactionByHash(txHash: string): Promise<RPC.GetTransactionByHashResponse>;
|
|
31
33
|
getTransactionByBlockIdAndIndex(blockIdentifier: BlockIdentifier, index: number): Promise<RPC.GetTransactionByBlockIdAndIndex>;
|
|
32
|
-
getTransactionReceipt(txHash:
|
|
34
|
+
getTransactionReceipt(txHash: string): Promise<GetTransactionReceiptResponse>;
|
|
33
35
|
getClass(classHash: RPC.Felt): Promise<RPC.ContractClass>;
|
|
34
|
-
getClassAt(contractAddress: string, blockIdentifier: BlockIdentifier): Promise<
|
|
36
|
+
getClassAt(contractAddress: string, blockIdentifier: BlockIdentifier): Promise<RPC.ContractClass>;
|
|
35
37
|
getCode(_contractAddress: string, _blockIdentifier?: BlockIdentifier): Promise<GetCodeResponse>;
|
|
36
|
-
getEstimateFee(invocation: Invocation,
|
|
38
|
+
getEstimateFee(invocation: Invocation, invocationDetails: InvocationsDetailsWithNonce, blockIdentifier?: BlockIdentifier): Promise<EstimateFeeResponse>;
|
|
37
39
|
declareContract({ contract, version, }: DeclareContractPayload): Promise<DeclareContractResponse>;
|
|
38
40
|
deployContract({ contract, constructorCalldata, addressSalt, }: DeployContractPayload): Promise<DeployContractResponse>;
|
|
39
|
-
invokeFunction(functionInvocation: Invocation, details:
|
|
41
|
+
invokeFunction(functionInvocation: Invocation, details: InvocationsDetailsWithNonce): Promise<InvokeFunctionResponse>;
|
|
40
42
|
callContract(call: Call, blockIdentifier?: BlockIdentifier): Promise<CallContractResponse>;
|
|
41
43
|
traceTransaction(transactionHash: RPC.TransactionHash): Promise<RPC.Trace>;
|
|
42
44
|
traceBlockTransactions(blockHash: RPC.BlockHash): Promise<RPC.Traces>;
|
|
43
|
-
waitForTransaction(txHash:
|
|
45
|
+
waitForTransaction(txHash: string, retryInterval?: number): Promise<void>;
|
|
44
46
|
/**
|
|
45
47
|
* Gets the transaction count from a block.
|
|
46
48
|
*
|
package/provider/rpc.js
CHANGED
|
@@ -52,8 +52,9 @@ var RpcProvider = /** @class */ (function () {
|
|
|
52
52
|
function RpcProvider(optionsOrProvider) {
|
|
53
53
|
var _this = this;
|
|
54
54
|
this.responseParser = new rpc_1.RPCResponseParser();
|
|
55
|
-
var nodeUrl = optionsOrProvider.nodeUrl;
|
|
55
|
+
var nodeUrl = optionsOrProvider.nodeUrl, retries = optionsOrProvider.retries;
|
|
56
56
|
this.nodeUrl = nodeUrl;
|
|
57
|
+
this.retries = retries || 200;
|
|
57
58
|
this.getChainId().then(function (chainId) {
|
|
58
59
|
_this.chainId = chainId;
|
|
59
60
|
});
|
|
@@ -71,7 +72,7 @@ var RpcProvider = /** @class */ (function () {
|
|
|
71
72
|
throw new Error("".concat(code, ": ").concat(message));
|
|
72
73
|
}
|
|
73
74
|
};
|
|
74
|
-
RpcProvider.prototype.fetchEndpoint = function (method,
|
|
75
|
+
RpcProvider.prototype.fetchEndpoint = function (method, params) {
|
|
75
76
|
var _a;
|
|
76
77
|
return __awaiter(this, void 0, void 0, function () {
|
|
77
78
|
var rawResult, _b, error, result, error_1;
|
|
@@ -79,7 +80,7 @@ var RpcProvider = /** @class */ (function () {
|
|
|
79
80
|
switch (_c.label) {
|
|
80
81
|
case 0:
|
|
81
82
|
_c.trys.push([0, 3, , 4]);
|
|
82
|
-
return [4 /*yield*/, this.fetch(method,
|
|
83
|
+
return [4 /*yield*/, this.fetch(method, params)];
|
|
83
84
|
case 1:
|
|
84
85
|
rawResult = _c.sent();
|
|
85
86
|
return [4 /*yield*/, rawResult.json()];
|
|
@@ -123,36 +124,45 @@ var RpcProvider = /** @class */ (function () {
|
|
|
123
124
|
RpcProvider.prototype.getBlockWithTxHashes = function (blockIdentifier) {
|
|
124
125
|
if (blockIdentifier === void 0) { blockIdentifier = 'pending'; }
|
|
125
126
|
return __awaiter(this, void 0, void 0, function () {
|
|
126
|
-
var
|
|
127
|
+
var block_id;
|
|
127
128
|
return __generator(this, function (_a) {
|
|
128
|
-
|
|
129
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getBlockWithTxHashes',
|
|
129
|
+
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
130
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getBlockWithTxHashes', { block_id: block_id })];
|
|
130
131
|
});
|
|
131
132
|
});
|
|
132
133
|
};
|
|
133
134
|
RpcProvider.prototype.getBlockWithTxs = function (blockIdentifier) {
|
|
134
135
|
if (blockIdentifier === void 0) { blockIdentifier = 'pending'; }
|
|
135
136
|
return __awaiter(this, void 0, void 0, function () {
|
|
136
|
-
var
|
|
137
|
+
var block_id;
|
|
137
138
|
return __generator(this, function (_a) {
|
|
138
|
-
|
|
139
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getBlockWithTxs',
|
|
139
|
+
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
140
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getBlockWithTxs', { block_id: block_id })];
|
|
140
141
|
});
|
|
141
142
|
});
|
|
142
143
|
};
|
|
143
144
|
RpcProvider.prototype.getClassHashAt = function (blockIdentifier, contractAddress) {
|
|
144
145
|
return __awaiter(this, void 0, void 0, function () {
|
|
145
|
-
var
|
|
146
|
+
var block_id;
|
|
146
147
|
return __generator(this, function (_a) {
|
|
147
|
-
|
|
148
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getClassHashAt',
|
|
148
|
+
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
149
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getClassHashAt', {
|
|
150
|
+
block_id: block_id,
|
|
151
|
+
contract_address: contractAddress,
|
|
152
|
+
})];
|
|
149
153
|
});
|
|
150
154
|
});
|
|
151
155
|
};
|
|
152
|
-
RpcProvider.prototype.getNonce = function (contractAddress) {
|
|
156
|
+
RpcProvider.prototype.getNonce = function (contractAddress, blockIdentifier) {
|
|
157
|
+
if (blockIdentifier === void 0) { blockIdentifier = 'pending'; }
|
|
153
158
|
return __awaiter(this, void 0, void 0, function () {
|
|
159
|
+
var block_id;
|
|
154
160
|
return __generator(this, function (_a) {
|
|
155
|
-
|
|
161
|
+
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
162
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getNonce', {
|
|
163
|
+
contract_address: contractAddress,
|
|
164
|
+
block_id: block_id,
|
|
165
|
+
})];
|
|
156
166
|
});
|
|
157
167
|
});
|
|
158
168
|
};
|
|
@@ -172,25 +182,25 @@ var RpcProvider = /** @class */ (function () {
|
|
|
172
182
|
};
|
|
173
183
|
RpcProvider.prototype.getStateUpdate = function (blockIdentifier) {
|
|
174
184
|
return __awaiter(this, void 0, void 0, function () {
|
|
175
|
-
var
|
|
185
|
+
var block_id;
|
|
176
186
|
return __generator(this, function (_a) {
|
|
177
|
-
|
|
178
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getStateUpdate',
|
|
187
|
+
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
188
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getStateUpdate', { block_id: block_id })];
|
|
179
189
|
});
|
|
180
190
|
});
|
|
181
191
|
};
|
|
182
192
|
RpcProvider.prototype.getStorageAt = function (contractAddress, key, blockIdentifier) {
|
|
183
193
|
if (blockIdentifier === void 0) { blockIdentifier = 'pending'; }
|
|
184
194
|
return __awaiter(this, void 0, void 0, function () {
|
|
185
|
-
var parsedKey,
|
|
195
|
+
var parsedKey, block_id;
|
|
186
196
|
return __generator(this, function (_a) {
|
|
187
197
|
parsedKey = (0, number_1.toHex)((0, number_1.toBN)(key));
|
|
188
|
-
|
|
189
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getStorageAt',
|
|
190
|
-
contractAddress,
|
|
191
|
-
parsedKey,
|
|
192
|
-
|
|
193
|
-
|
|
198
|
+
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
199
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getStorageAt', {
|
|
200
|
+
contract_address: contractAddress,
|
|
201
|
+
key: parsedKey,
|
|
202
|
+
block_id: block_id,
|
|
203
|
+
})];
|
|
194
204
|
});
|
|
195
205
|
});
|
|
196
206
|
};
|
|
@@ -205,42 +215,42 @@ var RpcProvider = /** @class */ (function () {
|
|
|
205
215
|
RpcProvider.prototype.getTransactionByHash = function (txHash) {
|
|
206
216
|
return __awaiter(this, void 0, void 0, function () {
|
|
207
217
|
return __generator(this, function (_a) {
|
|
208
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getTransactionByHash',
|
|
218
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getTransactionByHash', { transaction_hash: txHash })];
|
|
209
219
|
});
|
|
210
220
|
});
|
|
211
221
|
};
|
|
212
222
|
RpcProvider.prototype.getTransactionByBlockIdAndIndex = function (blockIdentifier, index) {
|
|
213
223
|
return __awaiter(this, void 0, void 0, function () {
|
|
214
|
-
var
|
|
224
|
+
var block_id;
|
|
215
225
|
return __generator(this, function (_a) {
|
|
216
|
-
|
|
217
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getTransactionByBlockIdAndIndex',
|
|
218
|
-
block.identifier,
|
|
219
|
-
index,
|
|
220
|
-
])];
|
|
226
|
+
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
227
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getTransactionByBlockIdAndIndex', { block_id: block_id, index: index })];
|
|
221
228
|
});
|
|
222
229
|
});
|
|
223
230
|
};
|
|
224
231
|
RpcProvider.prototype.getTransactionReceipt = function (txHash) {
|
|
225
232
|
return __awaiter(this, void 0, void 0, function () {
|
|
226
233
|
return __generator(this, function (_a) {
|
|
227
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getTransactionReceipt',
|
|
234
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getTransactionReceipt', { transaction_hash: txHash }).then(this.responseParser.parseGetTransactionReceiptResponse)];
|
|
228
235
|
});
|
|
229
236
|
});
|
|
230
237
|
};
|
|
231
238
|
RpcProvider.prototype.getClass = function (classHash) {
|
|
232
239
|
return __awaiter(this, void 0, void 0, function () {
|
|
233
240
|
return __generator(this, function (_a) {
|
|
234
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getClass',
|
|
241
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getClass', { class_hash: classHash })];
|
|
235
242
|
});
|
|
236
243
|
});
|
|
237
244
|
};
|
|
238
245
|
RpcProvider.prototype.getClassAt = function (contractAddress, blockIdentifier) {
|
|
239
246
|
return __awaiter(this, void 0, void 0, function () {
|
|
240
|
-
var
|
|
247
|
+
var block_id;
|
|
241
248
|
return __generator(this, function (_a) {
|
|
242
|
-
|
|
243
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getClassAt',
|
|
249
|
+
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
250
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getClassAt', {
|
|
251
|
+
block_id: block_id,
|
|
252
|
+
contract_address: contractAddress,
|
|
253
|
+
})];
|
|
244
254
|
});
|
|
245
255
|
});
|
|
246
256
|
};
|
|
@@ -251,23 +261,22 @@ var RpcProvider = /** @class */ (function () {
|
|
|
251
261
|
});
|
|
252
262
|
});
|
|
253
263
|
};
|
|
254
|
-
RpcProvider.prototype.getEstimateFee = function (invocation,
|
|
264
|
+
RpcProvider.prototype.getEstimateFee = function (invocation, invocationDetails, blockIdentifier) {
|
|
255
265
|
if (blockIdentifier === void 0) { blockIdentifier = 'pending'; }
|
|
256
|
-
if (invocationDetails === void 0) { invocationDetails = {}; }
|
|
257
266
|
return __awaiter(this, void 0, void 0, function () {
|
|
258
267
|
var block_id;
|
|
259
268
|
return __generator(this, function (_a) {
|
|
260
269
|
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
261
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_estimateFee',
|
|
262
|
-
{
|
|
270
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_estimateFee', {
|
|
271
|
+
request: {
|
|
263
272
|
contract_address: invocation.contractAddress,
|
|
264
|
-
entry_point_selector: (0, hash_1.getSelectorFromName)(invocation.entrypoint),
|
|
265
273
|
calldata: (0, provider_1.parseCalldata)(invocation.calldata),
|
|
266
274
|
signature: (0, number_1.bigNumberishArrayToHexadecimalStringArray)(invocation.signature || []),
|
|
267
275
|
version: (0, number_1.toHex)((0, number_1.toBN)((invocationDetails === null || invocationDetails === void 0 ? void 0 : invocationDetails.version) || 0)),
|
|
276
|
+
max_fee: (0, number_1.toHex)((0, number_1.toBN)((invocationDetails === null || invocationDetails === void 0 ? void 0 : invocationDetails.maxFee) || 0)),
|
|
268
277
|
},
|
|
269
|
-
block_id,
|
|
270
|
-
|
|
278
|
+
block_id: block_id,
|
|
279
|
+
}).then(this.responseParser.parseFeeEstimateResponse)];
|
|
271
280
|
});
|
|
272
281
|
});
|
|
273
282
|
};
|
|
@@ -277,14 +286,14 @@ var RpcProvider = /** @class */ (function () {
|
|
|
277
286
|
var contractDefinition;
|
|
278
287
|
return __generator(this, function (_b) {
|
|
279
288
|
contractDefinition = (0, provider_1.parseContract)(contract);
|
|
280
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_addDeclareTransaction',
|
|
281
|
-
{
|
|
289
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_addDeclareTransaction', {
|
|
290
|
+
contract_class: {
|
|
282
291
|
program: contractDefinition.program,
|
|
283
292
|
entry_points_by_type: contractDefinition.entry_points_by_type,
|
|
284
293
|
abi: contractDefinition.abi, // rpc 2.0
|
|
285
294
|
},
|
|
286
|
-
(0, number_1.toHex)((0, number_1.toBN)(version || 0)),
|
|
287
|
-
|
|
295
|
+
version: (0, number_1.toHex)((0, number_1.toBN)(version || 0)),
|
|
296
|
+
})];
|
|
288
297
|
});
|
|
289
298
|
});
|
|
290
299
|
};
|
|
@@ -294,31 +303,30 @@ var RpcProvider = /** @class */ (function () {
|
|
|
294
303
|
var contractDefinition;
|
|
295
304
|
return __generator(this, function (_b) {
|
|
296
305
|
contractDefinition = (0, provider_1.parseContract)(contract);
|
|
297
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_addDeployTransaction',
|
|
298
|
-
addressSalt !== null && addressSalt !== void 0 ? addressSalt : (0, stark_1.randomAddress)(),
|
|
299
|
-
(0, number_1.bigNumberishArrayToHexadecimalStringArray)(constructorCalldata !== null && constructorCalldata !== void 0 ? constructorCalldata : []),
|
|
300
|
-
{
|
|
306
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_addDeployTransaction', {
|
|
307
|
+
contract_address_salt: addressSalt !== null && addressSalt !== void 0 ? addressSalt : (0, stark_1.randomAddress)(),
|
|
308
|
+
constructor_calldata: (0, number_1.bigNumberishArrayToHexadecimalStringArray)(constructorCalldata !== null && constructorCalldata !== void 0 ? constructorCalldata : []),
|
|
309
|
+
contract_definition: {
|
|
301
310
|
program: contractDefinition.program,
|
|
302
311
|
entry_points_by_type: contractDefinition.entry_points_by_type,
|
|
303
312
|
abi: contractDefinition.abi, // rpc 2.0
|
|
304
313
|
},
|
|
305
|
-
|
|
314
|
+
})];
|
|
306
315
|
});
|
|
307
316
|
});
|
|
308
317
|
};
|
|
309
318
|
RpcProvider.prototype.invokeFunction = function (functionInvocation, details) {
|
|
310
319
|
return __awaiter(this, void 0, void 0, function () {
|
|
311
320
|
return __generator(this, function (_a) {
|
|
312
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_addInvokeTransaction',
|
|
313
|
-
{
|
|
321
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_addInvokeTransaction', {
|
|
322
|
+
function_invocation: {
|
|
314
323
|
contract_address: functionInvocation.contractAddress,
|
|
315
|
-
entry_point_selector: (0, hash_1.getSelectorFromName)(functionInvocation.entrypoint),
|
|
316
324
|
calldata: (0, provider_1.parseCalldata)(functionInvocation.calldata),
|
|
317
325
|
},
|
|
318
|
-
(0, number_1.bigNumberishArrayToHexadecimalStringArray)(functionInvocation.signature || []),
|
|
319
|
-
(0, number_1.toHex)((0, number_1.toBN)(details.maxFee || 0)),
|
|
320
|
-
(0, number_1.toHex)((0, number_1.toBN)(details.version || 0)),
|
|
321
|
-
|
|
326
|
+
signature: (0, number_1.bigNumberishArrayToHexadecimalStringArray)(functionInvocation.signature || []),
|
|
327
|
+
max_fee: (0, number_1.toHex)((0, number_1.toBN)(details.maxFee || 0)),
|
|
328
|
+
version: (0, number_1.toHex)((0, number_1.toBN)(details.version || 0)),
|
|
329
|
+
})];
|
|
322
330
|
});
|
|
323
331
|
});
|
|
324
332
|
};
|
|
@@ -331,14 +339,14 @@ var RpcProvider = /** @class */ (function () {
|
|
|
331
339
|
switch (_a.label) {
|
|
332
340
|
case 0:
|
|
333
341
|
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
334
|
-
return [4 /*yield*/, this.fetchEndpoint('starknet_call',
|
|
335
|
-
{
|
|
342
|
+
return [4 /*yield*/, this.fetchEndpoint('starknet_call', {
|
|
343
|
+
request: {
|
|
336
344
|
contract_address: call.contractAddress,
|
|
337
345
|
entry_point_selector: (0, hash_1.getSelectorFromName)(call.entrypoint),
|
|
338
346
|
calldata: (0, provider_1.parseCalldata)(call.calldata),
|
|
339
347
|
},
|
|
340
|
-
block_id,
|
|
341
|
-
|
|
348
|
+
block_id: block_id,
|
|
349
|
+
})];
|
|
342
350
|
case 1:
|
|
343
351
|
result = _a.sent();
|
|
344
352
|
return [2 /*return*/, this.responseParser.parseCallContractResponse(result)];
|
|
@@ -349,26 +357,26 @@ var RpcProvider = /** @class */ (function () {
|
|
|
349
357
|
RpcProvider.prototype.traceTransaction = function (transactionHash) {
|
|
350
358
|
return __awaiter(this, void 0, void 0, function () {
|
|
351
359
|
return __generator(this, function (_a) {
|
|
352
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_traceTransaction',
|
|
360
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_traceTransaction', { transaction_hash: transactionHash })];
|
|
353
361
|
});
|
|
354
362
|
});
|
|
355
363
|
};
|
|
356
364
|
RpcProvider.prototype.traceBlockTransactions = function (blockHash) {
|
|
357
365
|
return __awaiter(this, void 0, void 0, function () {
|
|
358
366
|
return __generator(this, function (_a) {
|
|
359
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_traceBlockTransactions',
|
|
367
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_traceBlockTransactions', { block_hash: blockHash })];
|
|
360
368
|
});
|
|
361
369
|
});
|
|
362
370
|
};
|
|
363
371
|
RpcProvider.prototype.waitForTransaction = function (txHash, retryInterval) {
|
|
364
372
|
if (retryInterval === void 0) { retryInterval = 8000; }
|
|
365
373
|
return __awaiter(this, void 0, void 0, function () {
|
|
366
|
-
var
|
|
374
|
+
var retries, onchain, successStates, errorStates, res, message, error, error_2;
|
|
367
375
|
return __generator(this, function (_a) {
|
|
368
376
|
switch (_a.label) {
|
|
369
377
|
case 0:
|
|
378
|
+
retries = this.retries;
|
|
370
379
|
onchain = false;
|
|
371
|
-
retries = 200;
|
|
372
380
|
_a.label = 1;
|
|
373
381
|
case 1:
|
|
374
382
|
if (!!onchain) return [3 /*break*/, 7];
|
|
@@ -401,7 +409,7 @@ var RpcProvider = /** @class */ (function () {
|
|
|
401
409
|
throw error_2;
|
|
402
410
|
}
|
|
403
411
|
if (retries === 0) {
|
|
404
|
-
throw
|
|
412
|
+
throw new Error('waitForTransaction timedout with retries');
|
|
405
413
|
}
|
|
406
414
|
return [3 /*break*/, 6];
|
|
407
415
|
case 6:
|
|
@@ -424,10 +432,10 @@ var RpcProvider = /** @class */ (function () {
|
|
|
424
432
|
*/
|
|
425
433
|
RpcProvider.prototype.getTransactionCount = function (blockIdentifier) {
|
|
426
434
|
return __awaiter(this, void 0, void 0, function () {
|
|
427
|
-
var
|
|
435
|
+
var block_id;
|
|
428
436
|
return __generator(this, function (_a) {
|
|
429
|
-
|
|
430
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getBlockTransactionCount',
|
|
437
|
+
block_id = new utils_1.Block(blockIdentifier).identifier;
|
|
438
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getBlockTransactionCount', { block_id: block_id })];
|
|
431
439
|
});
|
|
432
440
|
});
|
|
433
441
|
};
|
|
@@ -466,7 +474,7 @@ var RpcProvider = /** @class */ (function () {
|
|
|
466
474
|
RpcProvider.prototype.getEvents = function (eventFilter) {
|
|
467
475
|
return __awaiter(this, void 0, void 0, function () {
|
|
468
476
|
return __generator(this, function (_a) {
|
|
469
|
-
return [2 /*return*/, this.fetchEndpoint('starknet_getEvents',
|
|
477
|
+
return [2 /*return*/, this.fetchEndpoint('starknet_getEvents', { filter: eventFilter })];
|
|
470
478
|
});
|
|
471
479
|
});
|
|
472
480
|
};
|
package/provider/sequencer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StarknetChainId } from '../constants';
|
|
2
|
-
import { Call, CallContractResponse, ContractClass, DeclareContractPayload, DeclareContractResponse, DeployContractPayload, DeployContractResponse, EstimateFeeResponse, GetBlockResponse, GetTransactionReceiptResponse, GetTransactionResponse, Invocation,
|
|
2
|
+
import { Call, CallContractResponse, ContractClass, DeclareContractPayload, DeclareContractResponse, DeployContractPayload, DeployContractResponse, EstimateFeeResponse, GetBlockResponse, GetTransactionReceiptResponse, GetTransactionResponse, Invocation, InvocationsDetailsWithNonce, InvokeFunctionResponse } from '../types';
|
|
3
3
|
import { GetContractAddressesResponse, GetTransactionStatusResponse, GetTransactionTraceResponse, Sequencer } from '../types/api';
|
|
4
4
|
import { BigNumberish } from '../utils/number';
|
|
5
5
|
import { ProviderInterface } from './interface';
|
|
@@ -30,14 +30,15 @@ export declare class SequencerProvider implements ProviderInterface {
|
|
|
30
30
|
getChainId(): Promise<StarknetChainId>;
|
|
31
31
|
callContract({ contractAddress, entrypoint: entryPointSelector, calldata }: Call, blockIdentifier?: BlockIdentifier): Promise<CallContractResponse>;
|
|
32
32
|
getBlock(blockIdentifier?: BlockIdentifier): Promise<GetBlockResponse>;
|
|
33
|
+
getNonce(contractAddress: string, blockIdentifier?: BlockIdentifier): Promise<BigNumberish>;
|
|
33
34
|
getStorageAt(contractAddress: string, key: BigNumberish, blockIdentifier?: BlockIdentifier): Promise<BigNumberish>;
|
|
34
35
|
getTransaction(txHash: BigNumberish): Promise<GetTransactionResponse>;
|
|
35
36
|
getTransactionReceipt(txHash: BigNumberish): Promise<GetTransactionReceiptResponse>;
|
|
36
37
|
getClassAt(contractAddress: string, blockIdentifier?: BlockIdentifier): Promise<ContractClass>;
|
|
37
|
-
invokeFunction(functionInvocation: Invocation, details:
|
|
38
|
+
invokeFunction(functionInvocation: Invocation, details: InvocationsDetailsWithNonce): Promise<InvokeFunctionResponse>;
|
|
38
39
|
deployContract({ contract, constructorCalldata, addressSalt, }: DeployContractPayload): Promise<DeployContractResponse>;
|
|
39
40
|
declareContract({ contract, }: DeclareContractPayload): Promise<DeclareContractResponse>;
|
|
40
|
-
getEstimateFee(invocation: Invocation,
|
|
41
|
+
getEstimateFee(invocation: Invocation, invocationDetails: InvocationsDetailsWithNonce, blockIdentifier?: BlockIdentifier): Promise<EstimateFeeResponse>;
|
|
41
42
|
getCode(contractAddress: string, blockIdentifier?: BlockIdentifier): Promise<Sequencer.GetCodeResponse>;
|
|
42
43
|
waitForTransaction(txHash: BigNumberish, retryInterval?: number): Promise<void>;
|
|
43
44
|
/**
|
package/provider/sequencer.js
CHANGED
|
@@ -257,6 +257,14 @@ var SequencerProvider = /** @class */ (function () {
|
|
|
257
257
|
});
|
|
258
258
|
});
|
|
259
259
|
};
|
|
260
|
+
SequencerProvider.prototype.getNonce = function (contractAddress, blockIdentifier) {
|
|
261
|
+
if (blockIdentifier === void 0) { blockIdentifier = 'pending'; }
|
|
262
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
263
|
+
return __generator(this, function (_a) {
|
|
264
|
+
return [2 /*return*/, this.fetchEndpoint('get_nonce', { contractAddress: contractAddress, blockIdentifier: blockIdentifier })];
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
};
|
|
260
268
|
SequencerProvider.prototype.getStorageAt = function (contractAddress, key, blockIdentifier) {
|
|
261
269
|
if (blockIdentifier === void 0) { blockIdentifier = 'pending'; }
|
|
262
270
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -307,11 +315,11 @@ var SequencerProvider = /** @class */ (function () {
|
|
|
307
315
|
return [2 /*return*/, this.fetchEndpoint('add_transaction', undefined, {
|
|
308
316
|
type: 'INVOKE_FUNCTION',
|
|
309
317
|
contract_address: functionInvocation.contractAddress,
|
|
310
|
-
entry_point_selector: (0, hash_1.getSelectorFromName)(functionInvocation.entrypoint),
|
|
311
318
|
calldata: (0, number_1.bigNumberishArrayToDecimalStringArray)((_a = functionInvocation.calldata) !== null && _a !== void 0 ? _a : []),
|
|
312
319
|
signature: (0, number_1.bigNumberishArrayToDecimalStringArray)((_b = functionInvocation.signature) !== null && _b !== void 0 ? _b : []),
|
|
320
|
+
nonce: (0, number_1.toHex)((0, number_1.toBN)(details.nonce)),
|
|
313
321
|
max_fee: (0, number_1.toHex)((0, number_1.toBN)(details.maxFee || 0)),
|
|
314
|
-
version: (0, number_1.toHex)((0, number_1.toBN)(details.version ||
|
|
322
|
+
version: (0, number_1.toHex)((0, number_1.toBN)(details.version || 1)),
|
|
315
323
|
}).then(this.responseParser.parseInvokeFunctionResponse)];
|
|
316
324
|
});
|
|
317
325
|
});
|
|
@@ -347,18 +355,18 @@ var SequencerProvider = /** @class */ (function () {
|
|
|
347
355
|
});
|
|
348
356
|
});
|
|
349
357
|
};
|
|
350
|
-
SequencerProvider.prototype.getEstimateFee = function (invocation,
|
|
358
|
+
SequencerProvider.prototype.getEstimateFee = function (invocation, invocationDetails, blockIdentifier) {
|
|
351
359
|
var _a;
|
|
352
360
|
if (blockIdentifier === void 0) { blockIdentifier = 'pending'; }
|
|
353
|
-
if (invocationDetails === void 0) { invocationDetails = {}; }
|
|
354
361
|
return __awaiter(this, void 0, void 0, function () {
|
|
355
362
|
return __generator(this, function (_b) {
|
|
356
363
|
return [2 /*return*/, this.fetchEndpoint('estimate_fee', { blockIdentifier: blockIdentifier }, {
|
|
364
|
+
type: 'INVOKE_FUNCTION',
|
|
357
365
|
contract_address: invocation.contractAddress,
|
|
358
|
-
entry_point_selector: (0, hash_1.getSelectorFromName)(invocation.entrypoint),
|
|
359
366
|
calldata: (_a = invocation.calldata) !== null && _a !== void 0 ? _a : [],
|
|
360
367
|
signature: (0, number_1.bigNumberishArrayToDecimalStringArray)(invocation.signature || []),
|
|
361
|
-
version: (0, number_1.toHex)((0, number_1.toBN)((invocationDetails === null || invocationDetails === void 0 ? void 0 : invocationDetails.version) ||
|
|
368
|
+
version: (0, number_1.toHex)((0, number_1.toBN)((invocationDetails === null || invocationDetails === void 0 ? void 0 : invocationDetails.version) || 1)),
|
|
369
|
+
nonce: (0, number_1.toHex)((0, number_1.toBN)(invocationDetails.nonce)),
|
|
362
370
|
}).then(this.responseParser.parseFeeEstimateResponse)];
|
|
363
371
|
});
|
|
364
372
|
});
|
package/signer/default.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Abi,
|
|
1
|
+
import { Abi, Call, InvocationsSignerDetails, KeyPair, Signature } from '../types';
|
|
2
2
|
import { TypedData } from '../utils/typedData';
|
|
3
3
|
import { SignerInterface } from './interface';
|
|
4
4
|
export declare class Signer implements SignerInterface {
|
|
5
5
|
protected keyPair: KeyPair;
|
|
6
6
|
constructor(keyPair?: KeyPair);
|
|
7
7
|
getPubKey(): Promise<string>;
|
|
8
|
-
signTransaction(transactions:
|
|
8
|
+
signTransaction(transactions: Call[], transactionsDetail: InvocationsSignerDetails, abis?: Abi[]): Promise<Signature>;
|
|
9
9
|
signMessage(typedData: TypedData, accountAddress: string): Promise<Signature>;
|
|
10
10
|
}
|
package/signer/default.js
CHANGED
|
@@ -60,8 +60,8 @@ var Signer = /** @class */ (function () {
|
|
|
60
60
|
if (abis && abis.length !== transactions.length) {
|
|
61
61
|
throw new Error('ABI must be provided for each transaction or no transaction');
|
|
62
62
|
}
|
|
63
|
-
calldata = (0, transaction_1.
|
|
64
|
-
msgHash = (0, hash_1.
|
|
63
|
+
calldata = (0, transaction_1.fromCallsToExecuteCalldata)(transactions);
|
|
64
|
+
msgHash = (0, hash_1.calculateTransactionHash)(transactionsDetail.walletAddress, transactionsDetail.version, calldata, transactionsDetail.maxFee, transactionsDetail.chainId, transactionsDetail.nonce);
|
|
65
65
|
return [2 /*return*/, (0, ellipticCurve_1.sign)(this.keyPair, msgHash)];
|
|
66
66
|
});
|
|
67
67
|
});
|
package/signer/interface.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Abi,
|
|
1
|
+
import { Abi, Call, InvocationsSignerDetails, Signature } from '../types';
|
|
2
2
|
import { TypedData } from '../utils/typedData';
|
|
3
3
|
export declare abstract class SignerInterface {
|
|
4
4
|
/**
|
|
@@ -29,5 +29,5 @@ export declare abstract class SignerInterface {
|
|
|
29
29
|
*
|
|
30
30
|
* @returns signature
|
|
31
31
|
*/
|
|
32
|
-
abstract signTransaction(transactions:
|
|
32
|
+
abstract signTransaction(transactions: Call[], transactionsDetail: InvocationsSignerDetails, abis?: Abi[]): Promise<Signature>;
|
|
33
33
|
}
|
package/src/account/default.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ZERO } from '../constants';
|
|
2
2
|
import { ProviderInterface, ProviderOptions } from '../provider';
|
|
3
3
|
import { Provider } from '../provider/default';
|
|
4
|
+
import { BlockIdentifier } from '../provider/utils';
|
|
4
5
|
import { Signer, SignerInterface } from '../signer';
|
|
5
6
|
import {
|
|
6
7
|
Abi,
|
|
@@ -12,32 +13,31 @@ import {
|
|
|
12
13
|
Signature,
|
|
13
14
|
} from '../types';
|
|
14
15
|
import { EstimateFee, EstimateFeeDetails } from '../types/account';
|
|
15
|
-
import {
|
|
16
|
-
import { BigNumberish, toBN
|
|
16
|
+
import { transactionVersion } from '../utils/hash';
|
|
17
|
+
import { BigNumberish, toBN } from '../utils/number';
|
|
17
18
|
import { compileCalldata, estimatedFeeToMaxFee } from '../utils/stark';
|
|
18
|
-
import {
|
|
19
|
+
import { fromCallsToExecuteCalldata } from '../utils/transaction';
|
|
19
20
|
import { TypedData, getMessageHash } from '../utils/typedData';
|
|
20
21
|
import { AccountInterface } from './interface';
|
|
21
22
|
|
|
22
23
|
export class Account extends Provider implements AccountInterface {
|
|
23
24
|
public signer: SignerInterface;
|
|
24
25
|
|
|
26
|
+
public address: string;
|
|
27
|
+
|
|
25
28
|
constructor(
|
|
26
29
|
providerOrOptions: ProviderOptions | ProviderInterface,
|
|
27
|
-
|
|
30
|
+
address: string,
|
|
28
31
|
keyPairOrSigner: KeyPair | SignerInterface
|
|
29
32
|
) {
|
|
30
33
|
super(providerOrOptions);
|
|
34
|
+
this.address = address.toLowerCase();
|
|
31
35
|
this.signer =
|
|
32
36
|
'getPubKey' in keyPairOrSigner ? keyPairOrSigner : new Signer(keyPairOrSigner as KeyPair);
|
|
33
37
|
}
|
|
34
38
|
|
|
35
|
-
public async getNonce(): Promise<
|
|
36
|
-
|
|
37
|
-
contractAddress: this.address,
|
|
38
|
-
entrypoint: 'get_nonce',
|
|
39
|
-
});
|
|
40
|
-
return toHex(toBN(result[0]));
|
|
39
|
+
public async getNonce(blockIdentifier?: BlockIdentifier): Promise<BigNumberish> {
|
|
40
|
+
return super.getNonce(this.address, blockIdentifier);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
public async estimateFee(
|
|
@@ -45,13 +45,13 @@ export class Account extends Provider implements AccountInterface {
|
|
|
45
45
|
{ nonce: providedNonce, blockIdentifier }: EstimateFeeDetails = {}
|
|
46
46
|
): Promise<EstimateFee> {
|
|
47
47
|
const transactions = Array.isArray(calls) ? calls : [calls];
|
|
48
|
-
const nonce = providedNonce ?? (await this.getNonce());
|
|
49
|
-
const version = toBN(
|
|
48
|
+
const nonce = toBN(providedNonce ?? (await this.getNonce()));
|
|
49
|
+
const version = toBN(transactionVersion);
|
|
50
50
|
const chainId = await this.getChainId();
|
|
51
51
|
|
|
52
52
|
const signerDetails: InvocationsSignerDetails = {
|
|
53
53
|
walletAddress: this.address,
|
|
54
|
-
nonce
|
|
54
|
+
nonce,
|
|
55
55
|
maxFee: ZERO,
|
|
56
56
|
version,
|
|
57
57
|
chainId,
|
|
@@ -59,11 +59,11 @@ export class Account extends Provider implements AccountInterface {
|
|
|
59
59
|
|
|
60
60
|
const signature = await this.signer.signTransaction(transactions, signerDetails);
|
|
61
61
|
|
|
62
|
-
const calldata =
|
|
62
|
+
const calldata = fromCallsToExecuteCalldata(transactions);
|
|
63
63
|
const response = await super.getEstimateFee(
|
|
64
|
-
{ contractAddress: this.address,
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
{ contractAddress: this.address, calldata, signature },
|
|
65
|
+
{ version, nonce },
|
|
66
|
+
blockIdentifier
|
|
67
67
|
);
|
|
68
68
|
|
|
69
69
|
const suggestedMaxFee = estimatedFeeToMaxFee(response.overall_fee);
|
|
@@ -112,11 +112,12 @@ export class Account extends Provider implements AccountInterface {
|
|
|
112
112
|
|
|
113
113
|
const signature = await this.signer.signTransaction(transactions, signerDetails, abis);
|
|
114
114
|
|
|
115
|
-
const calldata =
|
|
115
|
+
const calldata = fromCallsToExecuteCalldata(transactions);
|
|
116
116
|
|
|
117
117
|
return this.invokeFunction(
|
|
118
|
-
{ contractAddress: this.address,
|
|
118
|
+
{ contractAddress: this.address, calldata, signature },
|
|
119
119
|
{
|
|
120
|
+
nonce,
|
|
120
121
|
maxFee,
|
|
121
122
|
version,
|
|
122
123
|
}
|
|
@@ -158,7 +159,7 @@ export class Account extends Provider implements AccountInterface {
|
|
|
158
159
|
try {
|
|
159
160
|
await this.callContract({
|
|
160
161
|
contractAddress: this.address,
|
|
161
|
-
entrypoint: '
|
|
162
|
+
entrypoint: 'isValidSignature',
|
|
162
163
|
calldata: compileCalldata({
|
|
163
164
|
hash: toBN(hash).toString(),
|
|
164
165
|
signature: signature.map((x) => toBN(x).toString()),
|