UNPKG

@silvana-one/coordination

Version:

Silvana Coordination Client

1,557 lines (1,531 loc) 73.5 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; 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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // dist/node/index.js var index_exports = {}; __export(index_exports, { AgentRegistry: () => AgentRegistry, AppInstanceManager: () => AppInstanceManager, JobManager: () => JobManager, buildMovePackage: () => buildMovePackage, buildPublishTx: () => buildPublishTx, buildUpgradeTx: () => buildUpgradeTx, convertFieldsToPublicKey: () => convertFieldsToPublicKey, convertMinaPublicKey: () => convertMinaPublicKey, convertMinaPublicKeyToFields: () => convertMinaPublicKeyToFields, convertMinaSignatureFromBase58: () => convertMinaSignatureFromBase58, convertMinaSignatureToBase58: () => convertMinaSignatureToBase58, createTestApp: () => createTestApp, createTestRegistry: () => createTestRegistry, executeTx: () => executeTx, fetchSuiDynamicField: () => fetchSuiDynamicField, fetchSuiDynamicFieldsList: () => fetchSuiDynamicFieldsList, fetchSuiObject: () => fetchSuiObject, generateEd25519: () => generateEd25519, getIPFSUrl: () => getIPFSUrl, getState: () => getState, getSuiAddress: () => getSuiAddress, getSuiBalance: () => getSuiBalance, getWalrusUrl: () => getWalrusUrl, network: () => network, publicKeyToU256: () => publicKeyToU256, publishCodeToMVR: () => publishCodeToMVR, publishToMVR: () => publishToMVR, readFromIPFS: () => readFromIPFS, readFromWalrus: () => readFromWalrus, saveToIPFS: () => saveToIPFS, saveToWalrus: () => saveToWalrus, signFields: () => signFields, signMessage: () => signMessage, silvanaFaucet: () => silvanaFaucet, silvanaFaucetGetKey: () => silvanaFaucetGetKey, silvanaFaucetPingKey: () => silvanaFaucetPingKey, silvanaFaucetReturnKey: () => silvanaFaucetReturnKey, silvanaRegistryAddress: () => silvanaRegistryAddress, silvanaRegistryPackage: () => silvanaRegistryPackage, sleep: () => sleep, suiBalance: () => suiBalance, suiClient: () => suiClient, u256ToFields: () => u256ToFields, u256ToPublicKey: () => u256ToPublicKey, verifyFields: () => verifyFields, verifyWithAddress: () => verifyWithAddress, waitTx: () => waitTx, walrusDaemon: () => walrusDaemon }); module.exports = __toCommonJS(index_exports); // dist/node/base58/base58.js var import_js_sha256 = require("js-sha256"); // dist/node/base58/bigint-helpers.js var mask64 = (1n << 64n) - 1n; var hexToNum = {}; for (let i = 0; i < 16; i++) hexToNum[i.toString(16).charCodeAt(0)] = i; var encoder = new TextEncoder(); var tmpBytes = new Uint8Array(64); function changeBase(digits, base, newBase) { let x = fromBase(digits, base); let newDigits = toBase(x, newBase); return newDigits; } 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/base58/base58.js var alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".split(""); var inverseAlphabet = {}; alphabet.forEach((c, i) => { inverseAlphabet[c] = i; }); function toBytesWithVersionNumber(t, versionNumber) { let bytes = toBytes(t, versionNumber); bytes.unshift(versionNumber); return bytes; } function bigIntToBytes(x, length) { if (x < 0n) { throw Error(`bigIntToBytes: negative numbers are not supported, got ${x}`); } let bytes = Array(length); for (let i = 0; i < length; i++, x >>= 8n) { bytes[i] = Number(x & 0xffn); } if (x > 0n) { throw Error(`bigIntToBytes: input does not fit in ${length} bytes`); } return bytes; } function toBytes(t, versionNumber) { if (t.length !== 2) throw new Error("Expected 2 elements in t"); let bytes = []; let subBytes1 = bigIntToBytes(t[0], 32); subBytes1.unshift(versionNumber); bytes.push(...subBytes1); bytes.push(Number(t[1])); return bytes; } function toBase58Check(input, versionByte) { let withVersion = [versionByte, ...input]; let checksum = computeChecksum(withVersion); let withChecksum = withVersion.concat(checksum); return toBase58(withChecksum); } function toBase58(bytes) { let z = 0; while (bytes[z] === 0) z++; let digits = [...bytes].map(BigInt).reverse(); let base58Digits = changeBase(digits, 256n, 58n).reverse(); base58Digits = Array(z).fill(0n).concat(base58Digits); return base58Digits.map((x) => alphabet[Number(x)]).join(""); } function fromBase58Check(base58, versionByte) { let bytes = fromBase58(base58); let checksum = bytes.slice(-4); let originalBytes = bytes.slice(0, -4); let actualChecksum = computeChecksum(originalBytes); if (!arrayEqual(checksum, actualChecksum)) throw Error("fromBase58Check: invalid checksum"); if (originalBytes[0] !== versionByte) throw Error(`fromBase58Check: input version byte ${versionByte} does not match encoded version byte ${originalBytes[0]}`); return originalBytes.slice(1); } function fromBase58(base58) { let base58Digits = [...base58].map((c) => { let digit = inverseAlphabet[c]; if (digit === void 0) throw Error("fromBase58: invalid character"); return BigInt(digit); }); let z = 0; while (base58Digits[z] === 0n) z++; let digits = changeBase(base58Digits.reverse(), 58n, 256n).reverse(); digits = Array(z).fill(0n).concat(digits); return digits.map(Number); } function computeChecksum(input) { let hash1 = import_js_sha256.sha256.create(); hash1.update(input); let hash2 = import_js_sha256.sha256.create(); hash2.update(hash1.array()); return hash2.array().slice(0, 4); } function arrayEqual(a, b) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } return true; } // dist/node/base58/versions.js var versionNumbers = { field: 1, scalar: 1, publicKey: 1, signature: 1 }; var versionBytes = { publicKey: 203, privateKey: 90, signature: 154 }; // dist/node/base58/signature.js function assertNonNegativeInteger(n, message) { if (!Number.isInteger(n) || n < 0) throw Error(message); } function bytesToBigInt(bytes) { let x = 0n; let bitPosition = 0n; for (let byte of bytes) { x += BigInt(byte) << bitPosition; bitPosition += 8n; } return x; } function readBytesInternal(bytes, start) { const rBytes = bytes.slice(start, start + 32); const sBytes = bytes.slice(start + 32, start + 64); const r = bytesToBigInt(rBytes); const s = bytesToBigInt(sBytes); return { r, s }; } function readBytes(bytes, offset, versionNumber) { let version = bytes[offset++]; if (version !== versionNumber) { throw Error(`fromBytes: Invalid version byte. Expected ${versionNumber}, got ${version}.`); } return readBytesInternal(bytes, offset); } var readBytes_ = (bytes, offset) => { assertNonNegativeInteger(offset, "readBytes: offset must be integer >= 0"); if (offset >= bytes.length) throw Error("readBytes: offset must be within bytes length"); return readBytes(bytes, offset, versionNumbers.signature); }; function fromBytes(bytes) { return readBytes_(bytes, 0); } function toBytes2(signature) { const result = new Array(65); result[0] = versionNumbers.signature; let r = signature.r; for (let i = 0; i < 32; i++) { result[i + 1] = Number(r & 0xffn); r >>= 8n; } let s = signature.s; for (let i = 0; i < 32; i++) { result[i + 33] = Number(s & 0xffn); s >>= 8n; } return result; } function convertMinaSignatureFromBase58(signature) { const bytes = fromBase58Check(signature, versionBytes.signature); const minaSignature = fromBytes(bytes); return minaSignature; } function convertMinaSignatureToBase58(signature) { const bytes = toBytes2(signature); return toBase58Check(bytes, versionBytes.signature); } // dist/node/base58/public-key.js function convertFieldsToPublicKey(fields) { let bytes = toBytesWithVersionNumber([fields.x, fields.isOdd ? 1n : 0n], versionNumbers.publicKey); return toBase58Check(bytes, versionBytes.publicKey); } // dist/node/execute.js var import_transactions2 = require("@mysten/sui/transactions"); // dist/node/sui-client.js var import_client = require("@mysten/sui/client"); var import_transactions = require("@mysten/sui/transactions"); var network = process.env.NEXT_PUBLIC_SUI_CHAIN || process.env.SUI_CHAIN || "testnet"; if (!network) { throw new Error("SUI_CHAIN is not set"); } if (network === "testnet") { const plugin = (0, import_transactions.namedPackagesPlugin)({ url: "https://testnet.mvr.mystenlabs.com" }); import_transactions.Transaction.registerGlobalSerializationPlugin("namedPackagesPlugin", plugin); } if (network === "mainnet") { const plugin = (0, import_transactions.namedPackagesPlugin)({ url: "https://mainnet.mvr.mystenlabs.com" }); import_transactions.Transaction.registerGlobalSerializationPlugin("namedPackagesPlugin", plugin); } var suiClient = new import_client.SuiClient({ url: getUrl(network) }); function getUrl(network2) { if (network2 === "testnet") { return process.env.SUI_TESTNET_URL || process.env.NEXT_PUBLIC_SUI_TESTNET_URL || "https://rpc-testnet.suiscan.xyz:443"; } else if (network2 === "devnet") { return process.env.SUI_DEVNET_URL || process.env.NEXT_PUBLIC_SUI_DEVNET_URL || "https://rpc-ws-devnet.suiscan.xyz"; } else if (network2 === "mainnet") { return process.env.SUI_MAINNET_URL || process.env.NEXT_PUBLIC_SUI_MAINNET_URL || "https://rpc-mainnet.suiscan.xyz:443"; } else { return (0, import_client.getFullnodeUrl)(network2); } } // dist/node/execute.js var import_nanoid = require("nanoid"); // dist/node/sleep.js function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } // dist/node/execute.js var executors = {}; var locks = {}; var LOCK_TIMEOUT = 1e3 * 60 * 2; async function getLock(address) { const id = (0, import_nanoid.nanoid)(); let locked = false; const start = Date.now(); while (!locked && Date.now() - start < LOCK_TIMEOUT) { if (locks[address]) { await sleep(Math.floor(Math.random() * 10) + 10); } else { locks[address] = id; await sleep(10); if (locks[address] === id) { locked = true; return id; } } } return void 0; } async function releaseLock(params) { const { address, id } = params; if (locks[address] === id) { locks[address] = void 0; } } function getExecutor(keyPair) { const keyPairId = keyPair.toSuiAddress(); if (!executors[keyPairId]) { executors[keyPairId] = new import_transactions2.ParallelTransactionExecutor({ client: suiClient, signer: keyPair, initialCoinBalance: 500000000n, minimumCoinBalance: 300000000n, maxPoolSize: 5 }); locks[keyPairId] = void 0; } return executors[keyPairId]; } async function executeTx(params) { let lockId; let address; try { const { tx, keyPair, useParallelExecutor = false, showErrors = true } = params; let executedTx; let start = 0; let end = 0; if (useParallelExecutor) { address = keyPair.toSuiAddress(); lockId = await getLock(address); if (!lockId) { throw new Error("Failed to get lock"); } start = Date.now(); const executor = getExecutor(keyPair); executedTx = (await executor.executeTransaction(tx, { showEffects: true, showObjectChanges: true, showInput: true, showEvents: true, showBalanceChanges: true })).data; end = Date.now(); await waitTx(executedTx.digest); await sleep(1e3); await releaseLock({ address, id: lockId }); } else { address = keyPair.toSuiAddress(); lockId = await getLock(address); if (!lockId) { throw new Error("Failed to get lock"); } const signedTx = await tx.sign({ signer: keyPair, client: suiClient }); start = Date.now(); executedTx = await suiClient.executeTransactionBlock({ transactionBlock: signedTx.bytes, signature: signedTx.signature, options: { showEffects: true, showObjectChanges: true, showInput: true, showEvents: true, showBalanceChanges: true } }); end = Date.now(); await releaseLock({ address, id: lockId }); } if (executedTx?.effects?.status?.status === "failure") { const errorMessage = executedTx?.effects?.status?.error || "Unknown error"; if (showErrors) { console.log(`Errors for tx ${executedTx.digest}:`, errorMessage); } return { tx: executedTx, digest: executedTx.digest, events: executedTx?.events?.[0]?.parsedJson, executeTime: end - start, error: errorMessage }; } return { tx: executedTx, digest: executedTx.digest, events: executedTx?.events?.[0]?.parsedJson, executeTime: end - start }; } catch (error) { if (lockId && address) { await releaseLock({ address, id: lockId }); } console.error("Error in executeTx", error.message); return void 0; } } async function waitTx(digest) { console.time(`wait sui tx`); const txWaitResult = await suiClient.waitForTransaction({ digest, options: { showEffects: true, showObjectChanges: true, showInput: true, showEvents: true, showBalanceChanges: true } }); console.timeEnd(`wait sui tx`); return txWaitResult; } // dist/node/publish.js var import_transactions3 = require("@mysten/sui/transactions"); async function buildPublishTx(params) { const { modules, dependencies, keypair } = params; const address = keypair.toSuiAddress(); const tx = new import_transactions3.Transaction(); const { Result: publishedDex } = tx.publish({ modules, dependencies }); const { Result: dex } = tx.transferObjects([ { Result: publishedDex } ], address); tx.setSender(address); return { tx }; } // dist/node/upgrade.js var import_transactions4 = require("@mysten/sui/transactions"); async function buildUpgradeTx(params) { const { modules, dependencies, digest, address, keypair, packageID, upgradeCap } = params; const tx = new import_transactions4.Transaction(); const ticket = tx.moveCall({ target: "0x2::package::authorize_upgrade", arguments: [ tx.object(upgradeCap), tx.pure.u8(import_transactions4.UpgradePolicy.COMPATIBLE), tx.pure.vector("u8", digest) ] }); const upgradeData = tx.upgrade({ package: packageID, ticket, modules, dependencies }); const commitData = tx.moveCall({ target: "0x2::package::commit_upgrade", arguments: [tx.object(upgradeCap), upgradeData] }); const paginatedCoins = await suiClient.getCoins({ owner: address }); const coins = paginatedCoins.data.map((coin) => { return { objectId: coin.coinObjectId, version: coin.version, digest: coin.digest }; }); tx.setSender(address); tx.setGasOwner(address); tx.setGasPayment(coins); tx.setGasBudget(3e8); return { tx }; } // dist/node/mvr.js var import_transactions5 = require("@mysten/sui/transactions"); function publishToMVR(params) { const { upgradeCap, packageName, mvrName, safeAddress } = params; const transaction = new import_transactions5.Transaction(); const packageInfo = transaction.moveCall({ target: `@mvr/metadata::package_info::new`, arguments: [transaction.object(upgradeCap)] }); const display = transaction.moveCall({ target: `@mvr/metadata::display::default`, arguments: [transaction.pure.string(packageName)] }); transaction.moveCall({ target: `@mvr/metadata::package_info::set_display`, arguments: [transaction.object(packageInfo), display] }); transaction.moveCall({ target: "@mvr/metadata::package_info::set_metadata", arguments: [ transaction.object(packageInfo), transaction.pure.string("default"), transaction.pure.string(mvrName) ] }); transaction.moveCall({ target: `@mvr/metadata::package_info::transfer`, arguments: [ transaction.object(packageInfo), transaction.pure.address(safeAddress) ] }); return transaction; } function publishCodeToMVR(params) { const { packageInfo, gitRepository, gitSubdirectory, gitCommitHash, version } = params; const transaction = new import_transactions5.Transaction(); const git = transaction.moveCall({ target: `@mvr/metadata::git::new`, arguments: [ transaction.pure.string(gitRepository), transaction.pure.string(gitSubdirectory), transaction.pure.string(gitCommitHash) ] }); transaction.moveCall({ target: `@mvr/metadata::package_info::set_git_versioning`, arguments: [ transaction.object(packageInfo), transaction.pure.u64(version), git ] }); return transaction; } // dist/node/agent.js var import_transactions6 = require("@mysten/sui/transactions"); var import_utils = require("@mysten/sui/utils"); // dist/node/fetch.js async function fetchSuiObject(objectID) { const data = await suiClient.getObject({ id: objectID, options: { showContent: true } }); return data; } async function fetchSuiDynamicFieldsList(objectID) { const data = await suiClient.getDynamicFields({ parentId: objectID }); return data; } async function fetchSuiDynamicField(params) { try { const { objectID, parentID, fieldName, type, key } = params; if (!objectID && !parentID) { console.error("objectID or parentID is required"); return void 0; } let id = parentID; if (objectID && !parentID) { const suiObject = await fetchSuiObject(objectID); id = suiObject?.data?.content?.fields?.[fieldName]?.fields?.id?.id; } if (!id) { return void 0; } const field = await suiClient.getDynamicFieldObject({ parentId: id, name: { type, value: key } }); return field.data?.content?.fields; } catch (error) { console.error("fetchSuiDynamicField: Error fetching dynamic field", error?.message); return void 0; } } // dist/node/package.js var silvanaRegistryPackage = process.env.SILVANA_REGISTRY_PACKAGE ?? process.env.NEXT_PUBLIC_SILVANA_REGISTRY_PACKAGE ?? "@silvana/agent"; var silvanaRegistryAddress = process.env.SILVANA_REGISTRY_ADDRESS ?? process.env.NEXT_PUBLIC_SILVANA_REGISTRY_ADDRESS; // dist/node/agent.js var AgentRegistry = class { constructor(params) { this.registry = params.registry; } static createAgentRegistry(params) { const { name, transaction } = params; console.log("Creating agent registry", name); const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::create_registry`, arguments: [tx.pure.string(name)] }); return tx; } createDeveloper(params) { const { name, developerOwner, github, image, description, site, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::add_developer`, arguments: [ tx.object(this.registry), tx.pure.address(developerOwner), tx.pure.string(name), tx.pure.string(github), tx.pure.option("string", image ?? null), tx.pure.option("string", description ?? null), tx.pure.option("string", site ?? null), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } updateDeveloper(params) { const { name, github, image, description, site, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::update_developer`, arguments: [ tx.object(this.registry), tx.pure.string(name), tx.pure.string(github), tx.pure.option("string", image ?? null), tx.pure.option("string", description ?? null), tx.pure.option("string", site ?? null), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } removeDeveloper(params) { const { name, agentNames, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::remove_developer`, arguments: [ tx.object(this.registry), tx.pure.string(name), tx.pure.vector("string", agentNames), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } createAgent(params) { const { developer, name, image, description, site, chains, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::add_agent`, arguments: [ tx.object(this.registry), tx.pure.string(developer), tx.pure.string(name), tx.pure.option("string", image ?? null), tx.pure.option("string", description ?? null), tx.pure.option("string", site ?? null), tx.pure.vector("string", chains), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } updateAgent(params) { const { developer, name, image, description, site, chains, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::update_agent`, arguments: [ tx.object(this.registry), tx.pure.string(developer), tx.pure.string(name), tx.pure.option("string", image ?? null), tx.pure.option("string", description ?? null), tx.pure.option("string", site ?? null), tx.pure.vector("string", chains), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } removeAgent(params) { const { developer, agent, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::remove_agent`, arguments: [ tx.object(this.registry), tx.pure.string(developer), tx.pure.string(agent), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } addAgentMethod(params) { const { developer, agent, method, dockerImage, dockerSha256, minMemoryGb, minCpuCores, requiresTee, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::add_method`, arguments: [ tx.object(this.registry), tx.pure.string(developer), tx.pure.string(agent), tx.pure.string(method), tx.pure.string(dockerImage), tx.pure.option("string", dockerSha256 ?? null), tx.pure.u16(minMemoryGb), tx.pure.u16(minCpuCores), tx.pure.bool(requiresTee), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } updateAgentMethod(params) { const { developer, agent, method, dockerImage, dockerSha256, minMemoryGb, minCpuCores, requiresTee, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::update_method`, arguments: [ tx.object(this.registry), tx.pure.string(developer), tx.pure.string(agent), tx.pure.string(method), tx.pure.string(dockerImage), tx.pure.option("string", dockerSha256 ?? null), tx.pure.u16(minMemoryGb), tx.pure.u16(minCpuCores), tx.pure.bool(requiresTee), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } removeAgentMethod(params) { const { developer, agent, method, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::remove_method`, arguments: [ tx.object(this.registry), tx.pure.string(developer), tx.pure.string(agent), tx.pure.string(method), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } addMethodToApp(params) { const { appName, methodName, description, developerName, agentName, agentMethod, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); const appMethod = tx.moveCall({ target: `${silvanaRegistryPackage}::app_method::new`, arguments: [ tx.pure.option("string", description ?? null), tx.pure.string(developerName), tx.pure.string(agentName), tx.pure.string(agentMethod) ] }); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::add_method_to_app`, arguments: [ tx.object(this.registry), tx.pure.string(appName), tx.pure.string(methodName), appMethod ] }); return tx; } addMetadata(params) { const { appInstanceId, key, value, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::app_instance::add_metadata`, arguments: [ tx.object(appInstanceId), tx.pure.string(key), tx.pure.string(value) ] }); return tx; } setDefaultMethod(params) { const { developer, agent, method, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::set_default_method`, arguments: [ tx.object(this.registry), tx.pure.string(developer), tx.pure.string(agent), tx.pure.string(method), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } removeDefaultMethod(params) { const { developer, agent, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::remove_default_method`, arguments: [ tx.object(this.registry), tx.pure.string(developer), tx.pure.string(agent), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } async getDeveloper(params) { const developerObject = await fetchSuiDynamicField({ objectID: this.registry, fieldName: "developers", type: "0x1::string::String", key: params.name }); if (!developerObject) { return void 0; } let agents = []; const agentsObject = developerObject?.agents?.fields?.id?.id; if (agentsObject) { const agentsList = await fetchSuiDynamicFieldsList(agentsObject); const agentsArray = agentsList?.data; if (Array.isArray(agentsArray)) { agents = agentsArray.map((agent) => agent?.name?.value).filter((agent) => agent !== void 0 && typeof agent === "string"); } } const developer = { id: developerObject?.id?.id, name: developerObject.name, github: developerObject.github, image: developerObject?.image ?? void 0, description: developerObject?.description ?? void 0, site: developerObject?.site ?? void 0, owner: developerObject.owner, agents, createdAt: Number(developerObject.created_at), updatedAt: Number(developerObject.updated_at), version: Number(developerObject.version) }; if (!developer.id || !developer.name || !developer.github || !developer.owner || !developer.createdAt || !developer.updatedAt) { return void 0; } return developer; } async getDeveloperNames(params) { const developerObject = await fetchSuiDynamicField({ objectID: this.registry, fieldName: "developers_index", type: "address", key: params.developerAddress }); if (!developerObject) { return void 0; } const developer = { id: developerObject?.id?.id, developer_address: developerObject.developer, names: developerObject.names, version: Number(developerObject.version) }; if (!developer.id || !developer.developer_address || !developer.names) { return void 0; } return developer; } async getAgent(params) { const developerObject = await fetchSuiDynamicField({ objectID: this.registry, fieldName: "developers", type: "0x1::string::String", key: params.developer }); const id = developerObject?.agents?.fields?.id?.id; if (!id) { return void 0; } const agentObject = await fetchSuiDynamicField({ parentID: id, fieldName: "agents", type: "0x1::string::String", key: params.agent }); if (!agentObject) { return void 0; } const methods = {}; const methodsData = agentObject?.methods?.fields?.contents; if (methodsData && Array.isArray(methodsData)) { for (const entry of methodsData) { const key = entry?.fields?.key; const value = entry?.fields?.value; if (key && value) { methods[key] = { dockerImage: value.docker_image, dockerSha256: value.docker_sha256 ?? void 0, minMemoryGb: Number(value.min_memory_gb), minCpuCores: Number(value.min_cpu_cores), requiresTee: Boolean(value.requires_tee) }; } } } let defaultMethod; const defaultMethodData = agentObject?.default_method; if (defaultMethodData && typeof defaultMethodData === "object" && !Array.isArray(defaultMethodData)) { defaultMethod = { dockerImage: defaultMethodData.docker_image, dockerSha256: defaultMethodData.docker_sha256 ?? void 0, minMemoryGb: Number(defaultMethodData.min_memory_gb), minCpuCores: Number(defaultMethodData.min_cpu_cores), requiresTee: Boolean(defaultMethodData.requires_tee) }; } const agent = { id: agentObject?.id?.id, name: agentObject.name, image: agentObject?.image ?? void 0, description: agentObject?.description ?? void 0, site: agentObject?.site ?? void 0, chains: agentObject?.chains ?? [], methods, defaultMethod, createdAt: Number(agentObject.created_at), updatedAt: Number(agentObject.updated_at), version: Number(agentObject.version) }; if (!agent.id || !agent.name) { return void 0; } return agent; } async getApp(params) { const appObject = await fetchSuiDynamicField({ objectID: this.registry, fieldName: "apps", type: "0x1::string::String", key: params.name }); if (!appObject) { return void 0; } const methods = {}; const methodsData = appObject?.methods?.fields?.contents; if (methodsData && Array.isArray(methodsData)) { for (const entry of methodsData) { const key = entry?.fields?.key; const value = entry?.fields?.value?.fields; if (key && value) { methods[key] = { description: value.description ?? void 0, developer: value.developer, agent: value.agent, agentMethod: value.agent_method }; } } } const instances = []; const instancesData = appObject?.instances?.fields?.contents; if (instancesData && Array.isArray(instancesData)) { for (const instance of instancesData) { if (instance?.fields?.key) { instances.push(instance.fields.key); } } } const app = { id: appObject?.id?.id, name: appObject.name, description: appObject?.description ?? void 0, methods, owner: appObject.owner, createdAt: Number(appObject.created_at), updatedAt: Number(appObject.updated_at), version: Number(appObject.version), instances }; if (!app.id || !app.name || !app.owner) { return void 0; } return app; } createApp(params) { const { name, owner, description, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::add_app`, arguments: [ tx.object(this.registry), tx.pure.string(name), tx.pure.address(owner), tx.pure.option("string", description ?? null), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } removeApp(params) { const { name, transaction } = params; const tx = transaction ?? new import_transactions6.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::registry::remove_app`, arguments: [ tx.object(this.registry), tx.pure.string(name), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } static async getDockerImageDetails(params) { try { const { dockerImage } = params; const colonPos = dockerImage.lastIndexOf(":"); const repository = colonPos !== -1 ? dockerImage.slice(0, colonPos) : dockerImage; const tag = colonPos !== -1 ? dockerImage.slice(colonPos + 1) : "latest"; const tokenResponse = await fetch("https://auth.docker.io/token?" + new URLSearchParams({ service: "registry.docker.io", scope: `repository:${repository}:pull` })); if (!tokenResponse.ok) { return void 0; } const tokenData = await tokenResponse.json(); const token = tokenData.token; if (!token) { return void 0; } const manifestResponse = await fetch(`https://registry-1.docker.io/v2/${repository}/manifests/${tag}`, { headers: { Authorization: `Bearer ${token}`, Accept: "application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.v2+json" } }); if (!manifestResponse.ok) { return void 0; } const contentType = manifestResponse.headers.get("content-type") || ""; let digest = manifestResponse.headers.get("docker-content-digest") || ""; let manifest; if (contentType.includes("index") || contentType.includes("list")) { const idx = await manifestResponse.json(); const platformManifest = idx.manifests?.find((m) => m.platform?.architecture === "amd64" && m.platform?.os === "linux"); if (!platformManifest) { return void 0; } const platformDigest = platformManifest.digest; const actualManifestResponse = await fetch(`https://registry-1.docker.io/v2/${repository}/manifests/${platformDigest}`, { headers: { Authorization: `Bearer ${token}`, Accept: "application/vnd.docker.distribution.manifest.v2+json" } }); if (!actualManifestResponse.ok) { return void 0; } manifest = await actualManifestResponse.json(); const actualDigest = actualManifestResponse.headers.get("docker-content-digest"); if (actualDigest) { digest = actualDigest; } } else { manifest = await manifestResponse.json(); } if (!manifest?.layers || !Array.isArray(manifest.layers)) { return void 0; } const numberOfLayers = manifest.layers.length; const sha2562 = digest.startsWith("sha256:") ? digest.slice(7) : digest; if (!sha2562) { return void 0; } return { sha256: sha2562, numberOfLayers }; } catch (error) { console.error("Error fetching Docker image details:", error); return void 0; } } }; // dist/node/build.js async function buildMovePackage(path) { const { execSync } = await import("child_process"); let bytes = void 0; console.log("Running sui client publish command..."); try { const output = execSync(`sui move build --dump-bytecode-as-base64 --ignore-chain --path ${path}`, { encoding: "utf-8" }); bytes = JSON.parse(output); if (!bytes) { throw new Error("Error building package"); } return bytes; } catch (error) { console.error("Error running command:", error); throw error; } } // dist/node/walrus.js var walrusDaemon = process.env.NEXT_PUBLIC_WALRUS_DAEMON || process.env.WALRUS_DAEMON || "testnet"; var daemon = walrusDaemon === "local" ? "local" : "testnet"; var basePublisherUrl = daemon === "local" ? "http://127.0.0.1:31415" : "https://wal-publisher-testnet.staketab.org"; var readerUrl = daemon === "local" ? "http://127.0.0.1:31415/v1/blobs/" : "https://wal-aggregator-testnet.staketab.org/v1/blobs/"; var MIN_EPOCHS = 14; var MAX_EPOCHS = 53; async function saveToWalrus({ data, address, numEpochs = MIN_EPOCHS }) { let sendToParam = address ? `&send_object_to=${address}` : ""; let epochs = numEpochs < MIN_EPOCHS ? MIN_EPOCHS : numEpochs > MAX_EPOCHS ? MAX_EPOCHS : numEpochs; console.log("Writing to Walrus"); console.time("written"); const response = await fetch(`${basePublisherUrl}/v1/blobs?epochs=${epochs}${sendToParam}`, { method: "PUT", body: data }); console.timeEnd("written"); if (response.status === 200) { const info = await response.json(); const blobId = info?.newlyCreated?.blobObject?.blobId ?? info?.alreadyCertified?.blobId; console.log("Walrus blobId", blobId); return blobId; } else { console.error("saveToDA failed:", { statusText: response.statusText, status: response.status }); return void 0; } } async function readFromWalrus({ blobId }) { if (!blobId) { throw new Error("blobId is not provided"); } console.log("Reading walrus blob", blobId); console.time("read"); const response = await fetch(`${readerUrl}${blobId}`); console.timeEnd("read"); if (!response.ok) { console.error("readFromDA failed:", { statusText: response.statusText, status: response.status }); return void 0; } else { const blob = await response.text(); return blob; } } async function getWalrusUrl(params) { const { blobId } = params; if (!blobId) { throw new Error("blobId is not set"); } const url = `${readerUrl}${blobId}`; return url; } // dist/node/faucet.js var import_ed25519 = require("@mysten/sui/keypairs/ed25519"); async function silvanaFaucet(params) { const { address, amount = 1 } = params; const response = await fetch(`${silvanaFaucetEndpoint()}/fund`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ address, amount }) }); if (!response.ok) { throw new Error(`Failed to fund address: ${address} ${amount} ${response.status} ${response.statusText}`); } return response.json(); } async function silvanaFaucetGetKey(params = { autoReturn: false }) { const response = await fetch(`${silvanaFaucetEndpoint()}/get_key`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ auto_return: params.autoReturn }) }); if (!response.ok) { throw new Error(`Failed to get key: ${response.status} ${response.statusText}`); } return response.json(); } async function silvanaFaucetPingKey(params) { const { address } = params; if (!address) { return { message: "Address is required", success: false }; } const response = await fetch(`${silvanaFaucetEndpoint()}/ping_key`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ address }) }); if (!response.ok) { throw new Error(`Failed to return key: ${response.status} ${response.statusText}`); } return response.json(); } async function silvanaFaucetReturnKey(params) { const address = params.address ?? (params.secretKey ? import_ed25519.Ed25519Keypair.fromSecretKey(params.secretKey).toSuiAddress() : void 0); if (!address) { return { message: "Address or secret key is required", success: false }; } const response = await fetch(`${silvanaFaucetEndpoint()}/return_key`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ address }) }); if (!response.ok) { throw new Error(`Failed to return key: ${response.status} ${response.statusText}`); } return response.json(); } function silvanaFaucetEndpoint() { const silvanaFaucetEndpoint2 = process.env.SILVANA_FAUCET_ENDPOINT; if (!silvanaFaucetEndpoint2) { throw new Error("SILVANA_FAUCET_ENDPOINT is not set"); } return silvanaFaucetEndpoint2; } // dist/node/ipfs.js var import_pinata = require("pinata"); var pinataJwt = process.env.PINATA_JWT; var pinataGateway = process.env.PINATA_GATEWAY_URL; var pinataGatewayKey = process.env.PINATA_GATEWAY_API_KEY; var pinata = new import_pinata.PinataSDK({ pinataJwt, pinataGateway, pinataGatewayKey }); async function saveToIPFS(params) { try { if (!pinataJwt || !pinataGateway || !pinataGatewayKey) { throw new Error("PINATA_JWT, PINATA_GATEWAY_URL, or PINATA_GATEWAY_API_KEY is not set"); } const { data, filename, owner, days, description } = params; if (data === void 0 || data === null) throw new Error("data is not set"); if (typeof data !== "string") throw new Error("data is not a string"); if (data.length === 0) throw new Error("data is empty"); const file = new File([data], filename ?? "da", { type: "text/plain" }); const expiry = days ? Date.now() + days * 24 * 60 * 60 * 1e3 : void 0; const keyvalues = { app: "dex:devnet", owner: owner ?? "", expires: expiry ? new Date(expiry).toISOString() : "never", expiry: expiry ? expiry.toString() : "0", description: description ?? "", type: "text/plain", mime_type: "text/plain" }; const upload = await pinata.upload.public.file(file, { metadata: { name: filename ?? "da", keyvalues } }).name(filename ?? "da"); console.log("IPFS: ", upload.cid); return upload.cid; } catch (error) { console.error("Save to IPFS failed", error.message); return void 0; } } async function readFromIPFS(params) { const { blobId } = params; if (!blobId) { throw new Error("blobId is not set"); } try { if (!pinataJwt || !pinataGateway || !pinataGatewayKey) { throw new Error("PINATA_JWT, PINATA_GATEWAY_URL, or PINATA_GATEWAY_API_KEY is not set"); } const url = await getIPFSUrl({ blobId }); const response = await fetch(url); if (!response.ok) { throw new Error("Failed to fetch from IPFS"); } const data = await response.text(); return data; } catch (error) { console.error("Read from IPFS failed", error); return void 0; } } async function getIPFSUrl(params) { const { blobId } = params; if (!blobId) { throw new Error("blobId is not set"); } const gateway = process.env.PINATA_GATEWAY_URL ?? "https://gateway.pinata.cloud/ipfs/"; const apiToken = process.env.PINATA_GATEWAY_API_KEY; const url = "https://" + gateway + "/ipfs/" + blobId + (apiToken ? "?pinataGatewayToken=" + apiToken : ""); return url; } // dist/node/public-key.js var import_mina_signer = __toESM(require("mina-signer"), 1); var client = new import_mina_signer.default({ network: "testnet" }); function publicKeyToU256(publicKey) { const raw = client.publicKeyToRaw(publicKey); const swappedRaw = raw.match(/.{1,2}/g)?.reverse().join("") || ""; const u256 = BigInt("0x" + swappedRaw); return u256; } var MAX_BIT = 2n ** 255n; function u256ToFields(u256) { const isOdd = (u256 & MAX_BIT) != 0n; const x = u256 - (isOdd ? MAX_BIT : 0n); return { x, isOdd }; } function u256ToPublicKey(u256) { const { x, isOdd } = u256ToFields(u256); return convertFieldsToPublicKey({ x, isOdd }); } function convertMinaPublicKey(publicKey) { const u256 = publicKeyToU256(publicKey); return u256ToFields(u256); } function convertMinaPublicKeyToFields(publicKey) { if (!publicKey) return []; const { x, isOdd } = convertMinaPublicKey(publicKey); return [x, isOdd ? 1n : 0n]; } function signFields(params) { const { privateKey, fields } = params; const signedData = client.signFields(fields.map(BigInt), privateKey); return signedData; } function verifyFields(params) { const { publicKey, fields, signature } = params; return client.verifyFields({ data: fields, publicKey, signature }); } // dist/node/job.js var import_transactions7 = require("@mysten/sui/transactions"); var import_utils2 = require("@mysten/sui/utils"); var JobManager = class { constructor(params) { this.jobs = params.jobs; } static createJobs(maxAttempts) { const tx = new import_transactions7.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::jobs::create_jobs`, arguments: [ tx.pure.option("u8", maxAttempts ?? null) ] }); return tx; } createJob(params) { const { description, developer, agent, agentMethod, app, appInstance, appInstanceMethod, sequences, data } = params; const tx = new import_transactions7.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::jobs::create_job`, arguments: [ tx.object(this.jobs), tx.pure.option("string", description ?? null), tx.pure.string(developer), tx.pure.string(agent), tx.pure.string(agentMethod), tx.pure.string(app), tx.pure.string(appInstance), tx.pure.string(appInstanceMethod), tx.pure.option("vector<u64>", sequences ?? null), tx.pure.vector("u8", Array.from(data)), tx.object(import_utils2.SUI_CLOCK_OBJECT_ID) ] }); return tx; } startJob(jobId) { const tx = new import_transactions7.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::jobs::start_job`, arguments: [ tx.object(this.jobs), tx.pure.u64(jobId), tx.object(import_utils2.SUI_CLOCK_OBJECT_ID) ] }); return tx; } completeJob(jobId) { const tx = new import_transactions7.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::jobs::complete_job`, arguments: [ tx.object(this.jobs), tx.pure.u64(jobId) ] }); return tx; } failJob(params) { const { jobId, error } = params; const tx = new import_transactions7.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::jobs::fail_job`, arguments: [ tx.object(this.jobs), tx.pure.u64(jobId), tx.pure.string(error), tx.object(import_utils2.SUI_CLOCK_OBJECT_ID) ] }); return tx; } updateMaxAttempts(maxAttempts) { const tx = new import_transactions7.Transaction(); tx.moveCall({ target: `${silvanaRegistryPackage}::jobs::update_max_attempts`, arguments: [ tx.object(this.jobs), tx.pure.u64(maxAttempts) ] }); return tx; } async getJob(jobId) { try { const jobsObject = await fetchSuiObject(this.jobs); if (!jobsObject) return void 0; const jobsTableId = jobsObject?.jobs?.fields?.id?.id;