@suiware/ai-tools
Version:
Pluggable tools for Vercel AI SDK which allow AI assistants to interact with Sui Network and perform various actions.
279 lines (276 loc) • 8.06 kB
JavaScript
import { SUI_DECIMALS, isValidSuiAddress } from '@mysten/sui/utils';
import BigNumber from 'bignumber.js';
import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { Secp256k1Keypair } from '@mysten/sui/keypairs/secp256k1';
import { Secp256r1Keypair } from '@mysten/sui/keypairs/secp256r1';
import { Transaction } from '@mysten/sui/transactions';
import EnvFileRW from 'env-file-rw';
import * as path from 'path';
var __pow = Math.pow;
var __async = (__this, __arguments, generator) => {
return new Promise((resolve2, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve2(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
function formatBalance(balance, decimals) {
return BigNumber(balance.toString()).shiftedBy(-decimals).toFixed(8);
}
function suiToMist(amount) {
return (typeof amount === "string" ? parseFloat(amount) : amount) * __pow(10, SUI_DECIMALS);
}
function disableConsoleLog() {
const originalConsoleLog = console.log;
console.log = () => {
};
return originalConsoleLog;
}
function enableConsoleLog(originalConsoleLog) {
console.log = originalConsoleLog;
}
var Environment = class _Environment {
// Singleton.
static getInstance() {
if (!_Environment.instance) {
_Environment.instance = new _Environment();
}
return _Environment.instance;
}
getSetting(name) {
var _a;
return (_a = this.env) == null ? void 0 : _a.get(name);
}
setSetting(name, value) {
var _a;
(_a = this.env) == null ? void 0 : _a.set(name, value);
}
saveSettings() {
var _a;
(_a = this.env) == null ? void 0 : _a.save();
}
constructor() {
var _a;
const providedEnvConfigFilePath = (_a = process.env) == null ? void 0 : _a.SUIWARE_MCP_ENV_CONFIG_FILE_PATH;
let envPath = ".env";
if (providedEnvConfigFilePath) {
envPath = providedEnvConfigFilePath;
}
if (!path.isAbsolute(envPath)) {
envPath = path.resolve(process.cwd(), envPath);
}
try {
this.env = new EnvFileRW(envPath, true);
} catch (e) {
}
}
};
function getSetting(name) {
var _a;
const env = Environment.getInstance();
return ((_a = process.env) == null ? void 0 : _a[name]) || env.getSetting(name);
}
function saveSettings(settings) {
const env = Environment.getInstance();
for (const [key, value] of Object.entries(settings)) {
env.setSetting(key, value);
process.env[key] = value;
}
env.saveSettings();
}
// src/services/SuiService.ts
var SuiService = class _SuiService {
constructor() {
this.coinInfoMap = /* @__PURE__ */ new Map();
this.init();
const network = this.getNetwork();
const privateKey = this.getPrivateKey();
this.signer = this.extractSignerFromPrivateKey(privateKey);
this.client = new SuiClient({
url: getFullnodeUrl(network)
});
}
// Singleton.
static getInstance() {
if (!_SuiService.instance) {
_SuiService.instance = new _SuiService();
}
return _SuiService.instance;
}
getNetwork() {
return this.network;
}
getPrivateKey() {
return this.privateKey;
}
getSuiClient() {
return this.client;
}
/**
* Execute a transaction.
*
* @param transaction - The transaction block to execute.
* @returns The transaction response.
*/
executeTransaction(transaction) {
return __async(this, null, function* () {
const instance = _SuiService.getInstance();
if (!instance.signer) {
throw new Error("Signer not found");
}
return instance.client.signAndExecuteTransaction({
transaction,
signer: instance.signer
});
});
}
/**
* Get the address of the wallet.
*
* @returns The address of the wallet.
*/
getAddress() {
return this.signer.toSuiAddress();
}
/**
* Gets the balance of the wallet.
*
* @returns The balance of the wallet in MIST (smallest Sui unit).
*/
getBalance() {
return __async(this, null, function* () {
const address = this.getAddress();
if (!address) {
throw new Error("Address not found");
}
const balance = yield this.client.getBalance({
owner: address
});
return BigInt(balance.totalBalance);
});
}
/**
* Waits for a transaction receipt.
*
* @param digest - The digest of the transaction to wait for.
* @returns The transaction receipt.
*/
waitForTransactionReceipt(digest) {
return __async(this, null, function* () {
return this.client.waitForTransaction({
digest,
options: {
// showEvents: true,
// showEffects: true,
}
});
});
}
/**
* Transfer the given amount of SUI to the given address.
*
* @param to - The destination address.
* @param value - The amount to transfer in whole SUI units
* @returns The transaction digest.
*/
nativeTransfer(to, value) {
return __async(this, null, function* () {
const amountInMist = suiToMist(value);
const tx = new Transaction();
const [coin] = tx.splitCoins(tx.gas, [amountInMist]);
tx.transferObjects([coin], to);
const response = yield this.executeTransaction(tx);
if (!response.digest) {
throw new Error("Transaction failed");
}
return response.digest;
});
}
createAccount(network) {
const keypair = Ed25519Keypair.generate();
const address = keypair.toSuiAddress();
const privateKey = `suiprivkey${Buffer.from(keypair.getSecretKey()).toString("hex")}`;
this.network = network;
this.privateKey = privateKey;
this.signer = this.extractSignerFromPrivateKey(privateKey);
this.saveConfig();
return {
address,
privateKey,
network
};
}
static isValidPrivateKey(privateKey) {
return privateKey != null && privateKey.startsWith("suiprivkey");
}
static isValidSuiAddress(address) {
return isValidSuiAddress(address);
}
static isNotMyOwnAddress(address) {
return this.getInstance().getAddress() !== address;
}
getCoinMetadata(coinType) {
return __async(this, null, function* () {
if (this.coinInfoMap.has(coinType)) {
return this.coinInfoMap.get(coinType) || null;
}
const metadata = yield this.client.getCoinMetadata({ coinType });
if (!metadata) {
return null;
}
this.coinInfoMap.set(coinType, metadata);
return metadata;
});
}
extractSignerFromPrivateKey(privateKey) {
const keypairClasses = [Ed25519Keypair, Secp256k1Keypair, Secp256r1Keypair];
for (const KeypairClass of keypairClasses) {
try {
return KeypairClass.fromSecretKey(privateKey);
} catch (e) {
}
}
throw new Error("Failed to initialize keypair from secret key");
}
init() {
const network = getSetting("SUI_NETWORK");
const privateKey = getSetting("SUI_PRIVATE_KEY");
if (network == null || network.trim() === "") {
throw new Error("Network is not set");
}
if (privateKey == null || !_SuiService.isValidPrivateKey(privateKey)) {
throw new Error("Private key is not valid");
}
this.network = network;
this.privateKey = privateKey;
}
saveConfig() {
if (!this.network) {
throw new Error("Network is not set");
}
if (!this.privateKey) {
throw new Error("Private key is not set");
}
saveSettings({
SUI_NETWORK: this.network,
SUI_PRIVATE_KEY: this.privateKey
});
}
};
export { SuiService, __async, __pow, disableConsoleLog, enableConsoleLog, formatBalance, getSetting, suiToMist };
//# sourceMappingURL=chunk-HFORSGSH.mjs.map
//# sourceMappingURL=chunk-HFORSGSH.mjs.map