@silvana-one/coordination
Version:
Silvana Coordination Client
1,557 lines (1,531 loc) • 73.5 kB
JavaScript
"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;