@hyperlane-xyz/cli
Version:
A command-line utility for common Hyperlane operations
1,154 lines (1,119 loc) • 120 kB
JavaScript
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.