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