@silvana-one/coordination
Version:
Silvana Coordination Client
928 lines (909 loc) • 29.1 kB
JavaScript
;
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
});