UNPKG

secret-network-ccl

Version:

Secret Network's Confidential Comutation Layer

695 lines (690 loc) 26.6 kB
var __getOwnPropNames = Object.getOwnPropertyNames; var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod) => function __require2() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; // node_modules/tsup/assets/esm_shims.js import { fileURLToPath } from "url"; import path from "path"; var init_esm_shims = __esm({ "node_modules/tsup/assets/esm_shims.js"() { "use strict"; } }); // config/abi.js var require_abi = __commonJS({ "config/abi.js"(exports, module) { "use strict"; init_esm_shims(); var abi2 = [ { type: "constructor", inputs: [], stateMutability: "nonpayable" }, { type: "function", name: "increaseTaskId", inputs: [{ name: "_newTaskId", type: "uint256", internalType: "uint256" }], outputs: [], stateMutability: "nonpayable" }, { type: "function", name: "initialize", inputs: [], outputs: [], stateMutability: "nonpayable" }, { type: "function", name: "owner", inputs: [], outputs: [{ name: "", type: "address", internalType: "address" }], stateMutability: "view" }, { type: "function", name: "payoutBalance", inputs: [], outputs: [], stateMutability: "nonpayable" }, { type: "function", name: "postExecution", inputs: [ { name: "_taskId", type: "uint256", internalType: "uint256" }, { name: "_sourceNetwork", type: "string", internalType: "string" }, { name: "_info", type: "tuple", internalType: "struct Gateway.PostExecutionInfo", components: [ { name: "payload_hash", type: "bytes32", internalType: "bytes32" }, { name: "packet_hash", type: "bytes32", internalType: "bytes32" }, { name: "callback_address", type: "bytes20", internalType: "bytes20" }, { name: "callback_selector", type: "bytes4", internalType: "bytes4" }, { name: "callback_gas_limit", type: "bytes4", internalType: "bytes4" }, { name: "packet_signature", type: "bytes", internalType: "bytes" }, { name: "result", type: "bytes", internalType: "bytes" } ] } ], outputs: [], stateMutability: "nonpayable" }, { type: "function", name: "renounceOwnership", inputs: [], outputs: [], stateMutability: "nonpayable" }, { type: "function", name: "requestRandomness", inputs: [ { name: "_numWords", type: "uint32", internalType: "uint32" }, { name: "_callbackGasLimit", type: "uint32", internalType: "uint32" } ], outputs: [{ name: "requestId", type: "uint256", internalType: "uint256" }], stateMutability: "payable" }, { type: "function", name: "send", inputs: [ { name: "_payloadHash", type: "bytes32", internalType: "bytes32" }, { name: "_userAddress", type: "address", internalType: "address" }, { name: "_routingInfo", type: "string", internalType: "string" }, { name: "_info", type: "tuple", internalType: "struct Gateway.ExecutionInfo", components: [ { name: "user_key", type: "bytes", internalType: "bytes" }, { name: "user_pubkey", type: "bytes", internalType: "bytes" }, { name: "routing_code_hash", type: "string", internalType: "string" }, { name: "task_destination_network", type: "string", internalType: "string" }, { name: "handle", type: "string", internalType: "string" }, { name: "nonce", type: "bytes12", internalType: "bytes12" }, { name: "callback_gas_limit", type: "uint32", internalType: "uint32" }, { name: "payload", type: "bytes", internalType: "bytes" }, { name: "payload_signature", type: "bytes", internalType: "bytes" } ] } ], outputs: [{ name: "_taskId", type: "uint256", internalType: "uint256" }], stateMutability: "payable" }, { type: "function", name: "taskId", inputs: [], outputs: [{ name: "", type: "uint256", internalType: "uint256" }], stateMutability: "view" }, { type: "function", name: "tasks", inputs: [{ name: "", type: "uint256", internalType: "uint256" }], outputs: [ { name: "payload_hash_reduced", type: "bytes31", internalType: "bytes31" }, { name: "completed", type: "bool", internalType: "bool" } ], stateMutability: "view" }, { type: "function", name: "transferOwnership", inputs: [{ name: "newOwner", type: "address", internalType: "address" }], outputs: [], stateMutability: "nonpayable" }, { type: "function", name: "upgradeHandler", inputs: [], outputs: [], stateMutability: "nonpayable" }, { type: "event", name: "FulfilledRandomWords", inputs: [{ name: "requestId", type: "uint256", indexed: true, internalType: "uint256" }], anonymous: false }, { type: "event", name: "Initialized", inputs: [{ name: "version", type: "uint64", indexed: false, internalType: "uint64" }], anonymous: false }, { type: "event", name: "OwnershipTransferred", inputs: [ { name: "previousOwner", type: "address", indexed: true, internalType: "address" }, { name: "newOwner", type: "address", indexed: true, internalType: "address" } ], anonymous: false }, { type: "event", name: "TaskCompleted", inputs: [ { name: "taskId", type: "uint256", indexed: true, internalType: "uint256" }, { name: "callbackSuccessful", type: "bool", indexed: false, internalType: "bool" } ], anonymous: false }, { type: "event", name: "logNewTask", inputs: [ { name: "task_id", type: "uint256", indexed: true, internalType: "uint256" }, { name: "source_network", type: "string", indexed: false, internalType: "string" }, { name: "user_address", type: "address", indexed: false, internalType: "address" }, { name: "routing_info", type: "string", indexed: false, internalType: "string" }, { name: "payload_hash", type: "bytes32", indexed: false, internalType: "bytes32" }, { name: "info", type: "tuple", indexed: false, internalType: "struct Gateway.ExecutionInfo", components: [ { name: "user_key", type: "bytes", internalType: "bytes" }, { name: "user_pubkey", type: "bytes", internalType: "bytes" }, { name: "routing_code_hash", type: "string", internalType: "string" }, { name: "task_destination_network", type: "string", internalType: "string" }, { name: "handle", type: "string", internalType: "string" }, { name: "nonce", type: "bytes12", internalType: "bytes12" }, { name: "callback_gas_limit", type: "uint32", internalType: "uint32" }, { name: "payload", type: "bytes", internalType: "bytes" }, { name: "payload_signature", type: "bytes", internalType: "bytes" } ] } ], anonymous: false }, { type: "error", name: "InvalidInitialization", inputs: [] }, { type: "error", name: "NotInitializing", inputs: [] }, { type: "error", name: "OwnableInvalidOwner", inputs: [{ name: "owner", type: "address", internalType: "address" }] }, { type: "error", name: "OwnableUnauthorizedAccount", inputs: [{ name: "account", type: "address", internalType: "address" }] } ]; module.exports = abi2; } }); // src/index.ts init_esm_shims(); // src/functions.ts init_esm_shims(); var abi = require_abi(); var { ethers } = __require("ethers"); var { arrayify, hexlify, SigningKey, keccak256, recoverPublicKey, computeAddress } = __require("ethers/lib/utils"); var { SecretNetworkClient } = __require("secretjs"); async function loadESModules() { try { const neutrino = await import("@solar-republic/neutrino"); const belt = await import("@blake.regalia/belt"); return { neutrino, belt }; } catch (error) { console.error("Failed to load ES modules:", error); return null; } } async function requestRandomness(privateKey, endpoint, secretPathAddress, network, randomNumbers, max) { const modules = await loadESModules(); if (!modules) { console.log("Required modules could not be loaded."); return; } const { ecdh, chacha20_poly1305_seal } = modules.neutrino; const { bytes, bytes_to_base64, json_to_bytes, sha256, concat, text_to_bytes, base64_to_bytes } = modules.belt; let routing_contract; let routing_code_hash; let gatewayPublicKey; let destination_network; if (network === "testnet") { routing_contract = "secret1t5fktxrmkzkw4a44ssuyc84per4hc0jk93gwnd"; routing_code_hash = "81b04bfb2ca756e135201152081a113e4c333648e7088558777a2743f382c566"; gatewayPublicKey = "A20KrD7xDmkFXpNMqJn1CLpRaDLcdKpO1NdBBS7VpWh3"; destination_network = "pulsar-3"; } else if (network === "mainnet") { routing_contract = "secret1j97fu60k8ehu0zumft9c69haakxdv7chdana8q"; routing_code_hash = "81b04bfb2ca756e135201152081a113e4c333648e7088558777a2743f382c566"; gatewayPublicKey = "AqDWMqzQ0vXaAvw4XqMKjeq01WOdGoIaOlUmJa0PF1nQ"; destination_network = "secret-4"; } else { console.log("Invalid network parameter. Please use 'testnet' or 'mainnet'."); return; } const gatewayPublicKeyBytes = base64_to_bytes(gatewayPublicKey); const iface = new ethers.utils.Interface(abi); const provider = new ethers.providers.JsonRpcProvider(endpoint); const my_wallet = new ethers.Wallet(privateKey, provider); const myAddress = my_wallet.address; const wallet = ethers.Wallet.createRandom(); const userPrivateKeyBytes = arrayify(wallet.privateKey); const userPublicKey = new SigningKey(wallet.privateKey).compressedPublicKey; const userPublicKeyBytes = arrayify(userPublicKey); const sharedKey = await sha256(ecdh(userPrivateKeyBytes, gatewayPublicKeyBytes)); const callback_gas_limit = 3e5; const handle = "request_random"; const data = JSON.stringify({ random_numbers: randomNumbers, wallet_address: myAddress, max }); let publicClientAddress = secretPathAddress; const callbackAddress = publicClientAddress.toLowerCase(); const callbackSelector = iface.getSighash(iface.getFunction("upgradeHandler")); const callbackGasLimit = Number(callback_gas_limit); const payload = { data, routing_info: routing_contract, routing_code_hash, user_address: myAddress, user_key: bytes_to_base64(userPublicKeyBytes), callback_address: bytes_to_base64(arrayify(callbackAddress)), callback_selector: bytes_to_base64(arrayify(callbackSelector)), callback_gas_limit: callbackGasLimit }; const payloadJson = JSON.stringify(payload); const plaintext = json_to_bytes(payload); const nonce = crypto.getRandomValues(bytes(12)); const [ciphertextClient, tagClient] = chacha20_poly1305_seal( sharedKey, nonce, plaintext ); const ciphertext = concat([ciphertextClient, tagClient]); const ciphertextHash = keccak256(ciphertext); const payloadHash = keccak256( concat([ text_to_bytes("Ethereum Signed Message:\n32"), arrayify(ciphertextHash) ]) ); const msgParams = ciphertextHash; const from = myAddress; const params = [from, msgParams]; const method = "personal_sign"; console.log(`Payload Hash: ${payloadHash}`); const messageArrayified = ethers.utils.arrayify(ciphertextHash); const payloadSignature = await my_wallet.signMessage(messageArrayified); console.log(`Payload Signature: ${payloadSignature}`); const user_pubkey = recoverPublicKey(payloadHash, payloadSignature); console.log(`Recovered public key: ${user_pubkey}`); console.log( `Verify this matches the user address: ${computeAddress(user_pubkey)}` ); const _userAddress = myAddress; const _routingInfo = routing_contract; const _payloadHash = payloadHash; const _info = { user_key: hexlify(userPublicKeyBytes), user_pubkey, routing_code_hash, task_destination_network: destination_network, handle, nonce: hexlify(nonce), payload: hexlify(ciphertext), payload_signature: payloadSignature, callback_gas_limit: Number(callbackGasLimit) }; console.log(`_userAddress: ${_userAddress} _routingInfo: ${_routingInfo} _payloadHash: ${_payloadHash} _info: ${JSON.stringify(_info)} _callbackAddress: ${callbackAddress}, _callbackSelector: ${callbackSelector} , _callbackGasLimit: ${callbackGasLimit}`); const functionData = iface.encodeFunctionData("send", [ _payloadHash, _userAddress, _routingInfo, _info ]); const gasFee = await provider.getGasPrice(); const amountOfGas = gasFee.mul(callbackGasLimit).mul(3).div(2); const tx = { gasLimit: ethers.utils.hexlify(15e4), to: publicClientAddress, value: ethers.utils.hexlify(amountOfGas), data: functionData }; try { const txResponse = await my_wallet.sendTransaction(tx); console.log(`Transaction sent! Hash: ${txResponse.hash}`); const receipt = await txResponse.wait(); console.log(`Transaction confirmed! Block Number: ${receipt.blockNumber}`); } catch (error) { console.error(`Error sending transaction: ${error}`); } } async function encryptData(privateKey, endpoint, secretPathAddress, network, data_to_encypt, password) { const modules = await loadESModules(); if (!modules) { console.log("Required modules could not be loaded."); return; } const { ecdh, chacha20_poly1305_seal } = modules.neutrino; const { bytes, bytes_to_base64, json_to_bytes, sha256, concat, text_to_bytes, base64_to_bytes } = modules.belt; let routing_contract; let routing_code_hash; let gatewayPublicKey; let destination_network; if (network === "testnet") { routing_contract = "secret1s79j3uaa0g49ncur884vv80ucz7hdwgltgke52"; routing_code_hash = "f0947ac3d0459bd5ccc24a43aa18762325f7582dc7919b4557ecf98b81345261"; gatewayPublicKey = "A20KrD7xDmkFXpNMqJn1CLpRaDLcdKpO1NdBBS7VpWh3"; destination_network = "pulsar-3"; } else if (network === "mainnet") { routing_contract = "secret14pq7cpme92a3pc6ty0yjnprudmh7epacrphwr0"; routing_code_hash = "f0947ac3d0459bd5ccc24a43aa18762325f7582dc7919b4557ecf98b81345261"; gatewayPublicKey = "AqDWMqzQ0vXaAvw4XqMKjeq01WOdGoIaOlUmJa0PF1nQ"; destination_network = "secret-4"; } else { console.log("Invalid network parameter. Please use 'testnet' or 'mainnet'."); return; } const iface = new ethers.utils.Interface(abi); const provider = new ethers.providers.JsonRpcProvider( endpoint ); const my_wallet = new ethers.Wallet(privateKey, provider); const myAddress = my_wallet.address; const wallet = ethers.Wallet.createRandom(); const userPrivateKeyBytes = arrayify(wallet.privateKey); const userPublicKey = new SigningKey(wallet.privateKey).compressedPublicKey; const userPublicKeyBytes = arrayify(userPublicKey); const gatewayPublicKeyBytes = base64_to_bytes(gatewayPublicKey); const sharedKey = await sha256( ecdh(userPrivateKeyBytes, gatewayPublicKeyBytes) ); const callback_gas_limit = 3e5; const handle = "request_encrypt"; const data = JSON.stringify({ data: data_to_encypt, password }); let publicClientAddress = secretPathAddress; const callbackAddress = publicClientAddress.toLowerCase(); const callbackSelector = iface.getSighash( iface.getFunction("upgradeHandler") ); const callbackGasLimit = Number(callback_gas_limit); const payload = { data, routing_info: routing_contract, routing_code_hash, user_address: myAddress, user_key: bytes_to_base64(userPublicKeyBytes), callback_address: bytes_to_base64(arrayify(callbackAddress)), callback_selector: bytes_to_base64(arrayify(callbackSelector)), callback_gas_limit: callbackGasLimit }; const payloadJson = JSON.stringify(payload); const plaintext = json_to_bytes(payload); const nonce = crypto.getRandomValues(bytes(12)); const [ciphertextClient, tagClient] = chacha20_poly1305_seal( sharedKey, nonce, plaintext ); const ciphertext = concat([ciphertextClient, tagClient]); const ciphertextHash = keccak256(ciphertext); const payloadHash = keccak256( concat([ text_to_bytes("Ethereum Signed Message:\n32"), arrayify(ciphertextHash) ]) ); const msgParams = ciphertextHash; const from = myAddress; const params = [from, msgParams]; const method = "personal_sign"; console.log(`Payload Hash: ${payloadHash}`); const messageArrayified = ethers.utils.arrayify(ciphertextHash); const payloadSignature = await my_wallet.signMessage(messageArrayified); console.log(`Payload Signature: ${payloadSignature}`); const user_pubkey = recoverPublicKey(payloadHash, payloadSignature); console.log(`Recovered public key: ${user_pubkey}`); console.log( `Verify this matches the user address: ${computeAddress(user_pubkey)}` ); const _userAddress = myAddress; const _routingInfo = routing_contract; const _payloadHash = payloadHash; const _info = { user_key: hexlify(userPublicKeyBytes), user_pubkey, routing_code_hash, task_destination_network: destination_network, //Destination for the task, here: pulsar-3 testnet handle, nonce: hexlify(nonce), payload: hexlify(ciphertext), payload_signature: payloadSignature, callback_gas_limit: Number(callbackGasLimit) }; console.log(`_userAddress: ${_userAddress} _routingInfo: ${_routingInfo} _payloadHash: ${_payloadHash} _info: ${JSON.stringify(_info)} _callbackAddress: ${callbackAddress}, _callbackSelector: ${callbackSelector} , _callbackGasLimit: ${callbackGasLimit}`); const functionData = iface.encodeFunctionData("send", [ _payloadHash, _userAddress, _routingInfo, _info ]); const gasFee = await provider.getGasPrice(); const amountOfGas = gasFee.mul(callbackGasLimit).mul(3).div(2); const tx = { gasLimit: ethers.utils.hexlify(15e4), // Use hexlify to ensure the gas limit is correctly formatted to: publicClientAddress, // from: myAddress, // This is not needed because the wallet knows the 'from' address value: ethers.utils.hexlify(amountOfGas), // Make sure to hexlify the amount data: functionData }; try { const txResponse = await my_wallet.sendTransaction(tx); console.log(`Transaction sent! Hash: ${txResponse.hash}`); const receipt = await txResponse.wait(); console.log(`Transaction confirmed! Block Number: ${receipt.blockNumber}`); } catch (error) { console.error(`Error sending transaction: ${error}`); } } async function executeSecretContract(privateKey, endpoint, secretPathAddress, contractAddress, codeHash, network, executeHandle, ...strings) { const modules = await loadESModules(); if (!modules) { console.log("Required modules could not be loaded."); return; } const { ecdh, chacha20_poly1305_seal } = modules.neutrino; const { bytes, bytes_to_base64, json_to_bytes, sha256, concat, text_to_bytes, base64_to_bytes } = modules.belt; let gatewayPublicKey; let destination_network; if (network === "testnet") { gatewayPublicKey = "A20KrD7xDmkFXpNMqJn1CLpRaDLcdKpO1NdBBS7VpWh3"; destination_network = "pulsar-3"; } else if (network === "mainnet") { gatewayPublicKey = "AqDWMqzQ0vXaAvw4XqMKjeq01WOdGoIaOlUmJa0PF1nQ"; destination_network = "secret-4"; } else { console.log("Invalid network parameter. Please use 'testnet' or 'mainnet'."); return; } const routing_contract = contractAddress; const routing_code_hash = codeHash; const iface = new ethers.utils.Interface(abi); const provider = new ethers.providers.JsonRpcProvider(endpoint); const my_wallet = new ethers.Wallet(privateKey, provider); const myAddress = my_wallet.address; const wallet = ethers.Wallet.createRandom(); const userPrivateKeyBytes = arrayify(wallet.privateKey); const userPublicKey = new SigningKey(wallet.privateKey).compressedPublicKey; const userPublicKeyBytes = arrayify(userPublicKey); const gatewayPublicKeyBytes = base64_to_bytes(gatewayPublicKey); const sharedKey = await sha256( ecdh(userPrivateKeyBytes, gatewayPublicKeyBytes) ); const callback_gas_limit = 3e5; const handle = executeHandle; const data = {}; strings.forEach((string) => { if (string) data[string.key] = string.value; }); const jsonData = JSON.stringify(data); let publicClientAddress = secretPathAddress; const callbackAddress = publicClientAddress.toLowerCase(); const callbackSelector = iface.getSighash(iface.getFunction("upgradeHandler")); const callbackGasLimit = Number(callback_gas_limit); const payload = { data: jsonData, routing_info: routing_contract, routing_code_hash, user_address: myAddress, user_key: bytes_to_base64(userPublicKeyBytes), callback_address: bytes_to_base64(arrayify(callbackAddress)), callback_selector: bytes_to_base64(arrayify(callbackSelector)), callback_gas_limit: callbackGasLimit }; const payloadJson = JSON.stringify(payload); const plaintext = json_to_bytes(payload); const nonce = crypto.getRandomValues(bytes(12)); const [ciphertextClient, tagClient] = chacha20_poly1305_seal( sharedKey, nonce, plaintext ); const ciphertext = concat([ciphertextClient, tagClient]); const ciphertextHash = keccak256(ciphertext); const payloadHash = keccak256( concat([ text_to_bytes("Ethereum Signed Message:\n32"), arrayify(ciphertextHash) ]) ); const msgParams = ciphertextHash; const from = myAddress; const params = [from, msgParams]; const method = "personal_sign"; console.log(`Payload Hash: ${payloadHash}`); const messageArrayified = ethers.utils.arrayify(ciphertextHash); const payloadSignature = await my_wallet.signMessage(messageArrayified); console.log(`Payload Signature: ${payloadSignature}`); const user_pubkey = recoverPublicKey(payloadHash, payloadSignature); console.log(`Recovered public key: ${user_pubkey}`); console.log( `Verify this matches the user address: ${computeAddress(user_pubkey)}` ); const _userAddress = myAddress; const _routingInfo = routing_contract; const _payloadHash = payloadHash; const _info = { user_key: hexlify(userPublicKeyBytes), user_pubkey, routing_code_hash, task_destination_network: destination_network, handle, nonce: hexlify(nonce), payload: hexlify(ciphertext), payload_signature: payloadSignature, callback_gas_limit: Number(callbackGasLimit) }; console.log(`_userAddress: ${_userAddress} _routingInfo: ${_routingInfo} _payloadHash: ${_payloadHash} _info: ${JSON.stringify(_info)} _callbackAddress: ${callbackAddress}, _callbackSelector: ${callbackSelector} , _callbackGasLimit: ${callbackGasLimit}`); const functionData = iface.encodeFunctionData("send", [ _payloadHash, _userAddress, _routingInfo, _info ]); const gasFee = await provider.getGasPrice(); const amountOfGas = gasFee.mul(callbackGasLimit).mul(3).div(2); const tx = { gasLimit: ethers.utils.hexlify(15e4), to: publicClientAddress, value: ethers.utils.hexlify(amountOfGas), data: functionData }; try { const txResponse = await my_wallet.sendTransaction(tx); console.log(`Transaction sent! Hash: ${txResponse.hash}`); const receipt = await txResponse.wait(); console.log(`Transaction confirmed! Block Number: ${receipt.blockNumber}`); } catch (error) { console.error(`Error sending transaction: ${error}`); } } async function queryRandomness(wallet, network) { let chainId; let url; let contractAddress; let contractCodeHash; if (network === "testnet") { chainId = "pulsar-3"; url = "https://lcd.testnet.secretsaturn.net"; contractAddress = "secret1t5fktxrmkzkw4a44ssuyc84per4hc0jk93gwnd"; contractCodeHash = "81b04bfb2ca756e135201152081a113e4c333648e7088558777a2743f382c566"; } else if (network === "mainnet") { chainId = "secret-4"; url = "https://lcd.mainnet.secretsaturn.net"; contractAddress = "secret1j97fu60k8ehu0zumft9c69haakxdv7chdana8q"; contractCodeHash = "81b04bfb2ca756e135201152081a113e4c333648e7088558777a2743f382c566"; } else { console.log("Invalid network parameter. Please use 'testnet' or 'mainnet'."); return; } const secretjs = new SecretNetworkClient({ url, chainId }); const query_tx = await secretjs.query.compute.queryContract({ contract_address: contractAddress, code_hash: contractCodeHash, query: { retrieve_random: { wallet } } }); console.log(query_tx); } async function querySecretContract(contractAddress, codeHash, network, queryName, queryParameters) { let chainId; let url; if (network === "testnet") { chainId = "pulsar-3"; url = "https://lcd.testnet.secretsaturn.net"; } else if (network === "mainnet") { chainId = "secret-4"; url = "https://lcd.mainnet.secretsaturn.net"; } else { console.log("Invalid network parameter. Please use 'testnet' or 'mainnet'."); return; } const secretjs = new SecretNetworkClient({ url, chainId }); const query = { [queryName]: {} }; if (queryParameters) { for (const [key, value] of Object.entries(queryParameters)) { query[queryName][key] = value; } } const query_tx = await secretjs.query.compute.queryContract({ contract_address: contractAddress, code_hash: codeHash, query }); console.log(query_tx); } export { encryptData, executeSecretContract, loadESModules, queryRandomness, querySecretContract, requestRandomness };