starknet 5.7.0 → 5.8.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/dist/index.mjs CHANGED
@@ -2479,6 +2479,9 @@ function felt(it) {
2479
2479
  if (typeof it === "string" && isStringWholeNumber(it)) {
2480
2480
  return it;
2481
2481
  }
2482
+ if (typeof it === "boolean") {
2483
+ return `${+it}`;
2484
+ }
2482
2485
  throw new Error(`${it} can't be computed by felt()`);
2483
2486
  }
2484
2487
 
@@ -2765,7 +2768,6 @@ function extractContractHashes(payload) {
2765
2768
  // src/utils/stark.ts
2766
2769
  var stark_exports = {};
2767
2770
  __export(stark_exports, {
2768
- compileCalldata: () => compileCalldata,
2769
2771
  compressProgram: () => compressProgram,
2770
2772
  estimatedFeeToMaxFee: () => estimatedFeeToMaxFee,
2771
2773
  formatSignature: () => formatSignature,
@@ -2807,21 +2809,6 @@ function signatureToDecimalArray(sig) {
2807
2809
  function signatureToHexArray(sig) {
2808
2810
  return bigNumberishArrayToHexadecimalStringArray(formatSignature(sig));
2809
2811
  }
2810
- function compileCalldata(args) {
2811
- const compiledData = Object.values(args).flatMap((value) => {
2812
- if (Array.isArray(value))
2813
- return [toBigInt(value.length).toString(), ...value.map((x) => toBigInt(x).toString())];
2814
- if (typeof value === "object" && "type" in value)
2815
- return Object.entries(value).filter(([k]) => k !== "type").map(([, v]) => toBigInt(v).toString());
2816
- return toBigInt(value).toString();
2817
- });
2818
- Object.defineProperty(compiledData, "compiled", {
2819
- enumerable: false,
2820
- writable: false,
2821
- value: true
2822
- });
2823
- return compiledData;
2824
- }
2825
2812
  function estimatedFeeToMaxFee(estimatedFee, overhead = 0.5) {
2826
2813
  const overHeadPercent = Math.round((1 + overhead) * 100);
2827
2814
  return toBigInt(estimatedFee) * toBigInt(overHeadPercent) / 100n;
@@ -2935,1055 +2922,964 @@ var HttpError = class extends LibraryError {
2935
2922
  }
2936
2923
  };
2937
2924
 
2938
- // src/utils/starknetId.ts
2939
- var starknetId_exports = {};
2940
- __export(starknetId_exports, {
2941
- StarknetIdContract: () => StarknetIdContract,
2942
- getStarknetIdContract: () => getStarknetIdContract,
2943
- useDecoded: () => useDecoded,
2944
- useEncoded: () => useEncoded
2945
- });
2946
- var basicAlphabet = "abcdefghijklmnopqrstuvwxyz0123456789-";
2947
- var basicSizePlusOne = BigInt(basicAlphabet.length + 1);
2948
- var bigAlphabet = "\u8FD9\u6765";
2949
- var basicAlphabetSize = BigInt(basicAlphabet.length);
2950
- var bigAlphabetSize = BigInt(bigAlphabet.length);
2951
- var bigAlphabetSizePlusOne = BigInt(bigAlphabet.length + 1);
2952
- function extractStars(str) {
2953
- let k = 0;
2954
- while (str.endsWith(bigAlphabet[bigAlphabet.length - 1])) {
2955
- str = str.substring(0, str.length - 1);
2956
- k += 1;
2925
+ // src/utils/calldata/formatter.ts
2926
+ var guard = {
2927
+ isBN: (data, type, key) => {
2928
+ if (!isBigInt(data[key]))
2929
+ throw new Error(
2930
+ `Data and formatter mismatch on ${key}:${type[key]}, expected response data ${key}:${data[key]} to be BN instead it is ${typeof data[key]}`
2931
+ );
2932
+ },
2933
+ unknown: (data, type, key) => {
2934
+ throw new Error(`Unhandled formatter type on ${key}:${type[key]} for data ${key}:${data[key]}`);
2957
2935
  }
2958
- return [str, k];
2959
- }
2960
- function useDecoded(encoded) {
2961
- let decoded = "";
2962
- encoded.forEach((subdomain) => {
2963
- while (subdomain !== ZERO) {
2964
- const code = subdomain % basicSizePlusOne;
2965
- subdomain /= basicSizePlusOne;
2966
- if (code === BigInt(basicAlphabet.length)) {
2967
- const nextSubdomain = subdomain / bigAlphabetSizePlusOne;
2968
- if (nextSubdomain === ZERO) {
2969
- const code2 = subdomain % bigAlphabetSizePlusOne;
2970
- subdomain = nextSubdomain;
2971
- if (code2 === ZERO)
2972
- decoded += basicAlphabet[0];
2973
- else
2974
- decoded += bigAlphabet[Number(code2) - 1];
2975
- } else {
2976
- const code2 = subdomain % bigAlphabetSize;
2977
- decoded += bigAlphabet[Number(code2)];
2978
- subdomain /= bigAlphabetSize;
2979
- }
2980
- } else
2981
- decoded += basicAlphabet[Number(code)];
2936
+ };
2937
+ function formatter(data, type, sameType) {
2938
+ return Object.entries(data).reduce((acc, [key, value]) => {
2939
+ const elType = sameType ?? type[key];
2940
+ if (!(key in type) && !sameType) {
2941
+ acc[key] = value;
2942
+ return acc;
2982
2943
  }
2983
- const [str, k] = extractStars(decoded);
2984
- if (k)
2985
- decoded = str + (k % 2 === 0 ? bigAlphabet[bigAlphabet.length - 1].repeat(k / 2 - 1) + bigAlphabet[0] + basicAlphabet[1] : bigAlphabet[bigAlphabet.length - 1].repeat((k - 1) / 2 + 1));
2986
- decoded += ".";
2987
- });
2988
- if (!decoded) {
2989
- return decoded;
2990
- }
2991
- return decoded.concat("stark");
2944
+ if (elType === "string") {
2945
+ if (Array.isArray(data[key])) {
2946
+ const arrayStr = formatter(
2947
+ data[key],
2948
+ data[key].map((_) => elType)
2949
+ );
2950
+ acc[key] = Object.values(arrayStr).join("");
2951
+ return acc;
2952
+ }
2953
+ guard.isBN(data, type, key);
2954
+ acc[key] = decodeShortString(value);
2955
+ return acc;
2956
+ }
2957
+ if (elType === "number") {
2958
+ guard.isBN(data, type, key);
2959
+ acc[key] = Number(value);
2960
+ return acc;
2961
+ }
2962
+ if (typeof elType === "function") {
2963
+ acc[key] = elType(value);
2964
+ return acc;
2965
+ }
2966
+ if (Array.isArray(elType)) {
2967
+ const arrayObj = formatter(data[key], elType, elType[0]);
2968
+ acc[key] = Object.values(arrayObj);
2969
+ return acc;
2970
+ }
2971
+ if (typeof elType === "object") {
2972
+ acc[key] = formatter(data[key], elType);
2973
+ return acc;
2974
+ }
2975
+ guard.unknown(data, type, key);
2976
+ return acc;
2977
+ }, {});
2992
2978
  }
2993
- function useEncoded(decoded) {
2994
- let encoded = BigInt(0);
2995
- let multiplier = BigInt(1);
2996
- if (decoded.endsWith(bigAlphabet[0] + basicAlphabet[1])) {
2997
- const [str, k] = extractStars(decoded.substring(0, decoded.length - 2));
2998
- decoded = str + bigAlphabet[bigAlphabet.length - 1].repeat(2 * (k + 1));
2999
- } else {
3000
- const [str, k] = extractStars(decoded);
3001
- if (k)
3002
- decoded = str + bigAlphabet[bigAlphabet.length - 1].repeat(1 + 2 * (k - 1));
3003
- }
3004
- for (let i = 0; i < decoded.length; i += 1) {
3005
- const char = decoded[i];
3006
- const index = basicAlphabet.indexOf(char);
3007
- const bnIndex = BigInt(basicAlphabet.indexOf(char));
3008
- if (index !== -1) {
3009
- if (i === decoded.length - 1 && decoded[i] === basicAlphabet[0]) {
3010
- encoded += multiplier * basicAlphabetSize;
3011
- multiplier *= basicSizePlusOne;
3012
- multiplier *= basicSizePlusOne;
3013
- } else {
3014
- encoded += multiplier * bnIndex;
3015
- multiplier *= basicSizePlusOne;
2979
+
2980
+ // src/utils/calldata/tuple.ts
2981
+ function parseNamedTuple(namedTuple) {
2982
+ const name = namedTuple.substring(0, namedTuple.indexOf(":"));
2983
+ const type = namedTuple.substring(name.length + ":".length);
2984
+ return { name, type };
2985
+ }
2986
+ function parseSubTuple(s) {
2987
+ if (!s.includes("("))
2988
+ return { subTuple: [], result: s };
2989
+ const subTuple = [];
2990
+ let result = "";
2991
+ let i = 0;
2992
+ while (i < s.length) {
2993
+ if (s[i] === "(") {
2994
+ let counter = 1;
2995
+ const lBracket = i;
2996
+ i++;
2997
+ while (counter) {
2998
+ if (s[i] === ")")
2999
+ counter--;
3000
+ if (s[i] === "(")
3001
+ counter++;
3002
+ i++;
3016
3003
  }
3017
- } else if (bigAlphabet.indexOf(char) !== -1) {
3018
- encoded += multiplier * basicAlphabetSize;
3019
- multiplier *= basicSizePlusOne;
3020
- const newid = (i === decoded.length - 1 ? 1 : 0) + bigAlphabet.indexOf(char);
3021
- encoded += multiplier * BigInt(newid);
3022
- multiplier *= bigAlphabetSize;
3004
+ subTuple.push(s.substring(lBracket, i));
3005
+ result += " ";
3006
+ i--;
3007
+ } else {
3008
+ result += s[i];
3023
3009
  }
3010
+ i++;
3024
3011
  }
3025
- return encoded;
3012
+ return {
3013
+ subTuple,
3014
+ result
3015
+ };
3026
3016
  }
3027
- var StarknetIdContract = /* @__PURE__ */ ((StarknetIdContract2) => {
3028
- StarknetIdContract2["MAINNET"] = "0x6ac597f8116f886fa1c97a23fa4e08299975ecaf6b598873ca6792b9bbfb678";
3029
- StarknetIdContract2["TESTNET"] = "0x3bab268e932d2cecd1946f100ae67ce3dff9fd234119ea2f6da57d16d29fce";
3030
- return StarknetIdContract2;
3031
- })(StarknetIdContract || {});
3032
- function getStarknetIdContract(chainId) {
3033
- switch (chainId) {
3034
- case "0x534e5f4d41494e" /* SN_MAIN */:
3035
- return "0x6ac597f8116f886fa1c97a23fa4e08299975ecaf6b598873ca6792b9bbfb678" /* MAINNET */;
3036
- case "0x534e5f474f45524c49" /* SN_GOERLI */:
3037
- return "0x3bab268e932d2cecd1946f100ae67ce3dff9fd234119ea2f6da57d16d29fce" /* TESTNET */;
3038
- default:
3039
- throw new Error("Starknet.id is not yet deployed on this network");
3017
+ function extractCairo0Tuple(type) {
3018
+ const cleanType = type.replace(/\s/g, "").slice(1, -1);
3019
+ const { subTuple, result } = parseSubTuple(cleanType);
3020
+ let recomposed = result.split(",").map((it) => {
3021
+ return subTuple.length ? it.replace(" ", subTuple.shift()) : it;
3022
+ });
3023
+ if (isTypeNamedTuple(type)) {
3024
+ recomposed = recomposed.reduce((acc, it) => {
3025
+ return acc.concat(parseNamedTuple(it));
3026
+ }, []);
3040
3027
  }
3028
+ return recomposed;
3041
3029
  }
3042
-
3043
- // src/provider/starknetId.ts
3044
- async function getStarkName(provider, address, StarknetIdContract2) {
3045
- const chainId = await provider.getChainId();
3046
- const contract = StarknetIdContract2 ?? getStarknetIdContract(chainId);
3047
- try {
3048
- const hexDomain = await provider.callContract({
3049
- contractAddress: contract,
3050
- entrypoint: "address_to_domain",
3051
- calldata: compileCalldata({
3052
- address
3053
- })
3054
- });
3055
- const decimalDomain = hexDomain.result.map((element) => BigInt(element)).slice(1);
3056
- const stringDomain = useDecoded(decimalDomain);
3057
- if (!stringDomain) {
3058
- throw Error("Starkname not found");
3059
- }
3060
- return stringDomain;
3061
- } catch (e) {
3062
- if (e instanceof Error && e.message === "Starkname not found") {
3063
- throw e;
3064
- }
3065
- throw Error("Could not get stark name");
3066
- }
3030
+ function extractCairo1Tuple(type) {
3031
+ const cleanType = type.replace(/\s/g, "").slice(1, -1);
3032
+ return cleanType.split(",");
3067
3033
  }
3068
- async function getAddressFromStarkName(provider, name, StarknetIdContract2) {
3069
- const chainId = await provider.getChainId();
3070
- const contract = StarknetIdContract2 ?? getStarknetIdContract(chainId);
3071
- try {
3072
- const addressData = await provider.callContract({
3073
- contractAddress: contract,
3074
- entrypoint: "domain_to_address",
3075
- calldata: compileCalldata({
3076
- domain: [useEncoded(name.replace(".stark", "")).toString(10)]
3077
- })
3078
- });
3079
- return addressData.result[0];
3080
- } catch {
3081
- throw Error("Could not get address from stark name");
3034
+ function extractTupleMemberTypes(type) {
3035
+ if (isCairo1Type(type)) {
3036
+ return extractCairo1Tuple(type);
3082
3037
  }
3038
+ return extractCairo0Tuple(type);
3083
3039
  }
3084
3040
 
3085
- // src/provider/utils.ts
3086
- var validBlockTags = ["latest", "pending"];
3087
- var Block = class {
3088
- constructor(_identifier) {
3089
- this.hash = null;
3090
- this.number = null;
3091
- this.tag = null;
3092
- this.valueOf = () => this.number;
3093
- this.toString = () => this.hash;
3094
- this.setIdentifier(_identifier);
3095
- }
3096
- setIdentifier(__identifier) {
3097
- if (typeof __identifier === "string" && isHex(__identifier)) {
3098
- this.hash = __identifier;
3099
- } else if (typeof __identifier === "bigint") {
3100
- this.hash = toHex(__identifier);
3101
- } else if (typeof __identifier === "number") {
3102
- this.number = __identifier;
3103
- } else if (typeof __identifier === "string" && validBlockTags.includes(__identifier)) {
3104
- this.tag = __identifier;
3105
- } else {
3106
- this.tag = "pending";
3107
- }
3108
- }
3109
- get queryIdentifier() {
3110
- if (this.number !== null) {
3111
- return `blockNumber=${this.number}`;
3112
- }
3113
- if (this.hash !== null) {
3114
- return `blockHash=${this.hash}`;
3115
- }
3116
- return `blockNumber=${this.tag}`;
3117
- }
3118
- get identifier() {
3119
- if (this.number !== null) {
3120
- return { block_number: this.number };
3121
- }
3122
- if (this.hash !== null) {
3123
- return { block_hash: this.hash };
3124
- }
3125
- return this.tag;
3126
- }
3127
- set identifier(_identifier) {
3128
- this.setIdentifier(_identifier);
3129
- }
3130
- get sequencerIdentifier() {
3131
- return this.hash !== null ? { blockHash: this.hash } : { blockNumber: this.number ?? this.tag };
3132
- }
3133
- };
3134
-
3135
- // src/provider/rpc.ts
3136
- var defaultOptions = {
3137
- headers: { "Content-Type": "application/json" },
3138
- blockIdentifier: "latest",
3139
- retries: 200
3140
- };
3141
- var RpcProvider = class {
3142
- constructor(optionsOrProvider) {
3143
- this.responseParser = new RPCResponseParser();
3144
- const { nodeUrl, retries, headers, blockIdentifier } = optionsOrProvider;
3145
- this.nodeUrl = nodeUrl;
3146
- this.retries = retries || defaultOptions.retries;
3147
- this.headers = { ...defaultOptions.headers, ...headers };
3148
- this.blockIdentifier = blockIdentifier || defaultOptions.blockIdentifier;
3149
- this.getChainId();
3150
- }
3151
- fetch(method, params) {
3152
- return fetchPonyfill_default(this.nodeUrl, {
3153
- method: "POST",
3154
- body: stringify2({ method, jsonrpc: "2.0", params, id: 0 }),
3155
- headers: this.headers
3156
- });
3157
- }
3158
- errorHandler(error) {
3159
- if (error) {
3160
- const { code, message } = error;
3161
- throw new LibraryError(`${code}: ${message}`);
3162
- }
3163
- }
3164
- async fetchEndpoint(method, params) {
3165
- var _a;
3166
- try {
3167
- const rawResult = await this.fetch(method, params);
3168
- const { error, result } = await rawResult.json();
3169
- this.errorHandler(error);
3170
- return result;
3171
- } catch (error) {
3172
- this.errorHandler((_a = error == null ? void 0 : error.response) == null ? void 0 : _a.data);
3173
- throw error;
3174
- }
3175
- }
3176
- async getChainId() {
3177
- this.chainId ?? (this.chainId = await this.fetchEndpoint("starknet_chainId"));
3178
- return this.chainId;
3179
- }
3180
- async getBlock(blockIdentifier = this.blockIdentifier) {
3181
- return this.getBlockWithTxHashes(blockIdentifier).then(
3182
- this.responseParser.parseGetBlockResponse
3041
+ // src/utils/calldata/requestParser.ts
3042
+ function parseTuple(element, typeStr) {
3043
+ const memberTypes = extractTupleMemberTypes(typeStr);
3044
+ const elements = Object.values(element);
3045
+ if (elements.length !== memberTypes.length) {
3046
+ throw Error(
3047
+ `ParseTuple: provided and expected abi tuple size do not match.
3048
+ provided: ${elements}
3049
+ expected: ${memberTypes}`
3183
3050
  );
3184
3051
  }
3185
- async getBlockHashAndNumber() {
3186
- return this.fetchEndpoint("starknet_blockHashAndNumber");
3187
- }
3188
- async getBlockWithTxHashes(blockIdentifier = this.blockIdentifier) {
3189
- const block_id = new Block(blockIdentifier).identifier;
3190
- return this.fetchEndpoint("starknet_getBlockWithTxHashes", { block_id });
3191
- }
3192
- async getBlockWithTxs(blockIdentifier = this.blockIdentifier) {
3193
- const block_id = new Block(blockIdentifier).identifier;
3194
- return this.fetchEndpoint("starknet_getBlockWithTxs", { block_id });
3052
+ return memberTypes.map((it, dx) => {
3053
+ return {
3054
+ element: elements[dx],
3055
+ type: it.type ?? it
3056
+ };
3057
+ });
3058
+ }
3059
+ function parseCalldataValue(element, type, structs) {
3060
+ if (element === void 0) {
3061
+ throw Error(`Missing parameter for type ${type}`);
3195
3062
  }
3196
- async getClassHashAt(contractAddress, blockIdentifier = this.blockIdentifier) {
3197
- const block_id = new Block(blockIdentifier).identifier;
3198
- return this.fetchEndpoint("starknet_getClassHashAt", {
3199
- block_id,
3200
- contract_address: contractAddress
3201
- });
3063
+ if (Array.isArray(element)) {
3064
+ throw Error(`Array inside array (nD) are not supported by cairo. Element: ${element} ${type}`);
3202
3065
  }
3203
- async getNonceForAddress(contractAddress, blockIdentifier = this.blockIdentifier) {
3204
- const block_id = new Block(blockIdentifier).identifier;
3205
- return this.fetchEndpoint("starknet_getNonce", {
3206
- contract_address: contractAddress,
3207
- block_id
3208
- });
3066
+ if (isTypeUint256(type)) {
3067
+ const el_uint256 = uint256(element);
3068
+ return [felt(el_uint256.low), felt(el_uint256.high)];
3209
3069
  }
3210
- async getPendingTransactions() {
3211
- return this.fetchEndpoint("starknet_pendingTransactions");
3070
+ if (structs[type] && structs[type].members.length) {
3071
+ const { members } = structs[type];
3072
+ const subElement = element;
3073
+ return members.reduce((acc, it) => {
3074
+ return acc.concat(parseCalldataValue(subElement[it.name], it.type, structs));
3075
+ }, []);
3212
3076
  }
3213
- async getProtocolVersion() {
3214
- throw new Error("Pathfinder does not implement this rpc 0.1.0 method");
3077
+ if (isTypeTuple(type)) {
3078
+ const tupled = parseTuple(element, type);
3079
+ return tupled.reduce((acc, it) => {
3080
+ const parsedData = parseCalldataValue(it.element, it.type, structs);
3081
+ return acc.concat(parsedData);
3082
+ }, []);
3215
3083
  }
3216
- async getStateUpdate(blockIdentifier = this.blockIdentifier) {
3217
- const block_id = new Block(blockIdentifier).identifier;
3218
- return this.fetchEndpoint("starknet_getStateUpdate", { block_id });
3084
+ if (typeof element === "object") {
3085
+ throw Error(`Parameter ${element} do not align with abi parameter ${type}`);
3219
3086
  }
3220
- async getStorageAt(contractAddress, key, blockIdentifier = this.blockIdentifier) {
3221
- const parsedKey = toHex(key);
3222
- const block_id = new Block(blockIdentifier).identifier;
3223
- return this.fetchEndpoint("starknet_getStorageAt", {
3224
- contract_address: contractAddress,
3225
- key: parsedKey,
3226
- block_id
3227
- });
3087
+ return felt(element);
3088
+ }
3089
+ function parseCalldataField(argsIterator, input, structs) {
3090
+ const { name, type } = input;
3091
+ let { value } = argsIterator.next();
3092
+ switch (true) {
3093
+ case isTypeArray(type):
3094
+ if (!Array.isArray(value) && !isText(value)) {
3095
+ throw Error(`ABI expected parameter ${name} to be array or long string, got ${value}`);
3096
+ }
3097
+ if (typeof value === "string") {
3098
+ value = splitLongString(value);
3099
+ }
3100
+ const result = [];
3101
+ result.push(felt(value.length));
3102
+ const arrayType = getArrayType(input.type);
3103
+ return value.reduce((acc, el) => {
3104
+ if (isTypeFelt(arrayType) || isTypeUint(arrayType) || isTypeContractAddress(arrayType)) {
3105
+ acc.push(felt(el));
3106
+ } else if (isTypeBool(arrayType) && typeof el === "boolean") {
3107
+ acc.push(el.toString());
3108
+ } else {
3109
+ acc.push(...parseCalldataValue(el, arrayType, structs));
3110
+ }
3111
+ return acc;
3112
+ }, result);
3113
+ case (isTypeStruct(type, structs) || isTypeTuple(type) || isTypeUint256(type)):
3114
+ return parseCalldataValue(value, type, structs);
3115
+ case isTypeBool(type):
3116
+ return `${+value}`;
3117
+ default:
3118
+ return felt(value);
3228
3119
  }
3229
- async getTransaction(txHash) {
3230
- return this.getTransactionByHash(txHash).then(this.responseParser.parseGetTransactionResponse);
3120
+ }
3121
+
3122
+ // src/utils/calldata/responseParser.ts
3123
+ function parseResponseStruct(responseIterator, type, structs) {
3124
+ if (type in structs && structs[type]) {
3125
+ return structs[type].members.reduce((acc, el) => {
3126
+ acc[el.name] = parseResponseStruct(responseIterator, el.type, structs);
3127
+ return acc;
3128
+ }, {});
3231
3129
  }
3232
- async getTransactionByHash(txHash) {
3233
- return this.fetchEndpoint("starknet_getTransactionByHash", { transaction_hash: txHash });
3130
+ if (isTypeTuple(type)) {
3131
+ const memberTypes = extractTupleMemberTypes(type);
3132
+ return memberTypes.reduce((acc, it, idx) => {
3133
+ const tName = (it == null ? void 0 : it.name) ? it.name : idx;
3134
+ const tType = (it == null ? void 0 : it.type) ? it.type : it;
3135
+ acc[tName] = parseResponseStruct(responseIterator, tType, structs);
3136
+ return acc;
3137
+ }, {});
3234
3138
  }
3235
- async getTransactionByBlockIdAndIndex(blockIdentifier, index) {
3236
- const block_id = new Block(blockIdentifier).identifier;
3237
- return this.fetchEndpoint("starknet_getTransactionByBlockIdAndIndex", { block_id, index });
3139
+ const temp = responseIterator.next().value;
3140
+ return BigInt(temp);
3141
+ }
3142
+ function responseParser(responseIterator, output, structs, parsedResult) {
3143
+ const { name, type } = output;
3144
+ let temp;
3145
+ switch (true) {
3146
+ case isLen(name):
3147
+ temp = responseIterator.next().value;
3148
+ return BigInt(temp);
3149
+ case isTypeBool(type):
3150
+ temp = responseIterator.next().value;
3151
+ return Boolean(BigInt(temp));
3152
+ case isTypeUint256(type):
3153
+ const low = responseIterator.next().value;
3154
+ const high = responseIterator.next().value;
3155
+ return uint256ToBN({ low, high });
3156
+ case isTypeArray(type):
3157
+ const parsedDataArr = [];
3158
+ if (isCairo1Type(type)) {
3159
+ responseIterator.next();
3160
+ let it = responseIterator.next();
3161
+ while (!it.done) {
3162
+ parsedDataArr.push(BigInt(it.value));
3163
+ it = responseIterator.next();
3164
+ }
3165
+ return parsedDataArr;
3166
+ }
3167
+ if (parsedResult && parsedResult[`${name}_len`]) {
3168
+ const arrLen = parsedResult[`${name}_len`];
3169
+ while (parsedDataArr.length < arrLen) {
3170
+ parsedDataArr.push(
3171
+ parseResponseStruct(responseIterator, output.type.replace("*", ""), structs)
3172
+ );
3173
+ }
3174
+ }
3175
+ return parsedDataArr;
3176
+ case (type in structs || isTypeTuple(type)):
3177
+ return parseResponseStruct(responseIterator, type, structs);
3178
+ default:
3179
+ temp = responseIterator.next().value;
3180
+ return BigInt(temp);
3238
3181
  }
3239
- async getTransactionReceipt(txHash) {
3240
- return this.fetchEndpoint("starknet_getTransactionReceipt", { transaction_hash: txHash });
3241
- }
3242
- async getClassByHash(classHash) {
3243
- return this.getClass(classHash);
3244
- }
3245
- async getClass(classHash, blockIdentifier = this.blockIdentifier) {
3246
- const block_id = new Block(blockIdentifier).identifier;
3247
- return this.fetchEndpoint("starknet_getClass", { class_hash: classHash, block_id });
3248
- }
3249
- async getClassAt(contractAddress, blockIdentifier = this.blockIdentifier) {
3250
- const block_id = new Block(blockIdentifier).identifier;
3251
- return this.fetchEndpoint("starknet_getClassAt", {
3252
- block_id,
3253
- contract_address: contractAddress
3254
- });
3255
- }
3256
- async getCode(_contractAddress, _blockIdentifier) {
3257
- throw new Error("RPC does not implement getCode function");
3258
- }
3259
- async getEstimateFee(invocation, invocationDetails, blockIdentifier = this.blockIdentifier) {
3260
- return this.getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier);
3261
- }
3262
- async getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier = this.blockIdentifier) {
3263
- const block_id = new Block(blockIdentifier).identifier;
3264
- return this.fetchEndpoint("starknet_estimateFee", {
3265
- request: {
3266
- type: RPC.TransactionType.INVOKE,
3267
- sender_address: invocation.contractAddress,
3268
- calldata: parseCalldata(invocation.calldata),
3269
- signature: signatureToHexArray(invocation.signature),
3270
- version: toHex((invocationDetails == null ? void 0 : invocationDetails.version) || 0),
3271
- nonce: toHex(invocationDetails.nonce),
3272
- max_fee: toHex((invocationDetails == null ? void 0 : invocationDetails.maxFee) || 0)
3273
- },
3274
- block_id
3275
- }).then(this.responseParser.parseFeeEstimateResponse);
3276
- }
3277
- async getDeclareEstimateFee({ senderAddress, contractDefinition, signature }, details, blockIdentifier = this.blockIdentifier) {
3278
- const block_id = new Block(blockIdentifier).identifier;
3279
- if ("program" in contractDefinition) {
3280
- return this.fetchEndpoint("starknet_estimateFee", {
3281
- request: {
3282
- type: RPC.TransactionType.DECLARE,
3283
- contract_class: {
3284
- program: contractDefinition.program,
3285
- entry_points_by_type: contractDefinition.entry_points_by_type,
3286
- abi: contractDefinition.abi
3287
- },
3288
- sender_address: senderAddress,
3289
- signature: signatureToHexArray(signature),
3290
- version: toHex((details == null ? void 0 : details.version) || 0),
3291
- nonce: toHex(details.nonce),
3292
- max_fee: toHex((details == null ? void 0 : details.maxFee) || 0)
3293
- },
3294
- block_id
3295
- }).then(this.responseParser.parseFeeEstimateResponse);
3296
- }
3297
- throw new Error("RPC do not support Sierra Contracts yet");
3298
- }
3299
- async getDeployAccountEstimateFee({ classHash, constructorCalldata, addressSalt, signature }, details, blockIdentifier = this.blockIdentifier) {
3300
- const block_id = new Block(blockIdentifier).identifier;
3301
- return this.fetchEndpoint("starknet_estimateFee", {
3302
- request: {
3303
- type: RPC.TransactionType.DEPLOY_ACCOUNT,
3304
- constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata || []),
3305
- class_hash: toHex(classHash),
3306
- contract_address_salt: toHex(addressSalt || 0),
3307
- signature: signatureToHexArray(signature),
3308
- version: toHex((details == null ? void 0 : details.version) || 0),
3309
- nonce: toHex(details.nonce),
3310
- max_fee: toHex((details == null ? void 0 : details.maxFee) || 0)
3311
- },
3312
- block_id
3313
- }).then(this.responseParser.parseFeeEstimateResponse);
3314
- }
3315
- async getEstimateFeeBulk(_invocations, _blockIdentifier = this.blockIdentifier) {
3316
- throw new Error("RPC does not implement getInvokeEstimateFeeBulk function");
3317
- }
3318
- async declareContract({ contractDefinition, signature, senderAddress }, details) {
3319
- if ("program" in contractDefinition) {
3320
- return this.fetchEndpoint("starknet_addDeclareTransaction", {
3321
- declare_transaction: {
3322
- contract_class: {
3323
- program: contractDefinition.program,
3324
- entry_points_by_type: contractDefinition.entry_points_by_type,
3325
- abi: contractDefinition.abi
3326
- },
3327
- type: RPC.TransactionType.DECLARE,
3328
- version: "0x1",
3329
- max_fee: toHex(details.maxFee || 0),
3330
- signature: signatureToHexArray(signature),
3331
- sender_address: senderAddress,
3332
- nonce: toHex(details.nonce)
3333
- }
3334
- });
3335
- }
3336
- throw new Error("RPC do not support Sierra Contracts yet");
3337
- }
3338
- async deployAccountContract({ classHash, constructorCalldata, addressSalt, signature }, details) {
3339
- return this.fetchEndpoint("starknet_addDeployAccountTransaction", {
3340
- deploy_account_transaction: {
3341
- constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata || []),
3342
- class_hash: toHex(classHash),
3343
- contract_address_salt: toHex(addressSalt || 0),
3344
- type: RPC.TransactionType.DEPLOY_ACCOUNT,
3345
- max_fee: toHex(details.maxFee || 0),
3346
- version: toHex(details.version || 0),
3347
- signature: signatureToHexArray(signature),
3348
- nonce: toHex(details.nonce)
3349
- }
3350
- });
3351
- }
3352
- async invokeFunction(functionInvocation, details) {
3353
- return this.fetchEndpoint("starknet_addInvokeTransaction", {
3354
- invoke_transaction: {
3355
- sender_address: functionInvocation.contractAddress,
3356
- calldata: parseCalldata(functionInvocation.calldata),
3357
- type: RPC.TransactionType.INVOKE,
3358
- max_fee: toHex(details.maxFee || 0),
3359
- version: "0x1",
3360
- signature: signatureToHexArray(functionInvocation.signature),
3361
- nonce: toHex(details.nonce)
3362
- }
3363
- });
3364
- }
3365
- async callContract(call, blockIdentifier = this.blockIdentifier) {
3366
- const block_id = new Block(blockIdentifier).identifier;
3367
- const result = await this.fetchEndpoint("starknet_call", {
3368
- request: {
3369
- contract_address: call.contractAddress,
3370
- entry_point_selector: getSelectorFromName(call.entrypoint),
3371
- calldata: parseCalldata(call.calldata)
3372
- },
3373
- block_id
3374
- });
3375
- return this.responseParser.parseCallContractResponse(result);
3376
- }
3377
- async traceTransaction(transactionHash) {
3378
- return this.fetchEndpoint("starknet_traceTransaction", { transaction_hash: transactionHash });
3379
- }
3380
- async traceBlockTransactions(blockHash) {
3381
- return this.fetchEndpoint("starknet_traceBlockTransactions", { block_hash: blockHash });
3382
- }
3383
- async waitForTransaction(txHash, options) {
3384
- const errorStates = ["REJECTED" /* REJECTED */, "NOT_RECEIVED" /* NOT_RECEIVED */];
3385
- let { retries } = this;
3386
- let onchain = false;
3387
- let txReceipt = {};
3388
- const retryInterval = (options == null ? void 0 : options.retryInterval) ?? 8e3;
3389
- const successStates = (options == null ? void 0 : options.successStates) ?? [
3390
- "ACCEPTED_ON_L1" /* ACCEPTED_ON_L1 */,
3391
- "ACCEPTED_ON_L2" /* ACCEPTED_ON_L2 */,
3392
- "PENDING" /* PENDING */
3393
- ];
3394
- while (!onchain) {
3395
- await wait(retryInterval);
3396
- try {
3397
- txReceipt = await this.getTransactionReceipt(txHash);
3398
- if (!("status" in txReceipt)) {
3399
- const error = new Error("pending transaction");
3400
- throw error;
3401
- }
3402
- if (txReceipt.status && successStates.includes(txReceipt.status)) {
3403
- onchain = true;
3404
- } else if (txReceipt.status && errorStates.includes(txReceipt.status)) {
3405
- const message = txReceipt.status;
3406
- const error = new Error(message);
3407
- error.response = txReceipt;
3408
- throw error;
3409
- }
3410
- } catch (error) {
3411
- if (error instanceof Error && errorStates.includes(error.message)) {
3412
- throw error;
3413
- }
3414
- if (retries === 0) {
3415
- throw new Error(`waitForTransaction timed-out with retries ${this.retries}`);
3416
- }
3417
- }
3418
- retries -= 1;
3419
- }
3420
- await wait(retryInterval);
3421
- return txReceipt;
3422
- }
3423
- async getTransactionCount(blockIdentifier = this.blockIdentifier) {
3424
- const block_id = new Block(blockIdentifier).identifier;
3425
- return this.fetchEndpoint("starknet_getBlockTransactionCount", { block_id });
3426
- }
3427
- async getBlockNumber() {
3428
- return this.fetchEndpoint("starknet_blockNumber");
3429
- }
3430
- async getSyncingStats() {
3431
- return this.fetchEndpoint("starknet_syncing");
3432
- }
3433
- async getEvents(eventFilter) {
3434
- return this.fetchEndpoint("starknet_getEvents", { filter: eventFilter });
3435
- }
3436
- async getSimulateTransaction(_invocation, _invocationDetails, _blockIdentifier) {
3437
- throw new Error("RPC does not implement simulateTransaction function");
3182
+ }
3183
+
3184
+ // src/utils/calldata/validate.ts
3185
+ var validateFelt = (parameter, input) => {
3186
+ assert(
3187
+ typeof parameter === "string" || typeof parameter === "number" || typeof parameter === "bigint",
3188
+ `Validate: arg ${input.name} should be a felt typed as (String, Number or BigInt)`
3189
+ );
3190
+ };
3191
+ var validateUint = (parameter, input) => {
3192
+ if (typeof parameter === "number") {
3193
+ assert(
3194
+ parameter <= Number.MAX_SAFE_INTEGER,
3195
+ `Validation: Parameter is to large to be typed as Number use (BigInt or String)`
3196
+ );
3438
3197
  }
3439
- async getStarkName(address, StarknetIdContract2) {
3440
- return getStarkName(this, address, StarknetIdContract2);
3198
+ assert(
3199
+ typeof parameter === "string" || typeof parameter === "number" || typeof parameter === "bigint",
3200
+ `Validate: arg ${input.name} of cairo type ${input.type} should be type (String, Number or BigInt)`
3201
+ );
3202
+ const param = toBigInt(parameter);
3203
+ switch (input.type) {
3204
+ case "core::integer::u8" /* u8 */:
3205
+ assert(
3206
+ param >= 0n && param <= 255n,
3207
+ `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0 - 255]`
3208
+ );
3209
+ break;
3210
+ case "core::integer::u16" /* u16 */:
3211
+ assert(
3212
+ param >= 0n && param <= 65535n,
3213
+ `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0, 65535]`
3214
+ );
3215
+ break;
3216
+ case "core::integer::u32" /* u32 */:
3217
+ assert(
3218
+ param >= 0n && param <= 4294967295n,
3219
+ `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0, 4294967295]`
3220
+ );
3221
+ break;
3222
+ case "core::integer::u64" /* u64 */:
3223
+ assert(
3224
+ param >= 0n && param <= 2n ** 64n - 1n,
3225
+ `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0, 2^64-1]`
3226
+ );
3227
+ break;
3228
+ case "core::integer::u128" /* u128 */:
3229
+ assert(
3230
+ param >= 0n && param <= 2n ** 128n - 1n,
3231
+ `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0, 2^128-1]`
3232
+ );
3233
+ break;
3234
+ case "core::integer::u256" /* u256 */:
3235
+ assert(
3236
+ param >= 0n && param <= 2n ** 256n - 1n,
3237
+ `Validate: arg ${input.name} is ${input.type} 0 - 2^256-1`
3238
+ );
3239
+ break;
3240
+ default:
3241
+ break;
3441
3242
  }
3442
- async getAddressFromStarkName(name, StarknetIdContract2) {
3443
- return getAddressFromStarkName(this, name, StarknetIdContract2);
3243
+ };
3244
+ var validateBool = (parameter, input) => {
3245
+ assert(
3246
+ typeof parameter === "boolean",
3247
+ `Validate: arg ${input.name} of cairo type ${input.type} should be type (Boolean)`
3248
+ );
3249
+ };
3250
+ var validateStruct = (parameter, input, structs) => {
3251
+ assert(
3252
+ typeof parameter === "object" && !Array.isArray(parameter),
3253
+ `Validate: arg ${input.name} is cairo type struct (${input.type}), and should be defined as js object (not array)`
3254
+ );
3255
+ structs[input.type].members.forEach(({ name }) => {
3256
+ assert(
3257
+ Object.keys(parameter).includes(name),
3258
+ `Validate: arg ${input.name} should have a property ${name}`
3259
+ );
3260
+ });
3261
+ };
3262
+ var validateTuple = (parameter, input) => {
3263
+ assert(
3264
+ typeof parameter === "object" && !Array.isArray(parameter),
3265
+ `Validate: arg ${input.name} should be a tuple (defined as object)`
3266
+ );
3267
+ };
3268
+ var validateArray = (parameter, input, structs) => {
3269
+ const baseType = getArrayType(input.type);
3270
+ if (isTypeFelt(baseType) && isLongText(parameter))
3271
+ return;
3272
+ assert(Array.isArray(parameter), `Validate: arg ${input.name} should be an Array`);
3273
+ switch (true) {
3274
+ case isTypeFelt(baseType):
3275
+ parameter.forEach((param) => validateFelt(param, input));
3276
+ break;
3277
+ case isTypeTuple(baseType):
3278
+ parameter.forEach((it) => validateTuple(it, { name: input.name, type: baseType }));
3279
+ break;
3280
+ case isTypeStruct(baseType, structs):
3281
+ parameter.forEach(
3282
+ (it) => validateStruct(it, { name: input.name, type: baseType }, structs)
3283
+ );
3284
+ break;
3285
+ case isTypeUint(baseType):
3286
+ parameter.forEach((param) => validateUint(param, input));
3287
+ break;
3288
+ case isTypeBool(baseType):
3289
+ parameter.forEach((param) => validateBool(param, input));
3290
+ break;
3291
+ default:
3292
+ throw new Error(
3293
+ `Validate Unhandled: argument ${input.name}, type ${input.type}, value ${parameter}`
3294
+ );
3444
3295
  }
3445
3296
  };
3297
+ function validateFields(abiMethod, args, structs) {
3298
+ abiMethod.inputs.reduce((acc, input) => {
3299
+ const parameter = args[acc];
3300
+ switch (true) {
3301
+ case isLen(input.name):
3302
+ return acc;
3303
+ case isTypeFelt(input.type):
3304
+ validateFelt(parameter, input);
3305
+ break;
3306
+ case isTypeUint(input.type):
3307
+ validateUint(parameter, input);
3308
+ break;
3309
+ case isTypeBool(input.type):
3310
+ validateBool(parameter, input);
3311
+ break;
3312
+ case isTypeContractAddress(input.type):
3313
+ break;
3314
+ case isTypeStruct(input.type, structs):
3315
+ validateStruct(parameter, input, structs);
3316
+ break;
3317
+ case isTypeTuple(input.type):
3318
+ validateTuple(parameter, input);
3319
+ break;
3320
+ case isTypeArray(input.type):
3321
+ validateArray(parameter, input, structs);
3322
+ break;
3323
+ default:
3324
+ throw new Error(
3325
+ `Validate Unhandled: argument ${input.name}, type ${input.type}, value ${parameter}`
3326
+ );
3327
+ }
3328
+ return acc + 1;
3329
+ }, 0);
3330
+ }
3446
3331
 
3447
- // src/provider/sequencer.ts
3448
- import urljoin2 from "url-join";
3449
-
3450
- // src/utils/responseParser/index.ts
3451
- var ResponseParser = class {
3452
- };
3453
-
3454
- // src/utils/responseParser/sequencer.ts
3455
- var SequencerAPIResponseParser = class extends ResponseParser {
3456
- parseGetBlockResponse(res) {
3457
- return {
3458
- ...res,
3459
- new_root: res.state_root,
3460
- parent_hash: res.parent_block_hash,
3461
- transactions: Object.values(res.transactions).map((value) => "transaction_hash" in value && value.transaction_hash).filter(Boolean)
3462
- };
3463
- }
3464
- parseGetTransactionResponse(res) {
3465
- return {
3466
- ...res,
3467
- calldata: "calldata" in res.transaction ? res.transaction.calldata : [],
3468
- contract_class: "contract_class" in res.transaction ? res.transaction.contract_class : void 0,
3469
- entry_point_selector: "entry_point_selector" in res.transaction ? res.transaction.entry_point_selector : void 0,
3470
- max_fee: "max_fee" in res.transaction ? res.transaction.max_fee : void 0,
3471
- nonce: res.transaction.nonce,
3472
- sender_address: "sender_address" in res.transaction ? res.transaction.sender_address : void 0,
3473
- signature: "signature" in res.transaction ? res.transaction.signature : void 0,
3474
- transaction_hash: "transaction_hash" in res.transaction ? res.transaction.transaction_hash : void 0,
3475
- version: "version" in res.transaction ? res.transaction.version : void 0
3476
- };
3477
- }
3478
- parseGetTransactionReceiptResponse(res) {
3479
- return {
3480
- transaction_hash: res.transaction_hash,
3481
- status: res.status,
3482
- messages_sent: res.l2_to_l1_messages,
3483
- events: res.events,
3484
- ..."block_hash" in res && { block_hash: res.block_hash },
3485
- ..."block_number" in res && { block_number: res.block_number },
3486
- ..."actual_fee" in res && { actual_fee: res.actual_fee },
3487
- ..."transaction_index" in res && { transaction_index: res.transaction_index },
3488
- ..."execution_resources" in res && { execution_resources: res.execution_resources },
3489
- ..."l1_to_l2_consumed_message" in res && {
3490
- l1_to_l2_consumed_message: res["l1_to_l2_consumed_message"]
3491
- },
3492
- ..."transaction_failure_reason" in res && {
3493
- transaction_failure_reason: res.transaction_failure_reason
3494
- }
3495
- };
3332
+ // src/utils/calldata/index.ts
3333
+ var CallData = class {
3334
+ constructor(abi) {
3335
+ this.abi = abi;
3336
+ this.structs = CallData.getAbiStruct(abi);
3496
3337
  }
3497
- parseFeeEstimateResponse(res) {
3498
- if ("overall_fee" in res) {
3499
- let gasInfo = {};
3500
- try {
3501
- gasInfo = {
3502
- gas_consumed: toBigInt(res.gas_usage),
3503
- gas_price: toBigInt(res.gas_price)
3504
- };
3505
- } catch {
3506
- }
3507
- return {
3508
- overall_fee: toBigInt(res.overall_fee),
3509
- ...gasInfo
3510
- };
3338
+ validate(type, method, args = []) {
3339
+ if (type !== "DEPLOY") {
3340
+ const invocableFunctionNames = this.abi.filter((abi) => {
3341
+ if (abi.type !== "function")
3342
+ return false;
3343
+ const isView = abi.stateMutability === "view" || abi.state_mutability === "view";
3344
+ return type === "INVOKE" ? !isView : isView;
3345
+ }).map((abi) => abi.name);
3346
+ assert(
3347
+ invocableFunctionNames.includes(method),
3348
+ `${type === "INVOKE" ? "invocable" : "viewable"} method not found in abi`
3349
+ );
3511
3350
  }
3512
- return {
3513
- overall_fee: toBigInt(res.amount)
3514
- };
3515
- }
3516
- parseFeeEstimateBulkResponse(res) {
3517
- return [].concat(res).map((item) => {
3518
- if ("overall_fee" in item) {
3519
- let gasInfo = {};
3520
- try {
3521
- gasInfo = {
3522
- gas_consumed: toBigInt(item.gas_usage),
3523
- gas_price: toBigInt(item.gas_price)
3524
- };
3525
- } catch {
3526
- }
3527
- return {
3528
- overall_fee: toBigInt(item.overall_fee),
3529
- ...gasInfo
3530
- };
3531
- }
3532
- return {
3533
- overall_fee: toBigInt(item.amount)
3534
- };
3535
- });
3536
- }
3537
- parseFeeSimulateTransactionResponse(res) {
3538
- if ("overall_fee" in res.fee_estimation) {
3539
- let gasInfo = {};
3540
- try {
3541
- gasInfo = {
3542
- gas_consumed: toBigInt(res.fee_estimation.gas_usage),
3543
- gas_price: toBigInt(res.fee_estimation.gas_price)
3544
- };
3545
- } catch {
3546
- }
3547
- return {
3548
- trace: res.trace,
3549
- fee_estimation: {
3550
- ...gasInfo,
3551
- overall_fee: toBigInt(res.fee_estimation.overall_fee)
3552
- }
3553
- };
3351
+ const abiMethod = this.abi.find(
3352
+ (abi) => type === "DEPLOY" ? abi.name === method && abi.type === method : abi.name === method && abi.type === "function"
3353
+ );
3354
+ const inputsLength = CallData.abiInputsLength(abiMethod.inputs);
3355
+ if (args.length !== inputsLength) {
3356
+ throw Error(
3357
+ `Invalid number of arguments, expected ${inputsLength} arguments, but got ${args.length}`
3358
+ );
3554
3359
  }
3555
- return {
3556
- trace: res.trace,
3557
- fee_estimation: {
3558
- overall_fee: toBigInt(res.fee_estimation.amount)
3559
- }
3560
- };
3561
- }
3562
- parseCallContractResponse(res) {
3563
- return {
3564
- result: res.result
3565
- };
3566
- }
3567
- parseInvokeFunctionResponse(res) {
3568
- return {
3569
- transaction_hash: res.transaction_hash
3570
- };
3360
+ validateFields(abiMethod, args, this.structs);
3571
3361
  }
3572
- parseDeployContractResponse(res) {
3573
- return {
3574
- transaction_hash: res.transaction_hash,
3575
- contract_address: res.address
3576
- };
3362
+ compile(method, args) {
3363
+ const argsIterator = args[Symbol.iterator]();
3364
+ const { inputs } = this.abi.find((abi) => abi.name === method);
3365
+ return inputs.reduce(
3366
+ (acc, input) => isLen(input.name) ? acc : acc.concat(parseCalldataField(argsIterator, input, this.structs)),
3367
+ []
3368
+ );
3577
3369
  }
3578
- parseDeclareContractResponse(res) {
3579
- return {
3580
- transaction_hash: res.transaction_hash,
3581
- class_hash: res.class_hash
3370
+ static compile(rawArgs) {
3371
+ const createTree = (obj) => {
3372
+ const getEntries = (o, prefix = "") => {
3373
+ const oe = Array.isArray(o) ? [o.length.toString(), ...o] : o;
3374
+ return Object.entries(oe).flatMap(([k, v]) => {
3375
+ let value = v;
3376
+ if (isLongText(value))
3377
+ value = splitLongString(value);
3378
+ const kk = Array.isArray(oe) && k === "0" ? "$$len" : k;
3379
+ if (isBigInt(value))
3380
+ return [[`${prefix}${kk}`, felt(value)]];
3381
+ return Object(value) === value ? getEntries(value, `${prefix}${kk}.`) : [[`${prefix}${kk}`, felt(value)]];
3382
+ });
3383
+ };
3384
+ return Object.fromEntries(getEntries(obj));
3582
3385
  };
3386
+ let callTreeArray;
3387
+ if (!Array.isArray(rawArgs)) {
3388
+ const callTree = createTree(rawArgs);
3389
+ callTreeArray = Object.values(callTree);
3390
+ } else {
3391
+ const callObj = { ...rawArgs };
3392
+ const callTree = createTree(callObj);
3393
+ callTreeArray = Object.values(callTree);
3394
+ }
3395
+ Object.defineProperty(callTreeArray, "__compiled__", {
3396
+ enumerable: false,
3397
+ writable: false,
3398
+ value: true
3399
+ });
3400
+ return callTreeArray;
3583
3401
  }
3584
- parseGetStateUpdateResponse(res) {
3585
- const nonces = Object.entries(res.state_diff.nonces).map(([contract_address, nonce]) => ({
3586
- contract_address,
3587
- nonce
3588
- }));
3589
- const storage_diffs = Object.entries(res.state_diff.storage_diffs).map(
3590
- ([address, storage_entries]) => ({ address, storage_entries })
3591
- );
3592
- return {
3593
- ...res,
3594
- state_diff: {
3595
- ...res.state_diff,
3596
- storage_diffs,
3597
- nonces
3402
+ parse(method, response) {
3403
+ const { outputs } = this.abi.find((abi) => abi.name === method);
3404
+ const responseIterator = response.flat()[Symbol.iterator]();
3405
+ const parsed = outputs.flat().reduce((acc, output, idx) => {
3406
+ const propName = output.name ?? idx;
3407
+ acc[propName] = responseParser(responseIterator, output, this.structs, acc);
3408
+ if (acc[propName] && acc[`${propName}_len`]) {
3409
+ delete acc[`${propName}_len`];
3598
3410
  }
3599
- };
3411
+ return acc;
3412
+ }, {});
3413
+ return Object.keys(parsed).length === 1 && 0 in parsed ? parsed[0] : parsed;
3600
3414
  }
3601
- parseSierraContractClassResponse(res) {
3602
- return {
3603
- ...res,
3604
- abi: JSON.parse(res.abi)
3605
- };
3415
+ format(method, response, format) {
3416
+ const parsed = this.parse(method, response);
3417
+ return formatter(parsed, format);
3418
+ }
3419
+ static abiInputsLength(inputs) {
3420
+ return inputs.reduce((acc, input) => !isLen(input.name) ? acc + 1 : acc, 0);
3421
+ }
3422
+ static getAbiStruct(abi) {
3423
+ return abi.filter((abiEntry) => abiEntry.type === "struct").reduce(
3424
+ (acc, abiEntry) => ({
3425
+ ...acc,
3426
+ [abiEntry.name]: abiEntry
3427
+ }),
3428
+ {}
3429
+ );
3606
3430
  }
3607
3431
  };
3608
3432
 
3609
- // src/utils/url.ts
3610
- import urljoin from "url-join";
3611
- var protocolAndDomainRE = /^(?:\w+:)?\/\/(\S+)$/;
3612
- var localhostDomainRE = /^localhost[:?\d]*(?:[^:?\d]\S*)?$/;
3613
- var nonLocalhostDomainRE = /^[^\s.]+\.\S{2,}$/;
3614
- function isUrl(s) {
3615
- if (!s) {
3616
- return false;
3617
- }
3618
- if (typeof s !== "string") {
3619
- return false;
3433
+ // src/utils/starknetId.ts
3434
+ var starknetId_exports = {};
3435
+ __export(starknetId_exports, {
3436
+ StarknetIdContract: () => StarknetIdContract,
3437
+ getStarknetIdContract: () => getStarknetIdContract,
3438
+ useDecoded: () => useDecoded,
3439
+ useEncoded: () => useEncoded
3440
+ });
3441
+ var basicAlphabet = "abcdefghijklmnopqrstuvwxyz0123456789-";
3442
+ var basicSizePlusOne = BigInt(basicAlphabet.length + 1);
3443
+ var bigAlphabet = "\u8FD9\u6765";
3444
+ var basicAlphabetSize = BigInt(basicAlphabet.length);
3445
+ var bigAlphabetSize = BigInt(bigAlphabet.length);
3446
+ var bigAlphabetSizePlusOne = BigInt(bigAlphabet.length + 1);
3447
+ function extractStars(str) {
3448
+ let k = 0;
3449
+ while (str.endsWith(bigAlphabet[bigAlphabet.length - 1])) {
3450
+ str = str.substring(0, str.length - 1);
3451
+ k += 1;
3620
3452
  }
3621
- const match = s.match(protocolAndDomainRE);
3622
- if (!match) {
3623
- return false;
3453
+ return [str, k];
3454
+ }
3455
+ function useDecoded(encoded) {
3456
+ let decoded = "";
3457
+ encoded.forEach((subdomain) => {
3458
+ while (subdomain !== ZERO) {
3459
+ const code = subdomain % basicSizePlusOne;
3460
+ subdomain /= basicSizePlusOne;
3461
+ if (code === BigInt(basicAlphabet.length)) {
3462
+ const nextSubdomain = subdomain / bigAlphabetSizePlusOne;
3463
+ if (nextSubdomain === ZERO) {
3464
+ const code2 = subdomain % bigAlphabetSizePlusOne;
3465
+ subdomain = nextSubdomain;
3466
+ if (code2 === ZERO)
3467
+ decoded += basicAlphabet[0];
3468
+ else
3469
+ decoded += bigAlphabet[Number(code2) - 1];
3470
+ } else {
3471
+ const code2 = subdomain % bigAlphabetSize;
3472
+ decoded += bigAlphabet[Number(code2)];
3473
+ subdomain /= bigAlphabetSize;
3474
+ }
3475
+ } else
3476
+ decoded += basicAlphabet[Number(code)];
3477
+ }
3478
+ const [str, k] = extractStars(decoded);
3479
+ if (k)
3480
+ decoded = str + (k % 2 === 0 ? bigAlphabet[bigAlphabet.length - 1].repeat(k / 2 - 1) + bigAlphabet[0] + basicAlphabet[1] : bigAlphabet[bigAlphabet.length - 1].repeat((k - 1) / 2 + 1));
3481
+ decoded += ".";
3482
+ });
3483
+ if (!decoded) {
3484
+ return decoded;
3624
3485
  }
3625
- const everythingAfterProtocol = match[1];
3626
- if (!everythingAfterProtocol) {
3627
- return false;
3486
+ return decoded.concat("stark");
3487
+ }
3488
+ function useEncoded(decoded) {
3489
+ let encoded = BigInt(0);
3490
+ let multiplier = BigInt(1);
3491
+ if (decoded.endsWith(bigAlphabet[0] + basicAlphabet[1])) {
3492
+ const [str, k] = extractStars(decoded.substring(0, decoded.length - 2));
3493
+ decoded = str + bigAlphabet[bigAlphabet.length - 1].repeat(2 * (k + 1));
3494
+ } else {
3495
+ const [str, k] = extractStars(decoded);
3496
+ if (k)
3497
+ decoded = str + bigAlphabet[bigAlphabet.length - 1].repeat(1 + 2 * (k - 1));
3628
3498
  }
3629
- if (localhostDomainRE.test(everythingAfterProtocol) || nonLocalhostDomainRE.test(everythingAfterProtocol)) {
3630
- return true;
3499
+ for (let i = 0; i < decoded.length; i += 1) {
3500
+ const char = decoded[i];
3501
+ const index = basicAlphabet.indexOf(char);
3502
+ const bnIndex = BigInt(basicAlphabet.indexOf(char));
3503
+ if (index !== -1) {
3504
+ if (i === decoded.length - 1 && decoded[i] === basicAlphabet[0]) {
3505
+ encoded += multiplier * basicAlphabetSize;
3506
+ multiplier *= basicSizePlusOne;
3507
+ multiplier *= basicSizePlusOne;
3508
+ } else {
3509
+ encoded += multiplier * bnIndex;
3510
+ multiplier *= basicSizePlusOne;
3511
+ }
3512
+ } else if (bigAlphabet.indexOf(char) !== -1) {
3513
+ encoded += multiplier * basicAlphabetSize;
3514
+ multiplier *= basicSizePlusOne;
3515
+ const newid = (i === decoded.length - 1 ? 1 : 0) + bigAlphabet.indexOf(char);
3516
+ encoded += multiplier * BigInt(newid);
3517
+ multiplier *= bigAlphabetSize;
3518
+ }
3631
3519
  }
3632
- return false;
3520
+ return encoded;
3633
3521
  }
3634
- function buildUrl(baseUrl, defaultPath, urlOrPath) {
3635
- return isUrl(urlOrPath) ? urlOrPath : urljoin(baseUrl, urlOrPath ?? defaultPath);
3522
+ var StarknetIdContract = /* @__PURE__ */ ((StarknetIdContract2) => {
3523
+ StarknetIdContract2["MAINNET"] = "0x6ac597f8116f886fa1c97a23fa4e08299975ecaf6b598873ca6792b9bbfb678";
3524
+ StarknetIdContract2["TESTNET"] = "0x3bab268e932d2cecd1946f100ae67ce3dff9fd234119ea2f6da57d16d29fce";
3525
+ return StarknetIdContract2;
3526
+ })(StarknetIdContract || {});
3527
+ function getStarknetIdContract(chainId) {
3528
+ switch (chainId) {
3529
+ case "0x534e5f4d41494e" /* SN_MAIN */:
3530
+ return "0x6ac597f8116f886fa1c97a23fa4e08299975ecaf6b598873ca6792b9bbfb678" /* MAINNET */;
3531
+ case "0x534e5f474f45524c49" /* SN_GOERLI */:
3532
+ return "0x3bab268e932d2cecd1946f100ae67ce3dff9fd234119ea2f6da57d16d29fce" /* TESTNET */;
3533
+ default:
3534
+ throw new Error("Starknet.id is not yet deployed on this network");
3535
+ }
3636
3536
  }
3637
3537
 
3638
- // src/provider/sequencer.ts
3639
- function isEmptyQueryObject(obj) {
3640
- return obj === void 0 || Object.keys(obj).length === 0 || Object.keys(obj).length === 1 && Object.entries(obj).every(([k, v]) => k === "blockIdentifier" && v === null);
3641
- }
3642
- var defaultOptions2 = {
3643
- network: "SN_GOERLI2" /* SN_GOERLI2 */,
3644
- blockIdentifier: "pending"
3645
- };
3646
- var SequencerProvider = class {
3647
- constructor(optionsOrProvider = defaultOptions2) {
3648
- this.responseParser = new SequencerAPIResponseParser();
3649
- if ("network" in optionsOrProvider) {
3650
- this.baseUrl = SequencerProvider.getNetworkFromName(optionsOrProvider.network);
3651
- this.feederGatewayUrl = buildUrl(this.baseUrl, "feeder_gateway");
3652
- this.gatewayUrl = buildUrl(this.baseUrl, "gateway");
3653
- } else {
3654
- this.baseUrl = optionsOrProvider.baseUrl;
3655
- this.feederGatewayUrl = buildUrl(
3656
- this.baseUrl,
3657
- "feeder_gateway",
3658
- optionsOrProvider.feederGatewayUrl
3659
- );
3660
- this.gatewayUrl = buildUrl(this.baseUrl, "gateway", optionsOrProvider.gatewayUrl);
3538
+ // src/provider/starknetId.ts
3539
+ async function getStarkName(provider, address, StarknetIdContract2) {
3540
+ const chainId = await provider.getChainId();
3541
+ const contract = StarknetIdContract2 ?? getStarknetIdContract(chainId);
3542
+ try {
3543
+ const hexDomain = await provider.callContract({
3544
+ contractAddress: contract,
3545
+ entrypoint: "address_to_domain",
3546
+ calldata: CallData.compile({
3547
+ address
3548
+ })
3549
+ });
3550
+ const decimalDomain = hexDomain.result.map((element) => BigInt(element)).slice(1);
3551
+ const stringDomain = useDecoded(decimalDomain);
3552
+ if (!stringDomain) {
3553
+ throw Error("Starkname not found");
3661
3554
  }
3662
- this.chainId = (optionsOrProvider == null ? void 0 : optionsOrProvider.chainId) ?? SequencerProvider.getChainIdFromBaseUrl(this.baseUrl);
3663
- this.headers = optionsOrProvider.headers;
3664
- this.blockIdentifier = (optionsOrProvider == null ? void 0 : optionsOrProvider.blockIdentifier) || defaultOptions2.blockIdentifier;
3665
- }
3666
- static getNetworkFromName(name) {
3667
- switch (name) {
3668
- case ("SN_MAIN" /* SN_MAIN */ || "0x534e5f4d41494e" /* SN_MAIN */):
3669
- return "https://alpha-mainnet.starknet.io" /* SN_MAIN */;
3670
- case ("SN_GOERLI" /* SN_GOERLI */ || "0x534e5f474f45524c49" /* SN_GOERLI */):
3671
- return "https://alpha4.starknet.io" /* SN_GOERLI */;
3672
- case ("SN_GOERLI2" /* SN_GOERLI2 */ || "0x534e5f474f45524c4932" /* SN_GOERLI2 */):
3673
- return "https://alpha4-2.starknet.io" /* SN_GOERLI2 */;
3674
- default:
3675
- throw new Error("Could not detect base url from NetworkName");
3555
+ return stringDomain;
3556
+ } catch (e) {
3557
+ if (e instanceof Error && e.message === "Starkname not found") {
3558
+ throw e;
3676
3559
  }
3560
+ throw Error("Could not get stark name");
3677
3561
  }
3678
- static getChainIdFromBaseUrl(baseUrl) {
3679
- try {
3680
- const url = new URL(baseUrl);
3681
- if (url.host.includes("mainnet.starknet.io")) {
3682
- return "0x534e5f4d41494e" /* SN_MAIN */;
3683
- }
3684
- if (url.host.includes("alpha4-2.starknet.io")) {
3685
- return "0x534e5f474f45524c4932" /* SN_GOERLI2 */;
3686
- }
3687
- return "0x534e5f474f45524c49" /* SN_GOERLI */;
3688
- } catch {
3689
- console.error(`Could not parse baseUrl: ${baseUrl}`);
3690
- return "0x534e5f474f45524c49" /* SN_GOERLI */;
3562
+ }
3563
+ async function getAddressFromStarkName(provider, name, StarknetIdContract2) {
3564
+ const chainId = await provider.getChainId();
3565
+ const contract = StarknetIdContract2 ?? getStarknetIdContract(chainId);
3566
+ try {
3567
+ const addressData = await provider.callContract({
3568
+ contractAddress: contract,
3569
+ entrypoint: "domain_to_address",
3570
+ calldata: CallData.compile({
3571
+ domain: [useEncoded(name.replace(".stark", "")).toString(10)]
3572
+ })
3573
+ });
3574
+ return addressData.result[0];
3575
+ } catch {
3576
+ throw Error("Could not get address from stark name");
3577
+ }
3578
+ }
3579
+
3580
+ // src/provider/utils.ts
3581
+ var validBlockTags = ["latest", "pending"];
3582
+ var Block = class {
3583
+ constructor(_identifier) {
3584
+ this.hash = null;
3585
+ this.number = null;
3586
+ this.tag = null;
3587
+ this.valueOf = () => this.number;
3588
+ this.toString = () => this.hash;
3589
+ this.setIdentifier(_identifier);
3590
+ }
3591
+ setIdentifier(__identifier) {
3592
+ if (typeof __identifier === "string" && isHex(__identifier)) {
3593
+ this.hash = __identifier;
3594
+ } else if (typeof __identifier === "bigint") {
3595
+ this.hash = toHex(__identifier);
3596
+ } else if (typeof __identifier === "number") {
3597
+ this.number = __identifier;
3598
+ } else if (typeof __identifier === "string" && validBlockTags.includes(__identifier)) {
3599
+ this.tag = __identifier;
3600
+ } else {
3601
+ this.tag = "pending";
3691
3602
  }
3692
3603
  }
3693
- getFetchUrl(endpoint) {
3694
- const gatewayUrlEndpoints = ["add_transaction"];
3695
- return gatewayUrlEndpoints.includes(endpoint) ? this.gatewayUrl : this.feederGatewayUrl;
3696
- }
3697
- getFetchMethod(endpoint) {
3698
- const postMethodEndpoints = [
3699
- "add_transaction",
3700
- "call_contract",
3701
- "estimate_fee",
3702
- "estimate_message_fee",
3703
- "estimate_fee_bulk",
3704
- "simulate_transaction"
3705
- ];
3706
- return postMethodEndpoints.includes(endpoint) ? "POST" : "GET";
3707
- }
3708
- getQueryString(query) {
3709
- if (isEmptyQueryObject(query)) {
3710
- return "";
3604
+ get queryIdentifier() {
3605
+ if (this.number !== null) {
3606
+ return `blockNumber=${this.number}`;
3711
3607
  }
3712
- const queryString = Object.entries(query).map(([key, value]) => {
3713
- if (key === "blockIdentifier") {
3714
- const block = new Block(value);
3715
- return `${block.queryIdentifier}`;
3716
- }
3717
- return `${key}=${value}`;
3718
- }).join("&");
3719
- return `?${queryString}`;
3608
+ if (this.hash !== null) {
3609
+ return `blockHash=${this.hash}`;
3610
+ }
3611
+ return `blockNumber=${this.tag}`;
3720
3612
  }
3721
- getHeaders(method) {
3722
- if (method === "POST") {
3723
- return {
3724
- "Content-Type": "application/json",
3725
- ...this.headers
3726
- };
3613
+ get identifier() {
3614
+ if (this.number !== null) {
3615
+ return { block_number: this.number };
3727
3616
  }
3728
- return this.headers;
3617
+ if (this.hash !== null) {
3618
+ return { block_hash: this.hash };
3619
+ }
3620
+ return this.tag;
3729
3621
  }
3730
- async fetchEndpoint(endpoint, ...[query, request]) {
3731
- const baseUrl = this.getFetchUrl(endpoint);
3732
- const method = this.getFetchMethod(endpoint);
3733
- const queryString = this.getQueryString(query);
3734
- const url = urljoin2(baseUrl, endpoint, queryString);
3735
- return this.fetch(url, {
3736
- method,
3737
- body: request
3622
+ set identifier(_identifier) {
3623
+ this.setIdentifier(_identifier);
3624
+ }
3625
+ get sequencerIdentifier() {
3626
+ return this.hash !== null ? { blockHash: this.hash } : { blockNumber: this.number ?? this.tag };
3627
+ }
3628
+ };
3629
+
3630
+ // src/provider/rpc.ts
3631
+ var defaultOptions = {
3632
+ headers: { "Content-Type": "application/json" },
3633
+ blockIdentifier: "latest",
3634
+ retries: 200
3635
+ };
3636
+ var RpcProvider = class {
3637
+ constructor(optionsOrProvider) {
3638
+ this.responseParser = new RPCResponseParser();
3639
+ const { nodeUrl, retries, headers, blockIdentifier } = optionsOrProvider;
3640
+ this.nodeUrl = nodeUrl;
3641
+ this.retries = retries || defaultOptions.retries;
3642
+ this.headers = { ...defaultOptions.headers, ...headers };
3643
+ this.blockIdentifier = blockIdentifier || defaultOptions.blockIdentifier;
3644
+ this.getChainId();
3645
+ }
3646
+ fetch(method, params) {
3647
+ return fetchPonyfill_default(this.nodeUrl, {
3648
+ method: "POST",
3649
+ body: stringify2({ method, jsonrpc: "2.0", params, id: 0 }),
3650
+ headers: this.headers
3738
3651
  });
3739
3652
  }
3740
- async fetch(endpoint, options) {
3741
- const url = buildUrl(this.baseUrl, "", endpoint);
3742
- const method = (options == null ? void 0 : options.method) ?? "GET";
3743
- const headers = this.getHeaders(method);
3744
- const body = stringify2(options == null ? void 0 : options.body);
3653
+ errorHandler(error) {
3654
+ if (error) {
3655
+ const { code, message } = error;
3656
+ throw new LibraryError(`${code}: ${message}`);
3657
+ }
3658
+ }
3659
+ async fetchEndpoint(method, params) {
3660
+ var _a;
3745
3661
  try {
3746
- const response = await fetchPonyfill_default(url, {
3747
- method,
3748
- body,
3749
- headers
3750
- });
3751
- const textResponse = await response.text();
3752
- if (!response.ok) {
3753
- let responseBody;
3754
- try {
3755
- responseBody = parse2(textResponse);
3756
- } catch {
3757
- throw new HttpError(response.statusText, response.status);
3758
- }
3759
- throw new GatewayError(responseBody.message, responseBody.code);
3760
- }
3761
- const parseChoice = (options == null ? void 0 : options.parseAlwaysAsBigInt) ? parseAlwaysAsBig : parse2;
3762
- return parseChoice(textResponse);
3662
+ const rawResult = await this.fetch(method, params);
3663
+ const { error, result } = await rawResult.json();
3664
+ this.errorHandler(error);
3665
+ return result;
3763
3666
  } catch (error) {
3764
- if (error instanceof Error && !(error instanceof LibraryError))
3765
- throw Error(`Could not ${method} from endpoint \`${url}\`: ${error.message}`);
3667
+ this.errorHandler((_a = error == null ? void 0 : error.response) == null ? void 0 : _a.data);
3766
3668
  throw error;
3767
3669
  }
3768
3670
  }
3769
3671
  async getChainId() {
3770
- return Promise.resolve(this.chainId);
3771
- }
3772
- async callContract({ contractAddress, entrypoint: entryPointSelector, calldata = [] }, blockIdentifier = this.blockIdentifier) {
3773
- return this.fetchEndpoint(
3774
- "call_contract",
3775
- { blockIdentifier },
3776
- {
3777
- contract_address: contractAddress,
3778
- entry_point_selector: getSelectorFromName(entryPointSelector),
3779
- calldata
3780
- }
3781
- ).then(this.responseParser.parseCallContractResponse);
3672
+ this.chainId ?? (this.chainId = await this.fetchEndpoint("starknet_chainId"));
3673
+ return this.chainId;
3782
3674
  }
3783
3675
  async getBlock(blockIdentifier = this.blockIdentifier) {
3784
- return this.fetchEndpoint("get_block", { blockIdentifier }).then(
3676
+ return this.getBlockWithTxHashes(blockIdentifier).then(
3785
3677
  this.responseParser.parseGetBlockResponse
3786
3678
  );
3787
3679
  }
3680
+ async getBlockHashAndNumber() {
3681
+ return this.fetchEndpoint("starknet_blockHashAndNumber");
3682
+ }
3683
+ async getBlockWithTxHashes(blockIdentifier = this.blockIdentifier) {
3684
+ const block_id = new Block(blockIdentifier).identifier;
3685
+ return this.fetchEndpoint("starknet_getBlockWithTxHashes", { block_id });
3686
+ }
3687
+ async getBlockWithTxs(blockIdentifier = this.blockIdentifier) {
3688
+ const block_id = new Block(blockIdentifier).identifier;
3689
+ return this.fetchEndpoint("starknet_getBlockWithTxs", { block_id });
3690
+ }
3691
+ async getClassHashAt(contractAddress, blockIdentifier = this.blockIdentifier) {
3692
+ const block_id = new Block(blockIdentifier).identifier;
3693
+ return this.fetchEndpoint("starknet_getClassHashAt", {
3694
+ block_id,
3695
+ contract_address: contractAddress
3696
+ });
3697
+ }
3788
3698
  async getNonceForAddress(contractAddress, blockIdentifier = this.blockIdentifier) {
3789
- return this.fetchEndpoint("get_nonce", { contractAddress, blockIdentifier });
3699
+ const block_id = new Block(blockIdentifier).identifier;
3700
+ return this.fetchEndpoint("starknet_getNonce", {
3701
+ contract_address: contractAddress,
3702
+ block_id
3703
+ });
3704
+ }
3705
+ async getPendingTransactions() {
3706
+ return this.fetchEndpoint("starknet_pendingTransactions");
3707
+ }
3708
+ async getProtocolVersion() {
3709
+ throw new Error("Pathfinder does not implement this rpc 0.1.0 method");
3710
+ }
3711
+ async getStateUpdate(blockIdentifier = this.blockIdentifier) {
3712
+ const block_id = new Block(blockIdentifier).identifier;
3713
+ return this.fetchEndpoint("starknet_getStateUpdate", { block_id });
3790
3714
  }
3791
3715
  async getStorageAt(contractAddress, key, blockIdentifier = this.blockIdentifier) {
3792
- const parsedKey = toBigInt(key).toString(10);
3793
- return this.fetchEndpoint("get_storage_at", {
3794
- blockIdentifier,
3795
- contractAddress,
3796
- key: parsedKey
3716
+ const parsedKey = toHex(key);
3717
+ const block_id = new Block(blockIdentifier).identifier;
3718
+ return this.fetchEndpoint("starknet_getStorageAt", {
3719
+ contract_address: contractAddress,
3720
+ key: parsedKey,
3721
+ block_id
3797
3722
  });
3798
3723
  }
3799
3724
  async getTransaction(txHash) {
3800
- const txHashHex = toHex(txHash);
3801
- return this.fetchEndpoint("get_transaction", { transactionHash: txHashHex }).then((result) => {
3802
- if (Object.values(result).length === 1)
3803
- throw new LibraryError(result.status);
3804
- return this.responseParser.parseGetTransactionResponse(result);
3805
- });
3725
+ return this.getTransactionByHash(txHash).then(this.responseParser.parseGetTransactionResponse);
3726
+ }
3727
+ async getTransactionByHash(txHash) {
3728
+ return this.fetchEndpoint("starknet_getTransactionByHash", { transaction_hash: txHash });
3729
+ }
3730
+ async getTransactionByBlockIdAndIndex(blockIdentifier, index) {
3731
+ const block_id = new Block(blockIdentifier).identifier;
3732
+ return this.fetchEndpoint("starknet_getTransactionByBlockIdAndIndex", { block_id, index });
3806
3733
  }
3807
3734
  async getTransactionReceipt(txHash) {
3808
- const txHashHex = toHex(txHash);
3809
- return this.fetchEndpoint("get_transaction_receipt", { transactionHash: txHashHex }).then(
3810
- this.responseParser.parseGetTransactionReceiptResponse
3811
- );
3735
+ return this.fetchEndpoint("starknet_getTransactionReceipt", { transaction_hash: txHash });
3812
3736
  }
3813
- async getClassAt(contractAddress, blockIdentifier = this.blockIdentifier) {
3814
- return this.fetchEndpoint("get_full_contract", { blockIdentifier, contractAddress }).then(
3815
- (res) => {
3816
- if (isSierra(res)) {
3817
- return this.responseParser.parseSierraContractClassResponse(res);
3818
- }
3819
- return parseContract(res);
3820
- }
3821
- );
3737
+ async getClassByHash(classHash) {
3738
+ return this.getClass(classHash);
3822
3739
  }
3823
- async getClassHashAt(contractAddress, blockIdentifier = this.blockIdentifier) {
3824
- return this.fetchEndpoint("get_class_hash_at", { blockIdentifier, contractAddress });
3740
+ async getClass(classHash, blockIdentifier = this.blockIdentifier) {
3741
+ const block_id = new Block(blockIdentifier).identifier;
3742
+ return this.fetchEndpoint("starknet_getClass", { class_hash: classHash, block_id });
3825
3743
  }
3826
- async getClassByHash(classHash, blockIdentifier = this.blockIdentifier) {
3827
- return this.fetchEndpoint("get_class_by_hash", { classHash, blockIdentifier }).then((res) => {
3828
- if (isSierra(res)) {
3829
- return this.responseParser.parseSierraContractClassResponse(res);
3830
- }
3831
- return parseContract(res);
3744
+ async getClassAt(contractAddress, blockIdentifier = this.blockIdentifier) {
3745
+ const block_id = new Block(blockIdentifier).identifier;
3746
+ return this.fetchEndpoint("starknet_getClassAt", {
3747
+ block_id,
3748
+ contract_address: contractAddress
3832
3749
  });
3833
3750
  }
3834
- async getCompiledClassByClassHash(classHash, blockIdentifier = this.blockIdentifier) {
3835
- return this.fetchEndpoint("get_compiled_class_by_class_hash", { classHash, blockIdentifier });
3836
- }
3837
- async invokeFunction(functionInvocation, details) {
3838
- return this.fetchEndpoint("add_transaction", void 0, {
3839
- type: "INVOKE_FUNCTION" /* INVOKE */,
3840
- sender_address: functionInvocation.contractAddress,
3841
- calldata: bigNumberishArrayToDecimalStringArray(functionInvocation.calldata ?? []),
3842
- signature: signatureToDecimalArray(functionInvocation.signature),
3843
- nonce: toHex(details.nonce),
3844
- max_fee: toHex(details.maxFee || 0),
3845
- version: "0x1"
3846
- }).then(this.responseParser.parseInvokeFunctionResponse);
3751
+ async getCode(_contractAddress, _blockIdentifier) {
3752
+ throw new Error("RPC does not implement getCode function");
3847
3753
  }
3848
- async deployAccountContract({ classHash, constructorCalldata, addressSalt, signature }, details) {
3849
- return this.fetchEndpoint("add_transaction", void 0, {
3850
- type: "DEPLOY_ACCOUNT" /* DEPLOY_ACCOUNT */,
3851
- contract_address_salt: addressSalt ?? randomAddress(),
3852
- constructor_calldata: bigNumberishArrayToDecimalStringArray(constructorCalldata ?? []),
3853
- class_hash: toHex(classHash),
3854
- max_fee: toHex(details.maxFee || 0),
3855
- version: toHex(details.version || 0),
3856
- nonce: toHex(details.nonce),
3857
- signature: signatureToDecimalArray(signature)
3858
- }).then(this.responseParser.parseDeployContractResponse);
3754
+ async getEstimateFee(invocation, invocationDetails, blockIdentifier = this.blockIdentifier) {
3755
+ return this.getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier);
3859
3756
  }
3860
- async declareContract({ senderAddress, contractDefinition, signature, compiledClassHash }, details) {
3861
- if (!isSierra(contractDefinition)) {
3862
- return this.fetchEndpoint("add_transaction", void 0, {
3863
- type: "DECLARE" /* DECLARE */,
3864
- contract_class: contractDefinition,
3865
- nonce: toHex(details.nonce),
3866
- signature: signatureToDecimalArray(signature),
3867
- sender_address: senderAddress,
3868
- max_fee: toHex(details.maxFee || 0),
3869
- version: "0x1"
3870
- }).then(this.responseParser.parseDeclareContractResponse);
3757
+ async getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier = this.blockIdentifier) {
3758
+ const block_id = new Block(blockIdentifier).identifier;
3759
+ return this.fetchEndpoint("starknet_estimateFee", {
3760
+ request: {
3761
+ type: RPC.TransactionType.INVOKE,
3762
+ sender_address: invocation.contractAddress,
3763
+ calldata: parseCalldata(invocation.calldata),
3764
+ signature: signatureToHexArray(invocation.signature),
3765
+ version: toHex((invocationDetails == null ? void 0 : invocationDetails.version) || 0),
3766
+ nonce: toHex(invocationDetails.nonce),
3767
+ max_fee: toHex((invocationDetails == null ? void 0 : invocationDetails.maxFee) || 0)
3768
+ },
3769
+ block_id
3770
+ }).then(this.responseParser.parseFeeEstimateResponse);
3771
+ }
3772
+ async getDeclareEstimateFee({ senderAddress, contractDefinition, signature }, details, blockIdentifier = this.blockIdentifier) {
3773
+ const block_id = new Block(blockIdentifier).identifier;
3774
+ if ("program" in contractDefinition) {
3775
+ return this.fetchEndpoint("starknet_estimateFee", {
3776
+ request: {
3777
+ type: RPC.TransactionType.DECLARE,
3778
+ contract_class: {
3779
+ program: contractDefinition.program,
3780
+ entry_points_by_type: contractDefinition.entry_points_by_type,
3781
+ abi: contractDefinition.abi
3782
+ },
3783
+ sender_address: senderAddress,
3784
+ signature: signatureToHexArray(signature),
3785
+ version: toHex((details == null ? void 0 : details.version) || 0),
3786
+ nonce: toHex(details.nonce),
3787
+ max_fee: toHex((details == null ? void 0 : details.maxFee) || 0)
3788
+ },
3789
+ block_id
3790
+ }).then(this.responseParser.parseFeeEstimateResponse);
3871
3791
  }
3872
- return this.fetchEndpoint("add_transaction", void 0, {
3873
- type: "DECLARE" /* DECLARE */,
3874
- sender_address: senderAddress,
3875
- compiled_class_hash: compiledClassHash,
3876
- contract_class: contractDefinition,
3877
- nonce: toHex(details.nonce),
3878
- signature: signatureToDecimalArray(signature),
3879
- max_fee: toHex(details.maxFee || 0),
3880
- version: "0x2"
3881
- }).then(this.responseParser.parseDeclareContractResponse);
3792
+ throw new Error("RPC do not support Sierra Contracts yet");
3882
3793
  }
3883
- async getEstimateFee(invocation, invocationDetails, blockIdentifier = this.blockIdentifier, skipValidate = false) {
3884
- return this.getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier, skipValidate);
3794
+ async getDeployAccountEstimateFee({ classHash, constructorCalldata, addressSalt, signature }, details, blockIdentifier = this.blockIdentifier) {
3795
+ const block_id = new Block(blockIdentifier).identifier;
3796
+ return this.fetchEndpoint("starknet_estimateFee", {
3797
+ request: {
3798
+ type: RPC.TransactionType.DEPLOY_ACCOUNT,
3799
+ constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata || []),
3800
+ class_hash: toHex(classHash),
3801
+ contract_address_salt: toHex(addressSalt || 0),
3802
+ signature: signatureToHexArray(signature),
3803
+ version: toHex((details == null ? void 0 : details.version) || 0),
3804
+ nonce: toHex(details.nonce),
3805
+ max_fee: toHex((details == null ? void 0 : details.maxFee) || 0)
3806
+ },
3807
+ block_id
3808
+ }).then(this.responseParser.parseFeeEstimateResponse);
3885
3809
  }
3886
- async getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier = this.blockIdentifier, skipValidate = false) {
3887
- return this.fetchEndpoint(
3888
- "estimate_fee",
3889
- { blockIdentifier, skipValidate },
3890
- {
3891
- type: "INVOKE_FUNCTION" /* INVOKE */,
3892
- sender_address: invocation.contractAddress,
3893
- calldata: invocation.calldata ?? [],
3894
- signature: signatureToDecimalArray(invocation.signature),
3895
- version: toHex((invocationDetails == null ? void 0 : invocationDetails.version) || 1),
3896
- nonce: toHex(invocationDetails.nonce)
3897
- }
3898
- ).then(this.responseParser.parseFeeEstimateResponse);
3810
+ async getEstimateFeeBulk(_invocations, _blockIdentifier = this.blockIdentifier) {
3811
+ throw new Error("RPC does not implement getInvokeEstimateFeeBulk function");
3899
3812
  }
3900
- async getDeclareEstimateFee({ senderAddress, contractDefinition, signature, compiledClassHash }, details, blockIdentifier = this.blockIdentifier, skipValidate = false) {
3901
- if (!isSierra(contractDefinition)) {
3902
- return this.fetchEndpoint(
3903
- "estimate_fee",
3904
- { blockIdentifier, skipValidate },
3905
- {
3906
- type: "DECLARE" /* DECLARE */,
3813
+ async declareContract({ contractDefinition, signature, senderAddress }, details) {
3814
+ if ("program" in contractDefinition) {
3815
+ return this.fetchEndpoint("starknet_addDeclareTransaction", {
3816
+ declare_transaction: {
3817
+ contract_class: {
3818
+ program: contractDefinition.program,
3819
+ entry_points_by_type: contractDefinition.entry_points_by_type,
3820
+ abi: contractDefinition.abi
3821
+ },
3822
+ type: RPC.TransactionType.DECLARE,
3823
+ version: "0x1",
3824
+ max_fee: toHex(details.maxFee || 0),
3825
+ signature: signatureToHexArray(signature),
3907
3826
  sender_address: senderAddress,
3908
- contract_class: contractDefinition,
3909
- signature: signatureToDecimalArray(signature),
3910
- version: toHex((details == null ? void 0 : details.version) || toBigInt(feeTransactionVersion)),
3911
3827
  nonce: toHex(details.nonce)
3912
3828
  }
3913
- ).then(this.responseParser.parseFeeEstimateResponse);
3829
+ });
3914
3830
  }
3915
- return this.fetchEndpoint(
3916
- "estimate_fee",
3917
- { blockIdentifier, skipValidate },
3918
- {
3919
- type: "DECLARE" /* DECLARE */,
3920
- sender_address: senderAddress,
3921
- compiled_class_hash: compiledClassHash,
3922
- contract_class: contractDefinition,
3923
- nonce: toHex(details.nonce),
3924
- signature: signatureToDecimalArray(signature),
3925
- version: "0x2"
3926
- }
3927
- ).then(this.responseParser.parseFeeEstimateResponse);
3831
+ throw new Error("RPC do not support Sierra Contracts yet");
3928
3832
  }
3929
- async getDeployAccountEstimateFee({ classHash, addressSalt, constructorCalldata, signature }, details, blockIdentifier = this.blockIdentifier, skipValidate = false) {
3930
- return this.fetchEndpoint(
3931
- "estimate_fee",
3932
- { blockIdentifier, skipValidate },
3933
- {
3934
- type: "DEPLOY_ACCOUNT" /* DEPLOY_ACCOUNT */,
3833
+ async deployAccountContract({ classHash, constructorCalldata, addressSalt, signature }, details) {
3834
+ return this.fetchEndpoint("starknet_addDeployAccountTransaction", {
3835
+ deploy_account_transaction: {
3836
+ constructor_calldata: bigNumberishArrayToHexadecimalStringArray(constructorCalldata || []),
3935
3837
  class_hash: toHex(classHash),
3936
- constructor_calldata: bigNumberishArrayToDecimalStringArray(constructorCalldata || []),
3937
3838
  contract_address_salt: toHex(addressSalt || 0),
3938
- signature: signatureToDecimalArray(signature),
3939
- version: toHex((details == null ? void 0 : details.version) || 0),
3839
+ type: RPC.TransactionType.DEPLOY_ACCOUNT,
3840
+ max_fee: toHex(details.maxFee || 0),
3841
+ version: toHex(details.version || 0),
3842
+ signature: signatureToHexArray(signature),
3940
3843
  nonce: toHex(details.nonce)
3941
3844
  }
3942
- ).then(this.responseParser.parseFeeEstimateResponse);
3845
+ });
3943
3846
  }
3944
- async getEstimateFeeBulk(invocations, blockIdentifier = this.blockIdentifier) {
3945
- const params = invocations.map((invocation) => {
3946
- let res;
3947
- if (invocation.type === "INVOKE_FUNCTION") {
3948
- res = {
3949
- type: invocation.type,
3950
- sender_address: invocation.contractAddress,
3951
- calldata: invocation.calldata ?? []
3952
- };
3953
- } else if (invocation.type === "DECLARE") {
3954
- res = {
3955
- type: invocation.type,
3956
- sender_address: invocation.senderAddress,
3957
- contract_class: invocation.contractDefinition
3958
- };
3959
- } else {
3960
- res = {
3961
- type: invocation.type,
3962
- class_hash: toHex(toBigInt(invocation.classHash)),
3963
- constructor_calldata: bigNumberishArrayToDecimalStringArray(
3964
- invocation.constructorCalldata || []
3965
- ),
3966
- contract_address_salt: toHex(toBigInt(invocation.addressSalt || 0))
3967
- };
3847
+ async invokeFunction(functionInvocation, details) {
3848
+ return this.fetchEndpoint("starknet_addInvokeTransaction", {
3849
+ invoke_transaction: {
3850
+ sender_address: functionInvocation.contractAddress,
3851
+ calldata: parseCalldata(functionInvocation.calldata),
3852
+ type: RPC.TransactionType.INVOKE,
3853
+ max_fee: toHex(details.maxFee || 0),
3854
+ version: "0x1",
3855
+ signature: signatureToHexArray(functionInvocation.signature),
3856
+ nonce: toHex(details.nonce)
3968
3857
  }
3969
- return {
3970
- ...res,
3971
- signature: bigNumberishArrayToDecimalStringArray(formatSignature(invocation.signature)),
3972
- version: toHex(toBigInt((invocation == null ? void 0 : invocation.version) || 1)),
3973
- nonce: toHex(toBigInt(invocation.nonce))
3974
- };
3975
3858
  });
3976
- return this.fetchEndpoint("estimate_fee_bulk", { blockIdentifier }, params).then(
3977
- this.responseParser.parseFeeEstimateBulkResponse
3978
- );
3979
3859
  }
3980
- async getCode(contractAddress, blockIdentifier = this.blockIdentifier) {
3981
- return this.fetchEndpoint("get_code", { contractAddress, blockIdentifier });
3860
+ async callContract(call, blockIdentifier = this.blockIdentifier) {
3861
+ const block_id = new Block(blockIdentifier).identifier;
3862
+ const result = await this.fetchEndpoint("starknet_call", {
3863
+ request: {
3864
+ contract_address: call.contractAddress,
3865
+ entry_point_selector: getSelectorFromName(call.entrypoint),
3866
+ calldata: parseCalldata(call.calldata)
3867
+ },
3868
+ block_id
3869
+ });
3870
+ return this.responseParser.parseCallContractResponse(result);
3871
+ }
3872
+ async traceTransaction(transactionHash) {
3873
+ return this.fetchEndpoint("starknet_traceTransaction", { transaction_hash: transactionHash });
3874
+ }
3875
+ async traceBlockTransactions(blockHash) {
3876
+ return this.fetchEndpoint("starknet_traceBlockTransactions", { block_hash: blockHash });
3982
3877
  }
3983
3878
  async waitForTransaction(txHash, options) {
3984
3879
  const errorStates = ["REJECTED" /* REJECTED */, "NOT_RECEIVED" /* NOT_RECEIVED */];
3880
+ let { retries } = this;
3985
3881
  let onchain = false;
3986
- let res;
3882
+ let txReceipt = {};
3987
3883
  const retryInterval = (options == null ? void 0 : options.retryInterval) ?? 8e3;
3988
3884
  const successStates = (options == null ? void 0 : options.successStates) ?? [
3989
3885
  "ACCEPTED_ON_L1" /* ACCEPTED_ON_L1 */,
@@ -3992,64 +3888,48 @@ var SequencerProvider = class {
3992
3888
  ];
3993
3889
  while (!onchain) {
3994
3890
  await wait(retryInterval);
3995
- res = await this.getTransactionStatus(txHash);
3996
- if (successStates.includes(res.tx_status)) {
3997
- onchain = true;
3998
- } else if (errorStates.includes(res.tx_status)) {
3999
- const message = res.tx_failure_reason ? `${res.tx_status}: ${res.tx_failure_reason.code}
4000
- ${res.tx_failure_reason.error_message}` : res.tx_status;
4001
- const error = new Error(message);
4002
- error.response = res;
4003
- throw error;
3891
+ try {
3892
+ txReceipt = await this.getTransactionReceipt(txHash);
3893
+ if (!("status" in txReceipt)) {
3894
+ const error = new Error("pending transaction");
3895
+ throw error;
3896
+ }
3897
+ if (txReceipt.status && successStates.includes(txReceipt.status)) {
3898
+ onchain = true;
3899
+ } else if (txReceipt.status && errorStates.includes(txReceipt.status)) {
3900
+ const message = txReceipt.status;
3901
+ const error = new Error(message);
3902
+ error.response = txReceipt;
3903
+ throw error;
3904
+ }
3905
+ } catch (error) {
3906
+ if (error instanceof Error && errorStates.includes(error.message)) {
3907
+ throw error;
3908
+ }
3909
+ if (retries === 0) {
3910
+ throw new Error(`waitForTransaction timed-out with retries ${this.retries}`);
3911
+ }
4004
3912
  }
3913
+ retries -= 1;
4005
3914
  }
4006
- const txReceipt = await this.getTransactionReceipt(txHash);
4007
- return txReceipt;
4008
- }
4009
- async getTransactionStatus(txHash) {
4010
- const txHashHex = toHex(txHash);
4011
- return this.fetchEndpoint("get_transaction_status", { transactionHash: txHashHex });
4012
- }
4013
- async getContractAddresses() {
4014
- return this.fetchEndpoint("get_contract_addresses");
4015
- }
4016
- async getTransactionTrace(txHash) {
4017
- const txHashHex = toHex(txHash);
4018
- return this.fetchEndpoint("get_transaction_trace", { transactionHash: txHashHex });
3915
+ await wait(retryInterval);
3916
+ return txReceipt;
4019
3917
  }
4020
- async estimateMessageFee({ from_address, to_address, entry_point_selector, payload }, blockIdentifier = this.blockIdentifier) {
4021
- const validCallL1Handler = {
4022
- from_address: getDecimalString(from_address),
4023
- to_address: getHexString(to_address),
4024
- entry_point_selector: getSelector(entry_point_selector),
4025
- payload: getHexStringArray(payload)
4026
- };
4027
- return this.fetchEndpoint("estimate_message_fee", { blockIdentifier }, validCallL1Handler);
3918
+ async getTransactionCount(blockIdentifier = this.blockIdentifier) {
3919
+ const block_id = new Block(blockIdentifier).identifier;
3920
+ return this.fetchEndpoint("starknet_getBlockTransactionCount", { block_id });
4028
3921
  }
4029
- async getSimulateTransaction(invocation, invocationDetails, blockIdentifier = this.blockIdentifier, skipValidate = false) {
4030
- return this.fetchEndpoint(
4031
- "simulate_transaction",
4032
- { blockIdentifier, skipValidate },
4033
- {
4034
- type: "INVOKE_FUNCTION",
4035
- sender_address: invocation.contractAddress,
4036
- calldata: invocation.calldata ?? [],
4037
- signature: signatureToDecimalArray(invocation.signature),
4038
- version: toHex((invocationDetails == null ? void 0 : invocationDetails.version) || 1),
4039
- nonce: toHex(invocationDetails.nonce),
4040
- max_fee: toHex((invocationDetails == null ? void 0 : invocationDetails.maxFee) || 0)
4041
- }
4042
- ).then(this.responseParser.parseFeeSimulateTransactionResponse);
3922
+ async getBlockNumber() {
3923
+ return this.fetchEndpoint("starknet_blockNumber");
4043
3924
  }
4044
- async getStateUpdate(blockIdentifier = this.blockIdentifier) {
4045
- const args = new Block(blockIdentifier).sequencerIdentifier;
4046
- return this.fetchEndpoint("get_state_update", { ...args }).then(
4047
- this.responseParser.parseGetStateUpdateResponse
4048
- );
3925
+ async getSyncingStats() {
3926
+ return this.fetchEndpoint("starknet_syncing");
4049
3927
  }
4050
- async getBlockTraces(blockIdentifier = this.blockIdentifier) {
4051
- const args = new Block(blockIdentifier).sequencerIdentifier;
4052
- return this.fetchEndpoint("get_block_traces", { ...args });
3928
+ async getEvents(eventFilter) {
3929
+ return this.fetchEndpoint("starknet_getEvents", { filter: eventFilter });
3930
+ }
3931
+ async getSimulateTransaction(_invocation, _invocationDetails, _blockIdentifier) {
3932
+ throw new Error("RPC does not implement simulateTransaction function");
4053
3933
  }
4054
3934
  async getStarkName(address, StarknetIdContract2) {
4055
3935
  return getStarkName(this, address, StarknetIdContract2);
@@ -4059,622 +3939,732 @@ ${res.tx_failure_reason.error_message}` : res.tx_status;
4059
3939
  }
4060
3940
  };
4061
3941
 
4062
- // src/provider/default.ts
4063
- var Provider = class {
4064
- constructor(providerOrOptions) {
4065
- if (providerOrOptions instanceof Provider) {
4066
- this.provider = providerOrOptions.provider;
4067
- } else if (providerOrOptions instanceof RpcProvider || providerOrOptions instanceof SequencerProvider) {
4068
- this.provider = providerOrOptions;
4069
- } else if (providerOrOptions && "rpc" in providerOrOptions) {
4070
- this.provider = new RpcProvider(providerOrOptions.rpc);
4071
- } else if (providerOrOptions && "sequencer" in providerOrOptions) {
4072
- this.provider = new SequencerProvider(providerOrOptions.sequencer);
4073
- } else {
4074
- this.provider = new SequencerProvider();
4075
- }
4076
- }
4077
- async getChainId() {
4078
- return this.provider.getChainId();
4079
- }
4080
- async getBlock(blockIdentifier) {
4081
- return this.provider.getBlock(blockIdentifier);
4082
- }
4083
- async getClassAt(contractAddress, blockIdentifier) {
4084
- return this.provider.getClassAt(contractAddress, blockIdentifier);
4085
- }
4086
- async getClassHashAt(contractAddress, blockIdentifier) {
4087
- return this.provider.getClassHashAt(contractAddress, blockIdentifier);
4088
- }
4089
- getClassByHash(classHash) {
4090
- return this.provider.getClassByHash(classHash);
4091
- }
4092
- async getEstimateFee(invocationWithTxType, invocationDetails, blockIdentifier) {
4093
- return this.provider.getEstimateFee(invocationWithTxType, invocationDetails, blockIdentifier);
4094
- }
4095
- async getInvokeEstimateFee(invocationWithTxType, invocationDetails, blockIdentifier, skipValidate) {
4096
- return this.provider.getInvokeEstimateFee(
4097
- invocationWithTxType,
4098
- invocationDetails,
4099
- blockIdentifier,
4100
- skipValidate
4101
- );
4102
- }
4103
- async getEstimateFeeBulk(invocations, blockIdentifier) {
4104
- return this.provider.getEstimateFeeBulk(invocations, blockIdentifier);
3942
+ // src/provider/sequencer.ts
3943
+ import urljoin2 from "url-join";
3944
+
3945
+ // src/utils/responseParser/index.ts
3946
+ var ResponseParser = class {
3947
+ };
3948
+
3949
+ // src/utils/responseParser/sequencer.ts
3950
+ var SequencerAPIResponseParser = class extends ResponseParser {
3951
+ parseGetBlockResponse(res) {
3952
+ return {
3953
+ ...res,
3954
+ new_root: res.state_root,
3955
+ parent_hash: res.parent_block_hash,
3956
+ transactions: Object.values(res.transactions).map((value) => "transaction_hash" in value && value.transaction_hash).filter(Boolean)
3957
+ };
4105
3958
  }
4106
- async getNonceForAddress(contractAddress, blockIdentifier) {
4107
- return this.provider.getNonceForAddress(contractAddress, blockIdentifier);
3959
+ parseGetTransactionResponse(res) {
3960
+ return {
3961
+ ...res,
3962
+ calldata: "calldata" in res.transaction ? res.transaction.calldata : [],
3963
+ contract_class: "contract_class" in res.transaction ? res.transaction.contract_class : void 0,
3964
+ entry_point_selector: "entry_point_selector" in res.transaction ? res.transaction.entry_point_selector : void 0,
3965
+ max_fee: "max_fee" in res.transaction ? res.transaction.max_fee : void 0,
3966
+ nonce: res.transaction.nonce,
3967
+ sender_address: "sender_address" in res.transaction ? res.transaction.sender_address : void 0,
3968
+ signature: "signature" in res.transaction ? res.transaction.signature : void 0,
3969
+ transaction_hash: "transaction_hash" in res.transaction ? res.transaction.transaction_hash : void 0,
3970
+ version: "version" in res.transaction ? res.transaction.version : void 0
3971
+ };
4108
3972
  }
4109
- async getStorageAt(contractAddress, key, blockIdentifier) {
4110
- return this.provider.getStorageAt(contractAddress, key, blockIdentifier);
3973
+ parseGetTransactionReceiptResponse(res) {
3974
+ return {
3975
+ transaction_hash: res.transaction_hash,
3976
+ status: res.status,
3977
+ messages_sent: res.l2_to_l1_messages,
3978
+ events: res.events,
3979
+ ..."block_hash" in res && { block_hash: res.block_hash },
3980
+ ..."block_number" in res && { block_number: res.block_number },
3981
+ ..."actual_fee" in res && { actual_fee: res.actual_fee },
3982
+ ..."transaction_index" in res && { transaction_index: res.transaction_index },
3983
+ ..."execution_resources" in res && { execution_resources: res.execution_resources },
3984
+ ..."l1_to_l2_consumed_message" in res && {
3985
+ l1_to_l2_consumed_message: res["l1_to_l2_consumed_message"]
3986
+ },
3987
+ ..."transaction_failure_reason" in res && {
3988
+ transaction_failure_reason: res.transaction_failure_reason
3989
+ }
3990
+ };
4111
3991
  }
4112
- async getTransaction(txHash) {
4113
- return this.provider.getTransaction(txHash);
3992
+ parseFeeEstimateResponse(res) {
3993
+ if ("overall_fee" in res) {
3994
+ let gasInfo = {};
3995
+ try {
3996
+ gasInfo = {
3997
+ gas_consumed: toBigInt(res.gas_usage),
3998
+ gas_price: toBigInt(res.gas_price)
3999
+ };
4000
+ } catch {
4001
+ }
4002
+ return {
4003
+ overall_fee: toBigInt(res.overall_fee),
4004
+ ...gasInfo
4005
+ };
4006
+ }
4007
+ return {
4008
+ overall_fee: toBigInt(res.amount)
4009
+ };
4114
4010
  }
4115
- async getTransactionReceipt(txHash) {
4116
- return this.provider.getTransactionReceipt(txHash);
4011
+ parseFeeEstimateBulkResponse(res) {
4012
+ return [].concat(res).map((item) => {
4013
+ if ("overall_fee" in item) {
4014
+ let gasInfo = {};
4015
+ try {
4016
+ gasInfo = {
4017
+ gas_consumed: toBigInt(item.gas_usage),
4018
+ gas_price: toBigInt(item.gas_price)
4019
+ };
4020
+ } catch {
4021
+ }
4022
+ return {
4023
+ overall_fee: toBigInt(item.overall_fee),
4024
+ ...gasInfo
4025
+ };
4026
+ }
4027
+ return {
4028
+ overall_fee: toBigInt(item.amount)
4029
+ };
4030
+ });
4117
4031
  }
4118
- async callContract(request, blockIdentifier) {
4119
- return this.provider.callContract(request, blockIdentifier);
4032
+ parseFeeSimulateTransactionResponse(res) {
4033
+ if ("overall_fee" in res.fee_estimation) {
4034
+ let gasInfo = {};
4035
+ try {
4036
+ gasInfo = {
4037
+ gas_consumed: toBigInt(res.fee_estimation.gas_usage),
4038
+ gas_price: toBigInt(res.fee_estimation.gas_price)
4039
+ };
4040
+ } catch {
4041
+ }
4042
+ return {
4043
+ trace: res.trace,
4044
+ fee_estimation: {
4045
+ ...gasInfo,
4046
+ overall_fee: toBigInt(res.fee_estimation.overall_fee)
4047
+ }
4048
+ };
4049
+ }
4050
+ return {
4051
+ trace: res.trace,
4052
+ fee_estimation: {
4053
+ overall_fee: toBigInt(res.fee_estimation.amount)
4054
+ }
4055
+ };
4120
4056
  }
4121
- async invokeFunction(functionInvocation, details) {
4122
- return this.provider.invokeFunction(functionInvocation, details);
4057
+ parseCallContractResponse(res) {
4058
+ return {
4059
+ result: res.result
4060
+ };
4123
4061
  }
4124
- async deployAccountContract(payload, details) {
4125
- return this.provider.deployAccountContract(payload, details);
4062
+ parseInvokeFunctionResponse(res) {
4063
+ return {
4064
+ transaction_hash: res.transaction_hash
4065
+ };
4126
4066
  }
4127
- async declareContract(transaction, details) {
4128
- return this.provider.declareContract(transaction, details);
4067
+ parseDeployContractResponse(res) {
4068
+ return {
4069
+ transaction_hash: res.transaction_hash,
4070
+ contract_address: res.address
4071
+ };
4129
4072
  }
4130
- async getDeclareEstimateFee(transaction, details, blockIdentifier, skipValidate) {
4131
- return this.provider.getDeclareEstimateFee(transaction, details, blockIdentifier, skipValidate);
4073
+ parseDeclareContractResponse(res) {
4074
+ return {
4075
+ transaction_hash: res.transaction_hash,
4076
+ class_hash: res.class_hash
4077
+ };
4132
4078
  }
4133
- getDeployAccountEstimateFee(transaction, details, blockIdentifier, skipValidate) {
4134
- return this.provider.getDeployAccountEstimateFee(
4135
- transaction,
4136
- details,
4137
- blockIdentifier,
4138
- skipValidate
4079
+ parseGetStateUpdateResponse(res) {
4080
+ const nonces = Object.entries(res.state_diff.nonces).map(([contract_address, nonce]) => ({
4081
+ contract_address,
4082
+ nonce
4083
+ }));
4084
+ const storage_diffs = Object.entries(res.state_diff.storage_diffs).map(
4085
+ ([address, storage_entries]) => ({ address, storage_entries })
4139
4086
  );
4087
+ return {
4088
+ ...res,
4089
+ state_diff: {
4090
+ ...res.state_diff,
4091
+ storage_diffs,
4092
+ nonces
4093
+ }
4094
+ };
4140
4095
  }
4141
- async getCode(contractAddress, blockIdentifier) {
4142
- return this.provider.getCode(contractAddress, blockIdentifier);
4096
+ parseSierraContractClassResponse(res) {
4097
+ return {
4098
+ ...res,
4099
+ abi: JSON.parse(res.abi)
4100
+ };
4143
4101
  }
4144
- async waitForTransaction(txHash, options) {
4145
- return this.provider.waitForTransaction(txHash, options);
4102
+ };
4103
+
4104
+ // src/utils/url.ts
4105
+ import urljoin from "url-join";
4106
+ var protocolAndDomainRE = /^(?:\w+:)?\/\/(\S+)$/;
4107
+ var localhostDomainRE = /^localhost[:?\d]*(?:[^:?\d]\S*)?$/;
4108
+ var nonLocalhostDomainRE = /^[^\s.]+\.\S{2,}$/;
4109
+ function isUrl(s) {
4110
+ if (!s) {
4111
+ return false;
4146
4112
  }
4147
- async getSimulateTransaction(invocation, invocationDetails, blockIdentifier, skipValidate) {
4148
- return this.provider.getSimulateTransaction(
4149
- invocation,
4150
- invocationDetails,
4151
- blockIdentifier,
4152
- skipValidate
4153
- );
4113
+ if (typeof s !== "string") {
4114
+ return false;
4154
4115
  }
4155
- async getStateUpdate(blockIdentifier) {
4156
- return this.provider.getStateUpdate(blockIdentifier);
4116
+ const match = s.match(protocolAndDomainRE);
4117
+ if (!match) {
4118
+ return false;
4157
4119
  }
4158
- async getStarkName(address, StarknetIdContract2) {
4159
- return getStarkName(this, address, StarknetIdContract2);
4120
+ const everythingAfterProtocol = match[1];
4121
+ if (!everythingAfterProtocol) {
4122
+ return false;
4160
4123
  }
4161
- async getAddressFromStarkName(name, StarknetIdContract2) {
4162
- return getAddressFromStarkName(this, name, StarknetIdContract2);
4124
+ if (localhostDomainRE.test(everythingAfterProtocol) || nonLocalhostDomainRE.test(everythingAfterProtocol)) {
4125
+ return true;
4163
4126
  }
4164
- };
4127
+ return false;
4128
+ }
4129
+ function buildUrl(baseUrl, defaultPath, urlOrPath) {
4130
+ return isUrl(urlOrPath) ? urlOrPath : urljoin(baseUrl, urlOrPath ?? defaultPath);
4131
+ }
4165
4132
 
4166
- // src/provider/interface.ts
4167
- var ProviderInterface = class {
4133
+ // src/provider/sequencer.ts
4134
+ function isEmptyQueryObject(obj) {
4135
+ return obj === void 0 || Object.keys(obj).length === 0 || Object.keys(obj).length === 1 && Object.entries(obj).every(([k, v]) => k === "blockIdentifier" && v === null);
4136
+ }
4137
+ var defaultOptions2 = {
4138
+ network: "SN_GOERLI2" /* SN_GOERLI2 */,
4139
+ blockIdentifier: "pending"
4168
4140
  };
4169
-
4170
- // src/provider/index.ts
4171
- var defaultProvider = new Provider();
4172
-
4173
- // src/utils/calldata/formatter.ts
4174
- var guard = {
4175
- isBN: (data, type, key) => {
4176
- if (!isBigInt(data[key]))
4177
- throw new Error(
4178
- `Data and formatter mismatch on ${key}:${type[key]}, expected response data ${key}:${data[key]} to be BN instead it is ${typeof data[key]}`
4141
+ var SequencerProvider = class {
4142
+ constructor(optionsOrProvider = defaultOptions2) {
4143
+ this.responseParser = new SequencerAPIResponseParser();
4144
+ if ("network" in optionsOrProvider) {
4145
+ this.baseUrl = SequencerProvider.getNetworkFromName(optionsOrProvider.network);
4146
+ this.feederGatewayUrl = buildUrl(this.baseUrl, "feeder_gateway");
4147
+ this.gatewayUrl = buildUrl(this.baseUrl, "gateway");
4148
+ } else {
4149
+ this.baseUrl = optionsOrProvider.baseUrl;
4150
+ this.feederGatewayUrl = buildUrl(
4151
+ this.baseUrl,
4152
+ "feeder_gateway",
4153
+ optionsOrProvider.feederGatewayUrl
4179
4154
  );
4180
- },
4181
- unknown: (data, type, key) => {
4182
- throw new Error(`Unhandled formatter type on ${key}:${type[key]} for data ${key}:${data[key]}`);
4155
+ this.gatewayUrl = buildUrl(this.baseUrl, "gateway", optionsOrProvider.gatewayUrl);
4156
+ }
4157
+ this.chainId = (optionsOrProvider == null ? void 0 : optionsOrProvider.chainId) ?? SequencerProvider.getChainIdFromBaseUrl(this.baseUrl);
4158
+ this.headers = optionsOrProvider.headers;
4159
+ this.blockIdentifier = (optionsOrProvider == null ? void 0 : optionsOrProvider.blockIdentifier) || defaultOptions2.blockIdentifier;
4183
4160
  }
4184
- };
4185
- function formatter(data, type, sameType) {
4186
- return Object.entries(data).reduce((acc, [key, value]) => {
4187
- const elType = sameType ?? type[key];
4188
- if (!(key in type) && !sameType) {
4189
- acc[key] = value;
4190
- return acc;
4161
+ static getNetworkFromName(name) {
4162
+ switch (name) {
4163
+ case ("SN_MAIN" /* SN_MAIN */ || "0x534e5f4d41494e" /* SN_MAIN */):
4164
+ return "https://alpha-mainnet.starknet.io" /* SN_MAIN */;
4165
+ case ("SN_GOERLI" /* SN_GOERLI */ || "0x534e5f474f45524c49" /* SN_GOERLI */):
4166
+ return "https://alpha4.starknet.io" /* SN_GOERLI */;
4167
+ case ("SN_GOERLI2" /* SN_GOERLI2 */ || "0x534e5f474f45524c4932" /* SN_GOERLI2 */):
4168
+ return "https://alpha4-2.starknet.io" /* SN_GOERLI2 */;
4169
+ default:
4170
+ throw new Error("Could not detect base url from NetworkName");
4191
4171
  }
4192
- if (elType === "string") {
4193
- if (Array.isArray(data[key])) {
4194
- const arrayStr = formatter(
4195
- data[key],
4196
- data[key].map((_) => elType)
4197
- );
4198
- acc[key] = Object.values(arrayStr).join("");
4199
- return acc;
4172
+ }
4173
+ static getChainIdFromBaseUrl(baseUrl) {
4174
+ try {
4175
+ const url = new URL(baseUrl);
4176
+ if (url.host.includes("mainnet.starknet.io")) {
4177
+ return "0x534e5f4d41494e" /* SN_MAIN */;
4200
4178
  }
4201
- guard.isBN(data, type, key);
4202
- acc[key] = decodeShortString(value);
4203
- return acc;
4204
- }
4205
- if (elType === "number") {
4206
- guard.isBN(data, type, key);
4207
- acc[key] = Number(value);
4208
- return acc;
4209
- }
4210
- if (typeof elType === "function") {
4211
- acc[key] = elType(value);
4212
- return acc;
4179
+ if (url.host.includes("alpha4-2.starknet.io")) {
4180
+ return "0x534e5f474f45524c4932" /* SN_GOERLI2 */;
4181
+ }
4182
+ return "0x534e5f474f45524c49" /* SN_GOERLI */;
4183
+ } catch {
4184
+ console.error(`Could not parse baseUrl: ${baseUrl}`);
4185
+ return "0x534e5f474f45524c49" /* SN_GOERLI */;
4213
4186
  }
4214
- if (Array.isArray(elType)) {
4215
- const arrayObj = formatter(data[key], elType, elType[0]);
4216
- acc[key] = Object.values(arrayObj);
4217
- return acc;
4187
+ }
4188
+ getFetchUrl(endpoint) {
4189
+ const gatewayUrlEndpoints = ["add_transaction"];
4190
+ return gatewayUrlEndpoints.includes(endpoint) ? this.gatewayUrl : this.feederGatewayUrl;
4191
+ }
4192
+ getFetchMethod(endpoint) {
4193
+ const postMethodEndpoints = [
4194
+ "add_transaction",
4195
+ "call_contract",
4196
+ "estimate_fee",
4197
+ "estimate_message_fee",
4198
+ "estimate_fee_bulk",
4199
+ "simulate_transaction"
4200
+ ];
4201
+ return postMethodEndpoints.includes(endpoint) ? "POST" : "GET";
4202
+ }
4203
+ getQueryString(query) {
4204
+ if (isEmptyQueryObject(query)) {
4205
+ return "";
4218
4206
  }
4219
- if (typeof elType === "object") {
4220
- acc[key] = formatter(data[key], elType);
4221
- return acc;
4207
+ const queryString = Object.entries(query).map(([key, value]) => {
4208
+ if (key === "blockIdentifier") {
4209
+ const block = new Block(value);
4210
+ return `${block.queryIdentifier}`;
4211
+ }
4212
+ return `${key}=${value}`;
4213
+ }).join("&");
4214
+ return `?${queryString}`;
4215
+ }
4216
+ getHeaders(method) {
4217
+ if (method === "POST") {
4218
+ return {
4219
+ "Content-Type": "application/json",
4220
+ ...this.headers
4221
+ };
4222
4222
  }
4223
- guard.unknown(data, type, key);
4224
- return acc;
4225
- }, {});
4226
- }
4227
-
4228
- // src/utils/calldata/tuple.ts
4229
- function parseNamedTuple(namedTuple) {
4230
- const name = namedTuple.substring(0, namedTuple.indexOf(":"));
4231
- const type = namedTuple.substring(name.length + ":".length);
4232
- return { name, type };
4233
- }
4234
- function parseSubTuple(s) {
4235
- if (!s.includes("("))
4236
- return { subTuple: [], result: s };
4237
- const subTuple = [];
4238
- let result = "";
4239
- let i = 0;
4240
- while (i < s.length) {
4241
- if (s[i] === "(") {
4242
- let counter = 1;
4243
- const lBracket = i;
4244
- i++;
4245
- while (counter) {
4246
- if (s[i] === ")")
4247
- counter--;
4248
- if (s[i] === "(")
4249
- counter++;
4250
- i++;
4223
+ return this.headers;
4224
+ }
4225
+ async fetchEndpoint(endpoint, ...[query, request]) {
4226
+ const baseUrl = this.getFetchUrl(endpoint);
4227
+ const method = this.getFetchMethod(endpoint);
4228
+ const queryString = this.getQueryString(query);
4229
+ const url = urljoin2(baseUrl, endpoint, queryString);
4230
+ return this.fetch(url, {
4231
+ method,
4232
+ body: request
4233
+ });
4234
+ }
4235
+ async fetch(endpoint, options) {
4236
+ const url = buildUrl(this.baseUrl, "", endpoint);
4237
+ const method = (options == null ? void 0 : options.method) ?? "GET";
4238
+ const headers = this.getHeaders(method);
4239
+ const body = stringify2(options == null ? void 0 : options.body);
4240
+ try {
4241
+ const response = await fetchPonyfill_default(url, {
4242
+ method,
4243
+ body,
4244
+ headers
4245
+ });
4246
+ const textResponse = await response.text();
4247
+ if (!response.ok) {
4248
+ let responseBody;
4249
+ try {
4250
+ responseBody = parse2(textResponse);
4251
+ } catch {
4252
+ throw new HttpError(response.statusText, response.status);
4253
+ }
4254
+ throw new GatewayError(responseBody.message, responseBody.code);
4251
4255
  }
4252
- subTuple.push(s.substring(lBracket, i));
4253
- result += " ";
4254
- i--;
4255
- } else {
4256
- result += s[i];
4256
+ const parseChoice = (options == null ? void 0 : options.parseAlwaysAsBigInt) ? parseAlwaysAsBig : parse2;
4257
+ return parseChoice(textResponse);
4258
+ } catch (error) {
4259
+ if (error instanceof Error && !(error instanceof LibraryError))
4260
+ throw Error(`Could not ${method} from endpoint \`${url}\`: ${error.message}`);
4261
+ throw error;
4257
4262
  }
4258
- i++;
4259
4263
  }
4260
- return {
4261
- subTuple,
4262
- result
4263
- };
4264
- }
4265
- function extractCairo0Tuple(type) {
4266
- const cleanType = type.replace(/\s/g, "").slice(1, -1);
4267
- const { subTuple, result } = parseSubTuple(cleanType);
4268
- let recomposed = result.split(",").map((it) => {
4269
- return subTuple.length ? it.replace(" ", subTuple.shift()) : it;
4270
- });
4271
- if (isTypeNamedTuple(type)) {
4272
- recomposed = recomposed.reduce((acc, it) => {
4273
- return acc.concat(parseNamedTuple(it));
4274
- }, []);
4264
+ async getChainId() {
4265
+ return Promise.resolve(this.chainId);
4266
+ }
4267
+ async callContract({ contractAddress, entrypoint: entryPointSelector, calldata = [] }, blockIdentifier = this.blockIdentifier) {
4268
+ return this.fetchEndpoint(
4269
+ "call_contract",
4270
+ { blockIdentifier },
4271
+ {
4272
+ contract_address: contractAddress,
4273
+ entry_point_selector: getSelectorFromName(entryPointSelector),
4274
+ calldata
4275
+ }
4276
+ ).then(this.responseParser.parseCallContractResponse);
4277
+ }
4278
+ async getBlock(blockIdentifier = this.blockIdentifier) {
4279
+ return this.fetchEndpoint("get_block", { blockIdentifier }).then(
4280
+ this.responseParser.parseGetBlockResponse
4281
+ );
4275
4282
  }
4276
- return recomposed;
4277
- }
4278
- function extractCairo1Tuple(type) {
4279
- const cleanType = type.replace(/\s/g, "").slice(1, -1);
4280
- return cleanType.split(",");
4281
- }
4282
- function extractTupleMemberTypes(type) {
4283
- if (isCairo1Type(type)) {
4284
- return extractCairo1Tuple(type);
4283
+ async getNonceForAddress(contractAddress, blockIdentifier = this.blockIdentifier) {
4284
+ return this.fetchEndpoint("get_nonce", { contractAddress, blockIdentifier });
4285
4285
  }
4286
- return extractCairo0Tuple(type);
4287
- }
4288
-
4289
- // src/utils/calldata/requestParser.ts
4290
- function parseTuple(element, typeStr) {
4291
- const memberTypes = extractTupleMemberTypes(typeStr);
4292
- const elements = Object.values(element);
4293
- if (elements.length !== memberTypes.length) {
4294
- throw Error(
4295
- `ParseTuple: provided and expected abi tuple size do not match.
4296
- provided: ${elements}
4297
- expected: ${memberTypes}`
4286
+ async getStorageAt(contractAddress, key, blockIdentifier = this.blockIdentifier) {
4287
+ const parsedKey = toBigInt(key).toString(10);
4288
+ return this.fetchEndpoint("get_storage_at", {
4289
+ blockIdentifier,
4290
+ contractAddress,
4291
+ key: parsedKey
4292
+ });
4293
+ }
4294
+ async getTransaction(txHash) {
4295
+ const txHashHex = toHex(txHash);
4296
+ return this.fetchEndpoint("get_transaction", { transactionHash: txHashHex }).then((result) => {
4297
+ if (Object.values(result).length === 1)
4298
+ throw new LibraryError(result.status);
4299
+ return this.responseParser.parseGetTransactionResponse(result);
4300
+ });
4301
+ }
4302
+ async getTransactionReceipt(txHash) {
4303
+ const txHashHex = toHex(txHash);
4304
+ return this.fetchEndpoint("get_transaction_receipt", { transactionHash: txHashHex }).then(
4305
+ this.responseParser.parseGetTransactionReceiptResponse
4298
4306
  );
4299
4307
  }
4300
- return memberTypes.map((it, dx) => {
4301
- return {
4302
- element: elements[dx],
4303
- type: it.type ?? it
4304
- };
4305
- });
4306
- }
4307
- function parseCalldataValue(element, type, structs) {
4308
- if (element === void 0) {
4309
- throw Error(`Missing parameter for type ${type}`);
4308
+ async getClassAt(contractAddress, blockIdentifier = this.blockIdentifier) {
4309
+ return this.fetchEndpoint("get_full_contract", { blockIdentifier, contractAddress }).then(
4310
+ (res) => {
4311
+ if (isSierra(res)) {
4312
+ return this.responseParser.parseSierraContractClassResponse(res);
4313
+ }
4314
+ return parseContract(res);
4315
+ }
4316
+ );
4310
4317
  }
4311
- if (Array.isArray(element)) {
4312
- throw Error(`Array inside array (nD) are not supported by cairo. Element: ${element} ${type}`);
4318
+ async getClassHashAt(contractAddress, blockIdentifier = this.blockIdentifier) {
4319
+ return this.fetchEndpoint("get_class_hash_at", { blockIdentifier, contractAddress });
4313
4320
  }
4314
- if (isTypeUint256(type)) {
4315
- const el_uint256 = uint256(element);
4316
- return [felt(el_uint256.low), felt(el_uint256.high)];
4321
+ async getClassByHash(classHash, blockIdentifier = this.blockIdentifier) {
4322
+ return this.fetchEndpoint("get_class_by_hash", { classHash, blockIdentifier }).then((res) => {
4323
+ if (isSierra(res)) {
4324
+ return this.responseParser.parseSierraContractClassResponse(res);
4325
+ }
4326
+ return parseContract(res);
4327
+ });
4317
4328
  }
4318
- if (structs[type] && structs[type].members.length) {
4319
- const { members } = structs[type];
4320
- const subElement = element;
4321
- return members.reduce((acc, it) => {
4322
- return acc.concat(parseCalldataValue(subElement[it.name], it.type, structs));
4323
- }, []);
4329
+ async getCompiledClassByClassHash(classHash, blockIdentifier = this.blockIdentifier) {
4330
+ return this.fetchEndpoint("get_compiled_class_by_class_hash", { classHash, blockIdentifier });
4324
4331
  }
4325
- if (isTypeTuple(type)) {
4326
- const tupled = parseTuple(element, type);
4327
- return tupled.reduce((acc, it) => {
4328
- const parsedData = parseCalldataValue(it.element, it.type, structs);
4329
- return acc.concat(parsedData);
4330
- }, []);
4332
+ async invokeFunction(functionInvocation, details) {
4333
+ return this.fetchEndpoint("add_transaction", void 0, {
4334
+ type: "INVOKE_FUNCTION" /* INVOKE */,
4335
+ sender_address: functionInvocation.contractAddress,
4336
+ calldata: bigNumberishArrayToDecimalStringArray(functionInvocation.calldata ?? []),
4337
+ signature: signatureToDecimalArray(functionInvocation.signature),
4338
+ nonce: toHex(details.nonce),
4339
+ max_fee: toHex(details.maxFee || 0),
4340
+ version: "0x1"
4341
+ }).then(this.responseParser.parseInvokeFunctionResponse);
4342
+ }
4343
+ async deployAccountContract({ classHash, constructorCalldata, addressSalt, signature }, details) {
4344
+ return this.fetchEndpoint("add_transaction", void 0, {
4345
+ type: "DEPLOY_ACCOUNT" /* DEPLOY_ACCOUNT */,
4346
+ contract_address_salt: addressSalt ?? randomAddress(),
4347
+ constructor_calldata: bigNumberishArrayToDecimalStringArray(constructorCalldata ?? []),
4348
+ class_hash: toHex(classHash),
4349
+ max_fee: toHex(details.maxFee || 0),
4350
+ version: toHex(details.version || 0),
4351
+ nonce: toHex(details.nonce),
4352
+ signature: signatureToDecimalArray(signature)
4353
+ }).then(this.responseParser.parseDeployContractResponse);
4354
+ }
4355
+ async declareContract({ senderAddress, contractDefinition, signature, compiledClassHash }, details) {
4356
+ if (!isSierra(contractDefinition)) {
4357
+ return this.fetchEndpoint("add_transaction", void 0, {
4358
+ type: "DECLARE" /* DECLARE */,
4359
+ contract_class: contractDefinition,
4360
+ nonce: toHex(details.nonce),
4361
+ signature: signatureToDecimalArray(signature),
4362
+ sender_address: senderAddress,
4363
+ max_fee: toHex(details.maxFee || 0),
4364
+ version: "0x1"
4365
+ }).then(this.responseParser.parseDeclareContractResponse);
4366
+ }
4367
+ return this.fetchEndpoint("add_transaction", void 0, {
4368
+ type: "DECLARE" /* DECLARE */,
4369
+ sender_address: senderAddress,
4370
+ compiled_class_hash: compiledClassHash,
4371
+ contract_class: contractDefinition,
4372
+ nonce: toHex(details.nonce),
4373
+ signature: signatureToDecimalArray(signature),
4374
+ max_fee: toHex(details.maxFee || 0),
4375
+ version: "0x2"
4376
+ }).then(this.responseParser.parseDeclareContractResponse);
4377
+ }
4378
+ async getEstimateFee(invocation, invocationDetails, blockIdentifier = this.blockIdentifier, skipValidate = false) {
4379
+ return this.getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier, skipValidate);
4380
+ }
4381
+ async getInvokeEstimateFee(invocation, invocationDetails, blockIdentifier = this.blockIdentifier, skipValidate = false) {
4382
+ return this.fetchEndpoint(
4383
+ "estimate_fee",
4384
+ { blockIdentifier, skipValidate },
4385
+ {
4386
+ type: "INVOKE_FUNCTION" /* INVOKE */,
4387
+ sender_address: invocation.contractAddress,
4388
+ calldata: invocation.calldata ?? [],
4389
+ signature: signatureToDecimalArray(invocation.signature),
4390
+ version: toHex((invocationDetails == null ? void 0 : invocationDetails.version) || 1),
4391
+ nonce: toHex(invocationDetails.nonce)
4392
+ }
4393
+ ).then(this.responseParser.parseFeeEstimateResponse);
4394
+ }
4395
+ async getDeclareEstimateFee({ senderAddress, contractDefinition, signature, compiledClassHash }, details, blockIdentifier = this.blockIdentifier, skipValidate = false) {
4396
+ if (!isSierra(contractDefinition)) {
4397
+ return this.fetchEndpoint(
4398
+ "estimate_fee",
4399
+ { blockIdentifier, skipValidate },
4400
+ {
4401
+ type: "DECLARE" /* DECLARE */,
4402
+ sender_address: senderAddress,
4403
+ contract_class: contractDefinition,
4404
+ signature: signatureToDecimalArray(signature),
4405
+ version: toHex((details == null ? void 0 : details.version) || toBigInt(feeTransactionVersion)),
4406
+ nonce: toHex(details.nonce)
4407
+ }
4408
+ ).then(this.responseParser.parseFeeEstimateResponse);
4409
+ }
4410
+ return this.fetchEndpoint(
4411
+ "estimate_fee",
4412
+ { blockIdentifier, skipValidate },
4413
+ {
4414
+ type: "DECLARE" /* DECLARE */,
4415
+ sender_address: senderAddress,
4416
+ compiled_class_hash: compiledClassHash,
4417
+ contract_class: contractDefinition,
4418
+ nonce: toHex(details.nonce),
4419
+ signature: signatureToDecimalArray(signature),
4420
+ version: "0x2"
4421
+ }
4422
+ ).then(this.responseParser.parseFeeEstimateResponse);
4423
+ }
4424
+ async getDeployAccountEstimateFee({ classHash, addressSalt, constructorCalldata, signature }, details, blockIdentifier = this.blockIdentifier, skipValidate = false) {
4425
+ return this.fetchEndpoint(
4426
+ "estimate_fee",
4427
+ { blockIdentifier, skipValidate },
4428
+ {
4429
+ type: "DEPLOY_ACCOUNT" /* DEPLOY_ACCOUNT */,
4430
+ class_hash: toHex(classHash),
4431
+ constructor_calldata: bigNumberishArrayToDecimalStringArray(constructorCalldata || []),
4432
+ contract_address_salt: toHex(addressSalt || 0),
4433
+ signature: signatureToDecimalArray(signature),
4434
+ version: toHex((details == null ? void 0 : details.version) || 0),
4435
+ nonce: toHex(details.nonce)
4436
+ }
4437
+ ).then(this.responseParser.parseFeeEstimateResponse);
4438
+ }
4439
+ async getEstimateFeeBulk(invocations, blockIdentifier = this.blockIdentifier) {
4440
+ const params = invocations.map((invocation) => {
4441
+ let res;
4442
+ if (invocation.type === "INVOKE_FUNCTION") {
4443
+ res = {
4444
+ type: invocation.type,
4445
+ sender_address: invocation.contractAddress,
4446
+ calldata: invocation.calldata ?? []
4447
+ };
4448
+ } else if (invocation.type === "DECLARE") {
4449
+ res = {
4450
+ type: invocation.type,
4451
+ sender_address: invocation.senderAddress,
4452
+ contract_class: invocation.contractDefinition
4453
+ };
4454
+ } else {
4455
+ res = {
4456
+ type: invocation.type,
4457
+ class_hash: toHex(toBigInt(invocation.classHash)),
4458
+ constructor_calldata: bigNumberishArrayToDecimalStringArray(
4459
+ invocation.constructorCalldata || []
4460
+ ),
4461
+ contract_address_salt: toHex(toBigInt(invocation.addressSalt || 0))
4462
+ };
4463
+ }
4464
+ return {
4465
+ ...res,
4466
+ signature: bigNumberishArrayToDecimalStringArray(formatSignature(invocation.signature)),
4467
+ version: toHex(toBigInt((invocation == null ? void 0 : invocation.version) || 1)),
4468
+ nonce: toHex(toBigInt(invocation.nonce))
4469
+ };
4470
+ });
4471
+ return this.fetchEndpoint("estimate_fee_bulk", { blockIdentifier }, params).then(
4472
+ this.responseParser.parseFeeEstimateBulkResponse
4473
+ );
4331
4474
  }
4332
- if (typeof element === "object") {
4333
- throw Error(`Parameter ${element} do not align with abi parameter ${type}`);
4475
+ async getCode(contractAddress, blockIdentifier = this.blockIdentifier) {
4476
+ return this.fetchEndpoint("get_code", { contractAddress, blockIdentifier });
4334
4477
  }
4335
- return felt(element);
4336
- }
4337
- function parseCalldataField(argsIterator, input, structs) {
4338
- const { name, type } = input;
4339
- let { value } = argsIterator.next();
4340
- switch (true) {
4341
- case isTypeArray(type):
4342
- if (!Array.isArray(value) && !isText(value)) {
4343
- throw Error(`ABI expected parameter ${name} to be array or long string, got ${value}`);
4344
- }
4345
- if (typeof value === "string") {
4346
- value = splitLongString(value);
4478
+ async waitForTransaction(txHash, options) {
4479
+ const errorStates = ["REJECTED" /* REJECTED */, "NOT_RECEIVED" /* NOT_RECEIVED */];
4480
+ let onchain = false;
4481
+ let res;
4482
+ const retryInterval = (options == null ? void 0 : options.retryInterval) ?? 8e3;
4483
+ const successStates = (options == null ? void 0 : options.successStates) ?? [
4484
+ "ACCEPTED_ON_L1" /* ACCEPTED_ON_L1 */,
4485
+ "ACCEPTED_ON_L2" /* ACCEPTED_ON_L2 */,
4486
+ "PENDING" /* PENDING */
4487
+ ];
4488
+ while (!onchain) {
4489
+ await wait(retryInterval);
4490
+ res = await this.getTransactionStatus(txHash);
4491
+ if (successStates.includes(res.tx_status)) {
4492
+ onchain = true;
4493
+ } else if (errorStates.includes(res.tx_status)) {
4494
+ const message = res.tx_failure_reason ? `${res.tx_status}: ${res.tx_failure_reason.code}
4495
+ ${res.tx_failure_reason.error_message}` : res.tx_status;
4496
+ const error = new Error(message);
4497
+ error.response = res;
4498
+ throw error;
4347
4499
  }
4348
- const result = [];
4349
- result.push(felt(value.length));
4350
- const arrayType = getArrayType(input.type);
4351
- return value.reduce((acc, el) => {
4352
- if (isTypeFelt(arrayType) || isTypeUint(arrayType) || isTypeContractAddress(arrayType)) {
4353
- acc.push(felt(el));
4354
- } else if (isTypeBool(arrayType) && typeof el === "boolean") {
4355
- acc.push(el.toString());
4356
- } else {
4357
- acc.push(...parseCalldataValue(el, arrayType, structs));
4358
- }
4359
- return acc;
4360
- }, result);
4361
- case (isTypeStruct(type, structs) || isTypeTuple(type) || isTypeUint256(type)):
4362
- return parseCalldataValue(value, type, structs);
4363
- case isTypeBool(type):
4364
- return `${+value}`;
4365
- default:
4366
- return felt(value);
4367
- }
4368
- }
4369
-
4370
- // src/utils/calldata/responseParser.ts
4371
- function parseResponseStruct(responseIterator, type, structs) {
4372
- if (type in structs && structs[type]) {
4373
- return structs[type].members.reduce((acc, el) => {
4374
- acc[el.name] = parseResponseStruct(responseIterator, el.type, structs);
4375
- return acc;
4376
- }, {});
4500
+ }
4501
+ const txReceipt = await this.getTransactionReceipt(txHash);
4502
+ return txReceipt;
4377
4503
  }
4378
- if (isTypeTuple(type)) {
4379
- const memberTypes = extractTupleMemberTypes(type);
4380
- return memberTypes.reduce((acc, it, idx) => {
4381
- const tName = (it == null ? void 0 : it.name) ? it.name : idx;
4382
- const tType = (it == null ? void 0 : it.type) ? it.type : it;
4383
- acc[tName] = parseResponseStruct(responseIterator, tType, structs);
4384
- return acc;
4385
- }, {});
4504
+ async getTransactionStatus(txHash) {
4505
+ const txHashHex = toHex(txHash);
4506
+ return this.fetchEndpoint("get_transaction_status", { transactionHash: txHashHex });
4386
4507
  }
4387
- const temp = responseIterator.next().value;
4388
- return BigInt(temp);
4389
- }
4390
- function responseParser(responseIterator, output, structs, parsedResult) {
4391
- const { name, type } = output;
4392
- let temp;
4393
- switch (true) {
4394
- case isLen(name):
4395
- temp = responseIterator.next().value;
4396
- return BigInt(temp);
4397
- case isTypeBool(type):
4398
- temp = responseIterator.next().value;
4399
- return Boolean(BigInt(temp));
4400
- case isTypeUint256(type):
4401
- const low = responseIterator.next().value;
4402
- const high = responseIterator.next().value;
4403
- return uint256ToBN({ low, high });
4404
- case isTypeArray(type):
4405
- const parsedDataArr = [];
4406
- if (isCairo1Type(type)) {
4407
- responseIterator.next();
4408
- let it = responseIterator.next();
4409
- while (!it.done) {
4410
- parsedDataArr.push(BigInt(it.value));
4411
- it = responseIterator.next();
4412
- }
4413
- return parsedDataArr;
4414
- }
4415
- if (parsedResult && parsedResult[`${name}_len`]) {
4416
- const arrLen = parsedResult[`${name}_len`];
4417
- while (parsedDataArr.length < arrLen) {
4418
- parsedDataArr.push(
4419
- parseResponseStruct(responseIterator, output.type.replace("*", ""), structs)
4420
- );
4421
- }
4422
- }
4423
- return parsedDataArr;
4424
- case (type in structs || isTypeTuple(type)):
4425
- return parseResponseStruct(responseIterator, type, structs);
4426
- default:
4427
- temp = responseIterator.next().value;
4428
- return BigInt(temp);
4508
+ async getContractAddresses() {
4509
+ return this.fetchEndpoint("get_contract_addresses");
4429
4510
  }
4430
- }
4431
-
4432
- // src/utils/calldata/validate.ts
4433
- var validateFelt = (parameter, input) => {
4434
- assert(
4435
- typeof parameter === "string" || typeof parameter === "number" || typeof parameter === "bigint",
4436
- `Validate: arg ${input.name} should be a felt typed as (String, Number or BigInt)`
4437
- );
4438
- };
4439
- var validateUint = (parameter, input) => {
4440
- if (typeof parameter === "number") {
4441
- assert(
4442
- parameter <= Number.MAX_SAFE_INTEGER,
4443
- `Validation: Parameter is to large to be typed as Number use (BigInt or String)`
4444
- );
4511
+ async getTransactionTrace(txHash) {
4512
+ const txHashHex = toHex(txHash);
4513
+ return this.fetchEndpoint("get_transaction_trace", { transactionHash: txHashHex });
4445
4514
  }
4446
- assert(
4447
- typeof parameter === "string" || typeof parameter === "number" || typeof parameter === "bigint",
4448
- `Validate: arg ${input.name} of cairo type ${input.type} should be type (String, Number or BigInt)`
4449
- );
4450
- const param = toBigInt(parameter);
4451
- switch (input.type) {
4452
- case "core::integer::u8" /* u8 */:
4453
- assert(
4454
- param >= 0n && param <= 255n,
4455
- `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0 - 255]`
4456
- );
4457
- break;
4458
- case "core::integer::u16" /* u16 */:
4459
- assert(
4460
- param >= 0n && param <= 65535n,
4461
- `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0, 65535]`
4462
- );
4463
- break;
4464
- case "core::integer::u32" /* u32 */:
4465
- assert(
4466
- param >= 0n && param <= 4294967295n,
4467
- `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0, 4294967295]`
4468
- );
4469
- break;
4470
- case "core::integer::u64" /* u64 */:
4471
- assert(
4472
- param >= 0n && param <= 2n ** 64n - 1n,
4473
- `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0, 2^64-1]`
4474
- );
4475
- break;
4476
- case "core::integer::u128" /* u128 */:
4477
- assert(
4478
- param >= 0n && param <= 2n ** 128n - 1n,
4479
- `Validate: arg ${input.name} cairo typed ${input.type} should be in range [0, 2^128-1]`
4480
- );
4481
- break;
4482
- case "core::integer::u256" /* u256 */:
4483
- assert(
4484
- param >= 0n && param <= 2n ** 256n - 1n,
4485
- `Validate: arg ${input.name} is ${input.type} 0 - 2^256-1`
4486
- );
4487
- break;
4488
- default:
4489
- break;
4515
+ async estimateMessageFee({ from_address, to_address, entry_point_selector, payload }, blockIdentifier = this.blockIdentifier) {
4516
+ const validCallL1Handler = {
4517
+ from_address: getDecimalString(from_address),
4518
+ to_address: getHexString(to_address),
4519
+ entry_point_selector: getSelector(entry_point_selector),
4520
+ payload: getHexStringArray(payload)
4521
+ };
4522
+ return this.fetchEndpoint("estimate_message_fee", { blockIdentifier }, validCallL1Handler);
4490
4523
  }
4491
- };
4492
- var validateBool = (parameter, input) => {
4493
- assert(
4494
- typeof parameter === "boolean",
4495
- `Validate: arg ${input.name} of cairo type ${input.type} should be type (Boolean)`
4496
- );
4497
- };
4498
- var validateStruct = (parameter, input, structs) => {
4499
- assert(
4500
- typeof parameter === "object" && !Array.isArray(parameter),
4501
- `Validate: arg ${input.name} is cairo type struct (${input.type}), and should be defined as js object (not array)`
4502
- );
4503
- structs[input.type].members.forEach(({ name }) => {
4504
- assert(
4505
- Object.keys(parameter).includes(name),
4506
- `Validate: arg ${input.name} should have a property ${name}`
4507
- );
4508
- });
4509
- };
4510
- var validateTuple = (parameter, input) => {
4511
- assert(
4512
- typeof parameter === "object" && !Array.isArray(parameter),
4513
- `Validate: arg ${input.name} should be a tuple (defined as object)`
4514
- );
4515
- };
4516
- var validateArray = (parameter, input, structs) => {
4517
- const baseType = getArrayType(input.type);
4518
- if (isTypeFelt(baseType) && isLongText(parameter))
4519
- return;
4520
- assert(Array.isArray(parameter), `Validate: arg ${input.name} should be an Array`);
4521
- switch (true) {
4522
- case isTypeFelt(baseType):
4523
- parameter.forEach((param) => validateFelt(param, input));
4524
- break;
4525
- case isTypeTuple(baseType):
4526
- parameter.forEach((it) => validateTuple(it, { name: input.name, type: baseType }));
4527
- break;
4528
- case isTypeStruct(baseType, structs):
4529
- parameter.forEach(
4530
- (it) => validateStruct(it, { name: input.name, type: baseType }, structs)
4531
- );
4532
- break;
4533
- case isTypeUint(baseType):
4534
- parameter.forEach((param) => validateUint(param, input));
4535
- break;
4536
- case isTypeBool(baseType):
4537
- parameter.forEach((param) => validateBool(param, input));
4538
- break;
4539
- default:
4540
- throw new Error(
4541
- `Validate Unhandled: argument ${input.name}, type ${input.type}, value ${parameter}`
4542
- );
4524
+ async getSimulateTransaction(invocation, invocationDetails, blockIdentifier = this.blockIdentifier, skipValidate = false) {
4525
+ return this.fetchEndpoint(
4526
+ "simulate_transaction",
4527
+ { blockIdentifier, skipValidate },
4528
+ {
4529
+ type: "INVOKE_FUNCTION",
4530
+ sender_address: invocation.contractAddress,
4531
+ calldata: invocation.calldata ?? [],
4532
+ signature: signatureToDecimalArray(invocation.signature),
4533
+ version: toHex((invocationDetails == null ? void 0 : invocationDetails.version) || 1),
4534
+ nonce: toHex(invocationDetails.nonce),
4535
+ max_fee: toHex((invocationDetails == null ? void 0 : invocationDetails.maxFee) || 0)
4536
+ }
4537
+ ).then(this.responseParser.parseFeeSimulateTransactionResponse);
4538
+ }
4539
+ async getStateUpdate(blockIdentifier = this.blockIdentifier) {
4540
+ const args = new Block(blockIdentifier).sequencerIdentifier;
4541
+ return this.fetchEndpoint("get_state_update", { ...args }).then(
4542
+ this.responseParser.parseGetStateUpdateResponse
4543
+ );
4544
+ }
4545
+ async getBlockTraces(blockIdentifier = this.blockIdentifier) {
4546
+ const args = new Block(blockIdentifier).sequencerIdentifier;
4547
+ return this.fetchEndpoint("get_block_traces", { ...args });
4548
+ }
4549
+ async getStarkName(address, StarknetIdContract2) {
4550
+ return getStarkName(this, address, StarknetIdContract2);
4551
+ }
4552
+ async getAddressFromStarkName(name, StarknetIdContract2) {
4553
+ return getAddressFromStarkName(this, name, StarknetIdContract2);
4543
4554
  }
4544
4555
  };
4545
- function validateFields(abiMethod, args, structs) {
4546
- abiMethod.inputs.reduce((acc, input) => {
4547
- const parameter = args[acc];
4548
- switch (true) {
4549
- case isLen(input.name):
4550
- return acc;
4551
- case isTypeFelt(input.type):
4552
- validateFelt(parameter, input);
4553
- break;
4554
- case isTypeUint(input.type):
4555
- validateUint(parameter, input);
4556
- break;
4557
- case isTypeBool(input.type):
4558
- validateBool(parameter, input);
4559
- break;
4560
- case isTypeContractAddress(input.type):
4561
- break;
4562
- case isTypeStruct(input.type, structs):
4563
- validateStruct(parameter, input, structs);
4564
- break;
4565
- case isTypeTuple(input.type):
4566
- validateTuple(parameter, input);
4567
- break;
4568
- case isTypeArray(input.type):
4569
- validateArray(parameter, input, structs);
4570
- break;
4571
- default:
4572
- throw new Error(
4573
- `Validate Unhandled: argument ${input.name}, type ${input.type}, value ${parameter}`
4574
- );
4575
- }
4576
- return acc + 1;
4577
- }, 0);
4578
- }
4579
4556
 
4580
- // src/utils/calldata/index.ts
4581
- var CallData = class {
4582
- constructor(abi) {
4583
- this.abi = abi;
4584
- this.structs = CallData.getAbiStruct(abi);
4585
- }
4586
- validate(type, method, args = []) {
4587
- if (type !== "DEPLOY") {
4588
- const invocableFunctionNames = this.abi.filter((abi) => {
4589
- if (abi.type !== "function")
4590
- return false;
4591
- const isView = abi.stateMutability === "view" || abi.state_mutability === "view";
4592
- return type === "INVOKE" ? !isView : isView;
4593
- }).map((abi) => abi.name);
4594
- assert(
4595
- invocableFunctionNames.includes(method),
4596
- `${type === "INVOKE" ? "invocable" : "viewable"} method not found in abi`
4597
- );
4598
- }
4599
- const abiMethod = this.abi.find(
4600
- (abi) => type === "DEPLOY" ? abi.name === method && abi.type === method : abi.name === method && abi.type === "function"
4601
- );
4602
- const inputsLength = CallData.abiInputsLength(abiMethod.inputs);
4603
- if (args.length !== inputsLength) {
4604
- throw Error(
4605
- `Invalid number of arguments, expected ${inputsLength} arguments, but got ${args.length}`
4606
- );
4557
+ // src/provider/default.ts
4558
+ var Provider = class {
4559
+ constructor(providerOrOptions) {
4560
+ if (providerOrOptions instanceof Provider) {
4561
+ this.provider = providerOrOptions.provider;
4562
+ } else if (providerOrOptions instanceof RpcProvider || providerOrOptions instanceof SequencerProvider) {
4563
+ this.provider = providerOrOptions;
4564
+ } else if (providerOrOptions && "rpc" in providerOrOptions) {
4565
+ this.provider = new RpcProvider(providerOrOptions.rpc);
4566
+ } else if (providerOrOptions && "sequencer" in providerOrOptions) {
4567
+ this.provider = new SequencerProvider(providerOrOptions.sequencer);
4568
+ } else {
4569
+ this.provider = new SequencerProvider();
4607
4570
  }
4608
- validateFields(abiMethod, args, this.structs);
4609
4571
  }
4610
- compile(args, inputs) {
4611
- const argsIterator = args[Symbol.iterator]();
4612
- return inputs.reduce(
4613
- (acc, input) => isLen(input.name) ? acc : acc.concat(parseCalldataField(argsIterator, input, this.structs)),
4614
- []
4572
+ async getChainId() {
4573
+ return this.provider.getChainId();
4574
+ }
4575
+ async getBlock(blockIdentifier) {
4576
+ return this.provider.getBlock(blockIdentifier);
4577
+ }
4578
+ async getClassAt(contractAddress, blockIdentifier) {
4579
+ return this.provider.getClassAt(contractAddress, blockIdentifier);
4580
+ }
4581
+ async getClassHashAt(contractAddress, blockIdentifier) {
4582
+ return this.provider.getClassHashAt(contractAddress, blockIdentifier);
4583
+ }
4584
+ getClassByHash(classHash) {
4585
+ return this.provider.getClassByHash(classHash);
4586
+ }
4587
+ async getEstimateFee(invocationWithTxType, invocationDetails, blockIdentifier) {
4588
+ return this.provider.getEstimateFee(invocationWithTxType, invocationDetails, blockIdentifier);
4589
+ }
4590
+ async getInvokeEstimateFee(invocationWithTxType, invocationDetails, blockIdentifier, skipValidate) {
4591
+ return this.provider.getInvokeEstimateFee(
4592
+ invocationWithTxType,
4593
+ invocationDetails,
4594
+ blockIdentifier,
4595
+ skipValidate
4615
4596
  );
4616
4597
  }
4617
- static compile(data) {
4618
- const createTree = (obj) => {
4619
- const getEntries = (o, prefix = "") => {
4620
- const oe = Array.isArray(o) ? [o.length.toString(), ...o] : o;
4621
- return Object.entries(oe).flatMap(([k, v]) => {
4622
- let value = v;
4623
- if (isLongText(value))
4624
- value = splitLongString(value);
4625
- const kk = Array.isArray(oe) && k === "0" ? "$$len" : k;
4626
- if (isBigInt(value))
4627
- return [[`${prefix}${kk}`, felt(value)]];
4628
- return Object(value) === value ? getEntries(value, `${prefix}${kk}.`) : [[`${prefix}${kk}`, felt(value)]];
4629
- });
4630
- };
4631
- return Object.fromEntries(getEntries(obj));
4632
- };
4633
- let callTreeArray;
4634
- if (!Array.isArray(data)) {
4635
- const callTree = createTree(data);
4636
- callTreeArray = Object.values(callTree);
4637
- } else {
4638
- callTreeArray = data;
4639
- }
4640
- Object.defineProperty(callTreeArray, "compiled", {
4641
- enumerable: false,
4642
- writable: false,
4643
- value: true
4644
- });
4645
- return callTreeArray;
4598
+ async getEstimateFeeBulk(invocations, blockIdentifier) {
4599
+ return this.provider.getEstimateFeeBulk(invocations, blockIdentifier);
4646
4600
  }
4647
- parse(method, response) {
4648
- const { outputs } = this.abi.find((abi) => abi.name === method);
4649
- const responseIterator = response.flat()[Symbol.iterator]();
4650
- const parsed = outputs.flat().reduce((acc, output, idx) => {
4651
- const propName = output.name ?? idx;
4652
- acc[propName] = responseParser(responseIterator, output, this.structs, acc);
4653
- if (acc[propName] && acc[`${propName}_len`]) {
4654
- delete acc[`${propName}_len`];
4655
- }
4656
- return acc;
4657
- }, {});
4658
- return Object.keys(parsed).length === 1 && 0 in parsed ? parsed[0] : parsed;
4601
+ async getNonceForAddress(contractAddress, blockIdentifier) {
4602
+ return this.provider.getNonceForAddress(contractAddress, blockIdentifier);
4659
4603
  }
4660
- format(method, response, format) {
4661
- const parsed = this.parse(method, response);
4662
- return formatter(parsed, format);
4604
+ async getStorageAt(contractAddress, key, blockIdentifier) {
4605
+ return this.provider.getStorageAt(contractAddress, key, blockIdentifier);
4663
4606
  }
4664
- static abiInputsLength(inputs) {
4665
- return inputs.reduce((acc, input) => !isLen(input.name) ? acc + 1 : acc, 0);
4607
+ async getTransaction(txHash) {
4608
+ return this.provider.getTransaction(txHash);
4666
4609
  }
4667
- static getAbiStruct(abi) {
4668
- return abi.filter((abiEntry) => abiEntry.type === "struct").reduce(
4669
- (acc, abiEntry) => ({
4670
- ...acc,
4671
- [abiEntry.name]: abiEntry
4672
- }),
4673
- {}
4610
+ async getTransactionReceipt(txHash) {
4611
+ return this.provider.getTransactionReceipt(txHash);
4612
+ }
4613
+ async callContract(request, blockIdentifier) {
4614
+ return this.provider.callContract(request, blockIdentifier);
4615
+ }
4616
+ async invokeFunction(functionInvocation, details) {
4617
+ return this.provider.invokeFunction(functionInvocation, details);
4618
+ }
4619
+ async deployAccountContract(payload, details) {
4620
+ return this.provider.deployAccountContract(payload, details);
4621
+ }
4622
+ async declareContract(transaction, details) {
4623
+ return this.provider.declareContract(transaction, details);
4624
+ }
4625
+ async getDeclareEstimateFee(transaction, details, blockIdentifier, skipValidate) {
4626
+ return this.provider.getDeclareEstimateFee(transaction, details, blockIdentifier, skipValidate);
4627
+ }
4628
+ getDeployAccountEstimateFee(transaction, details, blockIdentifier, skipValidate) {
4629
+ return this.provider.getDeployAccountEstimateFee(
4630
+ transaction,
4631
+ details,
4632
+ blockIdentifier,
4633
+ skipValidate
4634
+ );
4635
+ }
4636
+ async getCode(contractAddress, blockIdentifier) {
4637
+ return this.provider.getCode(contractAddress, blockIdentifier);
4638
+ }
4639
+ async waitForTransaction(txHash, options) {
4640
+ return this.provider.waitForTransaction(txHash, options);
4641
+ }
4642
+ async getSimulateTransaction(invocation, invocationDetails, blockIdentifier, skipValidate) {
4643
+ return this.provider.getSimulateTransaction(
4644
+ invocation,
4645
+ invocationDetails,
4646
+ blockIdentifier,
4647
+ skipValidate
4674
4648
  );
4675
4649
  }
4650
+ async getStateUpdate(blockIdentifier) {
4651
+ return this.provider.getStateUpdate(blockIdentifier);
4652
+ }
4653
+ async getStarkName(address, StarknetIdContract2) {
4654
+ return getStarkName(this, address, StarknetIdContract2);
4655
+ }
4656
+ async getAddressFromStarkName(name, StarknetIdContract2) {
4657
+ return getAddressFromStarkName(this, name, StarknetIdContract2);
4658
+ }
4659
+ };
4660
+
4661
+ // src/provider/interface.ts
4662
+ var ProviderInterface = class {
4676
4663
  };
4677
4664
 
4665
+ // src/provider/index.ts
4666
+ var defaultProvider = new Provider();
4667
+
4678
4668
  // src/contract/default.ts
4679
4669
  var splitArgsAndOptions = (args) => {
4680
4670
  const options = [
@@ -4684,13 +4674,14 @@ var splitArgsAndOptions = (args) => {
4684
4674
  "formatResponse",
4685
4675
  "maxFee",
4686
4676
  "nonce",
4687
- "signature"
4677
+ "signature",
4678
+ "addressSalt"
4688
4679
  ];
4689
4680
  const lastArg = args[args.length - 1];
4690
4681
  if (typeof lastArg === "object" && options.some((x) => x in lastArg)) {
4691
4682
  return { args, options: args.pop() };
4692
4683
  }
4693
- return { args, options: {} };
4684
+ return { args };
4694
4685
  };
4695
4686
  function buildCall(contract, functionAbi) {
4696
4687
  return async function(...args) {
@@ -4727,20 +4718,20 @@ function buildEstimate(contract, functionAbi) {
4727
4718
  return contract.estimate(functionAbi.name, args);
4728
4719
  };
4729
4720
  }
4730
- var detectCairoVersion = (abi) => {
4731
- if (!abi)
4732
- return "0";
4733
- return abi.find((it) => "state_mutability" in it) ? "1" : "0";
4734
- };
4721
+ function getCalldata(args, callback) {
4722
+ if ("__compiled__" in args)
4723
+ return args;
4724
+ if (Array.isArray(args[0]) && "__compiled__" in args[0])
4725
+ return args[0];
4726
+ return callback();
4727
+ }
4735
4728
  var Contract = class {
4736
- constructor(abi, address, providerOrAccount = defaultProvider, cairoVersion = detectCairoVersion(abi)) {
4737
- this.version = "0";
4729
+ constructor(abi, address, providerOrAccount = defaultProvider) {
4738
4730
  this.address = address && address.toLowerCase();
4739
4731
  this.providerOrAccount = providerOrAccount;
4740
4732
  this.callData = new CallData(abi);
4741
4733
  this.structs = CallData.getAbiStruct(abi);
4742
4734
  this.abi = abi;
4743
- this.version = cairoVersion;
4744
4735
  const options = { enumerable: true, value: {}, writable: false };
4745
4736
  Object.defineProperties(this, {
4746
4737
  functions: { enumerable: true, value: {}, writable: false },
@@ -4797,15 +4788,21 @@ var Contract = class {
4797
4788
  }
4798
4789
  return this;
4799
4790
  }
4800
- async call(method, args = [], options = { parseRequest: true, parseResponse: true, formatResponse: void 0 }) {
4791
+ async call(method, args = [], {
4792
+ parseRequest = true,
4793
+ parseResponse = true,
4794
+ formatResponse = void 0,
4795
+ blockIdentifier = void 0
4796
+ } = {}) {
4801
4797
  assert(this.address !== null, "contract is not connected to an address");
4802
- const blockIdentifier = (options == null ? void 0 : options.blockIdentifier) || void 0;
4803
- let calldata = "compiled" in args ? args : args[0];
4804
- if (options.parseRequest && !(calldata == null ? void 0 : calldata.compiled)) {
4805
- const { inputs } = this.abi.find((abi) => abi.name === method);
4806
- this.callData.validate("CALL", method, args);
4807
- calldata = this.callData.compile(args, inputs);
4808
- }
4798
+ const calldata = getCalldata(args, () => {
4799
+ if (parseRequest) {
4800
+ this.callData.validate("CALL", method, args);
4801
+ return this.callData.compile(method, args);
4802
+ }
4803
+ console.warn("Call skipped parsing but provided rawArgs, possible malfunction request");
4804
+ return args;
4805
+ });
4809
4806
  return this.providerOrAccount.callContract(
4810
4807
  {
4811
4808
  contractAddress: this.address,
@@ -4814,25 +4811,25 @@ var Contract = class {
4814
4811
  },
4815
4812
  blockIdentifier
4816
4813
  ).then((x) => {
4817
- if (!options.parseResponse) {
4814
+ if (!parseResponse) {
4818
4815
  return x.result;
4819
4816
  }
4820
- if (options.formatResponse) {
4821
- return this.callData.format(method, x.result, options.formatResponse);
4817
+ if (formatResponse) {
4818
+ return this.callData.format(method, x.result, formatResponse);
4822
4819
  }
4823
4820
  return this.callData.parse(method, x.result);
4824
4821
  });
4825
4822
  }
4826
- invoke(method, args = [], options = {
4827
- parseRequest: true
4828
- }) {
4823
+ invoke(method, args = [], { parseRequest = true, maxFee, nonce, signature } = {}) {
4829
4824
  assert(this.address !== null, "contract is not connected to an address");
4830
- let calldata = "compiled" in args ? args : args[0];
4831
- if (options.parseRequest && !(calldata == null ? void 0 : calldata.compiled)) {
4832
- const { inputs } = this.abi.find((abi) => abi.name === method);
4833
- this.callData.validate("INVOKE", method, args);
4834
- calldata = this.callData.compile(args, inputs);
4835
- }
4825
+ const calldata = getCalldata(args, () => {
4826
+ if (parseRequest) {
4827
+ this.callData.validate("INVOKE", method, args);
4828
+ return this.callData.compile(method, args);
4829
+ }
4830
+ console.warn("Invoke skipped parsing but provided rawArgs, possible malfunction request");
4831
+ return args;
4832
+ });
4836
4833
  const invocation = {
4837
4834
  contractAddress: this.address,
4838
4835
  calldata,
@@ -4840,40 +4837,36 @@ var Contract = class {
4840
4837
  };
4841
4838
  if ("execute" in this.providerOrAccount) {
4842
4839
  return this.providerOrAccount.execute(invocation, void 0, {
4843
- maxFee: options.maxFee,
4844
- nonce: options.nonce
4840
+ maxFee,
4841
+ nonce
4845
4842
  });
4846
4843
  }
4847
- if (!options.nonce) {
4844
+ if (!nonce)
4848
4845
  throw new Error(`Nonce is required when invoking a function without an account`);
4849
- }
4850
4846
  console.warn(`Invoking ${method} without an account. This will not work on a public node.`);
4851
4847
  return this.providerOrAccount.invokeFunction(
4852
4848
  {
4853
4849
  ...invocation,
4854
- signature: options.signature
4850
+ signature
4855
4851
  },
4856
4852
  {
4857
- nonce: options.nonce
4853
+ nonce
4858
4854
  }
4859
4855
  );
4860
4856
  }
4861
4857
  async estimate(method, args = []) {
4862
- var _a;
4863
4858
  assert(this.address !== null, "contract is not connected to an address");
4864
- if (!((_a = args[0]) == null ? void 0 : _a.compiled)) {
4859
+ if (!getCalldata(args, () => false)) {
4865
4860
  this.callData.validate("INVOKE", method, args);
4866
4861
  }
4867
- const invocation = this.populateTransaction[method](...args);
4862
+ const invocation = this.populate(method, args);
4868
4863
  if ("estimateInvokeFee" in this.providerOrAccount) {
4869
4864
  return this.providerOrAccount.estimateInvokeFee(invocation);
4870
4865
  }
4871
4866
  throw Error("Contract must be connected to the account contract to estimate");
4872
4867
  }
4873
4868
  populate(method, args = []) {
4874
- var _a;
4875
- const { inputs } = this.abi.find((abi) => abi.name === method);
4876
- const calldata = ((_a = args == null ? void 0 : args[0]) == null ? void 0 : _a.compiled) ? args == null ? void 0 : args[0] : this.callData.compile(args, inputs);
4869
+ const calldata = getCalldata(args, () => this.callData.compile(method, args));
4877
4870
  return {
4878
4871
  contractAddress: this.address,
4879
4872
  entrypoint: method,
@@ -4893,36 +4886,24 @@ var ContractFactory = class {
4893
4886
  this.compiledContract = compiledContract;
4894
4887
  this.account = account;
4895
4888
  this.classHash = classHash;
4896
- this.callData = new CallData(abi);
4889
+ this.CallData = new CallData(abi);
4897
4890
  }
4898
4891
  async deploy(...args) {
4899
- var _a;
4900
- let constructorCalldata;
4901
- let parseRequest = true;
4902
- let addressSalt;
4903
- args.forEach((arg) => {
4904
- if (typeof arg !== "object")
4905
- return;
4906
- if ("addressSalt" in arg) {
4907
- addressSalt = arg.addressSalt;
4908
- }
4909
- if ("parseRequest" in arg) {
4910
- parseRequest = arg.parseRequest;
4892
+ const { args: param, options = { parseRequest: true } } = splitArgsAndOptions(args);
4893
+ const constructorCalldata = getCalldata(param, () => {
4894
+ if (options.parseRequest) {
4895
+ this.CallData.validate("DEPLOY", "constructor", param);
4896
+ return this.CallData.compile("constructor", param);
4911
4897
  }
4898
+ console.warn("Call skipped parsing but provided rawArgs, possible malfunction request");
4899
+ return param;
4912
4900
  });
4913
- if (!parseRequest || ((_a = args[0]) == null ? void 0 : _a.compiled)) {
4914
- constructorCalldata = args[0];
4915
- } else {
4916
- this.callData.validate("DEPLOY", "constructor", args);
4917
- const { inputs } = this.abi.find((abi) => abi.type === "constructor");
4918
- constructorCalldata = this.callData.compile(args, inputs);
4919
- }
4920
4901
  const {
4921
4902
  deploy: { contract_address, transaction_hash }
4922
4903
  } = await this.account.declareAndDeploy({
4923
4904
  contract: this.compiledContract,
4924
4905
  constructorCalldata,
4925
- salt: addressSalt
4906
+ salt: options.addressSalt
4926
4907
  });
4927
4908
  assert(Boolean(contract_address), "Deployment of the contract failed");
4928
4909
  const contractInstance = new Contract(
@@ -5550,7 +5531,7 @@ var Account = class extends Provider {
5550
5531
  unique = true,
5551
5532
  constructorCalldata = []
5552
5533
  } = it;
5553
- const compiledConstructorCallData = compileCalldata(constructorCalldata);
5534
+ const compiledConstructorCallData = CallData.compile(constructorCalldata);
5554
5535
  const deploySalt = salt ?? randomAddress();
5555
5536
  return {
5556
5537
  call: {
@@ -5574,7 +5555,10 @@ var Account = class extends Provider {
5574
5555
  });
5575
5556
  const calls = params.map((it) => it.call);
5576
5557
  const addresses = params.map((it) => it.address);
5577
- const invokeResponse = await this.execute(calls, void 0, details);
5558
+ const invokeResponse = await this.execute(calls, void 0, {
5559
+ ...details,
5560
+ cairoVersion: "0"
5561
+ });
5578
5562
  return {
5579
5563
  ...invokeResponse,
5580
5564
  contract_address: addresses
@@ -5646,7 +5630,7 @@ var Account = class extends Provider {
5646
5630
  await this.callContract({
5647
5631
  contractAddress: this.address,
5648
5632
  entrypoint: "isValidSignature",
5649
- calldata: compileCalldata({
5633
+ calldata: CallData.compile({
5650
5634
  hash: toBigInt(hash).toString(),
5651
5635
  signature: formatSignature(signature)
5652
5636
  })
@@ -5732,7 +5716,7 @@ var Account = class extends Provider {
5732
5716
  unique = true,
5733
5717
  constructorCalldata = []
5734
5718
  } = it;
5735
- const compiledConstructorCallData = compileCalldata(constructorCalldata);
5719
+ const compiledConstructorCallData = CallData.compile(constructorCalldata);
5736
5720
  return {
5737
5721
  contractAddress: UDC.ADDRESS,
5738
5722
  entrypoint: UDC.ENTRYPOINT,
@@ -5848,6 +5832,7 @@ export {
5848
5832
  encode_exports as encode,
5849
5833
  fixProto,
5850
5834
  fixStack,
5835
+ getCalldata,
5851
5836
  getChecksumAddress,
5852
5837
  hash_exports as hash,
5853
5838
  isUrl,
@@ -5856,6 +5841,7 @@ export {
5856
5841
  num_exports as num,
5857
5842
  number,
5858
5843
  shortString_exports as shortString,
5844
+ splitArgsAndOptions,
5859
5845
  stark_exports as stark,
5860
5846
  starknetId_exports as starknetId,
5861
5847
  transaction_exports as transaction,