UNPKG

@hyperlane-xyz/cli

Version:

A command-line utility for common Hyperlane operations

1,154 lines (1,119 loc) 120 kB
export const id = 773; export const ids = [773]; export const modules = { /***/ 5773: /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { // EXPORTS __webpack_require__.d(__webpack_exports__, { StarknetProtocolProvider: () => (/* reexport */ StarknetProtocolProvider) }); // UNUSED EXPORTS: StarknetHookArtifactManager, StarknetIsmArtifactManager, StarknetMailboxArtifactManager, StarknetProvider, StarknetSigner, StarknetValidatorAnnounceArtifactManager, StarknetWarpArtifactManager // EXTERNAL MODULE: ../utils/dist/validation.js var validation = __webpack_require__(21387); // EXTERNAL MODULE: ../provider-sdk/dist/index.js + 4 modules var dist = __webpack_require__(92201); // EXTERNAL MODULE: ../provider-sdk/dist/hook.js var hook = __webpack_require__(77230); // EXTERNAL MODULE: ../../node_modules/.pnpm/starknet@7.6.4/node_modules/starknet/dist/index.mjs + 41 modules var starknet_dist = __webpack_require__(98954); // EXTERNAL MODULE: ../../starknet/dist/index.js + 199 modules var starknet_dist_0 = __webpack_require__(17821); // EXTERNAL MODULE: ../utils/dist/typeof.js var dist_typeof = __webpack_require__(73689); // EXTERNAL MODULE: ../utils/dist/addresses.js var addresses = __webpack_require__(93142); // EXTERNAL MODULE: ../utils/dist/logging.js var logging = __webpack_require__(94523); ;// CONCATENATED MODULE: ../starknet-sdk/dist/contracts.js function isObjectRecord(value) { return !!value && typeof value === 'object'; } function getContractAbi(contract) { const abi = Reflect.get(contract, 'abi'); return Array.isArray(abi) ? abi : undefined; } function abiEntryHasMethod(entry, method) { if (!isObjectRecord(entry)) return false; if (entry['name'] === method) return true; const items = entry['items']; return Array.isArray(items) ? items.some((nestedEntry) => abiEntryHasMethod(nestedEntry, method)) : false; } function hasAbiMethod(contract, method) { const abi = getContractAbi(contract); if (!abi) return true; return abi.some((entry) => abiEntryHasMethod(entry, method)); } function isUint256Like(value) { if (!isObjectRecord(value)) return false; const low = value['low']; const high = value['high']; const isNumberish = (v) => typeof v === 'string' || typeof v === 'number' || typeof v === 'bigint'; return isNumberish(low) && isNumberish(high); } function describeUnknown(value) { if (typeof value === 'string' || typeof value === 'number' || typeof value === 'bigint' || typeof value === 'boolean') { return String(value); } if (isObjectRecord(value)) { if ('value' in value) return describeUnknown(value['value']); try { return JSON.stringify(value); } catch { return ''; } } return ''; } function isPopulatedInvokeTx(value) { if (!isObjectRecord(value)) return false; return ('contractAddress' in value && typeof value['entrypoint'] === 'string' && (!('calldata' in value) || Array.isArray(value['calldata']))); } var StarknetContractName; (function (StarknetContractName) { StarknetContractName["MAILBOX"] = "mailbox"; StarknetContractName["MESSAGE_ID_MULTISIG_ISM"] = "messageid_multisig_ism"; StarknetContractName["MERKLE_ROOT_MULTISIG_ISM"] = "merkleroot_multisig_ism"; StarknetContractName["ROUTING_ISM"] = "domain_routing_ism"; StarknetContractName["NOOP_ISM"] = "noop_ism"; StarknetContractName["HOOK"] = "hook"; StarknetContractName["MERKLE_TREE_HOOK"] = "merkle_tree_hook"; StarknetContractName["PROTOCOL_FEE"] = "protocol_fee"; StarknetContractName["VALIDATOR_ANNOUNCE"] = "validator_announce"; StarknetContractName["HYP_ERC20"] = "HypErc20"; StarknetContractName["HYP_ERC20_COLLATERAL"] = "HypErc20Collateral"; StarknetContractName["HYP_NATIVE"] = "HypNative"; StarknetContractName["ETHER"] = "Ether"; })(StarknetContractName || (StarknetContractName = {})); const STARKNET_DEFAULT_FEE_TOKEN_ADDRESSES = { starknet: '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d', starknetsepolia: '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d', paradex: '0x7348407ebad690fec0cc8597e87dc16ef7b269a655ff72587dafff83d462be2', paradexsepolia: '0x06f373b346561036d98ea10fb3e60d2f459c872b1933b50b21fe6ef4fda3b75e', }; function getStarknetContract(contractName, address, providerOrAccount, contractType = starknet_dist_0/* ContractType */.h$.CONTRACT) { const { abi } = (0,starknet_dist_0/* getCompiledContract */.wm)(contractName, contractType); return new starknet_dist/* Contract */.NZ(abi, contracts_normalizeStarknetAddressSafe(address), providerOrAccount); } function contracts_normalizeStarknetAddressSafe(value) { if (typeof value === 'string') { if ((0,addresses/* isZeroishAddress */.Hi)(value)) return addresses/* ZERO_ADDRESS_HEX_32 */.qx; return (0,starknet_dist/* addAddressPadding */.N6)((0,addresses/* ensure0x */.Ho)((0,addresses/* normalizeAddressStarknet */.sf)(value))); } if (typeof value === 'number' || typeof value === 'bigint') { return (0,starknet_dist/* addAddressPadding */.N6)((0,addresses/* ensure0x */.Ho)(BigInt(value).toString(16))); } if (isObjectRecord(value)) { if (isUint256Like(value)) { return (0,starknet_dist/* addAddressPadding */.N6)((0,addresses/* ensure0x */.Ho)(starknet_dist/* uint256 */.iN.uint256ToBN(value).toString(16))); } if ('value' in value) { return contracts_normalizeStarknetAddressSafe(value['value']); } } throw new Error(`Unable to normalize Starknet address: ${describeUnknown(value) || '[unsupported value]'}`); } function addressToEvmAddress(value) { return (0,addresses/* bytes32ToAddress */.ov)(contracts_normalizeStarknetAddressSafe(value)); } async function callContract(contract, method, args = []) { (0,validation/* assert */.v)(hasAbiMethod(contract, method), `Unable to call ${method} on contract ${contract.address}: method not found in ABI`); const fn = Reflect.get(contract, method); if (typeof fn === 'function') return Reflect.apply(fn, contract, args); const call = Reflect.get(contract, 'call'); if (typeof call === 'function') { const callArgs = args; return Reflect.apply(call, contract, [method, callArgs]); } throw new Error(`Unable to call ${method} on contract ${contract.address}`); } async function populateInvokeTx(contract, method, args = []) { (0,validation/* assert */.v)(hasAbiMethod(contract, method), `Unable to populate ${method} on contract ${contract.address}: method not found in ABI`); const populateTransaction = Reflect.get(contract, 'populateTransaction'); const populated = isObjectRecord(populateTransaction) && typeof populateTransaction[method] === 'function' ? populateTransaction[method] : undefined; if (typeof populated === 'function') { const tx = await populated(...args); if (isPopulatedInvokeTx(tx)) { return { kind: 'invoke', contractAddress: contracts_normalizeStarknetAddressSafe(tx.contractAddress), entrypoint: tx.entrypoint, calldata: tx.calldata ?? [], }; } } const abi = getContractAbi(contract); return { kind: 'invoke', contractAddress: contracts_normalizeStarknetAddressSafe(contract.address), entrypoint: method, calldata: abi ? new starknet_dist/* CallData */.fP(abi).compile(method, args) : args, }; } function extractEnumVariant(value) { if (value === null || value === undefined) return ''; if (value instanceof starknet_dist/* CairoCustomEnum */.bv) { return value.activeVariant(); } if (isObjectRecord(value) && 'activeVariant' in value && typeof value['activeVariant'] === 'function') { return value['activeVariant'](); } if (typeof value === 'string') return value; if (typeof value === 'number' || typeof value === 'bigint') { return value.toString(); } if (isObjectRecord(value)) { const entries = Object.entries(value); if (entries.length === 1) { const [entry] = entries; if (entry) return entry[0]; } for (const [key, nested] of entries) { if (nested !== undefined && nested !== null) { return key; } } } return describeUnknown(value); } function toNumber(value) { if (typeof value === 'number') { (0,validation/* assert */.v)(Number.isSafeInteger(value), `Unable to coerce value to safe integer: ${value}`); return value; } if (typeof value === 'bigint') { (0,validation/* assert */.v)(value <= BigInt(Number.MAX_SAFE_INTEGER) && value >= BigInt(Number.MIN_SAFE_INTEGER), `Unable to coerce value to safe integer: ${value}`); return Number(value); } if (typeof value === 'string') { const parsed = Number(value); (0,validation/* assert */.v)(Number.isSafeInteger(parsed), `Unable to coerce value to safe integer: ${value}`); return parsed; } if (isObjectRecord(value) && 'value' in value) { return toNumber(value['value']); } throw new Error(`Unable to coerce value to number: ${describeUnknown(value) || '[unsupported value]'}`); } function toBigInt(value) { if (typeof value === 'bigint') return value; if (typeof value === 'number') return BigInt(value); if (typeof value === 'string') return BigInt(value); if (isObjectRecord(value)) { if (isUint256Like(value)) { return starknet_dist/* uint256 */.iN.uint256ToBN(value); } if ('value' in value) return toBigInt(value['value']); } throw new Error(`Unable to coerce value to bigint: ${describeUnknown(value) || '[unsupported value]'}`); } function getFeeTokenAddress(params) { if (params.nativeDenom && !(0,addresses/* isZeroishAddress */.Hi)(params.nativeDenom)) { return contracts_normalizeStarknetAddressSafe(params.nativeDenom); } const token = STARKNET_DEFAULT_FEE_TOKEN_ADDRESSES[params.chainName]; (0,validation/* assert */.v)(token, `Missing Starknet fee token for chain ${params.chainName}`); return contracts_normalizeStarknetAddressSafe(token); } function normalizeRoutersAddress(value) { if (isUint256Like(value)) { return contracts_normalizeStarknetAddressSafe(starknet_dist/* num */.bu.toHex(starknet_dist/* uint256 */.iN.uint256ToBN(value))); } return contracts_normalizeStarknetAddressSafe(value); } /** * Creates a Contract instance using the on-chain ABI fetched from the provider. * If the contract is a proxy, resolves the implementation class ABI so * starknet.js parses responses with the correct types. * * Handles both Cairo 1 proxies (`get_implementation` returning a struct) * and Cairo 0 proxies (`implementation` returning a felt). */ async function getOnChainStarknetContract(provider, address) { const normalized = contracts_normalizeStarknetAddressSafe(address); const { abi } = await provider.getClassAt(normalized); const contract = new starknet_dist/* Contract */.NZ(abi, normalized, provider); const implHash = await resolveImplementationHash(contract); if ((0,dist_typeof/* isNullish */.u)(implHash) || implHash === 0n) return contract; const implClass = await provider.getClassByHash(`0x${implHash.toString(16)}`); return new starknet_dist/* Contract */.NZ(implClass.abi, normalized, provider); } async function resolveImplementationHash(contract) { try { // Cairo 1 proxy pattern if (hasAbiMethod(contract, 'get_implementation')) { return coerceClassHash(await callContract(contract, 'get_implementation')); } // Cairo 0 proxy pattern if (hasAbiMethod(contract, 'implementation')) { return coerceClassHash(await callContract(contract, 'implementation')); } } catch (error) { logging/* rootLogger */.Jk.warn({ address: contract.address, error }, 'Proxy resolution failed; falling back to contract own ABI'); } return undefined; } /** * Coerces a proxy implementation call result to a bigint class hash. * Handles both direct values (bigint/string) and single-field structs * returned by Cairo 0 (e.g. `{ implementation_hash_: bigint }`). */ function coerceClassHash(value) { if (typeof value === 'bigint') return value; if (typeof value === 'string') return BigInt(value); if (typeof value === 'number') return BigInt(value); if (isObjectRecord(value)) { const values = Object.values(value); if (values.length === 1) return coerceClassHash(values[0]); } return toBigInt(value); } /** * Determines whether a storage read error should trigger a fallback * to contract call-based reading. Some Starknet chains (e.g. Paradex) * have privacy enabled that disallows direct storage reads. */ /** JSON-RPC error codes that indicate storage reads are unavailable. */ const STORAGE_READ_FALLBACK_CODES = new Set([-32601, -32000]); /** Error message fragments (lowercase) that indicate storage reads are unavailable. */ const STORAGE_READ_FALLBACK_MESSAGES = [ 'method not found', 'method not allowed', 'not supported', 'unsupported', 'not implemented', ]; function shouldFallbackStorageRead(error) { const code = error && typeof error === 'object' ? Reflect.get(error, 'code') : undefined; if (STORAGE_READ_FALLBACK_CODES.has(code)) return true; const message = error instanceof Error ? error.message : typeof error === 'string' ? error : String(error && typeof error === 'object' ? Reflect.get(error, 'message') : error); const normalizedMessage = message.toLowerCase(); return STORAGE_READ_FALLBACK_MESSAGES.some((fragment) => normalizedMessage.includes(fragment)); } function isProbeMiss(error) { const message = error instanceof Error ? error.message : String(error); return [ 'entry point', 'entrypoint', 'viewable method not found in abi', 'not found in abi', 'not found in contract', 'invalid message selector', ].some((needle) => message.toLowerCase().includes(needle)); } //# sourceMappingURL=contracts.js.map ;// CONCATENATED MODULE: ../starknet-sdk/dist/mailbox/mailbox-query.js async function getMailboxConfig(provider, mailboxAddress) { const mailbox = getStarknetContract(StarknetContractName.MAILBOX, mailboxAddress, provider); const [owner, localDomain, defaultIsm, defaultHook, requiredHook, nonce] = await Promise.all([ callContract(mailbox, 'owner'), callContract(mailbox, 'get_local_domain'), callContract(mailbox, 'get_default_ism'), callContract(mailbox, 'get_default_hook'), callContract(mailbox, 'get_required_hook'), callContract(mailbox, 'nonce'), ]); return { address: contracts_normalizeStarknetAddressSafe(mailboxAddress), owner: contracts_normalizeStarknetAddressSafe(owner), localDomain: toNumber(localDomain), defaultIsm: contracts_normalizeStarknetAddressSafe(defaultIsm), defaultHook: contracts_normalizeStarknetAddressSafe(defaultHook), requiredHook: contracts_normalizeStarknetAddressSafe(requiredHook), nonce: toNumber(nonce), }; } async function isMessageDelivered(provider, mailboxAddress, messageId) { const mailbox = getStarknetContract(StarknetContractName.MAILBOX, mailboxAddress, provider); const delivered = await callContract(mailbox, 'delivered', [messageId]); if (typeof delivered === 'boolean') return delivered; return toBigInt(delivered) !== 0n; } //# sourceMappingURL=mailbox-query.js.map ;// CONCATENATED MODULE: ../starknet-sdk/dist/clients/provider.js let tokenTypeByClassHash; function getTokenTypeByClassHash() { if (tokenTypeByClassHash) { return tokenTypeByClassHash; } const entries = [ [ starknet_dist/* hash */.tW.computeContractClassHash((0,starknet_dist_0/* getCompiledContract */.wm)(StarknetContractName.HYP_ERC20, starknet_dist_0/* ContractType */.h$.TOKEN)), dist/* AltVM.TokenType */.bx.ks.synthetic, ], [ starknet_dist/* hash */.tW.computeContractClassHash((0,starknet_dist_0/* getCompiledContract */.wm)(StarknetContractName.HYP_ERC20_COLLATERAL, starknet_dist_0/* ContractType */.h$.TOKEN)), dist/* AltVM.TokenType */.bx.ks.collateral, ], [ starknet_dist/* hash */.tW.computeContractClassHash((0,starknet_dist_0/* getCompiledContract */.wm)(StarknetContractName.HYP_NATIVE, starknet_dist_0/* ContractType */.h$.TOKEN)), dist/* AltVM.TokenType */.bx.ks.native, ], ]; tokenTypeByClassHash = new Map(entries.map(([classHash, tokenType]) => [ BigInt(classHash).toString(), tokenType, ])); return tokenTypeByClassHash; } class StarknetProvider { provider; metadata; rpcUrls; static connect(rpcUrls, _chainId, extraParams) { (0,validation/* assert */.v)(extraParams?.metadata, 'metadata missing for Starknet provider'); const metadata = extraParams.metadata; (0,validation/* assert */.v)(rpcUrls.length > 0, 'at least one rpc url is required'); const blockTime = metadata.blocks?.estimateBlockTime; const transactionRetryIntervalFallback = !(0,dist_typeof/* isNullish */.u)(blockTime) && blockTime <= 1 ? 1000 : undefined; const provider = new starknet_dist/* RpcProvider */.bd({ nodeUrl: rpcUrls[0], transactionRetryIntervalFallback, }); return new StarknetProvider(provider, metadata, rpcUrls); } constructor(provider, metadata, rpcUrls) { this.provider = provider; this.metadata = metadata; this.rpcUrls = rpcUrls; } getRawProvider() { return this.provider; } withContract(name, address, providerOrAccount, contractType) { return getStarknetContract(name, address, providerOrAccount ?? this.provider, contractType); } get accountAddress() { throw new Error('StarknetProvider has no signer account'); } get feeTokenAddress() { return getFeeTokenAddress({ chainName: this.metadata.name, nativeDenom: this.metadata.nativeToken?.denom, }); } getFeeTokenAddress() { return this.feeTokenAddress; } parseString(value) { if (typeof value === 'string') return value; if (typeof value === 'number' || typeof value === 'bigint') { try { return starknet_dist/* shortString */.Gm.decodeShortString((0,addresses/* ensure0x */.Ho)(BigInt(value).toString(16))); } catch { return value.toString(); } } if (value && typeof value === 'object') { if ('value' in value) return this.parseString(value.value); const toStringFn = Reflect.get(value, 'toString'); if (typeof toStringFn === 'function' && toStringFn !== Object.prototype.toString) { const parsed = Reflect.apply(toStringFn, value, []); if (typeof parsed === 'string' && parsed !== '[object Object]') { return parsed; } } } return ''; } async populateInvokeCall(contract, method, args = []) { const tx = await populateInvokeTx(contract, method, args); (0,validation/* assert */.v)(tx.kind === 'invoke', 'Expected invoke Starknet transaction'); return { contractAddress: contracts_normalizeStarknetAddressSafe(tx.contractAddress), entrypoint: tx.entrypoint, calldata: tx.calldata, }; } unwrapBalance(value) { if (value && typeof value === 'object' && 'balance' in value) { return value.balance; } return value; } async determineTokenType(tokenAddress) { const address = contracts_normalizeStarknetAddressSafe(tokenAddress); const classHash = await this.provider.getClassHashAt(address); const tokenType = getTokenTypeByClassHash().get(BigInt(classHash).toString()); if (tokenType) return tokenType; try { const collateral = this.withContract(StarknetContractName.HYP_ERC20_COLLATERAL, address, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); await callContract(collateral, 'get_wrapped_token'); return dist/* AltVM.TokenType */.bx.ks.collateral; } catch (error) { if (!isProbeMiss(error)) throw error; } try { const native = this.withContract(StarknetContractName.HYP_NATIVE, address, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); await callContract(native, 'native_token'); return dist/* AltVM.TokenType */.bx.ks.native; } catch (error) { if (!isProbeMiss(error)) throw error; } return dist/* AltVM.TokenType */.bx.ks.synthetic; } /** * Reads ERC20 metadata by fetching the contract's own ABI from chain, * so starknet.js parses responses correctly regardless of whether * the contract uses felt252 (Cairo 0) or ByteArray (Cairo 1). */ async getTokenMetadata(tokenAddress) { const nativeToken = this.metadata.nativeToken; if (nativeToken?.denom && contracts_normalizeStarknetAddressSafe(tokenAddress) === contracts_normalizeStarknetAddressSafe(nativeToken.denom)) { return { name: nativeToken.name, symbol: nativeToken.symbol, decimals: nativeToken.decimals ?? 18, }; } const address = contracts_normalizeStarknetAddressSafe(tokenAddress); const token = await getOnChainStarknetContract(this.provider, address); const [name, symbol, decimals] = await Promise.all([ callContract(token, 'name'), callContract(token, 'symbol'), callContract(token, 'decimals'), ]); return { name: this.parseString(name), symbol: this.parseString(symbol), decimals: toNumber(decimals), }; } parseHookVariant(variant) { const upper = variant.toUpperCase(); if (upper.includes('MERKLE_TREE')) return dist/* AltVM.HookType */.bx.WD.MERKLE_TREE; if (upper.includes('PROTOCOL_FEE')) return dist/* AltVM.HookType */.bx.WD.PROTOCOL_FEE; if (upper.includes('INTERCHAIN_GAS_PAYMASTER')) { return dist/* AltVM.HookType */.bx.WD.INTERCHAIN_GAS_PAYMASTER; } return dist/* AltVM.HookType */.bx.WD.CUSTOM; } parseIsmVariant(variant) { const upper = variant.toUpperCase(); if (upper.includes('TEST') || upper.includes('NOOP') || upper.includes('NULL') || upper.includes('UNUSED')) { return dist/* AltVM.IsmType */.bx.GO.TEST_ISM; } if (upper.includes('MERKLE_ROOT_MULTISIG')) { return dist/* AltVM.IsmType */.bx.GO.MERKLE_ROOT_MULTISIG; } if (upper.includes('MESSAGE_ID_MULTISIG')) { return dist/* AltVM.IsmType */.bx.GO.MESSAGE_ID_MULTISIG; } if (upper.includes('ROUTING')) { return dist/* AltVM.IsmType */.bx.GO.ROUTING; } return dist/* AltVM.IsmType */.bx.GO.CUSTOM; } // ### QUERY BASE ### async isHealthy() { try { await this.provider.getBlockNumber(); return true; } catch { return false; } } getRpcUrls() { return this.rpcUrls; } async getHeight() { return this.provider.getBlockNumber(); } async getBalance(req) { const tokenAddress = req.denom ? contracts_normalizeStarknetAddressSafe(req.denom) : this.feeTokenAddress; const token = this.withContract(StarknetContractName.ETHER, tokenAddress, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); let balance; try { balance = await callContract(token, 'balanceOf', [ contracts_normalizeStarknetAddressSafe(req.address), ]); } catch (error) { if (!isProbeMiss(error)) throw error; balance = await callContract(token, 'balance_of', [ contracts_normalizeStarknetAddressSafe(req.address), ]); } return toBigInt(this.unwrapBalance(balance)); } async getTotalSupply(req) { const tokenAddress = req.denom ? contracts_normalizeStarknetAddressSafe(req.denom) : this.feeTokenAddress; const token = this.withContract(StarknetContractName.ETHER, tokenAddress, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); return toBigInt(await callContract(token, 'total_supply')); } async estimateTransactionFee(_req) { throw new Error('Starknet transaction fee estimation is unsupported without an account-backed signer'); } async isMessageDelivered(req) { return isMessageDelivered(this.provider, req.mailboxAddress, req.messageId); } // ### QUERY WARP ### async getToken(req) { const tokenAddress = contracts_normalizeStarknetAddressSafe(req.tokenAddress); const token = this.withContract(StarknetContractName.HYP_ERC20, tokenAddress, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); const tokenType = await this.determineTokenType(tokenAddress); const [owner, mailboxAddress, ismAddress, hookAddress] = await Promise.all([ callContract(token, 'owner'), callContract(token, 'mailbox'), callContract(token, 'interchain_security_module'), callContract(token, 'get_hook'), ]); let denom = tokenAddress; let name = ''; let symbol = ''; let decimals = this.metadata.nativeToken?.decimals ?? 18; try { const metadata = await this.getTokenMetadata(tokenAddress); name = metadata.name; symbol = metadata.symbol; decimals = metadata.decimals; } catch (error) { if (!isProbeMiss(error)) throw error; } if (tokenType === dist/* AltVM.TokenType */.bx.ks.collateral) { const collateral = this.withContract(StarknetContractName.HYP_ERC20_COLLATERAL, tokenAddress, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); const wrapped = await callContract(collateral, 'get_wrapped_token'); denom = contracts_normalizeStarknetAddressSafe(wrapped); try { const wrappedMeta = await this.getTokenMetadata(denom); name = wrappedMeta.name; symbol = wrappedMeta.symbol; decimals = wrappedMeta.decimals; } catch (error) { if (!isProbeMiss(error)) throw error; } } else if (tokenType === dist/* AltVM.TokenType */.bx.ks.native) { const native = this.withContract(StarknetContractName.HYP_NATIVE, tokenAddress, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); try { const nativeTokenAddress = await callContract(native, 'native_token'); denom = contracts_normalizeStarknetAddressSafe(nativeTokenAddress); } catch (error) { if (!isProbeMiss(error)) throw error; denom = this.metadata.nativeToken?.denom ?? this.feeTokenAddress; } name = this.metadata.nativeToken?.name ?? name; symbol = this.metadata.nativeToken?.symbol ?? symbol; decimals = this.metadata.nativeToken?.decimals ?? decimals; } return { address: tokenAddress, owner: contracts_normalizeStarknetAddressSafe(owner), tokenType, mailboxAddress: contracts_normalizeStarknetAddressSafe(mailboxAddress), ismAddress: contracts_normalizeStarknetAddressSafe(ismAddress), hookAddress: contracts_normalizeStarknetAddressSafe(hookAddress), denom, name, symbol, decimals, }; } async getRemoteRouters(req) { const token = this.withContract(StarknetContractName.HYP_ERC20, req.tokenAddress, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); const domains = await callContract(token, 'domains'); (0,validation/* assert */.v)(Array.isArray(domains), 'Expected Starknet token domains array'); const remoteRouters = await Promise.all(domains.map(async (domainId) => { const domain = toNumber(domainId); const [routerAddress, gas] = await Promise.all([ callContract(token, 'routers', [domainId]), callContract(token, 'destination_gas', [domainId]).catch(() => 0), ]); return { receiverDomainId: domain, receiverAddress: normalizeRoutersAddress(routerAddress), gas: toBigInt(gas).toString(), }; })); return { address: contracts_normalizeStarknetAddressSafe(req.tokenAddress), remoteRouters, }; } async getBridgedSupply(req) { const tokenInfo = await this.getToken({ tokenAddress: req.tokenAddress }); const token = this.withContract(StarknetContractName.HYP_ERC20, req.tokenAddress, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); if (tokenInfo.tokenType === dist/* AltVM.TokenType */.bx.ks.synthetic) { return toBigInt(await callContract(token, 'total_supply')); } return this.getBalance({ address: req.tokenAddress, denom: tokenInfo.denom, }); } async quoteRemoteTransfer(req) { const token = this.withContract(StarknetContractName.HYP_ERC20, req.tokenAddress, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); const quote = await callContract(token, 'quote_gas_payment', [ req.destinationDomainId, ]); return { denom: this.feeTokenAddress, amount: toBigInt(quote), }; } // ### TRANSFER TXS ### async getTransferTransaction(req) { const denom = req.denom ? contracts_normalizeStarknetAddressSafe(req.denom) : this.feeTokenAddress; const token = this.withContract(StarknetContractName.ETHER, denom, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); return populateInvokeTx(token, 'transfer', [ contracts_normalizeStarknetAddressSafe(req.recipient), req.amount, ]); } async getRemoteTransferTransaction(req) { return this.buildRemoteTransferTransaction(req); } async buildRemoteTransferTransaction(req, tokenInfo) { if (req.customHookAddress || req.customHookMetadata) { throw new Error('Custom hook metadata/addresses are unsupported for Starknet transfer_remote in provider-sdk'); } const tokenType = tokenInfo?.tokenType ?? (await this.determineTokenType(req.tokenAddress)); const token = this.withContract(StarknetContractName.HYP_ERC20, req.tokenAddress, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); const noneOption = new starknet_dist/* CairoOption */.ci(starknet_dist/* CairoOptionVariant */.RV.None); let value; if (tokenType === dist/* AltVM.TokenType */.bx.ks.native) { value = toBigInt(req.amount) + toBigInt(req.maxFee.amount); } else if (tokenType === dist/* AltVM.TokenType */.bx.ks.collateral) { value = toBigInt(req.maxFee.amount); } else { value = toBigInt(req.maxFee.amount); } return populateInvokeTx(token, 'transfer_remote', [ req.destinationDomainId, (0,addresses/* addressToBytes32 */.In)(req.recipient), req.amount, value, noneOption, noneOption, ]); } } //# sourceMappingURL=provider.js.map ;// CONCATENATED MODULE: ../starknet-sdk/dist/clients/signer.js class StarknetSigner extends StarknetProvider { signerAddress; static readStringField(value, key) { if (!value || typeof value !== 'object') return undefined; const candidate = Reflect.get(value, key); return typeof candidate === 'string' ? candidate : undefined; } static async connectWithSigner(rpcUrls, privateKey, extraParams) { (0,validation/* assert */.v)(extraParams?.metadata, 'metadata missing for Starknet signer'); const metadata = extraParams.metadata; const accountAddress = extraParams.accountAddress; (0,validation/* assert */.v)(accountAddress, 'accountAddress missing for Starknet signer'); (0,validation/* assert */.v)(privateKey, 'private key missing for Starknet signer'); const provider = StarknetProvider.connect(rpcUrls, metadata.chainId, { metadata, }); return new StarknetSigner(provider.getRawProvider(), metadata, rpcUrls, contracts_normalizeStarknetAddressSafe(accountAddress), privateKey); } account; constructor(provider, metadata, rpcUrls, signerAddress, privateKey) { super(provider, metadata, rpcUrls); this.signerAddress = signerAddress; this.account = new starknet_dist/* Account */.gD(provider, signerAddress, privateKey); } get accountAddress() { return this.signerAddress; } getSignerAddress() { return this.signerAddress; } supportsTransactionBatching() { return true; } async transactionToPrintableJson(transaction) { return transaction; } assertSuccessfulReceipt(transactionHash, receipt) { if (receipt.isSuccess()) return; if (receipt.isReverted()) { const receiptValue = receipt.value; const revertReason = typeof receiptValue === 'object' && typeof Reflect.get(receiptValue, 'revert_reason') === 'string' ? Reflect.get(receiptValue, 'revert_reason') : undefined; const details = typeof revertReason === 'string' && revertReason.length > 0 ? `: ${revertReason}` : ''; (0,validation/* assert */.v)(false, `Starknet transaction ${transactionHash} reverted${details}`); } if (receipt.isError()) { (0,validation/* assert */.v)(false, `Starknet transaction ${transactionHash} failed: ${receipt.value.message}`); } (0,validation/* assert */.v)(false, `Starknet transaction ${transactionHash} failed with status ${receipt.statusReceipt}`); } async deployContract(params) { const compiledContract = (0,starknet_dist_0/* getCompiledContract */.wm)(params.contractName, params.contractType); const compiledClassHash = (0,starknet_dist_0/* getCompiledClassHash */.mU)(params.contractName, params.contractType); const contractArtifact = (0,starknet_dist_0/* getContractArtifact */.tt)(params.contractName, params.contractType); (0,validation/* assert */.v)(contractArtifact.compiled_contract_class, `Missing compiled_contract_class for Starknet contract ${params.contractName}`); (0,validation/* assert */.v)(compiledClassHash, `Missing compiledClassHash for Starknet contract ${params.contractName}`); const hasConstructor = compiledContract.abi.some((item) => item.type === 'constructor'); const constructorCalldata = hasConstructor ? new starknet_dist/* CallData */.fP(compiledContract.abi).compile('constructor', params.constructorArgs) : undefined; const factory = new starknet_dist/* ContractFactory */.PM({ compiledContract, casm: contractArtifact.compiled_contract_class, compiledClassHash, account: this.account, }); const deployment = constructorCalldata === undefined ? await factory.deploy() : await factory.deploy(constructorCalldata); const transactionHash = deployment.deployTransactionHash ?? StarknetSigner.readStringField(deployment, 'transaction_hash'); (0,validation/* assert */.v)(transactionHash, 'missing Starknet deploy transaction hash'); const rawAddress = deployment.address || StarknetSigner.readStringField(deployment, 'contract_address'); (0,validation/* assert */.v)(rawAddress, 'missing Starknet deploy contract address'); const address = contracts_normalizeStarknetAddressSafe(rawAddress); const receipt = await this.account.waitForTransaction(transactionHash); this.assertSuccessfulReceipt(transactionHash, receipt); return { transactionHash, contractAddress: address, receipt, }; } async sendAndConfirmTransaction(transaction) { if (transaction.kind === 'deploy') { const deployed = await this.deployContract({ contractName: transaction.contractName, constructorArgs: transaction.constructorArgs, contractType: transaction.contractType, }); return { transactionHash: deployed.transactionHash, contractAddress: deployed.contractAddress, receipt: deployed.receipt, }; } const calls = transaction.calls ?? [ { contractAddress: transaction.contractAddress, entrypoint: transaction.entrypoint, calldata: transaction.calldata, }, ]; const response = await this.account.execute(calls); const transactionHash = response.transaction_hash; const receipt = await this.account.waitForTransaction(transactionHash); this.assertSuccessfulReceipt(transactionHash, receipt); return { transactionHash, receipt }; } async sendAndConfirmBatchTransactions(transactions) { const hasDeploy = transactions.some((tx) => tx.kind === 'deploy'); if (hasDeploy) { throw new Error('Batch transactions with deploy operations are unsupported on Starknet signer'); } const invokeTransactions = transactions.filter((tx) => tx.kind === 'invoke'); (0,validation/* assert */.v)(invokeTransactions.length === transactions.length, 'Batch transactions with non-invoke operations are unsupported on Starknet signer'); const calls = invokeTransactions.flatMap((invoke) => invoke.calls ?? [ { contractAddress: invoke.contractAddress, entrypoint: invoke.entrypoint, calldata: invoke.calldata, }, ]); const response = await this.account.execute(calls); const transactionHash = response.transaction_hash; const receipt = await this.account.waitForTransaction(transactionHash); this.assertSuccessfulReceipt(transactionHash, receipt); return { transactionHash, receipt }; } async estimateTransactionFee(req) { (0,validation/* assert */.v)(req.transaction.kind === 'invoke', 'Starknet transaction fee estimation only supports invoke transactions'); const calls = req.transaction.calls ?? [ { contractAddress: req.transaction.contractAddress, entrypoint: req.transaction.entrypoint, calldata: req.transaction.calldata, }, ]; const estimate = await this.account.estimateInvokeFee(calls); const gasUnits = estimate.l1_gas_consumed + estimate.l1_data_gas_consumed + (estimate.l2_gas_consumed ?? 0n); return { gasUnits, gasPrice: Number(estimate.l1_gas_price), fee: estimate.overall_fee, }; } async remoteTransfer(req) { const token = await this.getToken({ tokenAddress: req.tokenAddress }); const tokenType = token.tokenType; const tx = await this.buildRemoteTransferTransaction({ signer: this.signerAddress, ...req, }, token); const batchedTxs = []; if (tokenType === dist/* AltVM.TokenType */.bx.ks.native) { const nativeToken = getStarknetContract(StarknetContractName.ETHER, token.denom, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); batchedTxs.push(await populateInvokeTx(nativeToken, 'approve', [ contracts_normalizeStarknetAddressSafe(req.tokenAddress), toBigInt(req.amount) + toBigInt(req.maxFee.amount), ])); } else if (tokenType === dist/* AltVM.TokenType */.bx.ks.collateral) { const collateralToken = getStarknetContract(StarknetContractName.ETHER, token.denom, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); const collateralDenom = contracts_normalizeStarknetAddressSafe(token.denom); const feeDenom = contracts_normalizeStarknetAddressSafe(req.maxFee.denom); const approvalAmount = collateralDenom === feeDenom ? toBigInt(req.amount) + toBigInt(req.maxFee.amount) : toBigInt(req.amount); batchedTxs.push(await populateInvokeTx(collateralToken, 'approve', [ contracts_normalizeStarknetAddressSafe(req.tokenAddress), approvalAmount, ])); } const usesSharedCollateralAndFeeToken = tokenType === dist/* AltVM.TokenType */.bx.ks.collateral && contracts_normalizeStarknetAddressSafe(token.denom) === contracts_normalizeStarknetAddressSafe(req.maxFee.denom); if (tokenType !== dist/* AltVM.TokenType */.bx.ks.native && !usesSharedCollateralAndFeeToken) { const feeToken = getStarknetContract(StarknetContractName.ETHER, req.maxFee.denom, this.provider, starknet_dist_0/* ContractType */.h$.TOKEN); batchedTxs.push(await populateInvokeTx(feeToken, 'approve', [ contracts_normalizeStarknetAddressSafe(req.tokenAddress), toBigInt(req.maxFee.amount), ])); } if (batchedTxs.length > 0) { await this.sendAndConfirmBatchTransactions([...batchedTxs, tx]); } else { await this.sendAndConfirmTransaction(tx); } return { tokenAddress: req.tokenAddress }; } } //# sourceMappingURL=signer.js.map ;// CONCATENATED MODULE: ../starknet-sdk/dist/hook/hook-query.js function parseHookVariant(variant) { const upper = variant.toUpperCase(); if (upper.includes('MERKLE_TREE')) return dist/* AltVM.HookType */.bx.WD.MERKLE_TREE; if (upper.includes('PROTOCOL_FEE')) return dist/* AltVM.HookType */.bx.WD.PROTOCOL_FEE; if (upper.includes('INTERCHAIN_GAS_PAYMASTER')) { return dist/* AltVM.HookType */.bx.WD.INTERCHAIN_GAS_PAYMASTER; } return dist/* AltVM.HookType */.bx.WD.CUSTOM; } async function getHookType(provider, hookAddress) { try { const hook = getStarknetContract(StarknetContractName.HOOK, hookAddress, provider); const hookType = await callContract(hook, 'hook_type'); return parseHookVariant(extractEnumVariant(hookType)); } catch (error) { if (!isProbeMiss(error)) throw error; return dist/* AltVM.HookType */.bx.WD.CUSTOM; } } function getMerkleTreeHookConfig(hookAddress) { return { address: normalizeStarknetAddressSafe(hookAddress) }; } //# sourceMappingURL=hook-query.js.map ;// CONCATENATED MODULE: ../starknet-sdk/dist/hook/interchain-gas-paymaster-hook-artifact-manager.js function createStarknetInterchainGasPaymasterHookReader() { return { read: async () => { return (0,hook/* throwUnsupportedHookType */.DD)(dist/* AltVM.HookType */.bx.WD.INTERCHAIN_GAS_PAYMASTER, 'Starknet'); }, }; } function createStarknetInterchainGasPaymasterHookWriter() { return { read: async () => { return (0,hook/* throwUnsupportedHookType */.DD)(dist/* AltVM.HookType */.bx.WD.INTERCHAIN_GAS_PAYMASTER, 'Starknet'); }, create: async () => { return (0,hook/* throwUnsupportedHookType */.DD)(dist/* AltVM.HookType */.bx.WD.INTERCHAIN_GAS_PAYMASTER, 'Starknet'); }, update: async () => { return (0,hook/* throwUnsupportedHookType */.DD)(dist/* AltVM.HookType */.bx.WD.INTERCHAIN_GAS_PAYMASTER, 'Starknet'); }, }; } //# sourceMappingURL=interchain-gas-paymaster-hook-artifact-manager.js.map // EXTERNAL MODULE: ../provider-sdk/dist/artifact.js var dist_artifact = __webpack_require__(4287); ;// CONCATENATED MODULE: ../starknet-sdk/dist/hook/hook-tx.js function getCreateMerkleTreeHookTx(signer, mailboxAddress) { return { kind: 'deploy', contractName: StarknetContractName.MERKLE_TREE_HOOK, constructorArgs: [ contracts_normalizeStarknetAddressSafe(mailboxAddress), contracts_normalizeStarknetAddressSafe(signer), ], }; } function getCreateNoopHookTx() { return { kind: 'deploy', contractName: StarknetContractName.HOOK, constructorArgs: [], }; } //# sourceMappingURL=hook-tx.js.map ;// CONCATENATED MODULE: ../starknet-sdk/dist/hook/merkle-tree-hook-artifact-manager.js class StarknetMerkleTreeHookReader { async read(address) { return { artifactState: dist_artifact/* ArtifactState */.O2.DEPLOYED, config: { type: dist/* AltVM.HookType */.bx.WD.MERKLE_TREE }, deployed: { address: contracts_normalizeStarknetAddressSafe(address) }, }; } } class StarknetMerkleTreeHookWriter extends StarknetMerkleTreeHookReader { signer; mailboxAddress; constructor(signer, mailboxAddress) { super(); this.signer = signer; this.mailboxAddress = mailboxAddress; } async create(artifact) { const tx = getCreateMerkleTreeHookTx(this.signer.getSignerAddress(), this.mailboxAddress); const receipt = await this.signer.sendAndConfirmTransaction(tx); const hookAddress = receipt.contractAddress; (0,validation/* assert */.v)(hookAddress, 'failed to deploy Starknet merkle tree hook'); return [ { artifactState: dist_artifact/* ArtifactState */.O2.DEPLOYED, config: artifact.config, deployed: { address: hookAddress }, }, [receipt], ]; } async update(_artifact) { return []; } } //# sourceMappingURL=merkle-tree-hook-artifact-manager.js.map ;// CONCATENATED MODULE: ../starknet-sdk/dist/hook/protocol-fee-hook-artifact-manager.js const STARKNET_STORAGE_ADDRESS_BOUND = (1n << 251n) - 256n; const logger = logging/* rootLogger */.Jk.child({ module: 'starknet-hook-artifact-manager', }); const MAX_PROTOCOL_FEE_STORAGE_KEYS = [ 'max_protocol_fee', '_max_protocol_fee', ].map((name) => starknet_dist/* hash */.tW.starknetKeccak(name) % STARKNET_STORAGE_ADDRESS_BOUND); async function readUint256Storage(provider, contractAddress, key) { try { const rawProvider = provider.getRawProvider(); const [low, high] = await Promise.all([ rawProvider.getStorageAt(contractAddress, `0x${key.toString(16)}`), rawProvider.getStorageAt(contractAddress, `0x${(key + 1n).toString(16)}`), ]); return toBigInt(low) + (toBigInt(high) << 128n); } catch (error) { if (!shouldFallbackStorageRead(error)) { throw error; } logger.warn({ contractAddress, key: `0x${key.toString(16)}`, error, }, 'Falling back to lossy Starknet protocolFee max read after unsupported storage lookup'); return undefined; } } async function readProtocolFeeMaxFromStorage(provider, contractAddress, protocolFee) { // Different Starknet contract builds have used different storage keys for // max_protocol_fee. Accept any candidate that is at least the live // protocolFee, prefer a single non-zero value over zero sentinels, and only // fall back to all candidates when multiple non-zero slots are populated. const candidates = (await Promise.all(MAX_PROTOCOL_FEE_STORAGE_KEYS.map(async (key) => readUint256Storage(provider, contractAddress, key)))).filter((value) => value !== undefined && value >= protocolFee); if (candidates.length === 0) return undefined; const nonZeroCandidates = candidates.filter((value) => value > 0n); const relevantCandidates = nonZeroCandidates.length === 1 ? nonZeroCandidates : candidates; const uniqueValues = [ ...new Set(relevantCandidates.