starknet 3.18.0 → 3.19.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 +65 -0
- package/README.md +1 -0
- package/__mocks__/typedDataStructArrayExample.json +44 -0
- package/__tests__/account.test.ts +11 -56
- package/__tests__/contract.test.ts +11 -49
- package/__tests__/defaultProvider.test.ts +321 -0
- package/__tests__/fixtures.ts +32 -11
- package/__tests__/rpcProvider.test.ts +17 -0
- package/__tests__/sequencerProvider.test.ts +45 -0
- package/__tests__/utils/typedData.test.ts +24 -0
- package/account/default.d.ts +54 -77
- package/account/default.js +271 -596
- package/account/index.js +18 -31
- package/account/interface.d.ts +66 -95
- package/account/interface.js +20 -30
- package/constants.d.ts +17 -19
- package/constants.js +2038 -2059
- package/contract/contractFactory.d.ts +25 -29
- package/contract/contractFactory.js +94 -210
- package/contract/default.d.ts +117 -146
- package/contract/default.js +582 -776
- package/contract/index.js +19 -32
- package/contract/interface.d.ts +72 -92
- package/contract/interface.js +6 -5
- package/dist/account/default.d.ts +5 -9
- package/dist/account/default.js +35 -169
- package/dist/account/interface.d.ts +3 -15
- package/dist/contract/contractFactory.js +4 -4
- package/dist/contract/default.d.ts +3 -3
- package/dist/contract/default.js +3 -2
- package/dist/contract/interface.d.ts +2 -2
- package/dist/provider/default.d.ts +18 -134
- package/dist/provider/default.js +47 -410
- package/dist/provider/index.d.ts +2 -0
- package/dist/provider/index.js +2 -0
- package/dist/provider/interface.d.ts +45 -50
- package/dist/provider/rpc.d.ts +57 -0
- package/dist/provider/rpc.js +364 -0
- package/dist/provider/sequencer.d.ts +66 -0
- package/dist/provider/sequencer.js +443 -0
- package/dist/types/account.d.ts +2 -3
- package/dist/types/api/index.d.ts +16 -0
- package/dist/types/api/index.js +18 -0
- package/dist/types/api/rpc.d.ts +221 -0
- package/dist/types/{api.js → api/rpc.js} +0 -0
- package/dist/types/api/sequencer.d.ts +289 -0
- package/dist/types/api/sequencer.js +2 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.js +15 -1
- package/dist/types/lib.d.ts +3 -1
- package/dist/types/provider.d.ts +86 -0
- package/dist/types/provider.js +2 -0
- package/dist/utils/provider.d.ts +4 -0
- package/dist/utils/provider.js +38 -0
- package/dist/utils/responseParser/index.d.ts +11 -0
- package/dist/utils/responseParser/index.js +9 -0
- package/dist/utils/responseParser/rpc.d.ts +13 -0
- package/dist/utils/responseParser/rpc.js +96 -0
- package/dist/utils/responseParser/sequencer.d.ts +13 -0
- package/dist/utils/responseParser/sequencer.js +124 -0
- package/dist/utils/typedData/index.js +14 -0
- package/index.js +42 -75
- package/package.json +1 -1
- package/provider/default.d.ts +21 -175
- package/provider/default.js +139 -703
- package/provider/errors.d.ts +4 -4
- package/provider/errors.js +30 -40
- package/provider/index.d.ts +2 -0
- package/provider/index.js +22 -33
- package/provider/interface.d.ts +104 -131
- package/provider/interface.js +6 -5
- package/provider/rpc.d.ts +57 -0
- package/provider/rpc.js +364 -0
- package/provider/sequencer.d.ts +66 -0
- package/provider/sequencer.js +443 -0
- package/provider/utils.d.ts +7 -9
- package/provider/utils.js +39 -44
- package/signer/default.d.ts +5 -9
- package/signer/default.js +72 -177
- package/signer/index.js +18 -31
- package/signer/interface.d.ts +29 -33
- package/signer/interface.js +6 -5
- package/src/account/default.ts +26 -146
- package/src/account/interface.ts +5 -20
- package/src/contract/contractFactory.ts +3 -6
- package/src/contract/default.ts +6 -4
- package/src/contract/interface.ts +2 -2
- package/src/provider/default.ts +63 -394
- package/src/provider/index.ts +2 -0
- package/src/provider/interface.ts +68 -63
- package/src/provider/rpc.ts +300 -0
- package/src/provider/sequencer.ts +384 -0
- package/src/types/account.ts +2 -3
- package/src/types/api/index.ts +17 -0
- package/src/types/api/rpc.ts +247 -0
- package/src/types/api/sequencer.ts +331 -0
- package/src/types/index.ts +3 -1
- package/src/types/lib.ts +3 -1
- package/src/types/provider.ts +108 -0
- package/src/utils/provider.ts +28 -0
- package/src/utils/responseParser/index.ts +28 -0
- package/src/utils/responseParser/rpc.ts +93 -0
- package/src/utils/responseParser/sequencer.ts +127 -0
- package/src/utils/typedData/index.ts +18 -0
- package/types/account.d.ts +5 -7
- package/types/account.js +2 -2
- package/types/api/index.d.ts +16 -0
- package/types/api/index.js +18 -0
- package/types/api/rpc.d.ts +221 -0
- package/types/api/rpc.js +2 -0
- package/types/api/sequencer.d.ts +289 -0
- package/types/api/sequencer.js +2 -0
- package/types/contract.d.ts +1 -1
- package/types/contract.js +2 -2
- package/types/index.d.ts +3 -1
- package/types/index.js +35 -34
- package/types/lib.d.ts +36 -41
- package/types/lib.js +2 -2
- package/types/provider.d.ts +86 -0
- package/types/provider.js +2 -0
- package/types/signer.d.ts +2 -2
- package/types/signer.js +2 -2
- package/utils/address.js +26 -37
- package/utils/ellipticCurve.d.ts +1 -6
- package/utils/ellipticCurve.js +73 -137
- package/utils/encode.js +49 -85
- package/utils/hash.d.ts +4 -31
- package/utils/hash.js +76 -141
- package/utils/json.d.ts +13 -45
- package/utils/json.js +15 -22
- package/utils/number.d.ts +2 -9
- package/utils/number.js +47 -81
- package/utils/provider.d.ts +4 -0
- package/utils/provider.js +38 -0
- package/utils/responseParser/index.d.ts +11 -0
- package/utils/responseParser/index.js +9 -0
- package/utils/responseParser/rpc.d.ts +13 -0
- package/utils/responseParser/rpc.js +96 -0
- package/utils/responseParser/sequencer.d.ts +13 -0
- package/utils/responseParser/sequencer.js +124 -0
- package/utils/shortString.js +13 -21
- package/utils/stark.d.ts +0 -1
- package/utils/stark.js +59 -93
- package/utils/transaction.d.ts +3 -6
- package/utils/transaction.js +50 -81
- package/utils/typedData/index.d.ts +3 -15
- package/utils/typedData/index.js +109 -157
- package/utils/typedData/types.d.ts +9 -9
- package/utils/typedData/types.js +2 -2
- package/utils/typedData/utils.js +6 -6
- package/utils/uint256.d.ts +5 -5
- package/utils/uint256.js +16 -26
- package/www/docs/API/account.md +3 -4
- package/www/docs/API/contract.md +2 -2
- package/www/docs/API/contractFactory.md +2 -2
- package/www/docs/API/provider.md +185 -74
- package/www/guides/account.md +1 -8
- package/www/guides/erc20.md +3 -0
- package/__tests__/provider.test.ts +0 -168
- package/dist/types/api.d.ts +0 -261
- package/src/types/api.ts +0 -303
- package/types/api.d.ts +0 -287
- package/types/api.js +0 -2
package/src/account/interface.ts
CHANGED
|
@@ -2,13 +2,13 @@ import { ProviderInterface } from '../provider';
|
|
|
2
2
|
import { SignerInterface } from '../signer';
|
|
3
3
|
import {
|
|
4
4
|
Abi,
|
|
5
|
-
AddTransactionResponse,
|
|
6
5
|
Call,
|
|
7
|
-
|
|
6
|
+
EstimateFeeDetails,
|
|
7
|
+
EstimateFeeResponse,
|
|
8
8
|
InvocationsDetails,
|
|
9
|
+
InvokeFunctionResponse,
|
|
9
10
|
Signature,
|
|
10
11
|
} from '../types';
|
|
11
|
-
import { EstimateFee, EstimateFeeDetails } from '../types/account';
|
|
12
12
|
import { BigNumberish } from '../utils/number';
|
|
13
13
|
import { TypedData } from '../utils/typedData/types';
|
|
14
14
|
|
|
@@ -17,21 +17,6 @@ export abstract class AccountInterface extends ProviderInterface {
|
|
|
17
17
|
|
|
18
18
|
public abstract signer: SignerInterface;
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
* Deploys a given compiled contract (json) to starknet
|
|
22
|
-
*
|
|
23
|
-
* @param payload payload to be deployed containing:
|
|
24
|
-
* - compiled contract code
|
|
25
|
-
* - constructor calldata
|
|
26
|
-
* - address salt
|
|
27
|
-
* @param abi the abi of the contract
|
|
28
|
-
* @returns a confirmation of sending a transaction on the starknet contract
|
|
29
|
-
*/
|
|
30
|
-
public abstract override deployContract(
|
|
31
|
-
payload: DeployContractPayload,
|
|
32
|
-
abi?: Abi
|
|
33
|
-
): Promise<AddTransactionResponse>;
|
|
34
|
-
|
|
35
20
|
/**
|
|
36
21
|
* Estimate Fee for a method on starknet
|
|
37
22
|
*
|
|
@@ -46,7 +31,7 @@ export abstract class AccountInterface extends ProviderInterface {
|
|
|
46
31
|
public abstract estimateFee(
|
|
47
32
|
calls: Call | Call[],
|
|
48
33
|
estimateFeeDetails?: EstimateFeeDetails
|
|
49
|
-
): Promise<
|
|
34
|
+
): Promise<EstimateFeeResponse>;
|
|
50
35
|
|
|
51
36
|
/**
|
|
52
37
|
* Invoke execute function in account contract
|
|
@@ -64,7 +49,7 @@ export abstract class AccountInterface extends ProviderInterface {
|
|
|
64
49
|
transactions: Call | Call[],
|
|
65
50
|
abis?: Abi[],
|
|
66
51
|
transactionsDetail?: InvocationsDetails
|
|
67
|
-
): Promise<
|
|
52
|
+
): Promise<InvokeFunctionResponse>;
|
|
68
53
|
|
|
69
54
|
/**
|
|
70
55
|
* Sign an JSON object for off-chain usage with the starknet private key and return the signature
|
|
@@ -34,19 +34,16 @@ export class ContractFactory {
|
|
|
34
34
|
constructorCalldata?: RawCalldata,
|
|
35
35
|
addressSalt?: BigNumberish
|
|
36
36
|
): Promise<Contract> {
|
|
37
|
-
const {
|
|
37
|
+
const { contract_address, transaction_hash } = await this.providerOrAccount.deployContract({
|
|
38
38
|
contract: this.compiledContract,
|
|
39
39
|
constructorCalldata,
|
|
40
40
|
addressSalt,
|
|
41
41
|
});
|
|
42
|
-
assert(
|
|
43
|
-
code === 'TRANSACTION_RECEIVED' && Boolean(address),
|
|
44
|
-
'Deployment of the contract failed'
|
|
45
|
-
);
|
|
42
|
+
assert(Boolean(contract_address), 'Deployment of the contract failed');
|
|
46
43
|
|
|
47
44
|
const contractInstance = new Contract(
|
|
48
45
|
this.compiledContract.abi,
|
|
49
|
-
|
|
46
|
+
contract_address!,
|
|
50
47
|
this.providerOrAccount
|
|
51
48
|
);
|
|
52
49
|
contractInstance.deployTransactionHash = transaction_hash;
|
package/src/contract/default.ts
CHANGED
|
@@ -7,13 +7,13 @@ import { BlockIdentifier } from '../provider/utils';
|
|
|
7
7
|
import {
|
|
8
8
|
Abi,
|
|
9
9
|
AbiEntry,
|
|
10
|
-
AddTransactionResponse,
|
|
11
10
|
Args,
|
|
12
11
|
AsyncContractFunction,
|
|
13
12
|
Calldata,
|
|
14
13
|
ContractFunction,
|
|
15
14
|
FunctionAbi,
|
|
16
15
|
Invocation,
|
|
16
|
+
InvokeFunctionResponse,
|
|
17
17
|
Overrides,
|
|
18
18
|
ParsedStruct,
|
|
19
19
|
Result,
|
|
@@ -544,7 +544,7 @@ export class Contract implements ContractInterface {
|
|
|
544
544
|
method: string,
|
|
545
545
|
args: Array<any> = [],
|
|
546
546
|
options: Overrides = {}
|
|
547
|
-
): Promise<
|
|
547
|
+
): Promise<InvokeFunctionResponse> {
|
|
548
548
|
// ensure contract is connected
|
|
549
549
|
assert(this.address !== null, 'contract isnt connected to an address');
|
|
550
550
|
// validate method and args
|
|
@@ -578,6 +578,9 @@ export class Contract implements ContractInterface {
|
|
|
578
578
|
});
|
|
579
579
|
}
|
|
580
580
|
|
|
581
|
+
// eslint-disable-next-line no-console
|
|
582
|
+
console.warn(`Invoking ${method} without an account. This will not work on a public node.`);
|
|
583
|
+
|
|
581
584
|
return this.providerOrAccount.invokeFunction({
|
|
582
585
|
...invocation,
|
|
583
586
|
signature: options.signature || [],
|
|
@@ -609,13 +612,12 @@ export class Contract implements ContractInterface {
|
|
|
609
612
|
calldata,
|
|
610
613
|
entrypoint: method,
|
|
611
614
|
},
|
|
612
|
-
|
|
615
|
+
blockIdentifier
|
|
613
616
|
)
|
|
614
617
|
.then((x) => this.parseResponse(method, x.result));
|
|
615
618
|
}
|
|
616
619
|
|
|
617
620
|
public async estimate(method: string, args: Array<any> = []) {
|
|
618
|
-
// TODO; remove error as soon as estimate fees are supported
|
|
619
621
|
// ensure contract is connected
|
|
620
622
|
assert(this.address !== null, 'contract isnt connected to an address');
|
|
621
623
|
|
|
@@ -3,10 +3,10 @@ import { ProviderInterface } from '../provider';
|
|
|
3
3
|
import { BlockIdentifier } from '../provider/utils';
|
|
4
4
|
import {
|
|
5
5
|
Abi,
|
|
6
|
-
AddTransactionResponse,
|
|
7
6
|
AsyncContractFunction,
|
|
8
7
|
ContractFunction,
|
|
9
8
|
Invocation,
|
|
9
|
+
InvokeFunctionResponse,
|
|
10
10
|
Overrides,
|
|
11
11
|
Result,
|
|
12
12
|
} from '../types';
|
|
@@ -78,7 +78,7 @@ export abstract class ContractInterface {
|
|
|
78
78
|
method: string,
|
|
79
79
|
args?: Array<any>,
|
|
80
80
|
options?: Overrides
|
|
81
|
-
): Promise<
|
|
81
|
+
): Promise<InvokeFunctionResponse>;
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Calls a method on a contract
|
package/src/provider/default.ts
CHANGED
|
@@ -1,440 +1,109 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { ONE, StarknetChainId, ZERO } from '../constants';
|
|
1
|
+
import { StarknetChainId } from '../constants';
|
|
4
2
|
import {
|
|
5
|
-
|
|
6
|
-
AddTransactionResponse,
|
|
3
|
+
BlockTag,
|
|
7
4
|
Call,
|
|
8
5
|
CallContractResponse,
|
|
9
|
-
|
|
6
|
+
ContractClass,
|
|
10
7
|
DeclareContractPayload,
|
|
8
|
+
DeclareContractResponse,
|
|
11
9
|
DeployContractPayload,
|
|
12
|
-
|
|
10
|
+
DeployContractResponse,
|
|
11
|
+
EstimateFeeResponse,
|
|
13
12
|
GetBlockResponse,
|
|
14
|
-
|
|
15
|
-
GetContractAddressesResponse,
|
|
13
|
+
GetTransactionReceiptResponse,
|
|
16
14
|
GetTransactionResponse,
|
|
17
|
-
GetTransactionStatusResponse,
|
|
18
|
-
GetTransactionTraceResponse,
|
|
19
15
|
Invocation,
|
|
20
|
-
|
|
16
|
+
InvocationsDetails,
|
|
17
|
+
InvokeFunctionResponse,
|
|
21
18
|
} from '../types';
|
|
22
|
-
import {
|
|
23
|
-
import { parse, parseAlwaysAsBig, stringify } from '../utils/json';
|
|
24
|
-
import { BigNumberish, bigNumberishArrayToDecimalStringArray, toBN, toHex } from '../utils/number';
|
|
25
|
-
import { compressProgram, randomAddress } from '../utils/stark';
|
|
26
|
-
import { GatewayError, HttpError } from './errors';
|
|
19
|
+
import { BigNumberish } from '../utils/number';
|
|
27
20
|
import { ProviderInterface } from './interface';
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
import { RpcProvider, RpcProviderOptions } from './rpc';
|
|
22
|
+
import { SequencerProvider, SequencerProviderOptions } from './sequencer';
|
|
23
|
+
import { BlockIdentifier } from './utils';
|
|
31
24
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return new Promise((res) => {
|
|
36
|
-
setTimeout(res, delay);
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function isEmptyQueryObject(obj?: Record<any, any>): obj is undefined {
|
|
41
|
-
return (
|
|
42
|
-
obj === undefined ||
|
|
43
|
-
Object.keys(obj).length === 0 ||
|
|
44
|
-
(Object.keys(obj).length === 1 &&
|
|
45
|
-
Object.entries(obj).every(([k, v]) => k === 'blockIdentifier' && v === null))
|
|
46
|
-
);
|
|
25
|
+
export interface ProviderOptions {
|
|
26
|
+
sequencer?: SequencerProviderOptions;
|
|
27
|
+
rpc?: RpcProviderOptions;
|
|
47
28
|
}
|
|
48
29
|
|
|
49
30
|
export class Provider implements ProviderInterface {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
optionsOrProvider: ProviderOptions | ProviderInterface = { network: 'goerli-alpha' }
|
|
60
|
-
) {
|
|
61
|
-
if (optionsOrProvider instanceof ProviderInterface) {
|
|
62
|
-
this.baseUrl = optionsOrProvider.baseUrl;
|
|
63
|
-
this.feederGatewayUrl = optionsOrProvider.feederGatewayUrl;
|
|
64
|
-
this.gatewayUrl = optionsOrProvider.gatewayUrl;
|
|
65
|
-
this.chainId =
|
|
66
|
-
optionsOrProvider.chainId ?? Provider.getChainIdFromBaseUrl(optionsOrProvider.baseUrl);
|
|
31
|
+
private provider!: ProviderInterface;
|
|
32
|
+
|
|
33
|
+
constructor(providerOrOptions?: ProviderOptions | ProviderInterface) {
|
|
34
|
+
if (providerOrOptions && 'chainId' in providerOrOptions) {
|
|
35
|
+
this.provider = providerOrOptions;
|
|
36
|
+
} else if (providerOrOptions?.rpc) {
|
|
37
|
+
this.provider = new RpcProvider(providerOrOptions.rpc);
|
|
38
|
+
} else if (providerOrOptions?.sequencer) {
|
|
39
|
+
this.provider = new SequencerProvider(providerOrOptions.sequencer);
|
|
67
40
|
} else {
|
|
68
|
-
|
|
69
|
-
'baseUrl' in optionsOrProvider
|
|
70
|
-
? optionsOrProvider.baseUrl
|
|
71
|
-
: Provider.getNetworkFromName(optionsOrProvider.network);
|
|
72
|
-
this.baseUrl = baseUrl;
|
|
73
|
-
this.chainId = Provider.getChainIdFromBaseUrl(baseUrl);
|
|
74
|
-
this.feederGatewayUrl = urljoin(baseUrl, 'feeder_gateway');
|
|
75
|
-
this.gatewayUrl = urljoin(baseUrl, 'gateway');
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
protected static getNetworkFromName(name: NetworkName) {
|
|
80
|
-
switch (name) {
|
|
81
|
-
case 'mainnet-alpha':
|
|
82
|
-
return 'https://alpha-mainnet.starknet.io';
|
|
83
|
-
case 'goerli-alpha':
|
|
84
|
-
default:
|
|
85
|
-
return 'https://alpha4.starknet.io';
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
protected static getChainIdFromBaseUrl(baseUrl: string): StarknetChainId {
|
|
90
|
-
try {
|
|
91
|
-
const url = new URL(baseUrl);
|
|
92
|
-
if (url.host.includes('mainnet.starknet.io')) {
|
|
93
|
-
return StarknetChainId.MAINNET;
|
|
94
|
-
}
|
|
95
|
-
} catch {
|
|
96
|
-
// eslint-disable-next-line no-console
|
|
97
|
-
console.error(`Could not parse baseUrl: ${baseUrl}`);
|
|
98
|
-
}
|
|
99
|
-
return StarknetChainId.TESTNET;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private getFetchUrl(endpoint: keyof Endpoints) {
|
|
103
|
-
const gatewayUrlEndpoints = ['add_transaction'];
|
|
104
|
-
|
|
105
|
-
return gatewayUrlEndpoints.includes(endpoint) ? this.gatewayUrl : this.feederGatewayUrl;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
private getFetchMethod(endpoint: keyof Endpoints) {
|
|
109
|
-
const postMethodEndpoints = ['add_transaction', 'call_contract', 'estimate_fee'];
|
|
110
|
-
|
|
111
|
-
return postMethodEndpoints.includes(endpoint) ? 'POST' : 'GET';
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private getQueryString(query?: Record<string, any>): string {
|
|
115
|
-
if (isEmptyQueryObject(query)) {
|
|
116
|
-
return '';
|
|
117
|
-
}
|
|
118
|
-
const queryString = Object.entries(query)
|
|
119
|
-
.map(([key, value]) => {
|
|
120
|
-
if (key === 'blockIdentifier') {
|
|
121
|
-
return `${getFormattedBlockIdentifier(value)}`;
|
|
122
|
-
}
|
|
123
|
-
return `${key}=${value}`;
|
|
124
|
-
})
|
|
125
|
-
.join('&');
|
|
126
|
-
|
|
127
|
-
return `?${queryString}`;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
private getHeaders(method: 'POST' | 'GET'): Record<string, string> | undefined {
|
|
131
|
-
if (method === 'POST') {
|
|
132
|
-
return {
|
|
133
|
-
'Content-Type': 'application/json',
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
return undefined;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// typesafe fetch
|
|
140
|
-
protected async fetchEndpoint<T extends keyof Endpoints>(
|
|
141
|
-
endpoint: T,
|
|
142
|
-
// typescript type magiuc to create a nice fitting function interface
|
|
143
|
-
...[query, request]: Endpoints[T]['QUERY'] extends never
|
|
144
|
-
? Endpoints[T]['REQUEST'] extends never
|
|
145
|
-
? [] // when no query and no request is needed, we can omit the query and request parameters
|
|
146
|
-
: [undefined, Endpoints[T]['REQUEST']]
|
|
147
|
-
: Endpoints[T]['REQUEST'] extends never
|
|
148
|
-
? [Endpoints[T]['QUERY']] // when no request is needed, we can omit the request parameter
|
|
149
|
-
: [Endpoints[T]['QUERY'], Endpoints[T]['REQUEST']] // when both query and request are needed, we cant omit anything
|
|
150
|
-
): Promise<Endpoints[T]['RESPONSE']> {
|
|
151
|
-
const baseUrl = this.getFetchUrl(endpoint);
|
|
152
|
-
const method = this.getFetchMethod(endpoint);
|
|
153
|
-
const queryString = this.getQueryString(query);
|
|
154
|
-
const headers = this.getHeaders(method);
|
|
155
|
-
const url = urljoin(baseUrl, endpoint, queryString);
|
|
156
|
-
|
|
157
|
-
try {
|
|
158
|
-
const res = await fetch(url, {
|
|
159
|
-
method,
|
|
160
|
-
body: stringify(request),
|
|
161
|
-
headers,
|
|
162
|
-
});
|
|
163
|
-
const textResponse = await res.text();
|
|
164
|
-
if (!res.ok) {
|
|
165
|
-
// This will allow user to handle contract errors
|
|
166
|
-
let responseBody: any;
|
|
167
|
-
try {
|
|
168
|
-
responseBody = parse(textResponse);
|
|
169
|
-
} catch {
|
|
170
|
-
// if error parsing fails, return an http error
|
|
171
|
-
throw new HttpError(res.statusText, res.status);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const errorCode = responseBody.code || ((responseBody as any)?.status_code as string); // starknet-devnet uses status_code instead of code; They need to fix that
|
|
175
|
-
throw new GatewayError(responseBody.message, errorCode); // Caught locally, and re-thrown for the user
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (endpoint === 'estimate_fee') {
|
|
179
|
-
return parseAlwaysAsBig(textResponse, (_, v) => {
|
|
180
|
-
if (v && typeof v === 'bigint') {
|
|
181
|
-
return toBN(v.toString());
|
|
182
|
-
}
|
|
183
|
-
return v;
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
return parse(textResponse) as Endpoints[T]['RESPONSE'];
|
|
187
|
-
} catch (err) {
|
|
188
|
-
// rethrow custom errors
|
|
189
|
-
if (err instanceof GatewayError || err instanceof HttpError) {
|
|
190
|
-
throw err;
|
|
191
|
-
}
|
|
192
|
-
if (err instanceof Error) {
|
|
193
|
-
throw Error(`Could not ${method} from endpoint \`${url}\`: ${err.message}`);
|
|
194
|
-
}
|
|
195
|
-
throw err;
|
|
41
|
+
this.provider = new SequencerProvider();
|
|
196
42
|
}
|
|
197
43
|
}
|
|
198
44
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
*
|
|
202
|
-
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/f464ec4797361b6be8989e36e02ec690e74ef285/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L13-L15)
|
|
203
|
-
* @returns starknet smart contract addresses
|
|
204
|
-
*/
|
|
205
|
-
public async getContractAddresses(): Promise<GetContractAddressesResponse> {
|
|
206
|
-
return this.fetchEndpoint('get_contract_addresses');
|
|
45
|
+
public get chainId(): StarknetChainId {
|
|
46
|
+
return this.provider.chainId;
|
|
207
47
|
}
|
|
208
48
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
*
|
|
212
|
-
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/fc97bdd8322a7df043c87c371634b26c15ed6cee/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L25-L39)
|
|
213
|
-
*
|
|
214
|
-
* @param invokeTransaction - transaction to be invoked
|
|
215
|
-
* @param blockHash
|
|
216
|
-
* @param blockNumber
|
|
217
|
-
* @returns the result of the function on the smart contract.
|
|
218
|
-
*/
|
|
219
|
-
public async callContract(
|
|
220
|
-
{ contractAddress, entrypoint, calldata = [] }: Call,
|
|
221
|
-
{ blockIdentifier = 'pending' }: { blockIdentifier?: BlockIdentifier } = {}
|
|
222
|
-
): Promise<CallContractResponse> {
|
|
223
|
-
return this.fetchEndpoint(
|
|
224
|
-
'call_contract',
|
|
225
|
-
{ blockIdentifier },
|
|
226
|
-
{
|
|
227
|
-
signature: [],
|
|
228
|
-
contract_address: contractAddress,
|
|
229
|
-
entry_point_selector: getSelectorFromName(entrypoint),
|
|
230
|
-
calldata,
|
|
231
|
-
}
|
|
232
|
-
);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Gets the block information
|
|
237
|
-
*
|
|
238
|
-
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/fc97bdd8322a7df043c87c371634b26c15ed6cee/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L41-L53)
|
|
239
|
-
*
|
|
240
|
-
* @param blockHash
|
|
241
|
-
* @param blockNumber
|
|
242
|
-
* @returns the block object { block_number, previous_block_number, state_root, status, timestamp, transaction_receipts, transactions }
|
|
243
|
-
*/
|
|
244
|
-
public async getBlock(blockIdentifier: BlockIdentifier = null): Promise<GetBlockResponse> {
|
|
245
|
-
return this.fetchEndpoint('get_block', { blockIdentifier });
|
|
49
|
+
public async getBlock(blockIdentifier: BlockIdentifier = 'pending'): Promise<GetBlockResponse> {
|
|
50
|
+
return this.provider.getBlock(blockIdentifier);
|
|
246
51
|
}
|
|
247
52
|
|
|
248
|
-
|
|
249
|
-
* Gets the code of the deployed contract.
|
|
250
|
-
*
|
|
251
|
-
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/fc97bdd8322a7df043c87c371634b26c15ed6cee/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L55-L68)
|
|
252
|
-
*
|
|
253
|
-
* @param contractAddress
|
|
254
|
-
* @param blockHash
|
|
255
|
-
* @param blockNumber
|
|
256
|
-
* @returns Bytecode and ABI of compiled contract
|
|
257
|
-
*/
|
|
258
|
-
public async getCode(
|
|
53
|
+
public async getClassAt(
|
|
259
54
|
contractAddress: string,
|
|
260
55
|
blockIdentifier: BlockIdentifier = 'pending'
|
|
261
|
-
): Promise<
|
|
262
|
-
return this.
|
|
56
|
+
): Promise<ContractClass> {
|
|
57
|
+
return this.provider.getClassAt(contractAddress, blockIdentifier);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public async getEstimateFee(
|
|
61
|
+
invocation: Invocation,
|
|
62
|
+
blockIdentifier: BlockIdentifier = 'pending',
|
|
63
|
+
invocationDetails: InvocationsDetails = {}
|
|
64
|
+
): Promise<EstimateFeeResponse> {
|
|
65
|
+
return this.provider.getEstimateFee(invocation, blockIdentifier, invocationDetails);
|
|
263
66
|
}
|
|
264
67
|
|
|
265
|
-
// TODO: add proper type
|
|
266
|
-
/**
|
|
267
|
-
* Gets the contract's storage variable at a specific key.
|
|
268
|
-
*
|
|
269
|
-
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/fc97bdd8322a7df043c87c371634b26c15ed6cee/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L70-L85)
|
|
270
|
-
*
|
|
271
|
-
* @param contractAddress
|
|
272
|
-
* @param key - from getStorageVarAddress('<STORAGE_VARIABLE_NAME>') (WIP)
|
|
273
|
-
* @param blockHash
|
|
274
|
-
* @param blockNumber
|
|
275
|
-
* @returns the value of the storage variable
|
|
276
|
-
*/
|
|
277
68
|
public async getStorageAt(
|
|
278
69
|
contractAddress: string,
|
|
279
70
|
key: BigNumberish,
|
|
280
|
-
|
|
281
|
-
): Promise<
|
|
282
|
-
return this.
|
|
71
|
+
blockTagOrHash: BlockTag | BigNumberish = 'pending'
|
|
72
|
+
): Promise<BigNumberish> {
|
|
73
|
+
return this.provider.getStorageAt(contractAddress, key, blockTagOrHash);
|
|
283
74
|
}
|
|
284
75
|
|
|
285
|
-
/**
|
|
286
|
-
* Gets the status of a transaction.
|
|
287
|
-
*
|
|
288
|
-
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/f464ec4797361b6be8989e36e02ec690e74ef285/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L48-L52)
|
|
289
|
-
*
|
|
290
|
-
* @param txHash
|
|
291
|
-
* @returns the transaction status object { block_number, tx_status: NOT_RECEIVED | RECEIVED | PENDING | REJECTED | ACCEPTED_ONCHAIN }
|
|
292
|
-
*/
|
|
293
|
-
public async getTransactionStatus(txHash: BigNumberish): Promise<GetTransactionStatusResponse> {
|
|
294
|
-
const txHashHex = toHex(toBN(txHash));
|
|
295
|
-
return this.fetchEndpoint('get_transaction_status', { transactionHash: txHashHex });
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Gets the transaction receipt from a tx hash.
|
|
300
|
-
*
|
|
301
|
-
* [Reference] (https://github.com/starkware-libs/cairo-lang/blob/167b28bcd940fd25ea3816204fa882a0b0a49603/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L183)
|
|
302
|
-
*
|
|
303
|
-
* @param txHash
|
|
304
|
-
* @returns the transaction receipt object
|
|
305
|
-
*/
|
|
306
|
-
public async getTransactionReceipt(txHash: BigNumberish): Promise<TransactionReceiptResponse> {
|
|
307
|
-
const txHashHex = toHex(toBN(txHash));
|
|
308
|
-
return this.fetchEndpoint('get_transaction_receipt', { transactionHash: txHashHex });
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Gets the transaction information from a tx id.
|
|
313
|
-
*
|
|
314
|
-
* [Reference](https://github.com/starkware-libs/cairo-lang/blob/f464ec4797361b6be8989e36e02ec690e74ef285/src/starkware/starknet/services/api/feeder_gateway/feeder_gateway_client.py#L54-L58)
|
|
315
|
-
*
|
|
316
|
-
* @param txHash
|
|
317
|
-
* @returns the transacton object { transaction_id, status, transaction, block_number?, block_number?, transaction_index?, transaction_failure_reason? }
|
|
318
|
-
*/
|
|
319
76
|
public async getTransaction(txHash: BigNumberish): Promise<GetTransactionResponse> {
|
|
320
|
-
|
|
321
|
-
return this.fetchEndpoint('get_transaction', { transactionHash: txHashHex });
|
|
77
|
+
return this.provider.getTransaction(txHash);
|
|
322
78
|
}
|
|
323
79
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
* @param txHash
|
|
329
|
-
* @returns the transaction trace
|
|
330
|
-
*/
|
|
331
|
-
public async getTransactionTrace(txHash: BigNumberish): Promise<GetTransactionTraceResponse> {
|
|
332
|
-
const txHashHex = toHex(toBN(txHash));
|
|
333
|
-
return this.fetchEndpoint('get_transaction_trace', { transactionHash: txHashHex });
|
|
80
|
+
public async getTransactionReceipt(txHash: BigNumberish): Promise<GetTransactionReceiptResponse> {
|
|
81
|
+
return this.provider.getTransactionReceipt(txHash);
|
|
334
82
|
}
|
|
335
83
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
*/
|
|
342
|
-
public declareContract(payload: DeclareContractPayload): Promise<AddTransactionResponse> {
|
|
343
|
-
const parsedContract =
|
|
344
|
-
typeof payload.contract === 'string'
|
|
345
|
-
? (parse(payload.contract) as CompiledContract)
|
|
346
|
-
: payload.contract;
|
|
347
|
-
const contractDefinition = {
|
|
348
|
-
...parsedContract,
|
|
349
|
-
program: compressProgram(parsedContract.program),
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
return this.fetchEndpoint('add_transaction', undefined, {
|
|
353
|
-
type: 'DECLARE',
|
|
354
|
-
contract_class: contractDefinition,
|
|
355
|
-
nonce: toHex(ZERO),
|
|
356
|
-
signature: [],
|
|
357
|
-
sender_address: toHex(ONE),
|
|
358
|
-
});
|
|
84
|
+
public async callContract(
|
|
85
|
+
request: Call,
|
|
86
|
+
blockIdentifier: BlockIdentifier = 'pending'
|
|
87
|
+
): Promise<CallContractResponse> {
|
|
88
|
+
return this.provider.callContract(request, blockIdentifier);
|
|
359
89
|
}
|
|
360
90
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
* @returns a confirmation of sending a transaction on the starknet contract
|
|
367
|
-
*/
|
|
368
|
-
public deployContract(
|
|
369
|
-
payload: DeployContractPayload,
|
|
370
|
-
_abi?: Abi
|
|
371
|
-
): Promise<AddTransactionResponse> {
|
|
372
|
-
const parsedContract =
|
|
373
|
-
typeof payload.contract === 'string'
|
|
374
|
-
? (parse(payload.contract) as CompiledContract)
|
|
375
|
-
: payload.contract;
|
|
376
|
-
const contractDefinition = {
|
|
377
|
-
...parsedContract,
|
|
378
|
-
program: compressProgram(parsedContract.program),
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
return this.fetchEndpoint('add_transaction', undefined, {
|
|
382
|
-
type: 'DEPLOY',
|
|
383
|
-
contract_address_salt: payload.addressSalt ?? randomAddress(),
|
|
384
|
-
constructor_calldata: bigNumberishArrayToDecimalStringArray(
|
|
385
|
-
payload.constructorCalldata ?? []
|
|
386
|
-
),
|
|
387
|
-
contract_definition: contractDefinition,
|
|
388
|
-
});
|
|
91
|
+
public async invokeFunction(
|
|
92
|
+
functionInvocation: Invocation,
|
|
93
|
+
details: InvocationsDetails
|
|
94
|
+
): Promise<InvokeFunctionResponse> {
|
|
95
|
+
return this.provider.invokeFunction(functionInvocation, details);
|
|
389
96
|
}
|
|
390
97
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
* @deprecated This method wont be supported as soon as fees are mandatory
|
|
394
|
-
*
|
|
395
|
-
* @param invocation
|
|
396
|
-
* @param _abi - (optional) signature to send along
|
|
397
|
-
* @returns response from addTransaction
|
|
398
|
-
*/
|
|
399
|
-
public invokeFunction(invocation: Invocation, _abi?: Abi): Promise<AddTransactionResponse> {
|
|
400
|
-
return this.fetchEndpoint('add_transaction', undefined, {
|
|
401
|
-
type: 'INVOKE_FUNCTION',
|
|
402
|
-
contract_address: invocation.contractAddress,
|
|
403
|
-
entry_point_selector: getSelectorFromName(invocation.entrypoint),
|
|
404
|
-
calldata: bigNumberishArrayToDecimalStringArray(invocation.calldata ?? []),
|
|
405
|
-
signature: bigNumberishArrayToDecimalStringArray(invocation.signature ?? []),
|
|
406
|
-
});
|
|
98
|
+
public async deployContract(payload: DeployContractPayload): Promise<DeployContractResponse> {
|
|
99
|
+
return this.provider.deployContract(payload);
|
|
407
100
|
}
|
|
408
101
|
|
|
409
|
-
public async
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
while (!onchain) {
|
|
413
|
-
// eslint-disable-next-line no-await-in-loop
|
|
414
|
-
await wait(retryInterval);
|
|
415
|
-
// eslint-disable-next-line no-await-in-loop
|
|
416
|
-
const res = await this.getTransactionStatus(txHash);
|
|
417
|
-
|
|
418
|
-
const successStates = ['ACCEPTED_ON_L1', 'ACCEPTED_ON_L2', 'PENDING'];
|
|
419
|
-
const errorStates = ['REJECTED', 'NOT_RECEIVED'];
|
|
420
|
-
|
|
421
|
-
if (successStates.includes(res.tx_status)) {
|
|
422
|
-
onchain = true;
|
|
423
|
-
} else if (errorStates.includes(res.tx_status)) {
|
|
424
|
-
const message = res.tx_failure_reason
|
|
425
|
-
? `${res.tx_status}: ${res.tx_failure_reason.code}\n${res.tx_failure_reason.error_message}`
|
|
426
|
-
: res.tx_status;
|
|
427
|
-
const error = new Error(message) as Error & { response: GetTransactionStatusResponse };
|
|
428
|
-
error.response = res;
|
|
429
|
-
throw error;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
102
|
+
public async declareContract(payload: DeclareContractPayload): Promise<DeclareContractResponse> {
|
|
103
|
+
return this.provider.declareContract(payload);
|
|
432
104
|
}
|
|
433
105
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
*/
|
|
437
|
-
public async waitForTx(txHash: BigNumberish, retryInterval: number = 8000) {
|
|
438
|
-
return this.waitForTransaction(txHash, retryInterval);
|
|
106
|
+
public async waitForTransaction(txHash: BigNumberish, retryInterval?: number): Promise<void> {
|
|
107
|
+
return this.provider.waitForTransaction(txHash, retryInterval);
|
|
439
108
|
}
|
|
440
109
|
}
|
package/src/provider/index.ts
CHANGED