@silvana-one/mina-utils
Version:
Silvana Mina Utils
1,384 lines (1,357 loc) • 1.91 MB
JavaScript
"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,
Devnet: () => Devnet,
Fr: () => Fr,
Lightnet: () => Lightnet,
Local: () => Local,
Mainnet: () => Mainnet,
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,
Zeko: () => Zeko,
ZekoAlphaNet: () => ZekoAlphaNet,
accountBalance: () => accountBalance,
accountBalanceMina: () => accountBalanceMina,
accountExists: () => accountExists,
bigintFromBase56: () => bigintFromBase56,
bigintFromBase64: () => bigintFromBase64,
bigintToBase56: () => bigintToBase56,
bigintToBase64: () => bigintToBase64,
blsCommitment: () => blsCommitment,
checkAddress: () => checkAddress,
checkMinaZkappTransaction: () => checkMinaZkappTransaction,
commit: () => commit,
createIpfsURL: () => createIpfsURL,
createMerkleTree: () => createMerkleTree,
createTransactionPayloads: () => createTransactionPayloads,
currentNetwork: () => currentNetwork,
deserializeFields: () => deserializeFields,
deserializeIndexedMerkleMap: () => deserializeIndexedMerkleMap,
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,
loadIndexedMerkleMap: () => loadIndexedMerkleMap,
makeString: () => makeString,
networks: () => networks,
parseIndexedMapSerialized: () => parseIndexedMapSerialized,
parseTransactionPayloads: () => parseTransactionPayloads,
pinJSON: () => pinJSON,
rScalarPow: () => rScalarPow,
rScalarPowLegacy: () => rScalarPowLegacy,
rScalarPowProvable: () => rScalarPowProvable,
saveIndexedMerkleMap: () => saveIndexedMerkleMap,
scalar: () => scalar,
sendTx: () => sendTx,
serializeFields: () => serializeFields,
serializeIndexedMap: () => serializeIndexedMap,
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");
// dist/node/networks.js
var Mainnet = {
mina: [
//"https://proxy.devnet.minaexplorer.com/graphql",
"https://api.minascan.io/node/mainnet/v1/graphql"
],
archive: [
"https://api.minascan.io/archive/mainnet/v1/graphql"
//"https://archive.devnet.minaexplorer.com",
],
explorerAccountUrl: "https://minascan.io/mainnet/account/",
explorerTransactionUrl: "https://minascan.io/mainnet/tx/",
chainId: "mainnet",
name: "Mainnet"
};
var Local = {
mina: [],
archive: [],
chainId: "local"
};
var Devnet = {
mina: [
"https://api.minascan.io/node/devnet/v1/graphql"
//"https://proxy.devnet.minaexplorer.com/graphql",
],
archive: [
"https://api.minascan.io/archive/devnet/v1/graphql"
//"https://archive.devnet.minaexplorer.com",
],
explorerAccountUrl: "https://minascan.io/devnet/account/",
explorerTransactionUrl: "https://minascan.io/devnet/tx/",
chainId: "devnet",
name: "Devnet",
faucet: "https://faucet.minaprotocol.com"
};
var Zeko = {
mina: ["https://devnet.zeko.io/graphql"],
archive: ["https://devnet.zeko.io/graphql"],
explorerAccountUrl: "https://zekoscan.io/devnet/account/",
explorerTransactionUrl: "https://zekoscan.io/devnet/tx/",
chainId: "zeko",
name: "Zeko",
faucet: "https://zeko.io/faucet"
};
var ZekoAlphaNet = {
mina: ["http://m1.zeko.io/graphql"],
archive: ["http://m1.zeko.io/graphql"],
explorerAccountUrl: "",
explorerTransactionUrl: "",
chainId: "zeko:alphanet",
name: "Zeko AlphaNet",
faucet: ""
};
var Lightnet = {
mina: ["http://localhost:8080/graphql"],
archive: ["http://localhost:8282"],
accountManager: "http://localhost:8181",
chainId: "lightnet",
name: "Lightnet"
};
var networks = [Mainnet, Local, Devnet, Zeko, Lightnet];
// dist/node/utils/mina.js
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(instance, deployersNumber = 0, proofsEnabled = true, customMinaNodeUrl = void 0, customMinaArchiveNodeUrl = void 0) {
if (currentNetwork !== void 0) {
if (currentNetwork?.network.chainId === instance) {
return currentNetwork;
} else {
throw new Error(`Network is already initialized to different chain ${currentNetwork.network.chainId}, cannot initialize to ${instance}`);
}
}
const networkIdHash = import_o1js5.CircuitString.fromString(instance).hash();
if (instance === "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: Local,
networkIdHash
};
return currentNetwork;
}
const network = networks.find((n) => n.chainId === instance);
if (network === void 0) {
throw new Error("Unknown network");
}
const networkInstance = import_o1js5.Mina.Network({
mina: process.env.MINA_NODE_URL ?? process.env.NEXT_PUBLIC_MINA_NODE_URL ?? customMinaNodeUrl ?? network.mina,
archive: process.env.MINA_ARCHIVE_NODE_URL ?? process.env.NEXT_PUBLIC_MINA_ARCHIVE_NODE_URL ?? customMinaArchiveNodeUrl ?? network.archive,
lightnetAccountManager: network.accountManager,
networkId: instance === "mainnet" ? "mainnet" : "testnet",
bypassTransactionLimits: instance === "zeko"
});
import_o1js5.Mina.setActiveInstance(networkInstance);
const keys = [];
if (deployersNumber > 0) {
if (instance === "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/utils/indexed-map.js
var import_o1js6 = require("o1js");
// 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/utils/indexed-map.js
var { IndexedMerkleMap } = import_o1js6.Experimental;
async function loadIndexedMerkleMap(params) {
const { url, type, timeout = 6e4, attempts = 5 } = params;
let attempt = 0;
const start = Date.now();
let response = await fetch(url);
while (!response.ok && attempt < attempts && Date.now() - start < timeout) {
attempt++;
await sleep(5e3 * attempt);
response = await fetch(url);
}
if (!response.ok) {
throw new Error("Failed to fetch IndexedMerkleMap");
}
const json = await response.json();
const serializedIndexedMap = json.map;
if (!serializedIndexedMap)
throw new Error("wrong IndexedMerkleMap json format");
const map = deserializeIndexedMerkleMapInternal({
serializedIndexedMap,
type
});
if (!map) {
throw new Error("Failed to deserialize whitelist");
}
return map;
}
async function saveIndexedMerkleMap(params) {
const { map, name = "indexed-map", keyvalues, auth } = params;
const serialized = serializeIndexedMap(map);
const ipfsHash = await pinJSON({
data: { map: serialized },
name,
keyvalues,
auth
});
return ipfsHash;
}
function serializeIndexedMap(map) {
return {
height: map.height,
root: map.root.toJSON(),
length: map.length.toJSON(),
nodes: JSON.stringify(map.data.get().nodes, (_, v) => typeof v === "bigint" ? "n" + bigintToBase64(v) : v),
sortedLeaves: JSON.stringify(map.data.get().sortedLeaves.map((v) => [
bigintToBase64(v.key),
bigintToBase64(v.nextKey),
bigintToBase64(v.value),
bigintToBase64(BigInt(v.index))
]))
};
}
function deserializeIndexedMerkleMap(params) {
try {
const { serializedIndexedMap, type } = params;
return deserializeIndexedMerkleMapInternal({
serializedIndexedMap,
type: type ?? IndexedMerkleMap(serializedIndexedMap.height)
});
} catch (error) {
console.error("Error deserializing map:", error?.message ?? error);
return void 0;
}
}
function parseIndexedMapSerialized(serializedMap) {
const json = JSON.parse(serializedMap);
if (json.height === void 0 || json.root === void 0 || json.length === void 0 || json.nodes === void 0 || json.sortedLeaves === void 0)
throw new Error("wrong IndexedMerkleMap json format");
if (typeof json.height !== "number")
throw new Error("wrong IndexedMerkleMap height format");
if (typeof json.root !== "string")
throw new Error("wrong IndexedMerkleMap root format");
if (typeof json.length !== "string")
throw new Error("wrong IndexedMerkleMap length format");
if (typeof json.nodes !== "string")
throw new Error("wrong IndexedMerkleMap nodes format");
if (typeof json.sortedLeaves !== "string")
throw new Error("wrong IndexedMerkleMap sortedLeaves format");
return json;
}
function deserializeIndexedMerkleMapInternal(params) {
const { serializedIndexedMap, type } = params;
const map = new type();
if (serializedIndexedMap.height !== map.height) {
throw new Error("wrong IndexedMap height");
}
const nodes = JSON.parse(serializedIndexedMap.nodes, (_, v) => {
if (typeof v === "string" && v[0] === "n") {
return bigintFromBase64(v.slice(1));
}
return v;
});
const sortedLeaves = JSON.parse(serializedIndexedMap.sortedLeaves).map((row) => {
return {
key: bigintFromBase64(row[0]),
nextKey: bigintFromBase64(row[1]),
value: bigintFromBase64(row[2]),
index: Number(bigintFromBase64(row[3]))
};
});
map.root = import_o1js6.Field.fromJSON(serializedIndexedMap.root);
map.length = import_o1js6.Field.fromJSON(serializedIndexedMap.length);
map.data.updateAsProver(() => {
return {
nodes: nodes.map((row) => [...row]),
sortedLeaves: [...sortedLeaves]
};
});
return map;
}
// 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/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_o1js7 = 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 === "devnet" || chain === "mainnet");
if (chain === "zeko") {
const publicKey = import_o1js7.PublicKey.fromBase58(account);
await fetchMinaAccount({ publicKey });
const nonce = Number(import_o1js7.Mina.getAccount(publicKey).nonce.toBigint());
return nonce;
} else {
const blockberryNoncePromise = canUseBlockBerry ? getNonce({
account,
blockBerryApiKey,
chain
}) : void 0;
const publicKey = import_o1js7.PublicKey.fromBase58(account);
await fetchMinaAccount({ publicKey });
const senderNonce = Number(import_o1js7.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;
}
}
// dist/node/transactions/transaction.js
var import_o1js8 = 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_o1js8.Mina.Transaction.fromJSON(JSON.parse(tx));
const memo = transaction.transaction.memo;
return {
fee: import_o1js8.UInt64.from(signedJson.zkappCommand.feePayer.body.fee),
sender: import_o1js8.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_o1js8.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_o1js8.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_o1js8.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_o1js9 = require("o1js");
var TinyContract = class extends import_o1js9.SmartContract {
constructor() {
super(...arguments);
this.value = (0, import_o1js9.State)();
}
async setValue(value) {
this.value.set(value);
}
};
(0, import_tslib.__decorate)([
(0, import_o1js9.state)(import_o1js9.Field),
(0, import_tslib.__metadata)("design:type", Object)
], TinyContract.prototype, "value", void 0);
(0, import_tslib.__decorate)([
import_o1js9.method,
(0, import_tslib.__metadata)("design:type", Function),
(0, import_tslib.__metadata)("design:paramtypes", [import_o1js9.Field]),
(0, import_tslib.__metadata)("design:returntype", Promise)
], TinyContract.prototype, "setValue", null);
// dist/node/transactions/send.js
var import_o1js10 = require("o1js");
async function sendTx(params) {
const { tx, description = "", verbose = true, wait = true, chain = getCurrentNetwork().network.chainId, delay = chain === "zeko" || chain === "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 !== "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") {
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 !== "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")
console.error("Error sending tx", error);
}
}
async function getTxStatusFast(params) {
const { hash, chain = getCurrentNetwork().network.chainId } = params;
if (chain === "local" || chain === "zeko")
return { success: true, result: true };
try {
const txStatus = await (0, import_o1js10.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_o1js11 = require("o1js");
async function accountExists(address, tokenId) {
try {
const publicKey = typeof address === "string" ? import_o1js11.PublicKey.fromBase58(address) : address;
await fetchMinaAccount({ publicKey, tokenId, force: false });
return import_o1js11.Mina.hasAccount(publicKey, tokenId);
} catch (error) {
return false;
}
}
async function tokenBalance(address, tokenId) {
try {
const publicKey = typeof address === "string" ? import_o1js11.PublicKey.fromBase58(address) : address;
await fetchMinaAccount({ publicKey, tokenId, force: false });
return import_o1js11.Mina.hasAccount(publicKey, tokenId) ? Number(import_o1js11.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_o1js11.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_o1js15 = require("o1js");
// dist/node/commitment/constants.js
var import_o1js12 = require("o1js");
var BLS_FR = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n;
var Fr = (0, import_o1js12.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