UNPKG

starknet

Version:
1,604 lines (1,569 loc) 451 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); // src/global/constants.ts var constants_exports = {}; __export(constants_exports, { ADDR_BOUND: () => ADDR_BOUND, API_VERSION: () => API_VERSION, BaseUrl: () => _BaseUrl, DEFAULT_GLOBAL_CONFIG: () => DEFAULT_GLOBAL_CONFIG, HARDENING_4BYTES: () => HARDENING_4BYTES, HARDENING_BYTE: () => HARDENING_BYTE, IS_BROWSER: () => IS_BROWSER, LegacyUDC: () => LegacyUDC, MASK_250: () => MASK_250, MASK_31: () => MASK_31, MAX_STORAGE_ITEM_SIZE: () => MAX_STORAGE_ITEM_SIZE, NetworkName: () => _NetworkName, OutsideExecutionCallerAny: () => OutsideExecutionCallerAny, PAYMASTER_RPC_NODES: () => PAYMASTER_RPC_NODES, PRIME: () => PRIME, RANGE_FELT: () => RANGE_FELT, RANGE_I128: () => RANGE_I128, RANGE_I16: () => RANGE_I16, RANGE_I32: () => RANGE_I32, RANGE_I64: () => RANGE_I64, RANGE_I8: () => RANGE_I8, RANGE_U128: () => RANGE_U128, RANGE_U16: () => RANGE_U16, RANGE_U32: () => RANGE_U32, RANGE_U64: () => RANGE_U64, RANGE_U8: () => RANGE_U8, RANGE_U96: () => RANGE_U96, RPC_DEFAULT_NODES: () => RPC_DEFAULT_NODES, SNIP9_V1_INTERFACE_ID: () => SNIP9_V1_INTERFACE_ID, SNIP9_V2_INTERFACE_ID: () => SNIP9_V2_INTERFACE_ID, SN_VERSION_IMPLEMENTING_BLAKE_FOR_COMPILED_CLASS: () => SN_VERSION_IMPLEMENTING_BLAKE_FOR_COMPILED_CLASS, SYSTEM_MESSAGES: () => SYSTEM_MESSAGES, StarknetChainId: () => _StarknetChainId, SupportedRpcVersion: () => _SupportedRpcVersion, TEXT_TO_FELT_MAX_LEN: () => TEXT_TO_FELT_MAX_LEN, TransactionHashPrefix: () => _TransactionHashPrefix, UDC: () => UDC, ZERO: () => ZERO }); // src/types/api/index.ts var api_exports = {}; __export(api_exports, { JRPC: () => jsonrpc_exports, PAYMASTER_API: () => PAYMASTER_API, RPCSPEC010: () => RPCSPEC010, RPCSPEC09: () => RPCSPEC09 }); // src/types/api/jsonrpc.ts var jsonrpc_exports = {}; // src/types/api/index.ts import * as RPCSPEC09 from "@starknet-io/starknet-types-09"; import * as RPCSPEC010 from "@starknet-io/starknet-types-010"; import { PAYMASTER_API } from "@starknet-io/starknet-types-010"; // src/types/api/rpc.ts var rpc_exports = {}; __reExport(rpc_exports, starknet_types_010_star); import * as starknet_types_010_star from "@starknet-io/starknet-types-010"; // src/types/api/index.ts __reExport(api_exports, rpc_exports); // src/provider/types/spec.type.ts var { ETransactionVersion } = RPCSPEC09; var { ETransactionVersion2 } = RPCSPEC09; var { ETransactionVersion3 } = RPCSPEC09; var { EDataAvailabilityMode } = RPCSPEC010; var { EDAMode } = RPCSPEC010; function isRPC08Plus_ResourceBounds(entry) { return "l1_data_gas" in entry; } function isRPC08Plus_ResourceBoundsBN(entry) { return "l1_data_gas" in entry; } var { ETransactionStatus } = RPCSPEC010; var { ETransactionExecutionStatus } = RPCSPEC010; var { ETransactionType: TransactionType } = RPCSPEC09; var { EBlockStatus: BlockStatus } = RPCSPEC09; var { ETransactionFinalityStatus: TransactionFinalityStatus } = RPCSPEC09; var { ETransactionExecutionStatus: TransactionExecutionStatus } = RPCSPEC09; var { EBlockTag: BlockTag } = RPCSPEC09; // src/utils/encode.ts var encode_exports = {}; __export(encode_exports, { IS_BROWSER: () => IS_BROWSER, addHexPrefix: () => addHexPrefix, arrayBufferToString: () => arrayBufferToString, atobUniversal: () => atobUniversal, bigIntToUint8Array: () => bigIntToUint8Array, btoaUniversal: () => btoaUniversal, buf2hex: () => buf2hex, calcByteLength: () => calcByteLength, concatenateArrayBuffer: () => concatenateArrayBuffer, hexStringToUint8Array: () => hexStringToUint8Array, padLeft: () => padLeft, pascalToSnake: () => pascalToSnake, removeHexPrefix: () => removeHexPrefix, sanitizeBytes: () => sanitizeBytes, sanitizeHex: () => sanitizeHex, stringToUint8Array: () => stringToUint8Array, uint8ArrayToBigInt: () => uint8ArrayToBigInt, utf8ToArray: () => utf8ToArray, utf8ToBigInt: () => utf8ToBigInt, utf8ToUint8Array: () => utf8ToUint8Array }); import { base64 } from "@scure/base"; var IS_BROWSER = typeof window !== "undefined"; var STRING_ZERO = "0"; function arrayBufferToString(array) { return new Uint8Array(array).reduce((data, byte) => data + String.fromCharCode(byte), ""); } function utf8ToUint8Array(str) { return new TextEncoder().encode(str); } var utf8ToArray = utf8ToUint8Array; function utf8ToBigInt(str) { return uint8ArrayToBigInt(utf8ToUint8Array(str)); } function atobUniversal(a) { return base64.decode(a); } function btoaUniversal(b) { return base64.encode(new Uint8Array(b)); } function buf2hex(buffer) { return buffer.reduce((r, x) => r + x.toString(16).padStart(2, "0"), ""); } function removeHexPrefix(hex) { return hex.startsWith("0x") || hex.startsWith("0X") ? hex.slice(2) : hex; } function addHexPrefix(hex) { return `0x${removeHexPrefix(hex)}`; } function padString(str, length, left, padding = STRING_ZERO) { const diff = length - str.length; let result = str; if (diff > 0) { const pad = padding.repeat(diff); result = left ? pad + str : str + pad; } return result; } function padLeft(str, length, padding = STRING_ZERO) { return padString(str, length, true, padding); } function calcByteLength(str, byteSize = 8) { const { length } = str; const remainder = length % byteSize; return remainder ? (length - remainder) / byteSize * byteSize + byteSize : length; } function sanitizeBytes(str, byteSize = 8, padding = STRING_ZERO) { return padLeft(str, calcByteLength(str, byteSize), padding); } function sanitizeHex(hex) { const hexWithoutPrefix = removeHexPrefix(hex); const sanitizedHex = sanitizeBytes(hexWithoutPrefix, 2); return sanitizedHex ? addHexPrefix(sanitizedHex) : sanitizedHex; } var pascalToSnake = (text) => /[a-z]/.test(text) ? text.split(/(?=[A-Z])/).join("_").toUpperCase() : text; function concatenateArrayBuffer(uint8arrays) { const totalLength = uint8arrays.reduce((total, uint8array) => total + uint8array.byteLength, 0); const result = new Uint8Array(totalLength); let offset = 0; uint8arrays.forEach((uint8array) => { result.set(uint8array, offset); offset += uint8array.byteLength; }); return result; } function hexStringToUint8Array(hex) { if (!isHexString(addHexPrefix(hex))) { throw new Error(`Invalid hex string: "${hex}"`); } const paddedHex = removeHexPrefix(sanitizeHex(hex)); const bytes = new Uint8Array(paddedHex.length / 2); for (let i = 0; i < paddedHex.length; i += 2) { bytes[i / 2] = parseInt(paddedHex.substring(i, i + 2), 16); } return bytes; } function isHexString(hex) { return /^0[xX][0-9a-fA-F]*$/.test(hex); } function isDecimalString(str) { return /^[0-9]+$/.test(str); } function stringToUint8Array(str) { if (isHexString(str)) { return hexStringToUint8Array(str); } if (isDecimalString(str)) { const value = BigInt(str); return bigIntToUint8Array(value); } return utf8ToUint8Array(str); } function bigIntToUint8Array(value) { if (value < 0n) { throw new Error(`Cannot convert negative bigint ${value} to Uint8Array`); } if (value === 0n) { return new Uint8Array([0]); } let hex = value.toString(16); if (hex.length % 2 !== 0) { hex = `0${hex}`; } const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16); } return bytes; } function uint8ArrayToBigInt(data) { if (!data || data.length === 0) { return 0n; } let hex = "0x"; for (let i = 0; i < data.length; i += 1) { hex += data[i].toString(16).padStart(2, "0"); } return BigInt(hex); } // src/global/constants.ts var TEXT_TO_FELT_MAX_LEN = 31; var ZERO = 0n; var MASK_250 = 2n ** 250n - 1n; var MASK_31 = 2n ** 31n - 1n; var API_VERSION = ZERO; var PRIME = 2n ** 251n + 17n * 2n ** 192n + 1n; var MAX_STORAGE_ITEM_SIZE = 256n; var ADDR_BOUND = 2n ** 251n - MAX_STORAGE_ITEM_SIZE; var range = (min, max) => ({ min, max }); var RANGE_FELT = range(ZERO, PRIME - 1n); var RANGE_U8 = range(ZERO, 2n ** 8n - 1n); var RANGE_U16 = range(ZERO, 2n ** 16n - 1n); var RANGE_U32 = range(ZERO, 2n ** 32n - 1n); var RANGE_U64 = range(ZERO, 2n ** 64n - 1n); var RANGE_U96 = range(ZERO, 2n ** 96n - 1n); var RANGE_U128 = range(ZERO, 2n ** 128n - 1n); var RANGE_I8 = range(-(2n ** 7n), 2n ** 7n - 1n); var RANGE_I16 = range(-(2n ** 15n), 2n ** 15n - 1n); var RANGE_I32 = range(-(2n ** 31n), 2n ** 31n - 1n); var RANGE_I64 = range(-(2n ** 63n), 2n ** 63n - 1n); var RANGE_I128 = range(-(2n ** 127n), 2n ** 127n - 1n); var LegacyUDC = { ADDRESS: "0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", ENTRYPOINT: "deployContract" }; var UDC = { ADDRESS: "0x02ceed65a4bd731034c01113685c831b01c15d7d432f71afb1cf1634b53a2125", ENTRYPOINT: "deploy_contract" }; var OutsideExecutionCallerAny = "0x414e595f43414c4c4552"; var SNIP9_V1_INTERFACE_ID = "0x68cfd18b92d1907b8ba3cc324900277f5a3622099431ea85dd8089255e4181"; var SNIP9_V2_INTERFACE_ID = "0x1d1144bb2138366ff28d8e9ab57456b1d332ac42196230c3a602003c89872"; var HARDENING_BYTE = 128; var HARDENING_4BYTES = 2147483648n; var _BaseUrl = { SN_MAIN: "https://alpha-mainnet.starknet.io", SN_SEPOLIA: "https://alpha-sepolia.starknet.io" }; var _NetworkName = { SN_MAIN: "SN_MAIN", SN_SEPOLIA: "SN_SEPOLIA" }; var _StarknetChainId = { SN_MAIN: "0x534e5f4d41494e", // encodeShortString('SN_MAIN'), SN_SEPOLIA: "0x534e5f5345504f4c4941" // encodeShortString('SN_SEPOLIA') }; var _TransactionHashPrefix = { DECLARE: "0x6465636c617265", // encodeShortString('declare'), DEPLOY: "0x6465706c6f79", // encodeShortString('deploy'), DEPLOY_ACCOUNT: "0x6465706c6f795f6163636f756e74", // encodeShortString('deploy_account'), INVOKE: "0x696e766f6b65", // encodeShortString('invoke'), L1_HANDLER: "0x6c315f68616e646c6572" // encodeShortString('l1_handler'), }; var _SupportedRpcVersion = { "0.9.0": "0.9.0", "0.10.0": "0.10.0", v0_9_0: "0.9.0", v0_10_0: "0.10.0" }; var DEFAULT_GLOBAL_CONFIG = { rpcVersion: "0.10.0", transactionVersion: api_exports.ETransactionVersion.V3, // Starknet 0.14.0 only V3 transactions logLevel: "INFO", resourceBoundsOverhead: { l1_gas: { max_amount: 50, max_price_per_unit: 50 }, l1_data_gas: { max_amount: 50, max_price_per_unit: 50 }, l2_gas: { max_amount: 50, max_price_per_unit: 50 } }, defaultTipType: "recommendedTip", channelDefaults: { options: { headers: { "Content-Type": "application/json" }, blockIdentifier: BlockTag.LATEST, retries: 200 }, methods: { simulateTransaction: { skipValidate: true, skipFeeCharge: true }, getEstimateFee: { skipValidate: true } } }, fetch: void 0, websocket: void 0, buffer: void 0, blake: void 0 }; var RPC_DEFAULT_NODES = { SN_MAIN: [`https://api.zan.top/public/starknet-mainnet/rpc/`], SN_SEPOLIA: [`https://api.zan.top/public/starknet-sepolia/rpc/`] }; var PAYMASTER_RPC_NODES = { SN_MAIN: [`https://starknet.paymaster.avnu.fi`], SN_SEPOLIA: [`https://sepolia.paymaster.avnu.fi`] }; var SYSTEM_MESSAGES = { legacyTxWarningMessage: "You are using a deprecated transaction version (V0,V1,V2)!\nUpdate to the latest V3 transactions!", legacyTxRPC08Message: "RPC 0.8+ do not support legacy transactions, use RPC 0.8+ v3 transactions!", SWOldV3: "RPC 0.7 V3 tx (improper resource bounds) not supported in RPC 0.8+", channelVersionMismatch: "Channel specification version is not compatible with the connected node Specification Version", unsupportedSpecVersion: "The connected node specification version is not supported by this library", maxFeeInV3: "maxFee is not supported in V3 transactions, use resourceBounds instead", declareNonSierra: "Declaring non Sierra (Cairo0)contract using RPC 0.8+", unsupportedMethodForRpcVersion: "Unsupported method for RPC version", txEvictedFromMempool: "Transaction TTL, evicted from the mempool, try to increase the tip", consensusFailed: "Consensus failed to finalize the block proposal", txFailsBlockBuildingValidation: "Transaction fails block building validation" }; var SN_VERSION_IMPLEMENTING_BLAKE_FOR_COMPILED_CLASS = "0.14.1"; // src/global/config.ts var Configuration = class _Configuration { static instance; config; constructor() { this.initialize(); } initialize() { this.config = { ...DEFAULT_GLOBAL_CONFIG }; } static getInstance() { if (!_Configuration.instance) { _Configuration.instance = new _Configuration(); } return _Configuration.instance; } /** * Get a nested value from an object using a dot-notation path * @param obj - The object to traverse * @param path - The dot-notation path (e.g., 'a.b.c') * @returns The value at the path, or undefined if not found */ getNestedValue(obj, path) { const keys = path.split("."); return keys.reduce((current, key) => { if (current === null || current === void 0) { return void 0; } return current[key]; }, obj); } /** * Set a nested value in an object using a dot-notation path * @param obj - The object to modify * @param path - The dot-notation path (e.g., 'a.b.c') * @param value - The value to set */ setNestedValue(obj, path, value) { const keys = path.split("."); const lastKey = keys.pop(); const target = keys.reduce((current, key) => { if (!(key in current) || typeof current[key] !== "object" || current[key] === null) { current[key] = {}; } return current[key]; }, obj); target[lastKey] = value; } get(key, defaultValue) { if (key.includes(".")) { const value = this.getNestedValue(this.config, key); return value ?? defaultValue; } return this.config[key] ?? defaultValue; } set(key, value) { if (key.includes(".")) { this.setNestedValue(this.config, key, value); } else { this.config[key] = value; } } update(configData) { this.config = { ...this.config, ...configData }; } getAll() { return { ...this.config }; } reset() { this.initialize(); } delete(key) { delete this.config[key]; } hasKey(key) { return key in this.config; } }; var config = Configuration.getInstance(); // src/global/logger.type.ts var LogLevelIndex = { DEBUG: 5, INFO: 4, WARN: 3, ERROR: 2, FATAL: 1, OFF: 0 }; // src/global/logger.ts var Logger = class _Logger { static instance; config; constructor() { this.config = config; } static getInstance() { if (!_Logger.instance) { _Logger.instance = new _Logger(); } return _Logger.instance; } getTimestamp() { return (/* @__PURE__ */ new Date()).toISOString(); } shouldLog(messageLevel) { const configLevel = this.config.get("logLevel", "INFO"); return messageLevel <= LogLevelIndex[configLevel]; } formatMessage(logMessage) { const { level, message, timestamp, data } = logMessage; let formattedMessage = `[${timestamp}] ${level}: ${message}`; if (data) { try { formattedMessage += ` ${JSON.stringify(data, null, 2)}`; } catch (error) { formattedMessage += ` [JSON.stringify Error/Circular]: ${error}`; } } return formattedMessage; } log(level, message, data) { if (!this.shouldLog(LogLevelIndex[level])) { return; } const logMessage = { level, message, timestamp: this.getTimestamp(), data }; const formattedMessage = this.formatMessage(logMessage); switch (level) { case "DEBUG": console.debug(formattedMessage); break; case "INFO": console.info(formattedMessage); break; case "WARN": console.warn(formattedMessage); break; case "ERROR": case "FATAL": console.error(formattedMessage); break; case "OFF": break; default: console.log(formattedMessage); break; } } /** * debug will be displayed when LogLevel level is set to DEBUG(5) */ debug(message, data) { this.log("DEBUG", message, data); } /** * info will be displayed when LogLevel level is set to DEBUG(5), INFO(4) */ info(message, data) { this.log("INFO", message, data); } /** * warn will be displayed when LogLevel level is set to DEBUG(5), INFO(4), WARN(3) */ warn(message, data) { this.log("WARN", message, data); } /** * error will be displayed when LogLevel level is set to DEBUG(5), INFO(4), WARN(3), ERROR(2) */ error(message, data) { this.log("ERROR", message, data); } /** * fatal will be displayed when LogLevel level is set to DEBUG(5), INFO(4), WARN(3), ERROR(2), FATAL(1) */ fatal(message, data) { this.log("FATAL", message, data); } /** * Set the logging level you would like system to display * * 5 DEBUG - show all logs * * 4 INFO * * 3 WARN * * 2 ERROR * * 1 FATAL * * 0 OFF - disable logs */ setLogLevel(level) { this.config.set("logLevel", level); } getLogLevel() { return this.config.get("logLevel", "INFO"); } /** * * @returns logs levels displayed on the configured LogLevel */ getEnabledLogLevels() { return Object.keys(LogLevelIndex).filter((s) => { return this.shouldLog(LogLevelIndex[s]) && s !== "OFF"; }); } }; var logger = Logger.getInstance(); // src/channel/rpc_0_9_0.ts var rpc_0_9_0_exports = {}; __export(rpc_0_9_0_exports, { RpcChannel: () => RpcChannel }); // src/types/lib/contract/index.ts var EntryPointType = { EXTERNAL: "EXTERNAL", L1_HANDLER: "L1_HANDLER", CONSTRUCTOR: "CONSTRUCTOR" }; // src/types/calldata.ts var ValidateType = { DEPLOY: "DEPLOY", CALL: "CALL", INVOKE: "INVOKE" }; var Uint = { u8: "core::integer::u8", u16: "core::integer::u16", u32: "core::integer::u32", u64: "core::integer::u64", u96: "core::integer::u96", u128: "core::integer::u128", u256: "core::integer::u256", // This one is struct u512: "core::integer::u512" // This one is struct }; var Int = { i8: "core::integer::i8", i16: "core::integer::i16", i32: "core::integer::i32", i64: "core::integer::i64", i128: "core::integer::i128" }; var Literal = { ClassHash: "core::starknet::class_hash::ClassHash", ContractAddress: "core::starknet::contract_address::ContractAddress", Secp256k1Point: "core::starknet::secp256k1::Secp256k1Point", U96: "core::internal::bounded_int::BoundedInt::<0, 79228162514264337593543950335>" }; var ETH_ADDRESS = "core::starknet::eth_address::EthAddress"; var NON_ZERO_PREFIX = "core::zeroable::NonZero::"; // src/contract/types/index.type.ts function isAccount(providerOrAccount) { return "execute" in providerOrAccount; } // src/types/outsideExecution.ts var OutsideExecutionTypesV1 = { StarkNetDomain: [ { name: "name", type: "felt" }, { name: "version", type: "felt" }, { name: "chainId", type: "felt" } ], OutsideExecution: [ { name: "caller", type: "felt" }, { name: "nonce", type: "felt" }, { name: "execute_after", type: "felt" }, { name: "execute_before", type: "felt" }, { name: "calls_len", type: "felt" }, { name: "calls", type: "OutsideCall*" } ], OutsideCall: [ { name: "to", type: "felt" }, { name: "selector", type: "felt" }, { name: "calldata_len", type: "felt" }, { name: "calldata", type: "felt*" } ] }; var OutsideExecutionTypesV2 = { StarknetDomain: [ // SNIP-12 revision 1 is used, so should be "StarknetDomain", not "StarkNetDomain" { name: "name", type: "shortstring" }, { name: "version", type: "shortstring" }, // set to 2 in v2 { name: "chainId", type: "shortstring" }, { name: "revision", type: "shortstring" } ], OutsideExecution: [ { name: "Caller", type: "ContractAddress" }, { name: "Nonce", type: "felt" }, { name: "Execute After", type: "u128" }, { name: "Execute Before", type: "u128" }, { name: "Calls", type: "Call*" } ], Call: [ { name: "To", type: "ContractAddress" }, { name: "Selector", type: "selector" }, { name: "Calldata", type: "felt*" } ] }; var OutsideExecutionVersion = { UNSUPPORTED: "0", V1: "1", V2: "2" }; // src/utils/assert.ts function assert(condition, message) { if (!condition) { throw new Error(message || "Assertion failure"); } } // src/utils/json.ts var json_exports = {}; __export(json_exports, { parse: () => parse2, parseAlwaysAsBig: () => parseAlwaysAsBig, stringify: () => stringify2 }); import * as json from "lossless-json"; var parseIntAsNumberOrBigInt = (str) => { if (!json.isInteger(str)) return parseFloat(str); const num = parseInt(str, 10); return Number.isSafeInteger(num) ? num : BigInt(str); }; var parse2 = (str) => json.parse(String(str), void 0, parseIntAsNumberOrBigInt); var parseAlwaysAsBig = (str) => json.parse(String(str), void 0, json.parseNumberAndBigInt); var stringify2 = (value, replacer, space, numberStringifiers) => json.stringify(value, replacer, space, numberStringifiers); // src/utils/batch/index.ts var BatchClient = class { nodeUrl; headers; interval; requestId = 0; pendingRequests = {}; batchPromises = {}; delayTimer; delayPromise; delayPromiseResolve; baseFetch; rpcMethods; constructor(options) { this.nodeUrl = options.nodeUrl; this.headers = options.headers; this.interval = options.interval; this.baseFetch = options.baseFetch; this.rpcMethods = options.rpcMethods; } async wait() { if (!this.delayPromise || !this.delayPromiseResolve) { this.delayPromise = new Promise((resolve) => { this.delayPromiseResolve = resolve; }); } if (this.delayTimer) { clearTimeout(this.delayTimer); this.delayTimer = void 0; } this.delayTimer = setTimeout(() => { if (this.delayPromiseResolve) { this.delayPromiseResolve(); this.delayPromise = void 0; this.delayPromiseResolve = void 0; } }, this.interval); return this.delayPromise; } addPendingRequest(method, params, id) { const request = { id: id ?? `batched_${this.requestId += 1}`, jsonrpc: "2.0", method: method.description || String(method), params: params ?? void 0 }; this.pendingRequests[request.id] = request; return request.id; } async sendBatch(requests) { const raw = await this.baseFetch(this.nodeUrl, { method: "POST", body: stringify2(requests), headers: this.headers }); return raw.json(); } /** * Automatically batches and fetches JSON-RPC calls in a single request. * @param method Method to call * @param params Method parameters * @param id JSON-RPC Request ID * @returns JSON-RPC Response */ async fetch(method, params, id) { const requestId = this.addPendingRequest(method, params, id); await this.wait(); const requests = this.pendingRequests; this.pendingRequests = {}; if (!this.batchPromises[requestId]) { const promise = this.sendBatch(Object.values(requests)); Object.keys(requests).forEach((key) => { this.batchPromises[key] = promise; }); } const results = await this.batchPromises[requestId]; delete this.batchPromises[requestId]; const result = results.find((res) => res.id === requestId); if (!result) throw new Error(`Couldn't find the result for the request. Method: ${String(method)}`); return result; } }; // src/utils/num.ts var num_exports = {}; __export(num_exports, { addPercent: () => addPercent, assertInRange: () => assertInRange, bigNumberishArrayToDecimalStringArray: () => bigNumberishArrayToDecimalStringArray, bigNumberishArrayToHexadecimalStringArray: () => bigNumberishArrayToHexadecimalStringArray, cleanHex: () => cleanHex, getDecimalString: () => getDecimalString, getHexString: () => getHexString, getHexStringArray: () => getHexStringArray, getNext: () => getNext, hexToBytes: () => hexToBytes, hexToDecimalString: () => hexToDecimalString, isBigNumberish: () => isBigNumberish, isHex: () => isHex, isHexString: () => isHexString2, isStringWholeNumber: () => isStringWholeNumber, stringToSha256ToArrayBuff4: () => stringToSha256ToArrayBuff4, toBigInt: () => toBigInt, toCairoBool: () => toCairoBool, toHex: () => toHex, toHex64: () => toHex64, toHexString: () => toHexString, toStorageKey: () => toStorageKey, tryToBigInt: () => tryToBigInt }); import { hexToBytes as hexToBytesNoble } from "@noble/curves/abstract/utils"; import { sha256 } from "@noble/hashes/sha256"; // src/utils/typed.ts var isUndefined = (value) => { return typeof value === "undefined" || value === void 0; }; function isNumber(value) { return typeof value === "number"; } function isBoolean(value) { return typeof value === "boolean"; } function isBigInt(value) { return typeof value === "bigint"; } function isString(value) { return typeof value === "string"; } function isBuffer(obj) { return typeof Buffer !== "undefined" && obj instanceof Buffer; } function isObject(item) { return !!item && typeof item === "object" && !Array.isArray(item); } function isInteger2(value) { return Number.isInteger(value); } // src/utils/num.ts function isHex(hex) { return /^0[xX][0-9a-fA-F]*$/.test(hex); } var isHexString2 = isHex; function toBigInt(value) { return BigInt(value); } function tryToBigInt(value) { return value ? BigInt(value) : void 0; } function toHex(value) { return addHexPrefix(toBigInt(value).toString(16)); } var toHexString = toHex; function cleanHex(hex) { return toHex(hex); } function toStorageKey(number) { return addHexPrefix(toBigInt(number).toString(16).padStart(64, "0")); } function toHex64(number) { const res = addHexPrefix(toBigInt(number).toString(16).padStart(64, "0")); if (res.length !== 66) throw TypeError("number is too big for hex 0x(64) representation"); return res; } function hexToDecimalString(hex) { return BigInt(addHexPrefix(hex)).toString(10); } function assertInRange(input, lowerBound, upperBound, inputName = "") { const messageSuffix = inputName === "" ? "invalid length" : `invalid ${inputName} length`; const inputBigInt = BigInt(input); const lowerBoundBigInt = BigInt(lowerBound); const upperBoundBigInt = BigInt(upperBound); assert( inputBigInt >= lowerBoundBigInt && inputBigInt <= upperBoundBigInt, `Message not signable, ${messageSuffix}.` ); } function bigNumberishArrayToDecimalStringArray(data) { return data.map((x) => toBigInt(x).toString(10)); } function bigNumberishArrayToHexadecimalStringArray(data) { return data.map((x) => toHex(x)); } function isStringWholeNumber(str) { return /^\d+$/.test(str); } function getDecimalString(str) { if (isHex(str)) { return hexToDecimalString(str); } if (isStringWholeNumber(str)) { return str; } throw new Error(`${str} needs to be a hex-string or whole-number-string`); } function getHexString(str) { if (isHex(str)) { return str; } if (isStringWholeNumber(str)) { return toHexString(str); } throw new Error(`${str} needs to be a hex-string or whole-number-string`); } function getHexStringArray(array) { return array.map(getHexString); } function toCairoBool(value) { return (+value).toString(); } function hexToBytes(str) { if (!isHex(str)) throw new Error(`${str} needs to be a hex-string`); let adaptedValue = removeHexPrefix(str); if (adaptedValue.length % 2 !== 0) { adaptedValue = `0${adaptedValue}`; } return hexToBytesNoble(adaptedValue); } function addPercent(number, percent) { const bigIntNum = BigInt(number); return bigIntNum + bigIntNum * BigInt(percent) / 100n; } function stringToSha256ToArrayBuff4(str) { const int31 = (n) => Number(n & MASK_31); const result = int31(BigInt(addHexPrefix(buf2hex(sha256(str))))); return hexToBytes(toHex(result)); } function isBigNumberish(input) { return isNumber(input) || isBigInt(input) || isString(input) && (isHex(input) || isStringWholeNumber(input)); } function getNext(iterator) { const it = iterator.next(); if (it.done) throw new Error("Unexpected end of response"); return it.value; } // src/utils/hash/selector.ts var selector_exports = {}; __export(selector_exports, { getL1MessageHash: () => getL1MessageHash, getL2MessageHash: () => getL2MessageHash, getSelector: () => getSelector, getSelectorFromName: () => getSelectorFromName, keccakBn: () => keccakBn, solidityUint256PackedKeccak256: () => solidityUint256PackedKeccak256, starknetKeccak: () => starknetKeccak }); import { keccak } from "@scure/starknet"; import { keccak_256 } from "@noble/hashes/sha3"; import { bytesToHex } from "@noble/curves/abstract/utils"; function keccakBn(value) { const hexWithoutPrefix = removeHexPrefix(toHex(BigInt(value))); const evenHex = hexWithoutPrefix.length % 2 === 0 ? hexWithoutPrefix : `0${hexWithoutPrefix}`; return addHexPrefix(keccak(hexToBytes(addHexPrefix(evenHex))).toString(16)); } function keccakHex(str) { return addHexPrefix(keccak(utf8ToArray(str)).toString(16)); } function starknetKeccak(str) { const hash = BigInt(keccakHex(str)); return hash & MASK_250; } function getSelectorFromName(funcName) { return toHex(starknetKeccak(funcName)); } function getSelector(value) { if (isNumber(value) || isBigInt(value)) return toHex(value); if (isHex(value)) return value; if (isStringWholeNumber(value)) return toHex(value); return getSelectorFromName(value); } function solidityUint256PackedKeccak256(params) { const myEncode = addHexPrefix( params.reduce( (res, par) => res + removeHexPrefix(toHex(par)).padStart(64, "0"), "" ) ); return addHexPrefix(bytesToHex(keccak_256(hexToBytes(myEncode)))); } function getL2MessageHash(l1FromAddress, l2ToAddress, l2Selector, l2Calldata, l1Nonce) { return solidityUint256PackedKeccak256([ l1FromAddress, l2ToAddress, l1Nonce, l2Selector, l2Calldata.length, ...l2Calldata ]); } function getL1MessageHash(fromL2Address, toL1Address, payload) { return solidityUint256PackedKeccak256([fromL2Address, toL1Address, payload.length, ...payload]); } // src/utils/shortString.ts var shortString_exports = {}; __export(shortString_exports, { decodeShortString: () => decodeShortString, encodeShortString: () => encodeShortString, isASCII: () => isASCII, isDecimalString: () => isDecimalString2, isLongText: () => isLongText, isShortString: () => isShortString, isShortText: () => isShortText, isText: () => isText, splitLongString: () => splitLongString }); function isASCII(str) { return /^[\x00-\x7F]*$/.test(str); } function isShortString(str) { return str.length <= TEXT_TO_FELT_MAX_LEN; } function isDecimalString2(str) { return /^[0-9]*$/i.test(str); } function isText(val) { return isString(val) && !isHex(val) && !isStringWholeNumber(val); } var isShortText = (val) => isText(val) && isShortString(val); var isLongText = (val) => isText(val) && !isShortString(val); function splitLongString(longStr) { const regex = RegExp(`[^]{1,${TEXT_TO_FELT_MAX_LEN}}`, "g"); return longStr.match(regex) || []; } function encodeShortString(str) { if (!isASCII(str)) throw new Error(`${str} is not an ASCII string`); if (!isShortString(str)) throw new Error(`${str} is too long`); return addHexPrefix(str.replace(/./g, (char) => char.charCodeAt(0).toString(16))); } function decodeShortString(str) { if (!isASCII(str)) throw new Error(`${str} is not an ASCII string`); if (isHex(str)) { return removeHexPrefix(str).replace(/.{2}/g, (hex) => String.fromCharCode(parseInt(hex, 16))); } if (isDecimalString2(str)) { return decodeShortString("0X".concat(BigInt(str).toString(16))); } throw new Error(`${str} is not Hex or decimal`); } // src/utils/calldata/byteArray.ts var byteArray_exports = {}; __export(byteArray_exports, { byteArrayFromString: () => byteArrayFromString, stringFromByteArray: () => stringFromByteArray }); function stringFromByteArray(myByteArray) { const pending_word = BigInt(myByteArray.pending_word) === 0n ? "" : decodeShortString(toHex(myByteArray.pending_word)); return myByteArray.data.reduce((cumuledString, encodedString) => { const add = BigInt(encodedString) === 0n ? "" : decodeShortString(toHex(encodedString)); return cumuledString + add; }, "") + pending_word; } function byteArrayFromString(targetString) { const shortStrings = splitLongString(targetString); const remainder = shortStrings[shortStrings.length - 1]; const shortStringsEncoded = shortStrings.map(encodeShortString); const [pendingWord, pendingWordLength] = remainder === void 0 || remainder.length === 31 ? ["0x00", 0] : [shortStringsEncoded.pop(), remainder.length]; return { data: shortStringsEncoded.length === 0 ? [] : shortStringsEncoded, pending_word: pendingWord, pending_word_len: pendingWordLength }; } // src/utils/calldata/cairo.ts var cairo_exports = {}; __export(cairo_exports, { felt: () => felt, getAbiContractVersion: () => getAbiContractVersion, getArrayType: () => getArrayType, isCairo1Abi: () => isCairo1Abi, isCairo1Type: () => isCairo1Type, isLen: () => isLen, isTypeArray: () => isTypeArray, isTypeBool: () => isTypeBool, isTypeContractAddress: () => isTypeContractAddress, isTypeEnum: () => isTypeEnum, isTypeEthAddress: () => isTypeEthAddress, isTypeFelt: () => isTypeFelt, isTypeInt: () => isTypeInt, isTypeLiteral: () => isTypeLiteral, isTypeNamedTuple: () => isTypeNamedTuple, isTypeNonZero: () => isTypeNonZero, isTypeOption: () => isTypeOption, isTypeResult: () => isTypeResult, isTypeSecp256k1Point: () => isTypeSecp256k1Point, isTypeStruct: () => isTypeStruct, isTypeTuple: () => isTypeTuple, isTypeU96: () => isTypeU96, isTypeUint: () => isTypeUint, isTypeUint256: () => isTypeUint256, tuple: () => tuple, uint256: () => uint256, uint512: () => uint512 }); // src/utils/helpers.ts function addCompiledFlag(compiled) { Object.defineProperty(compiled, "__compiled__", { enumerable: false, writable: false, value: true }); return compiled; } // src/utils/cairoDataTypes/felt.ts function CairoFelt(it) { if (isBigInt(it) || Number.isInteger(it)) { return it.toString(); } if (isString(it)) { if (isHex(it)) { return BigInt(it).toString(); } if (isText(it)) { if (!isShortString(it)) { throw new Error( `${it} is a long string > 31 chars. Please split it into an array of short strings.` ); } return BigInt(encodeShortString(it)).toString(); } if (isStringWholeNumber(it)) { return it; } } if (isBoolean(it)) { return `${+it}`; } throw new Error(`${it} can't be computed by felt()`); } var CairoFelt252 = class _CairoFelt252 { /** * byte representation of the felt252 */ data; static abiSelector = "core::felt252"; constructor(data) { _CairoFelt252.validate(data); const processedData = _CairoFelt252.__processData(data); this.data = processedData.subarray(processedData.findIndex((x) => x > 0)); } static __processData(data) { if (isString(data)) { return stringToUint8Array(data); } if (isBigInt(data)) { return bigIntToUint8Array(data); } if (Number.isInteger(data)) { return bigIntToUint8Array(BigInt(data)); } if (isBoolean(data)) { return bigIntToUint8Array(BigInt(data ? 1 : 0)); } throw new Error(`${data} can't be computed by felt()`); } toBigInt() { return uint8ArrayToBigInt(this.data); } decodeUtf8() { return new TextDecoder().decode(this.data); } toHexString() { return addHexPrefix(this.toBigInt().toString(16)); } toApiRequest() { return addCompiledFlag([this.toHexString()]); } static validate(data) { assert(data !== null, "null value is not allowed for felt252"); assert(data !== void 0, "undefined value is not allowed for felt252"); assert( isString(data) || isNumber(data) || isBigInt(data) || isBoolean(data), `Unsupported data type '${typeof data}' for felt252. Expected string, number, bigint, or boolean` ); const value = _CairoFelt252.__processData(data); const bn = uint8ArrayToBigInt(value); assert(bn >= 0n && bn < PRIME, `Value ${value} is out of felt252 range [0, ${PRIME})`); } static is(data) { try { _CairoFelt252.validate(data); return true; } catch { return false; } } static isAbiType(abiType) { return abiType === _CairoFelt252.abiSelector; } static factoryFromApiResponse(responseIterator) { return new _CairoFelt252(getNext(responseIterator)); } }; // src/utils/cairoDataTypes/uint256.ts var UINT_128_MAX = (1n << 128n) - 1n; var UINT_256_MAX = (1n << 256n) - 1n; var UINT_256_MIN = 0n; var UINT_256_LOW_MAX = 340282366920938463463374607431768211455n; var UINT_256_HIGH_MAX = 340282366920938463463374607431768211455n; var UINT_256_LOW_MIN = 0n; var UINT_256_HIGH_MIN = 0n; var CairoUint256 = class _CairoUint256 { low; // TODO should be u128 high; // TODO should be u128 static abiSelector = "core::integer::u256"; constructor(...arr) { if (isObject(arr[0]) && arr.length === 1 && "low" in arr[0] && "high" in arr[0]) { const props = _CairoUint256.validateProps( arr[0].low, arr[0].high ); this.low = props.low; this.high = props.high; } else if (arr.length === 1) { const bigInt = _CairoUint256.validate(arr[0]); this.low = bigInt & UINT_128_MAX; this.high = bigInt >> 128n; } else if (arr.length === 2) { const props = _CairoUint256.validateProps(arr[0], arr[1]); this.low = props.low; this.high = props.high; } else { throw Error("Incorrect constructor parameters"); } } /** * Validate if BigNumberish can be represented as Unit256 */ static validate(bigNumberish) { assert(bigNumberish !== null, "null value is not allowed for u256"); assert(bigNumberish !== void 0, "undefined value is not allowed for u256"); assert( isBigNumberish(bigNumberish) || isObject(bigNumberish), `Unsupported data type '${typeof bigNumberish}' for u256. Expected string, number, bigint, or Uint256 object` ); const bigInt = BigInt(bigNumberish); assert(bigInt >= UINT_256_MIN, "bigNumberish is smaller than UINT_256_MIN"); assert(bigInt <= UINT_256_MAX, "bigNumberish is bigger than UINT_256_MAX"); return bigInt; } /** * Validate if low and high can be represented as Unit256 */ static validateProps(low, high) { const bigIntLow = BigInt(low); const bigIntHigh = BigInt(high); assert( bigIntLow >= UINT_256_LOW_MIN && bigIntLow <= UINT_256_LOW_MAX, "low is out of range UINT_256_LOW_MIN - UINT_256_LOW_MAX" ); assert( bigIntHigh >= UINT_256_HIGH_MIN && bigIntHigh <= UINT_256_HIGH_MAX, "high is out of range UINT_256_HIGH_MIN - UINT_256_HIGH_MAX" ); return { low: bigIntLow, high: bigIntHigh }; } /** * Check if BigNumberish can be represented as Unit256 */ static is(bigNumberish) { try { _CairoUint256.validate(bigNumberish); } catch (error) { return false; } return true; } /** * Check if provided abi type is this data type */ static isAbiType(abiType) { return abiType === _CairoUint256.abiSelector; } static factoryFromApiResponse(responseIterator) { const low = getNext(responseIterator); const high = getNext(responseIterator); return new _CairoUint256(low, high); } /** * Return bigint representation */ toBigInt() { return (this.high << 128n) + this.low; } /** * Return Uint256 structure with HexString props * {low: HexString, high: HexString} */ toUint256HexString() { return { low: addHexPrefix(this.low.toString(16)), high: addHexPrefix(this.high.toString(16)) }; } /** * Return Uint256 structure with DecimalString props * {low: DecString, high: DecString} */ toUint256DecimalString() { return { low: this.low.toString(10), high: this.high.toString(10) }; } /** * Return api requests representation witch is felt array */ toApiRequest() { return [CairoFelt(this.low), CairoFelt(this.high)]; } }; // src/utils/cairoDataTypes/uint512.ts var UINT_512_MAX = (1n << 512n) - 1n; var UINT_512_MIN = 0n; var UINT_128_MIN = 0n; var CairoUint512 = class _CairoUint512 { limb0; // TODO should be u128 limb1; // TODO should be u128 limb2; // TODO should be u128 limb3; // TODO should be u128 static abiSelector = "core::integer::u512"; constructor(...arr) { if (isObject(arr[0]) && arr.length === 1 && "limb0" in arr[0] && "limb1" in arr[0] && "limb2" in arr[0] && "limb3" in arr[0]) { const props = _CairoUint512.validateProps( arr[0].limb0, arr[0].limb1, arr[0].limb2, arr[0].limb3 ); this.limb0 = props.limb0; this.limb1 = props.limb1; this.limb2 = props.limb2; this.limb3 = props.limb3; } else if (arr.length === 1) { const bigInt = _CairoUint512.validate(arr[0]); this.limb0 = bigInt & UINT_128_MAX; this.limb1 = (bigInt & UINT_128_MAX << 128n) >> 128n; this.limb2 = (bigInt & UINT_128_MAX << 256n) >> 256n; this.limb3 = bigInt >> 384n; } else if (arr.length === 4) { const props = _CairoUint512.validateProps(arr[0], arr[1], arr[2], arr[3]); this.limb0 = props.limb0; this.limb1 = props.limb1; this.limb2 = props.limb2; this.limb3 = props.limb3; } else { throw Error("Incorrect Uint512 constructor parameters"); } } /** * Validate if BigNumberish can be represented as Uint512 */ static validate(bigNumberish) { assert(bigNumberish !== null, "null value is not allowed for u512"); assert(bigNumberish !== void 0, "undefined value is not allowed for u512"); assert( isBigNumberish(bigNumberish) || isObject(bigNumberish), `Unsupported data type '${typeof bigNumberish}' for u512. Expected string, number, bigint, or Uint512 object` ); const bigInt = BigInt(bigNumberish); assert(bigInt >= UINT_512_MIN, "bigNumberish is smaller than UINT_512_MIN."); assert(bigInt <= UINT_512_MAX, "bigNumberish is bigger than UINT_512_MAX."); return bigInt; } /** * Validate if limbs can be represented as Uint512 */ static validateProps(limb0, limb1, limb2, limb3) { const l0 = BigInt(limb0); const l1 = BigInt(limb1); const l2 = BigInt(limb2); const l3 = BigInt(limb3); [l0, l1, l2, l3].forEach((value, index) => { assert( value >= UINT_128_MIN && value <= UINT_128_MAX, `limb${index} is not in the range of a u128 number` ); }); return { limb0: l0, limb1: l1, limb2: l2, limb3: l3 }; } /** * Check if BigNumberish can be represented as Uint512 */ static is(bigNumberish) { try { _CairoUint512.validate(bigNumberish); } catch (error) { return false; } return true; } /** * Check if provided abi type is this data type */ static isAbiType(abiType) { return abiType === _CairoUint512.abiSelector; } static factoryFromApiResponse(responseIterator) { const limb0 = getNext(responseIterator); const limb1 = getNext(responseIterator); const limb2 = getNext(responseIterator); const limb3 = getNext(responseIterator); return new _CairoUint512(limb0, limb1, limb2, limb3); } /** * Return bigint representation */ toBigInt() { return (this.limb3 << 384n) + (this.limb2 << 256n) + (this.limb1 << 128n) + this.limb0; } /** * Return Uint512 structure with HexString props * limbx: HexString */ toUint512HexString() { return { limb0: addHexPrefix(this.limb0.toString(16)), limb1: addHexPrefix(this.limb1.toString(16)), limb2: addHexPrefix(this.limb2.toString(16)), limb3: addHexPrefix(this.limb3.toString(16)) }; } /** * Return Uint512 structure with DecimalString props * limbx DecString */ toUint512DecimalString() { return { limb0: this.limb0.toString(10), limb1: this.limb1.toString(10), limb2: this.limb2.toString(10), limb3: this.limb3.toString(10) }; } /** * Return api requests representation witch is felt array */ toApiRequest() { return [ CairoFelt(this.limb0), CairoFelt(this.limb1), CairoFelt(this.limb2), CairoFelt(this.limb3) ]; } }; // src/utils/calldata/cairo.ts var isLen = (name) => /_len$/.test(name); var isTypeFelt = (type) => type === "felt" || type === "core::felt252"; var isTypeArray = (type) => /\*/.test(type) || type.startsWith("core::array::Array::") || type.startsWith("core::array::Span::"); var isTypeTuple = (type) => /^\(.*\)$/i.test(type); var isTypeNamedTuple = (type) => /\(.*\)/i.test(type) && type.includes(":"); var isTypeStruct = (type, structs) => type in structs; var isTypeEnum = (type, enums) => type in enums; var isTypeOption = (type) => type.startsWith("core::option::Option::"); var isTypeResult = (type) => type.startsWith("core::result::Result::"); var isTypeUint = (type) => Object.values(Uint).includes(type); var isTypeInt = (type) => Object.values(Int).includes(type); var isTypeUint256 = (type) => CairoUint256.isAbiType(type); var isTypeLiteral = (type) => Object.values(Literal).includes(type); var isTypeBool = (type) => type === "core::bool"; var isTypeContractAddress = (type) => type === Literal.ContractAddress; var isTypeEthAddress = (type) => type === ETH_ADDRESS; var isTypeU96 = (type) => type === "core::internal::bounded_int::BoundedInt::<0, 79228162514264337593543950335>"; var isTypeSecp256k1Point = (type) => type === Literal.Secp256k1Point; var isCairo1Type = (type) => type.includes("::"); var getArrayType = (type) => { return isCairo1Type(type) ? type.substring(type.indexOf("<") + 1, type.lastIndexOf(">")) : type.replace("*", ""); }; function isCairo1Abi(abi) { const { cairo } = getAbiContractVersion(abi); if (cairo === void 0) { throw Error("Unable to determine Cairo version"); } return cairo === "1"; } function isTypeNonZero(type) { return type.startsWith(NON_ZERO_PREFIX); } function getAbiContractVersion(abi) { if (abi.find((it) => it.type === "interface")) { return { cairo: "1", compiler: "2" }; } const testSubject = abi.find( (it) => (it.type === "function" || it.type === "constructor") && (it.inputs.length || it.outputs.length) ); if (!testSubject) { return { cairo: void 0, compiler: void 0 }; } const io = testSubject.inputs.length ? testSubject.inputs : testSubject.outputs; if (isCairo1Type(io[0].type)) { return { cairo: "1", compiler: "1" }; } return { cairo: "0", compiler: "0" }; } var uint256 = (it) => { return new CairoUint256(it).toUint256DecimalString(); }; var uint512 = (it) => { return new CairoUint512(it).toUint512DecimalString(); }; var tuple = (...args) => ({ ...args }); function felt(it) { return CairoFelt(it); } // src/utils/calldata/enum/CairoCustomEnum.ts var CairoCustomEnum = class { /** * direct readonly access to variants of the Cairo Custom Enum. * @returns a value of type any * @example * ```typescript * const successValue = myCairoEnum.variant.Success; */ variant; /** * @param enumContent an object with the variants as keys and the content as value. Only one content shall be defined. */ constructor(enumContent) { const variantsList = Object.values(enumContent); if (variantsList.length === 0) { throw new Error("This Enum must have at least 1 variant"); } const nbActiveVariants = variantsList.filter((content) => !isUndefined(content)).length; if (nbActiveVariants !== 1) { throw new Error("This Enum must have exactly one active variant"); } this.variant = enumContent; } /** * * @returns the content of the valid variant of a Cairo custom Enum. */ unwrap() { const variants = Object.values(this.variant); return variants.find((item) => !isUndefined(item)); } /** * * @returns the name of the valid variant of a Cairo custom Enum. */ activeVariant() { const variants = Object.entries(this.variant); const activeVariant = variants.find((item) => !isUndefined(item[1])); return isUndefined(activeVariant) ? "" : activeVariant[0]; } }; // src/utils/calldata/enum/CairoOption.ts var CairoOptionVariant = { Some: 0, None: 1 }; var CairoOption = class { Some; None; constructor(variant, content) { if (!(variant in Object.values(CairoOptionVariant))) { throw new Error("Wrong variant! It should be CairoOptionVariant.Some or .None."); } if (variant === CairoOptionVariant.Some) { if (isUndefined(content)) { throw new Error( 'The creation of a Cairo Option with "Some" variant needs a content as input.'