@suiware/ai-tools
Version:
Pluggable tools for Vercel AI SDK which allow AI assistants to interact with Sui Network and perform various actions.
1 lines • 12.3 kB
Source Map (JSON)
{"version":3,"sources":["../src/core/utils/environment.ts","../src/services/SuiService.ts"],"names":[],"mappings":"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","file":"chunk-UXHRSDY6.mjs","sourcesContent":["import EnvFileRW from 'env-file-rw'\nimport * as path from 'path'\n\nconst envPath = path.resolve(process.cwd(), '.env')\nconst env = new EnvFileRW(envPath)\n\nexport function getSetting(name: string): string | undefined {\n return process.env?.[name] || env.get(name)\n}\n\nexport function saveSettings(settings: Record<string, string>): void {\n for (const [key, value] of Object.entries(settings)) {\n env.set(key, value)\n process.env[key] = value\n }\n env.save()\n}\n","import {\n CoinMetadata,\n getFullnodeUrl,\n SuiClient,\n SuiTransactionBlockResponse,\n} from '@mysten/sui/client'\nimport { Signer } from '@mysten/sui/cryptography'\nimport { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519'\nimport { Secp256k1Keypair } from '@mysten/sui/keypairs/secp256k1'\nimport { Secp256r1Keypair } from '@mysten/sui/keypairs/secp256r1'\nimport { Transaction } from '@mysten/sui/transactions'\nimport { isValidSuiAddress } from '@mysten/sui/utils'\nimport { getSetting, saveSettings } from '../core/utils/environment'\nimport { TSuiNetwork } from '../types/TSuiNetwork'\n\nexport class SuiService {\n private static instance: SuiService\n\n private network: TSuiNetwork | undefined\n private privateKey: string | undefined\n private signer: Signer\n private client: SuiClient\n private coinInfoMap: Map<string, CoinMetadata> = new Map<\n string,\n CoinMetadata\n >()\n\n private constructor() {\n this.readAndValidateConfig()\n\n const network = this.getNetwork()\n const privateKey = this.getPrivateKey()\n\n this.signer = this.getSignerFromPrivateKey(privateKey!)\n\n this.client = new SuiClient({\n url: getFullnodeUrl(network!),\n })\n }\n\n // Singleton.\n public static getInstance(): SuiService {\n if (!SuiService.instance) {\n SuiService.instance = new SuiService()\n }\n return SuiService.instance\n }\n\n public getNetwork(): TSuiNetwork | undefined {\n return this.network\n }\n\n public getPrivateKey(): string | undefined {\n return this.privateKey\n }\n\n public getSuiClient(): SuiClient {\n return this.client\n }\n\n /**\n * Execute a transaction.\n *\n * @param transaction - The transaction block to execute.\n * @returns The transaction response.\n */\n public async executeTransaction(\n transaction: Transaction\n ): Promise<SuiTransactionBlockResponse> {\n const instance = SuiService.getInstance()\n if (!instance.signer) {\n throw new Error('Signer not found')\n }\n\n return instance.client.signAndExecuteTransaction({\n transaction,\n signer: instance.signer,\n })\n }\n\n /**\n * Get the address of the wallet.\n *\n * @returns The address of the wallet.\n */\n public getAddress(): string {\n return this.signer.toSuiAddress()\n }\n\n /**\n * Gets the balance of the wallet.\n *\n * @returns The balance of the wallet in MIST (smallest Sui unit).\n */\n public async getBalance(): Promise<bigint> {\n const address = this.getAddress()\n if (!address) {\n throw new Error('Address not found')\n }\n\n const balance = await this.client.getBalance({\n owner: address,\n })\n\n return BigInt(balance.totalBalance)\n }\n\n /**\n * Waits for a transaction receipt.\n *\n * @param digest - The digest of the transaction to wait for.\n * @returns The transaction receipt.\n */\n public async waitForTransactionReceipt(\n digest: string\n ): Promise<SuiTransactionBlockResponse> {\n return this.client.waitForTransaction({\n digest,\n options: {\n // showEvents: true,\n // showEffects: true,\n },\n })\n }\n\n /**\n * Transfer the given amount of SUI to the given address.\n *\n * @param to - The destination address.\n * @param value - The amount to transfer in whole SUI units\n * @returns The transaction digest.\n */\n public async nativeTransfer(\n to: `0x${string}`,\n value: string | number\n ): Promise<`0x${string}`> {\n // Convert whole SUI units to MIST (1 SUI = 1e9 MIST)\n const amountInMist =\n (typeof value === 'string' ? parseFloat(value) : value) * 1e9\n\n const tx = new Transaction()\n\n // first, split the gas coin into multiple coins\n const [coin] = tx.splitCoins(tx.gas, [amountInMist])\n\n tx.transferObjects([coin], to)\n\n const response = await this.executeTransaction(tx)\n\n if (!response.digest) {\n throw new Error('Transaction failed')\n }\n\n return response.digest as `0x${string}`\n }\n\n public createAccount(network: TSuiNetwork): {\n address: string\n privateKey: string\n network: TSuiNetwork\n } {\n // Generate new keypair.\n const keypair = Ed25519Keypair.generate()\n const address = keypair.toSuiAddress()\n const privateKey = `suiprivkey${Buffer.from(keypair.getSecretKey()).toString('hex')}`\n\n // Save network and private key.\n this.network = network\n this.privateKey = privateKey\n this.signer = this.getSignerFromPrivateKey(privateKey)\n this.saveConfig()\n\n return {\n address,\n privateKey,\n network,\n }\n }\n\n public static isValidPrivateKey(privateKey: string | undefined) {\n return privateKey != null && privateKey.startsWith('suiprivkey')\n }\n\n public static isValidSuiAddress(address: string) {\n return isValidSuiAddress(address)\n }\n\n public static isNotMyOwnAddress(address: string) {\n return this.getInstance().getAddress() !== address\n }\n\n public async getCoinMetadata(coinType: string): Promise<CoinMetadata | null> {\n if (this.coinInfoMap.has(coinType)) {\n return this.coinInfoMap.get(coinType) || null\n }\n\n const metadata = await this.client.getCoinMetadata({ coinType: coinType })\n if (!metadata) {\n return null\n }\n\n this.coinInfoMap.set(coinType, metadata)\n\n return metadata\n }\n\n private getSignerFromPrivateKey(privateKey: string): Signer {\n const keypairClasses = [Ed25519Keypair, Secp256k1Keypair, Secp256r1Keypair]\n for (const KeypairClass of keypairClasses) {\n try {\n return KeypairClass.fromSecretKey(privateKey)\n } catch {}\n }\n throw new Error('Failed to initialize keypair from secret key')\n }\n\n private readAndValidateConfig(): void {\n const network = getSetting('SUI_NETWORK') as TSuiNetwork\n const privateKey = getSetting('SUI_PRIVATE_KEY')\n\n // @todo: Validate with a Zod schema.\n\n if (network == null || network.trim() === '') {\n throw new Error('Network is not set')\n }\n\n if (!SuiService.isValidPrivateKey(privateKey)) {\n throw new Error('Private key is not valid')\n }\n\n this.network = network\n this.privateKey = privateKey\n }\n\n private saveConfig(): void {\n if (!this.network) {\n throw new Error('Network is not set')\n }\n if (!this.privateKey) {\n throw new Error('Private key is not set')\n }\n saveSettings({\n SUI_NETWORK: this.network,\n SUI_PRIVATE_KEY: this.privateKey,\n })\n }\n}\n"]}