UNPKG

@silvana-one/coordination

Version:

Silvana Coordination Client

928 lines (909 loc) 29.1 kB
"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, { AgentRegistry: () => AgentRegistry, buildPublishTx: () => buildPublishTx, buildUpgradeTx: () => buildUpgradeTx, convertFieldsToPublicKey: () => convertFieldsToPublicKey, convertMinaSignatureFromBase58: () => convertMinaSignatureFromBase58, convertMinaSignatureToBase58: () => convertMinaSignatureToBase58, executeTx: () => executeTx, fetchSuiDynamicField: () => fetchSuiDynamicField, fetchSuiDynamicFieldsList: () => fetchSuiDynamicFieldsList, fetchSuiObject: () => fetchSuiObject, network: () => network, publishCodeToMVR: () => publishCodeToMVR, publishToMVR: () => publishToMVR, sleep: () => sleep, suiClient: () => suiClient, waitTx: () => waitTx }); 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 "https://rpc-testnet.suiscan.xyz:443"; } else if (network2 === "devnet") { return "https://rpc-ws-devnet.suiscan.xyz"; } else if (network2 === "mainnet") { return "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") { if (showErrors) { console.log(`Errors for tx ${executedTx.digest}:`, executedTx?.effects?.status?.error); throw new Error(`tx execution failed: ${executedTx.digest}`); } } 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); console.time("sign"); console.timeEnd("sign"); 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/agent.js var AgentRegistry = class { constructor(params) { this.registry = params.registry; } static createAgentRegistry(params) { console.log("Creating agent registry", params.name); const transaction = new import_transactions6.Transaction(); transaction.moveCall({ target: `@silvana/agent::registry::create_registry`, arguments: [transaction.pure.string(params.name)] }); return transaction; } createDeveloper(params) { const { name, github, image, description, site } = params; const tx = new import_transactions6.Transaction(); tx.moveCall({ target: `@silvana/agent::registry::add_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; } updateDeveloper(params) { const { name, github, image, description, site } = params; const tx = new import_transactions6.Transaction(); tx.moveCall({ target: `@silvana/agent::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 } = params; const tx = new import_transactions6.Transaction(); tx.moveCall({ target: `@silvana/agent::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, docker_image, docker_sha256, min_memory_gb, min_cpu_cores, supports_tee, chains } = params; const tx = new import_transactions6.Transaction(); tx.moveCall({ target: `@silvana/agent::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.string(docker_image), tx.pure.option("string", docker_sha256 ?? null), tx.pure.u16(min_memory_gb), tx.pure.u16(min_cpu_cores), tx.pure.bool(supports_tee), tx.pure.vector("string", chains), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } updateAgent(params) { const { developer, name, image, description, site, docker_image, docker_sha256, min_memory_gb, min_cpu_cores, supports_tee, chains } = params; const tx = new import_transactions6.Transaction(); tx.moveCall({ target: `@silvana/agent::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.string(docker_image), tx.pure.option("string", docker_sha256 ?? null), tx.pure.u16(min_memory_gb), tx.pure.u16(min_cpu_cores), tx.pure.bool(supports_tee), tx.pure.vector("string", chains), tx.object(import_utils.SUI_CLOCK_OBJECT_ID) ] }); return tx; } removeAgent(params) { const { developer, agent } = params; const tx = new import_transactions6.Transaction(); tx.moveCall({ target: `@silvana/agent::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; } 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 agent = { id: agentObject?.id?.id, name: agentObject.name, image: agentObject?.image ?? void 0, description: agentObject?.description ?? void 0, site: agentObject?.site ?? void 0, dockerImage: agentObject.docker_image, dockerSha256: agentObject?.docker_sha256 ?? void 0, minMemoryGb: Number(agentObject.min_memory_gb), minCpuCores: Number(agentObject.min_cpu_cores), supportsTEE: Boolean(agentObject.supports_tee), createdAt: Number(agentObject.created_at), updatedAt: Number(agentObject.updated_at), version: Number(agentObject.version) }; if (!agent.id || !agent.name || !agent.dockerImage || !agent.minMemoryGb || !agent.minCpuCores || !agent.createdAt || !agent.updatedAt) { return void 0; } return agent; } 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; } } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { AgentRegistry, buildPublishTx, buildUpgradeTx, convertFieldsToPublicKey, convertMinaSignatureFromBase58, convertMinaSignatureToBase58, executeTx, fetchSuiDynamicField, fetchSuiDynamicFieldsList, fetchSuiObject, network, publishCodeToMVR, publishToMVR, sleep, suiClient, waitTx });