UNPKG

@hyperlane-xyz/cli

Version:

A command-line utility for common Hyperlane operations

886 lines (863 loc) 8.8 MB
export const id = 79; export const ids = [79]; export const modules = { /***/ 13079: /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { // EXPORTS __webpack_require__.d(__webpack_exports__, { SealevelProtocolProvider: () => (/* reexport */ SvmProtocolProvider) }); // UNUSED EXPORTS: DeployStageKind, HYPERLANE_SVM_PROGRAM_BYTES, SealevelHookArtifactManager, SealevelIgpHookReader, SealevelIgpHookWriter, SealevelIsmArtifactManager, SealevelMailboxArtifactManager, SealevelMailboxReader, SealevelMailboxWriter, SealevelMerkleTreeHookReader, SealevelMerkleTreeHookWriter, SealevelMessageIdMultisigIsmReader, SealevelMessageIdMultisigIsmWriter, SealevelProvider, SealevelSigner, SealevelTestIsmReader, SealevelTestIsmWriter, SealevelValidatorAnnounceArtifactManager, SealevelValidatorAnnounceReader, SealevelValidatorAnnounceWriter, SvmCrossCollateralTokenReader, SvmCrossCollateralTokenWriter, buildSetDefaultIsmInstruction, buildTransactionMessage, convertLegacySolanaTransaction, createDeployProgramPlan, createRpc, createUpgradeProgramPlan, decodeCrossCollateralStateAccount, decodeHyperlaneTokenAccount, decodeIgpAccount, decodeIgpProgramDataAccount, decodeMailboxInboxAccount, decodeMailboxOutboxAccount, decodeMultisigIsmAccessControlAccount, decodeMultisigIsmDomainDataAccount, decodeOverheadIgpAccount, decodeTestIsmStorageAccount, decodeValidatorAnnounceAccount, decodeValidatorStorageLocationsAccount, deriveAtaPayerPda, deriveCrossCollateralDispatchAuthorityPda, deriveCrossCollateralStatePda, deriveHyperlaneTokenPda, deriveIgpAccountPda, deriveIgpProgramDataPda, deriveMailboxInboxPda, deriveMailboxOutboxPda, deriveMultisigIsmAccessControlPda, deriveMultisigIsmDomainDataPda, deriveOverheadIgpAccountPda, deriveReplayProtectionPda, deriveTestIsmStoragePda, deriveValidatorAnnouncePda, deriveValidatorStorageLocationsPda, executeDeployPlan, fetchMailboxInboxAccount, fetchMultisigIsmAccessControl, getComputeBudgetInstructions, getMultisigIsmTransferOwnershipInstruction, getProgramUpgradeAuthority, getSetUpgradeAuthorityInstruction, isLegacySolanaTransaction, resolveProgram, serializeUnsignedTransaction // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+addresses@6.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@6.0.2/node_modules/@solana/addresses/dist/index.node.mjs var index_node = __webpack_require__(89735); // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+instructions@6.1.0_typescript@6.0.2/node_modules/@solana/instructions/dist/index.node.mjs var dist_index_node = __webpack_require__(49957); // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+transaction-messages@6.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@6.0.2/node_modules/@solana/transaction-messages/dist/index.node.mjs var transaction_messages_dist_index_node = __webpack_require__(65175); // EXTERNAL MODULE: ../utils/dist/validation.js var validation = __webpack_require__(21387); // EXTERNAL MODULE: ../utils/dist/logging.js var logging = __webpack_require__(94523); ;// CONCATENATED MODULE: ../svm-sdk/dist/constants.js const PROGRAM_INSTRUCTION_DISCRIMINATOR = new Uint8Array([ 1, 1, 1, 1, 1, 1, 1, 1, ]); const constants_SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111'; const RENT_SYSVAR_ADDRESS = 'SysvarRent111111111111111111111111111111111'; const CLOCK_SYSVAR_ADDRESS = 'SysvarC1ock11111111111111111111111111111111'; // Kept as literals to avoid adding a direct '@solana/sysvars' dependency here. const SPL_NOOP_PROGRAM_ADDRESS = 'noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV'; const constants_LOADER_V3_PROGRAM_ADDRESS = 'BPFLoaderUpgradeab1e11111111111111111111111'; // Solana hard limit on account data size. const MAX_ACCOUNT_DATA_SIZE = 10_485_760; // Fixed base fee per signature on Solana. // https://solana.com/docs/core/fees#base-fee const LAMPORTS_PER_SIGNATURE = 5_000; // https://spl.solana.com/token const SPL_TOKEN_PROGRAM_ADDRESS = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'; // https://spl.solana.com/token-2022 const TOKEN_2022_PROGRAM_ADDRESS = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'; // https://github.com/metaplex-foundation/mpl-token-metadata/blob/c314930196b6b16e1ba8fefdf206e9af7b0e4c37/programs/token-metadata/program/src/lib.rs#L25 const METAPLEX_METADATA_PROGRAM_ADDRESS = 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'; // Hand-rolled to avoid adding @solana-program/compute-budget as a dependency. const COMPUTE_BUDGET_PROGRAM_ID = (0,index_node/* address */.hl)('ComputeBudget111111111111111111111111111111'); // Default compute unit budget for SVM deployment transactions. const constants_DEFAULT_COMPUTE_UNITS = 400_000; //# sourceMappingURL=constants.js.map // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+rpc@6.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@6.0.2/node_modules/@solana/rpc/dist/index.node.mjs + 7 modules var rpc_dist_index_node = __webpack_require__(15328); // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+accounts@6.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@6.0.2/node_modules/@solana/accounts/dist/index.node.mjs var accounts_dist_index_node = __webpack_require__(96659); ;// CONCATENATED MODULE: ../svm-sdk/dist/rpc.js function createRpc(url) { return (0,rpc_dist_index_node/* createSolanaRpc */.AP)(url); } // Returns MaybeEncodedAccount to preserve Kit's explicit existence-check shape. // Callers should branch on .exists or use assertAccountExists(). async function fetchAccount(rpc, address) { return fetchEncodedAccount(rpc, address); } /** * Fetches raw account data bytes, returning null when the account does not exist. */ async function rpc_fetchAccountDataRaw(rpc, address) { const maybeAccount = await (0,accounts_dist_index_node/* fetchEncodedAccount */.oG)(rpc, address, { commitment: 'confirmed', }); if (!maybeAccount.exists) return null; return maybeAccount.data; } //# sourceMappingURL=rpc.js.map ;// CONCATENATED MODULE: ../svm-sdk/dist/clients/provider.js class SvmProvider { rpc; rpcUrls; static async connect(rpcUrls, _chainId, _extraParams) { (0,validation/* assert */.v)(rpcUrls.length > 0, 'At least one RPC URL is required'); const rpc = createRpc(rpcUrls[0]); return new SvmProvider(rpc, rpcUrls); } constructor(rpc, rpcUrls) { this.rpc = rpc; this.rpcUrls = rpcUrls; } // ### QUERY BASE ### async isHealthy() { try { await this.rpc.getSlot().send(); return true; } catch (error) { logging/* rootLogger */.Jk.debug('SVM health check failed', { error }); return false; } } getRpcUrls() { return this.rpcUrls; } async getHeight() { const slot = await this.rpc.getSlot().send(); return Number(slot); } async getBalance(req) { const balance = await this.rpc.getBalance((0,index_node/* address */.hl)(req.address)).send(); return balance.value; } async getTotalSupply(_req) { throw new Error('getTotalSupply not supported on Sealevel'); } async estimateTransactionFee(req) { const signerAddresses = new Set(); // Collect signers from instruction account metas for (const ix of req.transaction.instructions) { if (ix.accounts) { for (const account of ix.accounts) { if (account.role >= dist_index_node/* AccountRole */.Uv.READONLY_SIGNER) { signerAddresses.add(account.address); } } } } // Collect additional signers for (const signer of req.transaction.additionalSigners ?? []) { signerAddresses.add(signer.address); } // +1 for fee payer (may already be in the set, but overcount to be safe) const numSigners = signerAddresses.size + 1; const gasPrice = await this.queryBaseFeePerSignature(); const fee = BigInt(numSigners) * BigInt(gasPrice); const gasUnits = BigInt(req.transaction.computeUnits ?? constants_DEFAULT_COMPUTE_UNITS); return { gasUnits, gasPrice, fee }; } /** * Queries the RPC for the base fee per signature using a minimal * unsigned message. */ async queryBaseFeePerSignature() { try { const { value: latestBlockhash } = await this.rpc .getLatestBlockhash() .send(); const baseMessage = (0,transaction_messages_dist_index_node/* createTransactionMessage */.mN)({ version: 0 }); const withFeePayer = (0,transaction_messages_dist_index_node/* setTransactionMessageFeePayer */.t_)(constants_SYSTEM_PROGRAM_ADDRESS, baseMessage); const withLifetime = (0,transaction_messages_dist_index_node/* setTransactionMessageLifetimeUsingBlockhash */.S$)(latestBlockhash, withFeePayer); const compiled = (0,transaction_messages_dist_index_node/* compileTransactionMessage */.rt)(withLifetime); const messageBytes = (0,transaction_messages_dist_index_node/* getCompiledTransactionMessageEncoder */.dU)().encode(compiled); const base64Message = Buffer.from(messageBytes).toString('base64'); const result = await this.rpc.getFeeForMessage(base64Message).send(); if (result.value != null) { return Number(result.value); } } catch (error) { logging/* rootLogger */.Jk.debug('getFeeForMessage failed, using static fallback', { error, }); } return LAMPORTS_PER_SIGNATURE; } async isMessageDelivered(_req) { throw new Error('isMessageDelivered not supported on Sealevel, use the Artifact API instead'); } // ### QUERY WARP ### async getToken(_req) { throw new Error('getToken not supported on Sealevel, use the Artifact API instead'); } async getRemoteRouters(_req) { throw new Error('getRemoteRouters not supported on Sealevel, use the Artifact API instead'); } async getBridgedSupply(_req) { throw new Error('getBridgedSupply not supported on Sealevel, use the Artifact API instead'); } async quoteRemoteTransfer(_req) { throw new Error('quoteRemoteTransfer not supported on Sealevel, use the Artifact API instead'); } } //# sourceMappingURL=provider.js.map // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+codecs-strings@6.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@6.0.2/node_modules/@solana/codecs-strings/dist/index.node.mjs var codecs_strings_dist_index_node = __webpack_require__(98915); // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+signers@6.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@6.0.2/node_modules/@solana/signers/dist/index.node.mjs var signers_dist_index_node = __webpack_require__(26285); // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+transactions@6.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@6.0.2/node_modules/@solana/transactions/dist/index.node.mjs var transactions_dist_index_node = __webpack_require__(89331); // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+keys@6.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@6.0.2/node_modules/@solana/keys/dist/index.node.mjs var keys_dist_index_node = __webpack_require__(27303); // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+errors@6.1.0_typescript@6.0.2/node_modules/@solana/errors/dist/index.node.mjs var errors_dist_index_node = __webpack_require__(13197); // EXTERNAL MODULE: ../utils/dist/addresses.js var addresses = __webpack_require__(93142); // EXTERNAL MODULE: ../utils/dist/async.js var dist_async = __webpack_require__(14918); ;// CONCATENATED MODULE: ../svm-sdk/dist/legacy-compat.js /** * Converts legacy @solana/web3.js Transaction objects to @solana/kit SvmTransaction format. * Used when SDK adapters return legacy Transactions but the SvmSigner expects kit-format instructions. */ const SET_COMPUTE_UNIT_LIMIT_DISCRIMINATOR = 2; function convertAccountMeta(meta) { const address = (0,index_node/* address */.hl)(meta.pubkey.toBase58()); const role = meta.isSigner ? meta.isWritable ? dist_index_node/* AccountRole */.Uv.WRITABLE_SIGNER : dist_index_node/* AccountRole */.Uv.READONLY_SIGNER : meta.isWritable ? dist_index_node/* AccountRole */.Uv.WRITABLE : dist_index_node/* AccountRole */.Uv.READONLY; return { address, role }; } function convertInstruction(ix) { return { programAddress: (0,index_node/* address */.hl)(ix.programId.toBase58()), accounts: ix.keys.map(convertAccountMeta), data: new Uint8Array(ix.data), }; } /** * Converts a legacy @solana/web3.js Transaction to the SvmTransaction format * expected by SvmSigner. The SetComputeUnitLimit instruction is extracted into * `computeUnits` (the signer recreates it). All other instructions — including * SetComputeUnitPrice — are preserved as-is. * * @param legacyTx Legacy Transaction returned by SDK adapters. * @param extraSigners Keypairs that partial-signed the legacy tx (e.g. random * wallet for message storage PDAs). Converted to @solana/kit TransactionSigners. */ async function convertLegacySolanaTransaction(legacyTx, extraSigners) { let computeUnits; const instructions = []; for (const ix of legacyTx.instructions) { const isComputeBudget = ix.programId.toBase58() === COMPUTE_BUDGET_PROGRAM_ID; if (isComputeBudget && ix.data[0] === SET_COMPUTE_UNIT_LIMIT_DISCRIMINATOR && ix.data.length >= 5) { // Extract compute unit limit — SvmSigner recreates this instruction // from the `computeUnits` field via buildTransactionMessage. const dataArr = new Uint8Array(ix.data); computeUnits = new DataView(dataArr.buffer, dataArr.byteOffset).getUint32(1, true); continue; } // Preserve all other instructions including SetComputeUnitPrice. instructions.push(convertInstruction(ix)); } let additionalSigners; if (extraSigners?.length) { additionalSigners = await Promise.all(extraSigners.map((kp) => (0,signers_dist_index_node/* createKeyPairSignerFromBytes */.Lt)(kp.secretKey))); } return { instructions, computeUnits, additionalSigners, }; } /** * Detects whether an object is a legacy @solana/web3.js Transaction * by checking for the `programId` property on its first instruction. */ function isLegacySolanaTransaction(tx) { if (typeof tx !== 'object' || tx === null) return false; // CAST: tx is narrowed to non-null object above; Partial<LegacyTransaction> ensures // property access stays in sync with the interface. const maybeIx = tx.instructions; if (!Array.isArray(maybeIx) || maybeIx.length === 0) return false; const first = maybeIx[0]; return (typeof first === 'object' && first !== null && 'programId' in first && !('programAddress' in first)); } //# sourceMappingURL=legacy-compat.js.map // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+codecs-numbers@6.1.0_typescript@6.0.2/node_modules/@solana/codecs-numbers/dist/index.node.mjs var codecs_numbers_dist_index_node = __webpack_require__(17991); // EXTERNAL MODULE: ../../node_modules/.pnpm/@solana+rpc-types@6.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@6.0.2/node_modules/@solana/rpc-types/dist/index.node.mjs var rpc_types_dist_index_node = __webpack_require__(81133); ;// CONCATENATED MODULE: ../svm-sdk/dist/tx.js // Max data per BPFLoaderUpgradeable Write tx: 1232 packet limit minus tx // overhead. With 2 signers (payer != authority) overhead is ~355 bytes, // giving ~877 bytes max. Use 850 to leave margin for all signer configs. const tx_DEFAULT_WRITE_CHUNK_SIZE = 850; const DEFAULT_PRIORITY_FEE_MICRO_LAMPORTS = 1; function createSetComputeUnitLimitInstruction(units) { const data = new Uint8Array(5); data[0] = 2; new DataView(data.buffer).setUint32(1, units, true); return { programAddress: COMPUTE_BUDGET_PROGRAM_ID, accounts: [], data }; } function createSetComputeUnitPriceInstruction(microLamports) { const data = new Uint8Array(9); data[0] = 3; new DataView(data.buffer).setBigUint64(1, microLamports, true); return { programAddress: COMPUTE_BUDGET_PROGRAM_ID, accounts: [], data }; } function getComputeBudgetInstructions(units = constants_DEFAULT_COMPUTE_UNITS, microLamports) { const instructions = [ createSetComputeUnitLimitInstruction(units), ]; if (microLamports !== undefined && microLamports > 0) { instructions.push(createSetComputeUnitPriceInstruction(BigInt(microLamports))); } return instructions; } function buildTransactionMessage(params) { const { instructions, feePayer, recentBlockhash, lastValidBlockHeight, computeUnits = constants_DEFAULT_COMPUTE_UNITS, priorityFeeMicroLamports, } = params; const computeBudgetIxs = getComputeBudgetInstructions(computeUnits, priorityFeeMicroLamports); const allInstructions = [...computeBudgetIxs, ...instructions]; const txMessage = (0,transaction_messages_dist_index_node/* createTransactionMessage */.mN)({ version: 0 }); const withFeePayer = (0,signers_dist_index_node/* setTransactionMessageFeePayerSigner */.pt)(feePayer, txMessage); const withLifetime = (0,transaction_messages_dist_index_node/* setTransactionMessageLifetimeUsingBlockhash */.S$)({ blockhash: recentBlockhash, lastValidBlockHeight }, withFeePayer); return (0,transaction_messages_dist_index_node/* appendTransactionMessageInstructions */.Fx)(allInstructions, withLifetime); } function transactionToInstructions(tx) { const computeUnits = tx.computeUnits ?? DEFAULT_COMPUTE_UNITS; const computeBudgetIxs = getComputeBudgetInstructions(computeUnits); return [...computeBudgetIxs, ...tx.instructions]; } // --------------------------------------------------------------------------- // Unsigned transaction serialization (Squads-compatible v0 format) // --------------------------------------------------------------------------- const base58Decoder = (0,codecs_strings_dist_index_node/* getBase58Decoder */.BC)(); const messageEncoder = (0,transaction_messages_dist_index_node/* getCompiledTransactionMessageEncoder */.dU)(); const shortU16Encoder = (0,codecs_numbers_dist_index_node/* getShortU16Encoder */.tD)(); /** Default blockhash (32 zero bytes) that needs to be replaced at submission time */ const DEFAULT_BLOCKHASH = (0,rpc_types_dist_index_node/* blockhash */.Ae)('11111111111111111111111111111111'); /** * Builds the wire bytes of an unsigned versioned (v0) transaction. * Prepends compact-u16 signature count + N zero-filled 64-byte signature * slots to the compiled message bytes. */ function buildUnsignedTransactionBytes(numSigners, messageBytes) { const sigCountBytes = shortU16Encoder.encode(numSigners); const sigsLen = numSigners * 64; const result = new Uint8Array(sigCountBytes.length + sigsLen + messageBytes.length); result.set(sigCountBytes, 0); // signature slots are already zero-filled by Uint8Array constructor result.set(messageBytes, sigCountBytes.length + sigsLen); return result; } /** * Serializes an SvmTransaction into base58-encoded formats compatible * with the Squads multisig UI. * * Produces two representations: * - `transaction_base58`: full unsigned v0 transaction (signatures + message) * - `message_base58`: compiled message only (no signature wrapper) * * Both use a default (all-zeros) blockhash since these are unsigned * transactions intended for offline / multisig signing workflows. */ function serializeUnsignedTransaction(instructions, feePayer) { const txMessage = (0,transaction_messages_dist_index_node/* createTransactionMessage */.mN)({ version: 0 }); const withFeePayer = (0,transaction_messages_dist_index_node/* setTransactionMessageFeePayer */.t_)(feePayer, txMessage); const withLifetime = (0,transaction_messages_dist_index_node/* setTransactionMessageLifetimeUsingBlockhash */.S$)({ blockhash: DEFAULT_BLOCKHASH, lastValidBlockHeight: 0n }, withFeePayer); const withInstructions = (0,transaction_messages_dist_index_node/* appendTransactionMessageInstructions */.Fx)(instructions, withLifetime); const compiled = (0,transaction_messages_dist_index_node/* compileTransactionMessage */.rt)(withInstructions); const messageBytes = messageEncoder.encode(compiled); const transactionBytes = buildUnsignedTransactionBytes(compiled.header.numSignerAccounts, messageBytes); return { transactionBase58: base58Decoder.decode(transactionBytes), messageBase58: base58Decoder.decode(messageBytes), }; } //# sourceMappingURL=tx.js.map ;// CONCATENATED MODULE: ../svm-sdk/dist/clients/signer.js class SvmTransactionError extends Error { constructor(signature, cause) { super(`Transaction failed: ${signature}, err: ${JSON.stringify(cause, (_k, v) => (typeof v === 'bigint' ? v.toString() : v))}`); this.name = 'SvmTransactionError'; this.cause = cause; } } const base58Encoder = (0,codecs_strings_dist_index_node/* getBase58Encoder */.nZ)(); function parseKeyBytes(privateKey) { // Try hex (32 bytes = 64 hex chars, 64 bytes = 128 hex chars) const stripped = (0,addresses/* strip0x */.LL)(privateKey); if (/^[0-9a-fA-F]{64}$/.test(stripped)) { return new Uint8Array(Buffer.from(stripped, 'hex')); } if (/^[0-9a-fA-F]{128}$/.test(stripped)) { return new Uint8Array(Buffer.from(stripped, 'hex')); } // Try base58 let keyBytes; try { keyBytes = base58Encoder.encode(privateKey); } catch (err) { throw new Error(`Failed to parse private key. Expected hex (64 or 128 chars) or base58. ` + `Base58 error: ${err instanceof Error ? err.message : String(err)}`); } if (keyBytes.length !== 32 && keyBytes.length !== 64) { throw new Error(`Base58-decoded key has invalid length: ${keyBytes.length}. Expected 32 (private key) or 64 (keypair).`); } return keyBytes; } const RPC_COMMITMENT_LEVEL = 'confirmed'; /** * Detects blockhash-not-found errors from sendTransaction. * The RPC wraps it as a preflight failure (-32002) with the * BlockhashNotFound error as its cause. */ function isBlockhashNotFoundError(error) { if ((0,errors_dist_index_node/* isSolanaError */.zbS)(error, errors_dist_index_node/* SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND */.fmt)) { return true; } if ((0,errors_dist_index_node/* isSolanaError */.zbS)(error, errors_dist_index_node/* SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE */.d0u)) { return (0,errors_dist_index_node/* isSolanaError */.zbS)(error.cause, errors_dist_index_node/* SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND */.fmt); } return false; } class SvmSigner extends SvmProvider { signer; logger = logging/* rootLogger */.Jk.child({ module: 'SvmSigner' }); constructor(rpc, rpcUrls, signer) { super(rpc, rpcUrls); this.signer = signer; } static async connectWithSigner(rpcUrls, privateKey, _extraParams) { (0,validation/* assert */.v)(rpcUrls.length > 0, 'At least one RPC URL is required'); const rpc = createRpc(rpcUrls[0]); const keyBytes = parseKeyBytes(privateKey); let keypair; if (keyBytes.length === 32) { keypair = await (0,signers_dist_index_node/* createKeyPairSignerFromPrivateKeyBytes */.bY)(keyBytes); } else if (keyBytes.length === 64) { keypair = await (0,signers_dist_index_node/* createKeyPairSignerFromBytes */.Lt)(keyBytes); } else { throw new Error(`Invalid key length: ${keyBytes.length}. Expected 32 (private key) or 64 (keypair).`); } return new SvmSigner(rpc, rpcUrls, keypair); } getSignerAddress() { return this.signer.address; } supportsTransactionBatching() { return false; } async transactionToPrintableJson(transaction) { const { transactionBase58, messageBase58 } = serializeUnsignedTransaction(transaction.instructions, transaction.feePayer ?? this.signer.address); return { annotation: transaction.annotation, instructions: transaction.instructions.map((ix) => ({ programAddress: ix.programAddress, accounts: ix.accounts, data: ix.data ? Buffer.from(ix.data).toString('hex') : undefined, })), computeUnits: transaction.computeUnits, transaction_base58: transactionBase58, message_base58: messageBase58, }; } /** * Builds, signs, and sends a transaction with a confirmed blockhash. * Retries on blockhash-not-found errors with backoff to handle * load-balanced RPC node desync. */ async signAndSend(tx, maxAttempts = 5) { for (let attempt = 0; attempt < maxAttempts; attempt++) { const { value: latestBlockhash } = await this.rpc .getLatestBlockhash({ commitment: RPC_COMMITMENT_LEVEL }) .send(); let txMessage = buildTransactionMessage({ instructions: tx.instructions, feePayer: this.signer, recentBlockhash: latestBlockhash.blockhash, lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, computeUnits: tx.computeUnits ?? constants_DEFAULT_COMPUTE_UNITS, }); if (tx.additionalSigners?.length) { txMessage = (0,signers_dist_index_node/* addSignersToTransactionMessage */.pO)(tx.additionalSigners, txMessage); } const signedTx = await (0,signers_dist_index_node/* signTransactionMessageWithSigners */.Q4)(txMessage); const signature = (0,transactions_dist_index_node/* getSignatureFromTransaction */.fz)(signedTx); try { const rawTx = (0,transactions_dist_index_node/* getBase64EncodedWireTransaction */.RO)(signedTx); await this.rpc .sendTransaction(rawTx, { encoding: 'base64', skipPreflight: tx.skipPreflight ?? false, // Set to 0 to avoid conflicts between the rpc/provider // retrying and the signer as it tracks and retries // pending txs manually maxRetries: 0n, preflightCommitment: RPC_COMMITMENT_LEVEL, }) .send(); return { signature, rawTx, lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, }; } catch (error) { if (isBlockhashNotFoundError(error) && attempt < maxAttempts - 1) { const delay = 500 * (attempt + 1); this.logger.debug(`Blockhash not found on attempt ${attempt + 1}, retrying in ${delay}ms`); await (0,dist_async/* sleep */.yy)(delay); continue; } throw error; } } // Unreachable: the loop always either returns or throws throw new Error('signAndSend: unreachable'); } /** * Evaluates a signature status result. Throws on error, returns * `{ confirmed: true, slot }` if confirmed/finalized, `{ confirmed: false }` * if still progressing, or `null` if the signature was not found. */ checkSignatureResult(signature, result) { if (!result) return null; if (result.err) { throw new SvmTransactionError(signature, result.err); } if (result.confirmationStatus === RPC_COMMITMENT_LEVEL || result.confirmationStatus === 'finalized') { return { confirmed: true, slot: result.slot }; } return { confirmed: false }; } /** * Sends a transaction and polls for confirmation. On blockhash expiry, * checks transaction history before resubmitting to prevent double-execution. */ async send(tx) { const maxBlockhashAttempts = 3; const pollIntervalMs = 2000; let lastSignature; for (let blockhashAttempt = 0; blockhashAttempt < maxBlockhashAttempts; blockhashAttempt++) { const { signature, rawTx, lastValidBlockHeight } = await this.signAndSend(tx); lastSignature = signature; // Poll while blockhash is valid const result = await this.pollForConfirmation(signature, rawTx, lastValidBlockHeight, pollIntervalMs); if (result) { return result; } // Blockhash expired — check history before resubmitting let historyCheck = null; try { const historyStatus = await this.rpc .getSignatureStatuses([signature], { searchTransactionHistory: true, }) .send(); historyCheck = this.checkSignatureResult(signature, historyStatus.value[0]); } catch (error) { if (error instanceof SvmTransactionError) throw error; throw new Error(`Cannot safely resubmit: history lookup failed for ${signature}, aborting to prevent double-execution.`, { cause: error }); } if (historyCheck?.confirmed) { return { signature, slot: historyCheck.slot }; } if (historyCheck) { // Tx still progressing (e.g. 'processed') — keep polling same // signature with a fresh block height ceiling const { value: freshBlockhash } = await this.rpc .getLatestBlockhash({ commitment: RPC_COMMITMENT_LEVEL }) .send(); const retry = await this.pollForConfirmation(signature, rawTx, freshBlockhash.lastValidBlockHeight, pollIntervalMs); if (retry) return retry; throw new Error(`Transaction ${signature} was observed at 'processed' but never confirmed`); } if (blockhashAttempt < maxBlockhashAttempts - 1) { this.logger.debug(`Blockhash expired and tx not found, resubmitting (attempt ${blockhashAttempt + 2}/${maxBlockhashAttempts})`); } } throw new Error(`Transaction not confirmed after ${maxBlockhashAttempts} blockhash attempts (last signature: ${lastSignature})`); } /** * Polls getSignatureStatuses while the blockhash is still valid. * Rebroadcasts the same signed tx periodically (fire-and-forget). * Returns the receipt if confirmed, or null if the blockhash expired. */ async pollForConfirmation(signature, rawTx, lastValidBlockHeight, pollIntervalMs) { const maxBlockHeightFailures = 3; const wallClockDeadline = Date.now() + 2 * 60 * 1000; let blockHeightFailures = 0; let delay = Math.max(Math.floor(pollIntervalMs / 4), 250); while (Date.now() < wallClockDeadline) { await (0,dist_async/* sleep */.yy)(delay); delay = Math.min(Math.floor(delay * 1.5), pollIntervalMs); // Check confirmation status try { const status = await this.rpc.getSignatureStatuses([signature]).send(); const check = this.checkSignatureResult(signature, status.value[0]); if (check?.confirmed) { return { signature, slot: check.slot }; } // Transaction seen (e.g. 'processed') — keep polling, don't rebroadcast if (check) continue; } catch (error) { if (error instanceof SvmTransactionError) throw error; this.logger.debug('Status poll failed', { error }); } // Check if blockhash expired try { const currentBlockHeight = await this.rpc .getBlockHeight({ commitment: RPC_COMMITMENT_LEVEL }) .send(); // Reset on successful fetch blockHeightFailures = 0; if (currentBlockHeight > lastValidBlockHeight) { return null; } } catch (error) { blockHeightFailures++; this.logger.debug('Block height check failed', { error }); if (blockHeightFailures >= maxBlockHeightFailures) { this.logger.warn(`Block height check failed ${maxBlockHeightFailures} times, treating as expired`); return null; } } // Rebroadcast same signed tx (fire-and-forget, always skip preflight) try { await this.rpc .sendTransaction(rawTx, { encoding: 'base64', skipPreflight: true, maxRetries: 0n, }) .send(); } catch (error) { this.logger.debug('Rebroadcast failed', { error, signature }); } } // Wall-clock timeout exceeded — tx fate unknown, unsafe to resubmit throw new Error(`Poll timeout exceeded for ${signature}, aborting to prevent potential double-execution`); } async sendAndConfirmTransaction(transaction) { const tx = isLegacySolanaTransaction(transaction) ? await convertLegacySolanaTransaction(transaction, transaction.extraSigners) : transaction; const receipt = await this.send(tx); return this.fetchTransactionMeta(receipt); } /** * Fetches full transaction to populate meta (including logs) on the receipt. * Retries with backoff since RPC indexing can lag behind confirmation. * // TODO: make meta-fetch opt-in once the legacy compat layer is removed */ async fetchTransactionMeta(receipt, maxRetries = 5) { (0,keys_dist_index_node/* assertIsSignature */.P)(receipt.signature); for (let attempt = 0; attempt < maxRetries; attempt++) { try { const fullTx = await this.rpc .getTransaction(receipt.signature, { commitment: RPC_COMMITMENT_LEVEL, maxSupportedTransactionVersion: 0, encoding: 'jsonParsed', }) .send(); if (fullTx?.meta?.logMessages) { return { ...receipt, meta: { logMessages: fullTx.meta.logMessages }, }; } } catch (error) { this.logger.debug(`Attempt ${attempt + 1} failed to fetch tx meta`, { error, }); } if (attempt < maxRetries - 1) { await (0,dist_async/* sleep */.yy)(1000 * (attempt + 1)); } } this.logger.warn('Transaction meta unavailable after retries', { signature: receipt.signature, }); return receipt; } async sendAndConfirmBatchTransactions(_transactions) { throw new Error('Sealevel does not support transaction batching'); } } //# sourceMappingURL=signer.js.map ;// CONCATENATED MODULE: ../svm-sdk/dist/hyperlane/program-bytes.js /** * Auto-generated program bytes from compiled .so binaries. * DO NOT EDIT — regenerate with: * pnpm -C typescript/svm-sdk program:build * pnpm -C typescript/svm-sdk program:generate */ /** SHA-256 of Rust sealevel sources at generation time. Used for CI staleness detection. */ const SEALEVEL_SOURCE_HASH = '51857b8b96079e6a98161e7a4a9cb069edc25a18212983086a7da4e5235beb09'; const HYPERLANE_SVM_PROGRAM_BYTES = { mailbox: new Uint8Array([ 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 7, 1, 1, 0, 0, 0, 240, 235, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 208, 167, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 56, 0, 4, 0, 64, 0, 9, 0, 8, 0, 1, 0, 0, 0, 5, 0, 0, 0, 32, 1, 0, 0, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 0, 0, 160, 72, 2, 0, 0, 0, 0, 0, 160, 72, 2, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 192, 73, 2, 0, 0, 0, 0, 0, 192, 73, 2, 0, 0, 0, 0, 0, 192, 73, 2, 0, 0, 0, 0, 0, 240, 50, 0, 0, 0, 0, 0, 0, 240, 50, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 96, 125, 2, 0, 0, 0, 0, 0, 96, 125, 2, 0, 0, 0, 0, 0, 96, 125, 2, 0, 0, 0, 0, 0, 40, 42, 0, 0, 0, 0, 0, 0, 40, 42, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 176, 124, 2, 0, 0, 0, 0, 0, 176, 124, 2, 0, 0, 0, 0, 0, 176, 124, 2, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 191, 39, 0, 0, 0, 0, 0, 0, 123, 26, 232, 251, 0, 0, 0, 0, 122, 10, 232, 255, 0, 0, 0, 0, 122, 10, 224, 255, 0, 0, 0, 0, 122, 10, 216, 255, 0, 0, 0, 0, 122, 10, 208, 255, 0, 0, 0, 0, 191, 161, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 240, 251, 255, 255, 183, 6, 0, 0, 0, 0, 0, 0, 183, 2, 0, 0, 0, 0, 0, 0, 183, 3, 0, 0, 224, 3, 0, 0, 133, 16, 0, 0, 90, 71, 0, 0, 121, 120, 0, 0, 0, 0, 0, 0, 123, 122, 224, 251, 0, 0, 0, 0, 121, 113, 8, 0, 0, 0, 0, 0, 191, 18, 0, 0, 0, 0, 0, 0, 191, 41, 0, 0, 0, 0, 0, 0, 191, 103, 0, 0, 0, 0, 0, 0, 165, 9, 28, 0, 32, 0, 0, 0, 191, 130, 0, 0, 0, 0, 0, 0, 15, 114, 0, 0, 0, 0, 0, 0, 121, 35, 6, 0, 0, 0, 0, 0, 113, 36, 14, 0, 0, 0, 0, 0, 115, 74, 248, 255, 0, 0, 0, 0, 123, 58, 240, 255, 0, 0, 0, 0, 191, 164, 0, 0, 0, 0, 0, 0, 7, 4, 0, 0, 240, 251, 255, 255, 15, 116, 0, 0, 0, 0, 0, 0, 121, 165, 241, 255, 0, 0, 0, 0, 97, 32, 0, 0, 0, 0, 0, 0, 99, 4, 0, 0, 0, 0, 0, 0, 105, 32, 4, 0, 0, 0, 0, 0, 107, 4, 4, 0, 0, 0, 0, 0, 123, 84, 7, 0, 0, 0, 0, 0, 115, 52, 6, 0, 0, 0, 0, 0, 121, 35, 15, 0, 0, 0, 0, 0, 123, 52, 15, 0, 0, 0, 0, 0, 121, 35, 23, 0, 0, 0, 0, 0, 123, 52, 23, 0, 0, 0, 0, 0, 113, 34, 31, 0, 0, 0, 0, 0, 115, 36, 31, 0, 0, 0, 0, 0, 191, 146, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 224, 255, 255, 255, 191, 118, 0, 0, 0, 0, 0, 0, 7, 6, 0, 0, 32, 0, 0, 0, 85, 6, 226, 255, 0, 4, 0, 0, 53, 2, 12, 0, 8, 0, 0, 0, 24, 1, 0, 0, 88, 110, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 187, 55, 0, 0, 15, 120, 0, 0, 0, 0, 0, 0, 15, 152, 0, 0, 0, 0, 0, 0, 121, 161, 224, 251, 0, 0, 0, 0, 123, 129, 0, 0, 0, 0, 0, 0, 122, 1, 8, 0, 0, 0, 0, 0, 121, 161, 232, 251, 0, 0, 0, 0, 123, 1, 8, 0, 0, 0, 0, 0, 122, 1, 0, 0, 1, 0, 0, 0, 5, 0, 17, 0, 0, 0, 0, 0, 15, 104, 0, 0, 0, 0, 0, 0, 31, 97, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 248, 255, 255, 255, 121, 134, 0, 0, 0, 0, 0, 0, 121, 162, 224, 251, 0, 0, 0, 0, 123, 18, 8, 0, 0, 0, 0, 0, 7, 8, 0, 0, 8, 0, 0, 0, 123, 130, 0, 0, 0, 0, 0, 0, 121, 167, 232, 251, 0, 0, 0, 0, 191, 113, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 8, 0, 0, 0, 191, 162, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 240, 251, 255, 255, 183, 3, 0, 0, 0, 4, 0, 0, 133, 16, 0, 0, 24, 71, 0, 0, 123, 103, 8, 4, 0, 0, 0, 0, 122, 7, 0, 0, 0, 0, 0, 0, 149, 0, 0, 0, 0, 0, 0, 0, 191, 38, 0, 0, 0, 0, 0, 0, 113, 24, 100, 0, 0, 0, 0, 0, 121, 98, 0, 0, 0, 0, 0, 0, 121, 103, 16, 0, 0, 0, 0, 0, 29, 114, 80, 0, 0, 0, 0, 0, 121, 99, 8, 0, 0, 0, 0, 0, 191, 52, 0, 0, 0, 0, 0, 0, 15, 116, 0, 0, 0, 0, 0, 0, 115, 132, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 1, 0, 0, 0, 123, 118, 16, 0, 0, 0, 0, 0, 191, 36, 0, 0, 0, 0, 0, 0, 31, 116, 0, 0, 0, 0, 0, 0, 97, 24, 88, 0, 0, 0, 0, 0, 220, 8, 0, 0, 32, 0, 0, 0, 181, 4, 78, 0, 3, 0, 0, 0, 191, 52, 0, 0, 0, 0, 0, 0, 15, 116, 0, 0, 0, 0, 0, 0, 99, 132, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 4, 0, 0, 0, 123, 118, 16, 0, 0, 0, 0, 0, 31, 114, 0, 0, 0, 0, 0, 0, 97, 24, 92, 0, 0, 0, 0, 0, 220, 8, 0, 0, 32, 0, 0, 0, 181, 2, 79, 0, 3, 0, 0, 0, 15, 115, 0, 0, 0, 0, 0, 0, 99, 131, 0, 0, 0, 0, 0, 0, 191, 24, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 24, 0, 0, 0, 7, 7, 0, 0, 4, 0, 0, 0, 123, 118, 16, 0, 0, 0, 0, 0, 121, 99, 0, 0, 0, 0, 0, 0, 191, 50, 0, 0, 0, 0, 0, 0, 31, 114, 0, 0, 0, 0, 0, 0, 181, 2, 78, 0, 31, 0, 0, 0, 121, 98, 8, 0, 0, 0, 0, 0, 191, 36, 0, 0, 0, 0, 0, 0, 15, 116, 0, 0, 0, 0, 0, 0, 121, 133, 24, 0, 0, 0, 0, 0, 123, 84, 24, 0, 0, 0, 0, 0, 121, 133, 16, 0, 0, 0, 0, 0, 123, 84, 16, 0, 0, 0, 0, 0, 121, 133, 8, 0, 0, 0, 0, 0, 123, 84, 8, 0, 0, 0, 0, 0, 121, 133, 0, 0, 0, 0, 0, 0, 123, 84, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 32, 0, 0, 0, 123, 118, 16, 0, 0, 0, 0, 0, 191, 52, 0, 0, 0, 0, 0, 0, 31, 116, 0, 0, 0, 0, 0, 0, 97, 24, 96, 0, 0, 0, 0, 0, 220, 8, 0, 0, 32, 0, 0, 0, 181, 4, 69, 0, 3, 0, 0, 0, 191, 36, 0, 0, 0, 0, 0, 0, 15, 116, 0, 0, 0, 0, 0, 0, 99, 132, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 4, 0, 0, 0, 123, 118, 16, 0, 0, 0, 0, 0, 191, 24, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 56, 0, 0, 0, 31, 115, 0, 0, 0, 0, 0, 0, 181, 3, 70, 0, 31, 0, 0, 0, 15, 114, 0, 0, 0, 0, 0, 0, 121, 131, 24, 0, 0, 0, 0, 0, 123, 50, 24, 0, 0, 0, 0, 0, 121, 131, 16, 0, 0, 0, 0, 0, 123, 50, 16, 0, 0, 0, 0, 0, 121, 131, 8, 0, 0, 0, 0, 0, 123, 50, 8, 0, 0, 0, 0, 0, 121, 131, 0, 0, 0, 0, 0, 0, 123, 50, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 32, 0, 0, 0, 123, 118, 16, 0, 0, 0, 0, 0, 121, 99, 0, 0, 0, 0, 0, 0, 31, 115, 0, 0, 0, 0, 0, 0, 121, 18, 8, 0, 0, 0, 0, 0, 121, 24, 16, 0, 0, 0, 0, 0, 173, 131, 63, 0, 0, 0, 0, 0, 121, 97, 8, 0, 0, 0, 0, 0, 15, 113, 0, 0, 0, 0, 0, 0, 191, 131, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 195, 70, 0, 0, 15, 135, 0, 0, 0, 0, 0, 0, 123, 118, 16, 0, 0, 0, 0, 0, 149, 0, 0, 0, 0, 0, 0, 0, 191, 25, 0, 0, 0, 0, 0, 0, 191, 97, 0, 0, 0, 0, 0, 0, 191, 114, 0, 0, 0, 0, 0, 0, 183, 3, 0, 0, 1, 0, 0, 0, 133, 16, 0, 0, 159, 7, 0, 0, 191, 145, 0, 0, 0, 0, 0, 0, 121, 98, 0, 0, 0, 0, 0, 0, 121, 103, 16, 0, 0, 0, 0, 0, 5, 0, 167, 255, 0, 0, 0, 0, 191, 25, 0, 0, 0, 0, 0, 0, 191, 97, 0, 0, 0, 0, 0, 0, 191, 114, 0, 0, 0, 0, 0, 0, 183, 3, 0, 0, 4, 0, 0, 0, 133, 16, 0, 0, 150, 7, 0, 0, 191, 145, 0, 0, 0, 0, 0, 0, 121, 98, 0, 0, 0, 0, 0, 0, 121, 99, 8, 0, 0, 0, 0, 0, 121, 103, 16, 0, 0, 0, 0, 0, 5, 0, 168, 255, 0, 0, 0, 0, 191, 25, 0, 0, 0, 0, 0, 0, 191, 97, 0, 0, 0, 0, 0, 0, 191, 114, 0, 0, 0, 0, 0, 0, 183, 3, 0, 0, 4, 0, 0, 0, 133, 16, 0, 0, 140, 7, 0, 0, 191, 145, 0, 0, 0, 0, 0, 0, 121, 99, 8, 0, 0, 0, 0, 0, 121, 103, 16, 0, 0, 0, 0, 0, 5, 0, 168, 255, 0, 0, 0, 0, 191, 25, 0, 0, 0, 0, 0, 0, 191, 97, 0, 0, 0, 0, 0, 0, 191, 114, 0, 0, 0, 0, 0, 0, 183, 3, 0, 0, 32, 0, 0, 0, 133, 16, 0, 0, 131, 7, 0, 0, 191, 145, 0, 0, 0, 0, 0, 0, 121, 99, 0, 0, 0, 0, 0, 0, 121, 103, 16, 0, 0, 0, 0, 0, 5, 0, 169, 255, 0, 0, 0, 0, 191, 25, 0, 0, 0, 0, 0, 0, 191, 97, 0, 0, 0, 0, 0, 0, 191, 114, 0, 0, 0, 0, 0, 0, 183, 3, 0, 0, 4, 0, 0, 0, 133, 16, 0, 0, 122, 7, 0, 0, 191, 145, 0, 0, 0, 0, 0, 0, 121, 99, 0, 0, 0, 0, 0, 0, 121, 98, 8, 0, 0, 0, 0, 0, 121, 103, 16, 0, 0, 0, 0, 0, 5, 0, 177, 255, 0, 0, 0, 0, 191, 25, 0, 0, 0, 0, 0, 0, 191, 97, 0, 0, 0, 0, 0, 0, 191, 114, 0, 0, 0, 0, 0, 0, 183, 3, 0, 0, 32, 0, 0, 0, 133, 16, 0, 0, 112, 7, 0, 0, 191, 145, 0, 0, 0, 0, 0, 0, 121, 98, 8, 0, 0, 0, 0, 0, 121, 103, 16, 0, 0, 0, 0, 0, 5, 0, 177, 255, 0, 0, 0, 0, 191, 97, 0, 0, 0, 0, 0, 0, 191, 41, 0, 0, 0, 0, 0, 0, 191, 114, 0, 0, 0, 0, 0, 0, 191, 131, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 103, 7, 0, 0, 191, 146, 0, 0, 0, 0, 0, 0, 121, 103, 16, 0, 0, 0, 0, 0, 5, 0, 185, 255, 0, 0, 0, 0, 191, 54, 0, 0, 0, 0, 0, 0, 191, 39, 0, 0, 0, 0, 0, 0, 123, 26, 232, 255, 0, 0, 0, 0, 183, 9, 0, 0, 1, 0, 0, 0, 85, 6, 1, 0, 0, 0, 0, 0, 183, 9, 0, 0, 0, 0, 0, 0, 114, 10, 243, 255, 1, 0, 0, 0, 191, 162, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 243, 255, 255, 255, 191, 113, 0, 0, 0, 0, 0, 0, 191, 147, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 116, 70, 0, 0, 21, 6, 49, 0, 0, 0, 0, 0, 31, 150, 0, 0, 0, 0, 0, 0, 121, 161, 232, 255, 0, 0, 0, 0, 97, 17, 40, 0, 0, 0, 0, 0, 99, 26, 244, 255, 0, 0, 0, 0, 15, 151, 0, 0, 0, 0, 0, 0, 191, 105, 0, 0, 0, 0, 0, 0, 165, 6, 1, 0, 4, 0, 0, 0, 183, 9, 0, 0, 4, 0, 0, 0, 191, 162, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 244, 255, 255, 255, 191, 113, 0, 0, 0, 0, 0, 0, 191, 147, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 102, 70, 0, 0, 165, 6, 35, 0, 4, 0, 0, 0, 183, 8, 0, 0, 1, 0, 0, 0, 85, 6, 1, 0, 4, 0, 0, 0, 183, 8, 0, 0, 0, 0, 0, 0, 15, 151, 0, 0, 0, 0, 0, 0, 121, 162, 232, 255, 0, 0, 0, 0, 7, 2, 0, 0, 44, 0, 0, 0, 191, 113, 0, 0, 0, 0, 0, 0, 191, 131, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 92, 70, 0, 0, 21, 6, 25, 0, 4, 0, 0, 0, 15, 135, 0, 0, 0, 0, 0, 0, 167, 9, 0, 0, 255, 255, 255, 255, 15, 150, 0, 0, 0, 0, 0, 0, 191, 104, 0, 0, 0, 0, 0, 0, 165, 6, 1, 0, 32, 0, 0, 0, 183, 8, 0, 0, 32, 0, 0, 0, 191, 113, 0, 0, 0, 0, 0, 0, 121, 162, 232, 255, 0, 0, 0, 0, 191, 131, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 81, 70, 0, 0, 165, 6, 14, 0, 32, 0, 0, 0, 121, 161, 232, 255, 0, 0, 0, 0, 121, 17, 32, 0, 0, 0, 0, 0, 123, 26, 248, 255, 0, 0, 0, 0, 15, 135, 0, 0, 0, 0, 0, 0, 31, 134, 0, 0, 0, 0, 0, 0, 191, 99, 0, 0, 0, 0, 0, 0, 165, 6, 1, 0, 8, 0, 0, 0, 183, 3, 0, 0, 8, 0, 0, 0, 191, 162, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 248, 255, 255, 255, 191, 113, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 68, 70, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 37, 6, 21, 0, 7, 0, 0, 0, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 121, 17, 0, 0, 0, 0, 0, 0, 191, 19, 0, 0, 0, 0, 0, 0, 7, 3, 0, 0, 248, 255, 255, 255, 183, 2, 0, 0, 0, 0, 0, 0, 183, 4, 0, 0, 1, 0, 0, 0, 189, 19, 14, 0, 0, 0, 0, 0, 21, 4, 15, 0, 0, 0, 0, 0, 24, 0, 0, 0, 248, 127, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 85, 1, 16, 0, 0, 0, 0, 0, 24, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 173, 16, 18, 0, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 123, 1, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 240, 109, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 16, 0, 0, 0, 0, 0, 0, 149, 0, 0, 0, 0, 0, 0, 0, 183, 4, 0, 0, 0, 0, 0, 0, 85, 4, 241, 255, 0, 0, 0, 0, 191, 50, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 248, 127, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 21, 1, 240, 255, 0, 0, 0, 0, 87, 2, 0, 0, 248, 255, 255, 255, 191, 32, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 61, 16, 238, 255, 0, 0, 0, 0, 183, 1, 0, 0, 8, 0, 0, 0, 183, 2, 0, 0, 8, 0, 0, 0, 133, 16, 0, 0, 182, 56, 0, 0, 191, 39, 0, 0, 0, 0, 0, 0, 191, 22, 0, 0, 0, 0, 0, 0, 121, 121, 0, 0, 0, 0, 0, 0, 121, 113, 8, 0, 0, 0, 0, 0, 53, 1, 2, 0, 4, 0, 0, 0, 15, 25, 0, 0, 0, 0, 0, 0, 5, 0, 2, 0, 0, 0, 0, 0, 85, 1, 21, 0, 4, 0, 0, 0, 7, 9, 0, 0, 4, 0, 0, 0, 24, 1, 0, 0, 88, 110, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 157, 54, 0, 0, 123, 151, 0, 0, 0, 0, 0, 0, 122, 7, 8, 0, 0, 0, 0, 0, 191, 1, 0, 0, 0, 0, 0, 0, 87, 1, 0, 0, 3, 0, 0, 0, 191, 18, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 254, 255, 255, 255, 165, 2, 6, 0, 2, 0, 0, 0, 21, 1, 5, 0, 0, 0, 0, 0, 121, 1, 7, 0, 0, 0, 0, 0, 121, 18, 0, 0, 0, 0, 0, 0, 21, 2, 2, 0, 0, 0, 0, 0, 121, 1, 255, 255, 0, 0, 0, 0, 141, 0, 0, 0, 2, 0, 0, 0, 98, 6, 4, 0, 14, 0, 0, 0, 183, 1, 0, 0, 1, 0, 0, 0, 99, 22, 0, 0, 0, 0, 0, 0, 149, 0, 0, 0, 0, 0, 0, 0, 97, 148, 0, 0, 0, 0, 0, 0, 191, 18, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 251, 255, 255, 255, 113, 149, 4, 0, 0, 0, 0, 0, 123, 39, 8, 0, 0, 0, 0, 0, 21, 2, 40, 0, 0, 0, 0, 0, 191, 19, 0, 0, 0, 0, 0, 0, 7, 3, 0, 0, 250, 255, 255, 255, 113, 152, 5, 0, 0, 0, 0, 0, 123, 55, 8, 0, 0, 0, 0, 0, 191, 147, 0, 0, 0, 0, 0, 0, 7, 3, 0, 0, 6, 0, 0, 0, 123, 55, 0, 0, 0, 0, 0, 0, 115, 138, 215, 255, 0, 0, 0, 0, 21, 8, 37, 0, 0, 0, 0, 0, 85, 8, 57, 0, 1, 0, 0, 0, 165, 2, 215, 255, 33, 0, 0, 0, 123, 90, 104, 247, 0, 0, 0, 0, 123, 74, 112, 247, 0, 0, 0, 0, 121, 146, 12, 0, 0, 0, 0, 0, 113, 148, 20, 0, 0, 0, 0, 0, 115, 74, 176, 247, 0, 0, 0, 0, 97, 52, 0, 0, 0, 0, 0, 0, 99, 74, 160, 247, 0, 0, 0, 0, 105, 51, 4, 0, 0, 0, 0, 0, 107, 58, 164, 247, 0, 0, 0, 0, 123, 42, 168, 247, 0, 0, 0, 0, 121, 165, 169, 247, 0, 0, 0, 0, 7, 1, 0, 0, 218, 255, 255, 255, 123, 23, 8, 0, 0, 0, 0, 0, 191, 145, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 38, 0, 0, 0, 123, 23, 0, 0, 0, 0, 0, 0, 121, 145, 21, 0, 0, 0, 0, 0, 121, 147, 29, 0, 0, 0, 0, 0, 113, 148, 37, 0, 0, 0, 0, 0, 115, 42, 144, 247, 0, 0, 0, 0, 115, 74, 136, 247, 0, 0, 0, 0, 123, 58, 128, 247, 0, 0, 0, 0, 123, 26, 120, 247, 0, 0, 0, 0, 123, 90, 145, 247, 0, 0, 0, 0, 119, 5, 0, 0, 56, 0, 0, 0, 123, 90, 88, 247, 0, 0, 0, 0, 121, 161, 144, 247, 0, 0, 0, 0, 123, 26, 80, 247, 0, 0, 0, 0, 5, 0, 8, 0, 0, 0, 0, 0, 7, 9, 0, 0, 5, 0, 0, 0, 24, 1, 0, 0, 88, 110, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 16, 0, 0, 90, 54, 0, 0, 123, 151, 0, 0, 0, 0, 0, 0, 5, 0, 189, 255, 0, 0, 0, 0, 123, 90, 104, 247, 0, 0, 0, 0, 123, 74, 112, 247, 0, 0, 0, 0, 191, 161, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 168, 247, 255, 255, 191, 114, 0, 0, 0, 0, 0