UNPKG

@silvana-one/mina-utils

Version:
1,336 lines (1,313 loc) 1.9 MB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // dist/node/index.js var index_exports = {}; __export(index_exports, { BLS_FR: () => BLS_FR, Fr: () => Fr, Memory: () => Memory, R: () => R, S: () => S, TABLE0: () => TABLE0, TABLE0_ROOT: () => TABLE0_ROOT, TABLE1: () => TABLE1, TABLE1_ROOT: () => TABLE1_ROOT, TABLE2: () => TABLE22, TABLE2_ROOT: () => TABLE2_ROOT, TinyContract: () => TinyContract, WITNESSES0: () => WITNESSES0, WITNESSES1: () => WITNESSES1, WITNESSES2: () => WITNESSES2, Witness: () => Witness, accountBalance: () => accountBalance, accountBalanceMina: () => accountBalanceMina, accountExists: () => accountExists, bigintFromBase56: () => bigintFromBase56, bigintFromBase64: () => bigintFromBase64, bigintToBase56: () => bigintToBase56, bigintToBase64: () => bigintToBase64, blsCommitment: () => blsCommitment, checkAddress: () => checkAddress, checkMinaZkappTransaction: () => checkMinaZkappTransaction, commit: () => commit, convertFieldToCanonicalElement: () => convertFieldToCanonicalElement, createIpfsURL: () => createIpfsURL, createMerkleTree: () => createMerkleTree, createTransactionPayloads: () => createTransactionPayloads, currentNetwork: () => currentNetwork, deserializeFields: () => deserializeFields, digestStruct: () => digestStruct, fee: () => fee, fetchMinaAccount: () => fetchMinaAccount, fetchMinaActions: () => fetchMinaActions, fieldFromBase56: () => fieldFromBase56, fieldFromBase64: () => fieldFromBase64, fieldToBase56: () => fieldToBase56, fieldToBase64: () => fieldToBase64, formatTime: () => formatTime, fromBase: () => fromBase, getAccountNonce: () => getAccountNonce, getCurrentNetwork: () => getCurrentNetwork, getDeployer: () => getDeployer, getNetworkIdHash: () => getNetworkIdHash, getNonce: () => getNonce, getPaymentTxsFromBlockBerry: () => getPaymentTxsFromBlockBerry, getR: () => getR, getTable0Entry: () => getTable0Entry, getTable1Entry: () => getTable1Entry, getTable2Entry: () => getTable2Entry, getTxStatusFast: () => getTxStatusFast, getZkAppFromBlockBerry: () => getZkAppFromBlockBerry, getZkAppTxFromBlockBerry: () => getZkAppTxFromBlockBerry, getZkAppTxsFromBlockBerry: () => getZkAppTxsFromBlockBerry, initBlockchain: () => initBlockchain, makeString: () => makeString, parseTransactionPayloads: () => parseTransactionPayloads, pinJSON: () => pinJSON, rScalarPow: () => rScalarPow, rScalarPowLegacy: () => rScalarPowLegacy, rScalarPowProvable: () => rScalarPowProvable, scalar: () => scalar, sendTx: () => sendTx, serializeFields: () => serializeFields, serializeTransaction: () => serializeTransaction, sleep: () => sleep, toBase: () => toBase, tokenBalance: () => tokenBalance, transactionParams: () => transactionParams, txStatusBlockberry: () => txStatusBlockberry, update: () => update }); module.exports = __toCommonJS(index_exports); // dist/node/utils/base64-field.js var import_o1js = require("o1js"); // dist/node/utils/base64.js var TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; function bigintToBase56(value) { const digits = toBase(value, 56n); const str = digits.map((x) => TABLE[Number(x)]).join(""); return str; } function bigintFromBase56(str) { const base56Digits = str.split("").map((x2) => BigInt(TABLE.indexOf(x2))); const x = fromBase(base56Digits, 56n); return x; } function bigintToBase64(value) { const digits = toBase(value, 64n); const str = digits.map((x) => TABLE[Number(x)]).join(""); return str; } function bigintFromBase64(str) { const base64Digits = str.split("").map((x2) => BigInt(TABLE.indexOf(x2))); const x = fromBase(base64Digits, 64n); return x; } function fromBase(digits, base) { if (base <= 0n) throw Error("fromBase: base must be positive"); let basePowers = []; for (let power = base, n = 1; n < digits.length; power **= 2n, n *= 2) { basePowers.push(power); } let k = basePowers.length; digits = digits.concat(Array(2 ** k - digits.length).fill(0n)); for (let i = 0; i < k; i++) { let newDigits = Array(digits.length >> 1); let basePower = basePowers[i]; for (let j = 0; j < newDigits.length; j++) { newDigits[j] = digits[2 * j] + basePower * digits[2 * j + 1]; } digits = newDigits; } console.assert(digits.length === 1); let [digit] = digits; return digit; } function toBase(x, base) { if (base <= 0n) throw Error("toBase: base must be positive"); let basePowers = []; for (let power = base; power <= x; power **= 2n) { basePowers.push(power); } let digits = [x]; let k = basePowers.length; for (let i = 0; i < k; i++) { let newDigits = Array(2 * digits.length); let basePower = basePowers[k - 1 - i]; for (let j = 0; j < digits.length; j++) { let x2 = digits[j]; let high = x2 / basePower; newDigits[2 * j + 1] = high; newDigits[2 * j] = x2 - high * basePower; } digits = newDigits; } while (digits[digits.length - 1] === 0n) { digits.pop(); } return digits; } // dist/node/utils/base64-field.js var TABLE2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; function fieldToBase56(field) { const digits = toBase(field.toBigInt(), 56n); const str = digits.map((x) => TABLE2[Number(x)]).join(""); return str; } function fieldFromBase56(str) { const base56Digits = str.split("").map((x2) => BigInt(TABLE2.indexOf(x2))); const x = fromBase(base56Digits, 56n); return (0, import_o1js.Field)(x); } function fieldToBase64(field) { const digits = toBase(field.toBigInt(), 64n); const str = digits.map((x) => TABLE2[Number(x)]).join(""); return str; } function fieldFromBase64(str) { const base64Digits = str.split("").map((x2) => BigInt(TABLE2.indexOf(x2))); const x = fromBase(base64Digits, 64n); return (0, import_o1js.Field)(x); } // dist/node/utils/fetch.js var import_o1js2 = require("o1js"); // dist/node/utils/utils.js function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function makeString(length) { let outString = ``; const inOptions = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`; for (let i = 0; i < length; i++) { outString += inOptions.charAt(Math.floor(Math.random() * inOptions.length)); } return outString; } function formatTime(ms) { if (ms === void 0) return ""; if (ms < 1e3) return ms.toString() + " ms"; if (ms < 60 * 1e3) return parseInt((ms / 1e3).toString()).toString() + " sec"; if (ms < 60 * 60 * 1e3) { const minutes = parseInt((ms / 1e3 / 60).toString()); const seconds = parseInt(((ms - minutes * 60 * 1e3) / 1e3).toString()); return minutes.toString() + " min " + seconds.toString() + " sec"; } else { const hours = parseInt((ms / 1e3 / 60 / 60).toString()); const minutes = parseInt(((ms - hours * 60 * 60 * 1e3) / 1e3 / 60).toString()); return hours.toString() + " h " + minutes.toString() + " min"; } } var _Memory = class _Memory { constructor() { _Memory.rss = 0; } // eslint-disable-next-line @typescript-eslint/no-inferrable-types static info(description = ``, fullInfo = false) { const memoryData = process.memoryUsage(); const formatMemoryUsage = (data) => `${Math.round(data / 1024 / 1024)} MB`; const oldRSS = _Memory.rss; _Memory.rss = Math.round(memoryData.rss / 1024 / 1024); const memoryUsage = fullInfo ? { step: `${description}:`, rssDelta: `${(oldRSS === 0 ? 0 : _Memory.rss - oldRSS).toString()} MB -> Resident Set Size memory change`, rss: `${formatMemoryUsage(memoryData.rss)} -> Resident Set Size - total memory allocated`, heapTotal: `${formatMemoryUsage(memoryData.heapTotal)} -> total size of the allocated heap`, heapUsed: `${formatMemoryUsage(memoryData.heapUsed)} -> actual memory used during the execution`, external: `${formatMemoryUsage(memoryData.external)} -> V8 external memory` } : `RSS memory ${description}: ${formatMemoryUsage(memoryData.rss)}${oldRSS === 0 ? `` : `, changed by ` + (_Memory.rss - oldRSS).toString() + ` MB`}`; console.log(memoryUsage); } }; _Memory.rss = 0; var Memory = _Memory; // dist/node/utils/fetch.js async function fetchMinaAccount(params) { const { publicKey, tokenId, force = false } = params; const timeout = 1e3 * 60 * 3; let attempt = 0; const startTime = Date.now(); let result = { account: void 0 }; while (Date.now() - startTime < timeout) { try { const result2 = await (0, import_o1js2.fetchAccount)({ publicKey, tokenId }, void 0, { timeout: 5 * 1e3 }); return result2; } catch (error) { if (force === true) console.log("Error in fetchMinaAccount:", { error, publicKey: typeof publicKey === "string" ? publicKey : publicKey.toBase58(), tokenId: tokenId?.toString(), force }); else { console.log("fetchMinaAccount error", { error, publicKey: typeof publicKey === "string" ? publicKey : publicKey.toBase58(), tokenId: tokenId?.toString(), force }); return result; } } attempt++; await sleep(1e3 * 6 * attempt); } if (force === true) throw new Error(`fetchMinaAccount timeout ${{ publicKey: typeof publicKey === "string" ? publicKey : publicKey.toBase58(), tokenId: tokenId?.toString(), force }}`); else console.log("fetchMinaAccount timeout", typeof publicKey === "string" ? publicKey : publicKey.toBase58(), tokenId?.toString(), force); return result; } async function fetchMinaActions(publicKey, fromActionState, endActionState) { const timeout = 1e3 * 60 * 600; const startTime = Date.now(); while (Date.now() - startTime < timeout) { try { let actions = await import_o1js2.Mina.fetchActions(publicKey, { fromActionState, endActionState }); if (Array.isArray(actions)) return actions; else console.log("Cannot fetch actions - wrong format"); } catch (error) { console.log("Error in fetchMinaActions", error.toString().substring(0, 300)); } await sleep(1e3 * 60 * 2); } console.log("Timeout in fetchMinaActions"); return void 0; } async function checkMinaZkappTransaction(hash) { try { const result = await (0, import_o1js2.checkZkappTransaction)(hash); return result; } catch (error) { console.error("Error in checkZkappTransaction:", error); return { success: false }; } } // dist/node/utils/fields.js var import_o1js3 = require("o1js"); function serializeFields(fields) { const hash = import_o1js3.Poseidon.hash(fields); const value = [(0, import_o1js3.Field)(fields.length), hash, ...fields]; return value.map((f) => fieldToBase64(f)).join("."); } function deserializeFields(s) { try { const value = s.split(".").map((n) => fieldFromBase64(n)); const length = value[0]; if ((0, import_o1js3.Field)(value.length - 2).equals(length).toBoolean() === false) throw new Error("deserializeFields: invalid length"); const hash = import_o1js3.Poseidon.hash(value.slice(2)); if (hash.equals(value[1]).toBoolean()) { return value.slice(2); } else throw new Error("deserializeFields: invalid hash: data mismatch"); } catch (e) { throw new Error(`deserializeFields: invalid string: ${s}: ${e}`); } } // dist/node/utils/fee.js var import_o1js4 = require("o1js"); // dist/node/config.js var config = { MINAFEE: "200000000" }; var config_default = config; // dist/node/utils/fee.js async function fee() { return import_o1js4.UInt64.fromJSON(config_default.MINAFEE); } // dist/node/utils/mina.js var import_o1js5 = require("o1js"); var import_api = require("@silvana-one/api"); var currentNetwork = void 0; function getNetworkIdHash() { if (currentNetwork === void 0) { throw new Error("Network is not initialized"); } return currentNetwork.networkIdHash; } function getCurrentNetwork() { if (currentNetwork === void 0) { throw new Error("Network is not initialized"); } return currentNetwork; } function getDeployer() { if (currentNetwork === void 0) { throw new Error("Network is not initialized"); } if (currentNetwork.keys.length < 1) return void 0; return currentNetwork.keys[0]; } async function initBlockchain(params) { const { chain, deployersNumber = 0, proofsEnabled = true, customMinaNodeUrl = void 0, customMinaArchiveNodeUrl = void 0, networkId = void 0 } = params; if (currentNetwork !== void 0) { if (currentNetwork?.network.chainId === chain) { return currentNetwork; } else { throw new Error(`Network is already initialized to different chain ${currentNetwork.network.chainId}, cannot initialize to ${chain}`); } } const networkIdHash = import_o1js5.CircuitString.fromString(chain).hash(); if (chain === "mina:local") { const local = await import_o1js5.Mina.LocalBlockchain({ proofsEnabled }); import_o1js5.Mina.setActiveInstance(local); if (deployersNumber > local.testAccounts.length) throw new Error("Not enough test accounts"); currentNetwork = { keys: local.testAccounts, network: import_api.Local, networkIdHash }; return currentNetwork; } const network = import_api.networks.find((n) => n.chainId === chain); if (network === void 0) { throw new Error("Unknown network"); } const mina = process.env.MINA_NODE_URL ?? process.env.NEXT_PUBLIC_MINA_NODE_URL ?? customMinaNodeUrl ?? network.mina; const archive = process.env.MINA_ARCHIVE_NODE_URL ?? process.env.NEXT_PUBLIC_MINA_ARCHIVE_NODE_URL ?? customMinaArchiveNodeUrl ?? network.archive; console.log("mina endpoint:", mina); console.log("archive endpoint:", archive); const networkInstance = import_o1js5.Mina.Network({ mina, archive, lightnetAccountManager: network.accountManager, networkId: networkId ?? (chain === "mina:mainnet" ? "mainnet" : "testnet"), bypassTransactionLimits: chain === "zeko:testnet" || chain === "zeko:alphanet" }); import_o1js5.Mina.setActiveInstance(networkInstance); const keys = []; if (deployersNumber > 0) { if (chain === "mina:lightnet") { for (let i = 0; i < deployersNumber; i++) { const keyPair = await import_o1js5.Lightnet.acquireKeyPair(); const key = import_o1js5.Mina.TestPublicKey(keyPair.privateKey); keys.push(key); } } else { const deployers = process.env.DEPLOYERS; if (deployers === void 0 || Array.isArray(deployers) === false || deployers.length < deployersNumber) throw new Error("Deployers are not set"); for (let i = 0; i < deployersNumber; i++) { const privateKey = import_o1js5.PrivateKey.fromBase58(deployers[i]); const key = import_o1js5.Mina.TestPublicKey(privateKey); keys.push(key); } } } currentNetwork = { keys, network, networkIdHash }; return currentNetwork; } async function accountBalance(address) { await (0, import_o1js5.fetchAccount)({ publicKey: address }); if (import_o1js5.Mina.hasAccount(address)) return import_o1js5.Mina.getBalance(address); else return import_o1js5.UInt64.from(0); } async function accountBalanceMina(address) { return Number((await accountBalance(address)).toBigInt()) / 1e9; } // dist/node/storage/ipfs.js function createIpfsURL(params) { let { hash, gateway, apiToken } = params; gateway ??= process.env.PINATA_IPFS_GATEWAY ?? process.env.NEXT_PUBLIC_PINATA_IPFS_GATEWAY ?? process.env.REACT_APP_PINATA_IPFS_GATEWAY; apiToken ??= process.env.PINATA_GATEWAY_TOKEN ?? process.env.NEXT_PUBLIC_PINATA_GATEWAY_TOKEN ?? process.env.REACT_APP_PINATA_GATEWAY_TOKEN; if (!gateway) { gateway = "https://gateway.pinata.cloud/ipfs/"; } return gateway + hash + (apiToken ? "?pinataGatewayToken=" + apiToken : ""); } // dist/node/storage/pinata.js async function pinJSON(params) { const { data, name = "data.json", keyvalues = { library: "zkcloudworker" } } = params; const auth = params.auth ?? process.env.PINATA_JWT ?? process.env.NEXT_PUBLIC_PINATA_JWT ?? process.env.REACT_APP_PINATA_JWT; if (!auth) throw new Error("pinJSON: auth, PINATA_JWT, NEXT_PUBLIC_PINATA_JWT or REACT_APP_PINATA_JWT should be defined"); try { const pinataData = { pinataOptions: { cidVersion: 1 }, pinataMetadata: { name, keyvalues }, pinataContent: data }; const res = await fetch("https://api.pinata.cloud/pinning/pinJSONToIPFS", { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + auth }, body: JSON.stringify(pinataData) }); if (!res.ok) { throw new Error(`Pinata error: status: ${res.status} ${res.statusText}`); } const responseData = await res.json(); console.log("saveToIPFS result:", responseData); return responseData?.IpfsHash; } catch (error) { console.error("saveToIPFS error:", error?.message); return void 0; } } // dist/node/transactions/blockberry.js var TIMEOUT = 1e4; async function getZkAppTxsFromBlockBerry(params) { const { account, chain, blockBerryApiKey } = params; const options = { method: "GET", headers: { accept: "application/json", "x-api-key": blockBerryApiKey } }; try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), TIMEOUT); const response = await fetch(`https://api.blockberry.one/mina-${chain}/v1/zkapps/accounts/${account}/txs?size=10&orderBy=DESC&sortBy=AGE`, { ...options, signal: controller.signal }); clearTimeout(timeoutId); if (!response.ok) { console.error("Cannot fetch zkApp txs for account:", account, chain, response.statusText); return void 0; } const result = await response.json(); return result; } catch (err) { console.error("Cannot fetch zkApp txs for account - catch:", account, chain, err); return void 0; } } async function getPaymentTxsFromBlockBerry(params) { const { account, chain, blockBerryApiKey } = params; const options = { method: "GET", headers: { accept: "application/json", "x-api-key": blockBerryApiKey } }; try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), TIMEOUT); const response = await fetch(`https://api.blockberry.one/mina-${chain}/v1/accounts/` + account + "/txs?page=0&size=1&orderBy=DESC&sortBy=AGE&direction=OUT", { ...options, signal: controller.signal }); clearTimeout(timeoutId); if (!response.ok) { console.error("Cannot fetch payment txs for account:", account, chain, response.statusText); return void 0; } const result = await response.json(); return result; } catch (err) { console.error("Cannot fetch payment txs for account - catch:", account, chain, err); return void 0; } } async function getZkAppTxFromBlockBerry(params) { const { hash, chain, blockBerryApiKey } = params; const options = { method: "GET", headers: { accept: "application/json", "x-api-key": blockBerryApiKey } }; try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), TIMEOUT); const response = await fetch(`https://api.blockberry.one/mina-${chain}/v1/zkapps/txs/${hash}`, { ...options, signal: controller.signal }); clearTimeout(timeoutId); if (response.ok) { const result = await response.json(); return result; } else { console.error("getZkAppTxFromBlockBerry error while getting hash - not ok", { hash, chain, text: response.statusText, status: response.status }); return void 0; } } catch (err) { console.error("getZkAppTxFromBlockBerry error while getting mainnet hash - catch", hash, chain, err); return void 0; } } async function getZkAppFromBlockBerry(params) { const { account, chain, blockBerryApiKey } = params; const options = { method: "GET", headers: { accept: "application/json", "x-api-key": blockBerryApiKey } }; try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), TIMEOUT); const response = await fetch(`https://api.blockberry.one/mina-${chain}/v1/zkapps/${account}`, { ...options, signal: controller.signal }); clearTimeout(timeoutId); if (response.ok) { const result = await response.json(); return result; } else { console.error("getZkAppFromBlockBerry error while getting account", { account, chain, text: response.statusText, status: response.status }); return void 0; } } catch (err) { console.error("getZkAppFromBlockBerry error while getting account - catch", account, chain, err); return void 0; } } // dist/node/transactions/nonce.js var import_o1js6 = require("o1js"); async function getNonce(params) { const { account, chain, blockBerryApiKey } = params; try { if (account === void 0 || account === null || account === "") { return { success: false, nonce: -1, message: "Account is required" }; } if (blockBerryApiKey === void 0 || blockBerryApiKey === null || blockBerryApiKey === "") { return { success: false, nonce: -1, message: "blockBerryApiKey is required" }; } const zkAppTxsPromise = getZkAppTxsFromBlockBerry({ account, chain, blockBerryApiKey }); const paymentTxs = getPaymentTxsFromBlockBerry({ account, chain, blockBerryApiKey }); const paymentNonce = (await paymentTxs)?.data[0]?.nonce ?? -1; let zkNonce = -1; let found = false; const zkAppTxs = await zkAppTxsPromise; const size = zkAppTxs?.data?.length ?? 0; let i = 0; while (!found && i < size) { if (zkAppTxs?.data[i]?.proverAddress === account) { zkNonce = zkAppTxs?.data[i]?.nonce; found = true; } i++; } const nonce = Math.max(zkNonce, paymentNonce); return { success: true, nonce }; } catch (error) { return { success: false, nonce: -1, message: String(error) }; } } async function getAccountNonce(params) { const { account, chain = getCurrentNetwork().network.chainId, blockBerryApiKey, verbose = true } = params; const canUseBlockBerry = blockBerryApiKey !== void 0 && (chain === "mina:devnet" || chain === "mina:mainnet"); if (chain === "zeko:testnet" || chain === "mina:testnet") { const publicKey = import_o1js6.PublicKey.fromBase58(account); await fetchMinaAccount({ publicKey }); const nonce = Number(import_o1js6.Mina.getAccount(publicKey).nonce.toBigint()); return nonce; } else if (chain === "mina:devnet" || chain === "mina:mainnet") { const blockberryChain = chain === "mina:devnet" ? "devnet" : "mainnet"; const blockberryNoncePromise = canUseBlockBerry ? getNonce({ account, blockBerryApiKey, chain: blockberryChain }) : void 0; const publicKey = import_o1js6.PublicKey.fromBase58(account); await fetchMinaAccount({ publicKey }); const senderNonce = Number(import_o1js6.Mina.getAccount(publicKey).nonce.toBigint()); const blockberryNonce = blockberryNoncePromise ? (await blockberryNoncePromise).nonce ?? -1 : -1; const nonce = Math.max(senderNonce, blockberryNonce + 1); if (verbose && nonce > senderNonce) console.log(`Nonce changed from ${senderNonce} to ${nonce} for ${account}`); return nonce; } else { throw new Error(`Unsupported chain: ${chain}`); } } // dist/node/transactions/transaction.js var import_o1js7 = require("o1js"); function createTransactionPayloads(tx) { const transaction = tx.toJSON(); const txJSON = JSON.parse(transaction); const signedData = JSON.stringify({ zkappCommand: txJSON }); const proverPayload = serializeTransaction(tx); const fee2 = tx.transaction.feePayer.body.fee.toJSON(); const sender = tx.transaction.feePayer.body.publicKey.toBase58(); const nonce = Number(tx.transaction.feePayer.body.nonce.toBigint()); const memo = tx.transaction.memo; const minaSignerPayload = { zkappCommand: txJSON, feePayer: { feePayer: sender, fee: fee2, nonce, memo } }; const walletPayload = { transaction, nonce, onlySign: true, feePayer: { fee: fee2, memo } }; return { sender, nonce, memo, fee: fee2, walletPayload, minaSignerPayload, proverPayload, signedData, transaction }; } function transactionParams(params) { const { proverPayload, signedData } = params; const signedJson = JSON.parse(signedData); const { sender, tx } = JSON.parse(proverPayload); const transaction = import_o1js7.Mina.Transaction.fromJSON(JSON.parse(tx)); const memo = transaction.transaction.memo; return { fee: import_o1js7.UInt64.from(signedJson.zkappCommand.feePayer.body.fee), sender: import_o1js7.PublicKey.fromBase58(sender), nonce: Number(signedJson.zkappCommand.feePayer.body.nonce), memo }; } function parseTransactionPayloads(params) { const { txNew } = params; const proverPayload = "payloads" in params ? params.payloads.proverPayload : params.proverPayload; const signedData = "payloads" in params ? params.payloads.signedData : params.signedData; const signedJson = JSON.parse(signedData); const { tx, blindingValues, length, forestJSONs } = JSON.parse(proverPayload); const transaction = import_o1js7.Mina.Transaction.fromJSON(JSON.parse(tx)); const forests = forestJSONs.map((f) => JSON.parse(f)); if (length !== txNew.transaction.accountUpdates.length) { throw new Error(`New Transaction length mismatch: ${length} !== ${txNew.transaction.accountUpdates.length}`); } if (length !== transaction.transaction.accountUpdates.length) { throw new Error(`Serialized Transaction length mismatch: ${length} !== ${transaction.transaction.accountUpdates.length}`); } for (let i = 0; i < length; i++) { transaction.transaction.accountUpdates[i].lazyAuthorization = txNew.transaction.accountUpdates[i].lazyAuthorization; if (blindingValues[i] !== "") { if (transaction.transaction.accountUpdates[i].lazyAuthorization === void 0 || transaction.transaction.accountUpdates[i].lazyAuthorization.blindingValue === void 0) { throw new Error(`Lazy authorization blinding value is undefined for item ${i}`); } transaction.transaction.accountUpdates[i].lazyAuthorization.blindingValue = import_o1js7.Field.fromJSON(blindingValues[i]); } if (forests[i].length > 0) { if (transaction.transaction.accountUpdates[i].lazyAuthorization === void 0 || transaction.transaction.accountUpdates[i].lazyAuthorization.args === void 0) { throw new Error(`Lazy authorization args is undefined for item ${i}`); } deserializeLazyAuthorization(transaction.transaction.accountUpdates[i].lazyAuthorization.args, forests[i]); if (forests[i].restoredItems !== forests[i].length) { throw new Error(`Forest ${i} not fully restored`); } } } transaction.transaction.feePayer.authorization = signedJson.zkappCommand.feePayer.authorization; transaction.transaction.feePayer.body.fee = import_o1js7.UInt64.from(signedJson.zkappCommand.feePayer.body.fee); for (let i = 0; i < length; i++) { const signature = signedJson.zkappCommand.accountUpdates[i].authorization.signature; if (signature !== void 0 && signature !== null) { transaction.transaction.accountUpdates[i].authorization.signature = signedJson.zkappCommand.accountUpdates[i].authorization.signature; } } return transaction; } function serializeTransaction(tx) { const length = tx.transaction.accountUpdates.length; let i; const blindingValues = []; const forests = []; for (i = 0; i < length; i++) { const la = tx.transaction.accountUpdates[i].lazyAuthorization; if (la !== void 0 && la.blindingValue !== void 0 && la.kind === "lazy-proof") blindingValues.push(la.blindingValue.toJSON()); else blindingValues.push(""); const forest = { length: 0, items: [] }; serializeLazyAuthorization(tx.transaction.accountUpdates[i].lazyAuthorization?.args, forest); forests.push(forest); } const serializedTransaction = JSON.stringify({ tx: tx.toJSON(), blindingValues, forestJSONs: forests.map((f) => JSON.stringify(f)), length, fee: tx.transaction.feePayer.body.fee.toJSON(), sender: tx.transaction.feePayer.body.publicKey.toBase58(), nonce: tx.transaction.feePayer.body.nonce.toBigint().toString() }, null, 2); return serializedTransaction; } function serializeLazyAuthorization(lazyAuthorization, serialized) { if (lazyAuthorization?.hash !== void 0 && lazyAuthorization.hash.toJSON) { serialized.items.push({ h: fieldToBase64(lazyAuthorization.hash) }); } if (lazyAuthorization?.previousHash !== void 0 && lazyAuthorization.previousHash.toJSON) { serialized.items.push({ p: fieldToBase64(lazyAuthorization.previousHash) }); } if (lazyAuthorization?.callData !== void 0 && lazyAuthorization.callData.toJSON) { serialized.items.push({ c: fieldToBase64(lazyAuthorization.callData) }); } if (lazyAuthorization?.id !== void 0) { serialized.items.push({ i: lazyAuthorization.id }); } if (Array.isArray(lazyAuthorization)) { for (const item of lazyAuthorization) { serializeLazyAuthorization(item, serialized); } } if (typeof lazyAuthorization === "object") { for (const key in lazyAuthorization) { serializeLazyAuthorization(lazyAuthorization[key], serialized); } } serialized.length = serialized.items.length; } function deserializeLazyAuthorization(lazyAuthorization, serialized) { if (serialized.restoredItems === void 0) serialized.restoredItems = 0; if (lazyAuthorization?.hash !== void 0 && lazyAuthorization.hash.toJSON) { if (serialized.restoredItems >= serialized.length) throw new Error("Restored more items than expected"); const hash = serialized.items[serialized.restoredItems].h; if (hash === void 0) throw new Error(`Hash is undefined for item ${serialized.restoredItems}`); lazyAuthorization.hash = fieldFromBase64(hash); serialized.restoredItems++; } if (lazyAuthorization?.previousHash !== void 0 && lazyAuthorization.previousHash.toJSON) { if (serialized.restoredItems >= serialized.length) throw new Error("Restored more items than expected"); const previousHash = serialized.items[serialized.restoredItems].p; if (previousHash === void 0) throw new Error(`Previous hash is undefined for item ${serialized.restoredItems}`); lazyAuthorization.previousHash = fieldFromBase64(previousHash); serialized.restoredItems++; } if (lazyAuthorization?.callData !== void 0 && lazyAuthorization.callData.toJSON) { if (serialized.restoredItems >= serialized.length) throw new Error("Restored more items than expected"); const callData = serialized.items[serialized.restoredItems].c; if (callData === void 0) throw new Error(`Call data is undefined for item ${serialized.restoredItems}`); lazyAuthorization.callData = fieldFromBase64(callData); serialized.restoredItems++; } if (lazyAuthorization?.id !== void 0) { if (serialized.restoredItems >= serialized.length) throw new Error("Restored more items than expected"); const id = serialized.items[serialized.restoredItems].i; if (id === void 0) throw new Error(`Id is undefined for item ${serialized.restoredItems}`); lazyAuthorization.id = id; serialized.restoredItems++; } if (Array.isArray(lazyAuthorization)) { for (const item of lazyAuthorization) { deserializeLazyAuthorization(item, serialized); } } if (typeof lazyAuthorization === "object") { for (const key in lazyAuthorization) { deserializeLazyAuthorization(lazyAuthorization[key], serialized); } } } // dist/node/transactions/txstatus.js var TIMEOUT2 = 1e3 * 60 * 21; async function txStatusBlockberry(params) { const { hash, chain, time, blockBerryApiKey } = params; const tx = await getZkAppTxFromBlockBerry({ hash, chain, blockBerryApiKey }); if (tx?.txStatus) return tx?.txStatus; if (Date.now() - time > (params.timeout ?? TIMEOUT2)) { console.error("txStatus: Timeout while checking tx with blockberry", chain, hash); return "replaced"; } else { return "pending"; } } // dist/node/transactions/tiny-contract.js var import_tslib = require("tslib"); var import_o1js8 = require("o1js"); var TinyContract = class extends import_o1js8.SmartContract { constructor() { super(...arguments); this.value = (0, import_o1js8.State)(); } async setValue(value) { this.value.set(value); } }; (0, import_tslib.__decorate)([ (0, import_o1js8.state)(import_o1js8.Field), (0, import_tslib.__metadata)("design:type", Object) ], TinyContract.prototype, "value", void 0); (0, import_tslib.__decorate)([ import_o1js8.method, (0, import_tslib.__metadata)("design:type", Function), (0, import_tslib.__metadata)("design:paramtypes", [import_o1js8.Field]), (0, import_tslib.__metadata)("design:returntype", Promise) ], TinyContract.prototype, "setValue", null); // dist/node/transactions/send.js var import_o1js9 = require("o1js"); async function sendTx(params) { const { tx, description = "", verbose = true, wait = true, chain = getCurrentNetwork().network.chainId, delay = chain === "zeko:testnet" || chain === "zeko:alphanet" || chain === "mina:lightnet" ? 5e3 : 6e4, retry = 30 } = params; const accountUpdates = JSON.parse(tx.toJSON()).accountUpdates; const auCount = []; let proofAuthorizationCount = 0; for (const au of accountUpdates) { const { publicKey, tokenId, authorizationKind } = au.body; if (au.authorization.proof) { proofAuthorizationCount++; if (authorizationKind.isProved === false) console.error("Proof authorization exists but isProved is false"); } else if (authorizationKind.isProved === true) console.error("isProved is true but no proof authorization"); const index = auCount.findIndex((item) => item.publicKey === publicKey && item.tokenId === tokenId); if (index === -1) auCount.push({ publicKey, tokenId, count: 1 }); else auCount[index].count++; } if (verbose) console.log(`Account updates for ${description ?? "tx"}: ${auCount.length}, proof authorizations: ${proofAuthorizationCount}`); for (const au of auCount) { if (au.count > 1) { if (verbose) console.log(`DUPLICATE AU ${description ?? ""}: ${au.publicKey} ${au.tokenId !== "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf" ? "tokenId: " + au.tokenId : ""} count: ${au.count}`); } } try { let txSent; let sent = false; let attempt = 1; while (!sent && attempt <= retry) { txSent = await tx.safeSend(); if (txSent.status === "pending") { sent = true; if (verbose) console.log(`${description ?? ""} tx sent: hash: ${txSent.hash} status: ${txSent.status}`); } else if (chain !== "mina:local") { attempt++; console.error(`${description} tx NOT sent: hash: ${txSent?.hash} status: ${txSent?.status}, errors: ${String(txSent.errors ?? "")}`); if (verbose) console.log(`Retrying ${chain} tx, retry:`, attempt); await sleep(1e4 * attempt); } else attempt = retry + 1; } if (txSent === void 0) throw new Error("txSent is undefined"); if ((txSent.errors?.length ?? 0) > 0) { console.error(`${description ?? ""} tx error: hash: ${txSent.hash} status: ${txSent.status} errors: ${String(txSent.errors ?? "")}`); } if (txSent.status === "pending" && wait !== false && chain !== "zeko:testnet" && chain !== "zeko:alphanet") { if (verbose) console.log(`Waiting for tx inclusion...`); let txIncluded = await txSent.safeWait(); if (txIncluded.status !== "included") { console.error(`${description ?? ""} tx NOT included into block: hash: ${txIncluded.hash} status: ${txIncluded.status}, errors: ${String(txIncluded.errors ?? "")}`); } if (chain !== "mina:local") { const { publicKey, nonce } = tx.transaction.feePayer.body; const started = Date.now(); while (Date.now() - started < 1e3 * 60 * 10) { const newNonce = (await fetchMinaAccount({ publicKey, force: true })).account?.nonce; if (newNonce && Number(newNonce.toBigint()) > Number(nonce.toBigint())) { let txIncluded2 = await txSent.safeWait(); if (txIncluded2.status === "included") { if (verbose) console.log(`${description ?? ""} tx included into block: hash: ${txIncluded2.hash} status: ${txIncluded2.status}`); if (delay > 0) await sleep(delay); return txIncluded2; } else if (txIncluded2.status === "rejected") { console.error(`tx rejected: ${chain}: hash: ${txIncluded2.hash} status: ${txIncluded2.status} errors: ${txIncluded2.errors}`); await sleep(3e4); txIncluded2 = await txSent.safeWait(); if (txIncluded2.status === "included") { if (verbose) console.log(`${description ?? ""} tx included into block: hash: ${txIncluded2.hash} status: ${txIncluded2.status}`); if (delay > 0) await sleep(delay); return txIncluded2; } console.error(`tx failed: ${chain}: hash: ${txIncluded2.hash} status: ${txIncluded2.status} errors: ${txIncluded2.errors}`); return txIncluded2; } } if (verbose) console.log(`Waiting for ${chain} to update state for ${Math.floor((Date.now() - started) / 1e3)} sec...`); await sleep(3e4); } console.error(`${chain} do not reflect nonce update for tx ${txIncluded.hash} with status ${txIncluded.status}`); } if (verbose) console.log(`${description ?? ""} tx included into block: hash: ${txIncluded.hash} status: ${txIncluded.status}`); return txIncluded; } else return txSent; } catch (error) { if (chain !== "zeko:testnet") console.error("Error sending tx", error); } } async function getTxStatusFast(params) { const { hash, chain = getCurrentNetwork().network.chainId } = params; if (chain === "mina:local" || chain === "zeko:testnet") return { success: true, result: true }; try { const txStatus = await (0, import_o1js9.checkZkappTransaction)(hash); return { success: true, result: txStatus?.success ?? false }; } catch (error) { console.error("getTxStatusFast error while getting tx status - catch", hash, error); return { success: false, error: error?.message ?? "Cannot get tx status" }; } } // dist/node/transactions/account.js var import_o1js10 = require("o1js"); async function accountExists(address, tokenId) { try { const publicKey = typeof address === "string" ? import_o1js10.PublicKey.fromBase58(address) : address; await fetchMinaAccount({ publicKey, tokenId, force: false }); return import_o1js10.Mina.hasAccount(publicKey, tokenId); } catch (error) { return false; } } async function tokenBalance(address, tokenId) { try { const publicKey = typeof address === "string" ? import_o1js10.PublicKey.fromBase58(address) : address; await fetchMinaAccount({ publicKey, tokenId, force: false }); return import_o1js10.Mina.hasAccount(publicKey, tokenId) ? Number(import_o1js10.Mina.getAccount(publicKey, tokenId).balance.toBigInt()) : void 0; } catch (error) { console.error("Cannot fetch account balance", error); return void 0; } } async function checkAddress(address) { if (!address || typeof address !== "string") { console.error("checkAddress params are invalid:", address); return false; } try { const publicKey = import_o1js10.PublicKey.fromBase58(address); if (address !== publicKey.toBase58()) { console.log("checkAddress: address is not valid", address, publicKey.toBase58()); return false; } return true; } catch (error) { console.error("checkAddress catch", { address, error }); return false; } } // dist/node/commitment/commitment.js var import_o1js14 = require("o1js"); // dist/node/commitment/constants.js var import_o1js11 = require("o1js"); var BLS_FR = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n; var Fr = (0, import_o1js11.createForeignField)(BLS_FR); var R_VALUE = 0x149fa8c209ab655fd480a3aff7d16dc72b6a3943e4b95fcf7909f42d9c17a552n; function getR() { return Fr.from(R_VALUE); } function getTable0Entry(index) { if (index >= 1024) throw new Error("TABLE0 index out of bounds"); return Fr.from(TABLE0[index]); } function getTable1Entry(index) { if (index >= 1024) throw new Error("TABLE1 index out of bounds"); return Fr.from(TABLE1[index]); } function getTable2Entry(index) { if (index >= 1024) throw new Error("TABLE2 index out of bounds"); return Fr.from(TABLE22[index]); } var TABLE0 = [ 0x0000000000000000000000000000000000000000000000000000000000000001n, // R^0 = 1 0x149fa8c209ab655fd480a3aff7d16dc72b6a3943e4b95fcf7909f42d9c17a552n, // R^1 = R 0x5df995de0eb4fd377c1c4487338e6b2cac86012ba7ad28007b511f2e832ca5dfn, // R^2 0x4b3ead8c3dfd654f6e562478086b876b1b00635d558749f78d9e67bc730e33e8n, // R^3 0x1b7627cf3b0816f9e23fd6455446e6131fa1a6e39ada47481e8d13563cbf28f3n, // R^4 0x5e8ff2b9cdf997eaf93fff82ba1ad706e126842cda04aa98e5823641f0e104aen, // R^5 0x1fc84f346a381aaf5a83870a6c99fcd60ad57a819c5d0358158a71df8f30ca9bn, // R^6 0x6e2c601106ed0953badad4c2002a1cb669b68f97dc64bd1e6e65c4ff37a9c19fn, // R^7 0x7366a137b8ae4e5a287f8197096a179cbfc3ebf633d6e9de9c61d319c23f931an, // R^8 0x1cf1dabd25b6d47c5f55eab1e5da855faead0c3e0ea1f006f26d96603b370070n, // R^9 0x28b5085e0883923a5fe9bf9d108f8be3a432bd97156020d87dfce14ca429a152n, // R^10 0x5830b95fdb00a073da69509b71a80f3343004a16aa1018dfd8ff13bc73f974b5n, // R^11 0x5a32550797ab926c17788923bd556bdbda00d919d6bb8fec5406edb5d9d24bbfn, // R^12 0x1b6f299e48c145f90a27df014c50086b6f08e41702e19e1ebea3a998090c372dn, // R^13 0x53f29e90c29a5292a2699e9d56fd4d3ed80c583ab292c81c6f96d8667ad2a326n, // R^14 0x3ffe313e31dbf4382757ad449c2c8135e31b5460b7ebc15a18b13f8bedcc7217n, // R^15 0x3becfe52d6af64a31dedb53bc29ed2bc860fe0c214357baf25b840156666f865n, // R^16 0x1b027a226b227e964410ee322cde8e09e17d95ac365f6fe415f0862b29bb14e8n, // R^17 0x19aebbf7b44580dab6b54d212722234f73fda2644517b892f5bbd641953544a3n, // R^18 0x4a405283f982615a3128fb0dad9d309559c5277b6c2553ce65d5d7186b1b5855n, // R^19 0x71048a6425b6aa932506dc55a0dfe6cd695b168977abd8c8429b8d38dfd173ean, // R^20 0x62dee991e60cecc791f149ba4b96ec037fdde9e88b456d1c138e6f9ad5afb9fbn, // R^21 0x49dffef70692d2cbb8b5a4852ba3c9f25912563756921205ff289b1a34473ec5n, // R^22 0x2324bad90fc4792859c95ec12fb97248513bcdd6b4ce61c3e337edea3d677056n, // R^23 0x085ca5093e7a3e8d6408f73828aef93b6a95a489191fd769c028187f029ffa8dn, // R^24 0x3a61a8141101de545fb223b0b81f529690fa9ff542b9a8bdec88b6e14e047017n, // R^25 0x6d46459211a98cbdf9a4c3c1d25b6e5a2b3d27528a8d091c32c1fbe3f2d5fb72n, // R^26 0x524edba268a718d737deeb2443c7469faa3b5754d71ea5fea364291e044b8130n, // R^27 0x0e810fa53d537adb3fd5dd3fe854d0bead36c9f29c59e258d3a94024caa501den, // R^28 0x6a6bfbda1e831f027e9d5bb7b8c94d0a1d364a6959d19005c30c3c9993a64038n, // R^29 0x2fce864b3fea12712796eebd5a9b956e6a326e8b790973eb509e534a0027de2dn, // R^30 0x3b52aa155417fc8e117550174516a87c5edb985767f4006fc26dc50bf5425166n, // R^31 0x592db301afc2f04738f65ac64542881694928726ee7566f32531b6605088ee26n, // R^32 0x6bd958c72d264724572440ef2ce7d5188d0ca7dda91d216be87cc2ccbb1f21den, // R^33 0x393ffec28d4e3f0051d5fe3d3d61f7dbe49b5a414000178ee8f64eca9cecf2a8n, // R^34 0x3289382cc64971acbbdcff51667ecbaceb55fdc8a223790ebc4a82c168260a23n, // R^35 0x4264b815382a2c319d4a625406b0d736c13fb70660ca9a34f245ab124ef97b65n, // R^36 0x2b3ea1db90651f1cf09ac638f9434631e5b82201fe66c5f336778c14f4eceafbn, // R^37 0x52ff9470f870231d00fcdeac4869f8f9f70a9b0ff09a3bb7575f1dff68698d80n, // R^38 0x2667eabe1b9dab6c6d864cea6541b95a7376840f3c3e150d09928df9cc47a3b7n, // R^39 0x50045bc8bdbb0aeddc3148a6583c36975617b166c6da1279e43025139d299a59n, // R^40 0x300ab6e0b724119d1d197e0e31efff97ee1286af1602b0ffaddaf810f07f0661n, // R^41 0x45bbb7ad234842932f2d99e66cd9b8c7681a9b6a966c42f3394cd6870e16669fn, // R^42 0x10d663727245c978edada6cb2bf1702631142c2b28df35c0c878e6403e30371bn, // R^43 0x0d2549ad4f12f22bca6088380276c22125f36f05ada3924912d95f25129b5684n, // R^44 0x1767cdb24e30daa2dd564d5906f6fbb01c520da4a44060560258f4d1c3e13122n, // R^45 0x5434915e0b118a0d0b6229af4382101050a76eefdc66e0166155bba96cde58a1n, // R^46 0x71bc23874177c13de04e2541a9d47c49b3078da760803001b32a82357ef7b2f6n, // R^47 0x3aa5f7ca2cf54226e7ce899e404ef6b6b216fb0a9b2ad8546a7fe2ed5c9ce0c8n, // R^48 0x5c8466cd98ccad2c96762de43e850252842da79728440f665a3e0333891d5d87n, // R^49 0x1797ebb8557501f1adcea37658666664e54385f3fea6fc7717681fc1837ad183n, // R^50 0x58d3a829f86ba498794a7167f937870522fc774eea4b923a393c339272d091c7n, // R^51 0x233546374310725810c53fafe49a1691b2865e85cfdb6c17cf8e3d2cf6ecc9fbn, // R^52 0x011fd8729456057bf219a7e1034a7db7fcc3739d49c589224baee0d03fd64c04n, // R^53 0x1f3b34478cfc619a3fa58dc62473c9eed6cf3bb2c9f2e5eb570a07fe128ab5a0n, // R^54 0x691f8153655e0820c3a1c7dfbda63a1a823175f288341f2c4da51090ec82950fn, // R^55 0x665303958e333369495f47dafe7e873d83867fed1e2e86a9f7f196a1d454a35bn, // R^56 0x3ba197949d37404e2711e06bc9e49b3b1a6e3b710f6c93fdf77ea86546f2a302n, // R^57 0x056257f4793d20baffa7c27c2f290a07ddc58fc66283d3bf1d6f4294236cb59en, // R^58 0x418910649db13cb7ed1d5aeac6a805556b19a5cc8af76ac88638e68270080928n, // R^59 0x479e065423862aae362d7b2041bf47212e0b3f8f27754ef86a2dff4600e2920dn, // R^60 0x22668f06bbf654ed335c9426848db56e433f3d9d7f42e4f5b797b081caa13f9bn, // R^61 0x303d5ca14fb65dfe56c00334cb6d543a78be91ca1d1e4ee9c0ba2653f5ddbf30n, // R^62 0x0c8c636e0f8f4844dd4cddc47575973e2dfcc902e31214a1e993fe1e2fb1aaeen, // R^63 0x2aff5949c2776194793be80e1ae48b4740331e37ed6fd502c5adf476b0abf418n, // R^64 0x555021ba609370c7217521647e07a51858f0c5706d8f61cd11045c9bb96e395fn, // R^65 0x0c76744b596fc8428e71f968a5a963bd7fdc376f15bde5670e2f9cfece6b37d1n, // R^66 0x4f42f2352ee6b7a8eee14375c46c162bf73823a0ee7958fa52f9208108d4e54dn, // R^67 0x150357a92d53e68a4e61315ab039e4df1a1d5f38f318488f3689ded47c56f181n, // R^68 0x05a7330fa4615a2061e3f5df1a124116110e2e50e58914d8ecf6fb33f3706eb5n, // R^69 0x2e45b7b2d79ffd9a45db6aac90657d9dd1c02359856a19c6471a8c6ea0b2cd06n, // R^70 0x47fc64f748cda684b5d3fa8eb143e92b72a4f9c3d75ce81c45874ba8245e0367n, // R^71 0x136471c895de77f8fb3692b25cce4abbd5e22e09a525175ab7f6cea0cf4f9085n, // R^72 0x2185d4586e6dbc8b4169b7084e7195f6f3ac906ab2543d1849e09f55467873den, // R^73 0x22ab4e97717bf25b5916f3c5309162471ee898b4e39cb3b30bec96b53b3196adn, // R^74 0x641b9ff0b2c779ce14eaa3932fea99eb5b2f892a45ee912088e596f6962adc7bn, // R^75 0x2b56dfbe36e5fe627968401832f81c32d46009e3e6580facf5ee60043d145433n, // R^76 0x601a57b1bd147dac676e847afc1606469b7789d5e863662032c5e11d699020can, // R^77 0x2b65f59af053e633c27d8e5eb4cb4340e4a80af259fdbc904d1a32d548b63974n, // R^78 0x0741fbdcc27dfb732921b2ddbfca28dac8d4689421503ad94273f6cdafacbf09n, // R^79 0x1fe5ea93fd0bdf7075a1787fcfa73546e78c5b20d199413b3f5bcde71dc72b19n, // R^80 0x376e2dbca9eb1376c68381dbfc5a445de82cef6403f4d4b8ba7dfefaed3775b2n, // R^81 0x045edc20ad076ff3ec8a1eed4c1cf414d2d8f71e25e8507efda7cc5f5bf468a9n, // R^82 0x144b3f1a0fe9e383cf8b715f87c84746e04149ddd09df2fb90251c3aa208f021n, // R^83 0x58c5b53104730e95e271dc577d3f94728b4fdfd0762c07491aa622763e9ed30cn, // R^84 0x388045906969960ce01675b856718e13a054d0679c4ddd1f1e621d98a9c2131an, // R^85 0x220cc13329ddb31f5fa7dc88c655e55638dc6618845c70879feac23e9f03a0e3n, // R^86 0x4fff59248021ec9f92235b063848e65fb1fb43a4f8c38d86a552496671476bb7n, // R^87 0x06bf179d6e58f60044a98df24a164a58ea16f4cf6ebd72f7051121810e117ec6n, // R^88 0x0e272099e31b4f435abc6bb48e7e9815dc67f97603b84a26e70ef728a7845654n, // R^89 0x691dbcd47b78d9948e9a3daf3e6131ed0daa201256f0cc5ef1bfa26d33b2278cn, // R^90 0x15e08415c3efa64a59bc6ed10998a1bed28565abb3e2f5f416b2a34d5a59398dn, // R^91 0x57c95d787c3d05843f716cf1be4a0570f86cbd12a177aea811bff85ae8