UNPKG

@nosana/kit

Version:

Nosana KIT

162 lines (161 loc) 7.64 kB
import { Buffer } from 'buffer'; if (typeof window !== 'undefined' && typeof window.Buffer === 'undefined') { window.Buffer = Buffer; } import { getNosanaConfig, NosanaNetwork } from './config/index.js'; import { Logger } from './logger/Logger.js'; import { JobsProgram } from './programs/JobsProgram.js'; import { SolanaUtils } from './solana/SolanaUtils.js'; import { IPFS } from './ipfs/IPFS.js'; import { createKeyPairSignerFromBytes } from 'gill'; import { NosanaError, ErrorCodes } from './errors/NosanaError.js'; import bs58 from 'bs58'; export class NosanaClient { constructor(network = NosanaNetwork.MAINNET, customConfig) { this.config = getNosanaConfig(network, customConfig); if (this.config.wallet) { this.setWallet(this.config.wallet); } this.jobs = new JobsProgram(this); this.logger = Logger.getInstance(); this.solana = new SolanaUtils(this); this.ipfs = new IPFS(this.config.ipfs); } async setWallet(wallet) { try { // Check if we already have a KeyPairSigner type if (wallet && typeof wallet === 'object' && 'address' in wallet && 'signMessages' in wallet) { this.wallet = wallet; return this.wallet; } // Check if it's a browser wallet adapter (has publicKey and signTransaction/signMessage) if (wallet && typeof wallet === 'object' && 'publicKey' in wallet && ('signTransaction' in wallet || 'signMessage' in wallet)) { // Convert browser wallet adapter to KeyPairSigner-like interface const browserWallet = wallet; this.wallet = { address: browserWallet.publicKey.toString(), signMessages: async (messages) => { if (browserWallet.signMessage) { return Promise.all(messages.map(msg => browserWallet.signMessage(msg))); } throw new Error('Browser wallet does not support message signing'); }, signTransactions: async (transactions) => { if (browserWallet.signTransaction) { return Promise.all(transactions.map(tx => browserWallet.signTransaction(tx))); } throw new Error('Browser wallet does not support transaction signing'); } }; return this.wallet; } // If it's a string, try multiple conversion methods if (typeof wallet === 'string') { // Only try file/environment loading in Node.js environment if (typeof window === 'undefined') { try { // Use string concatenation to avoid bundler resolving this import at build time const nodeModule = 'gill' + '/node'; const { loadKeypairSignerFromFile, loadKeypairSignerFromEnvironment, loadKeypairSignerFromEnvironmentBase58 } = await import(nodeModule); // Try to load from file path if (await this.isValidFilePath(wallet)) { try { this.wallet = await loadKeypairSignerFromFile(wallet); return this.wallet; } catch (error) { this.logger.debug(`Failed to load keypair from file: ${error}`); } } // Try to load from environment variable try { this.wallet = await loadKeypairSignerFromEnvironment(wallet); return this.wallet; } catch (error) { this.logger.debug(`Failed to load keypair from environment: ${error}`); } // Try to load from environment variable as base58 try { this.wallet = await loadKeypairSignerFromEnvironmentBase58(wallet); return this.wallet; } catch (error) { this.logger.debug(`Failed to load keypair from environment base58: ${error}`); } } catch (error) { this.logger.debug(`Node.js modules not available: ${error}`); } } // Try to parse as JSON array if (wallet.startsWith('[')) { try { const key = JSON.parse(wallet); this.wallet = await createKeyPairSignerFromBytes(new Uint8Array(key)); return this.wallet; } catch (error) { this.logger.debug(`Failed to parse as JSON array: ${error}`); } } // Try to decode as base58 try { const key = Buffer.from(bs58.decode(wallet)).toJSON().data; this.wallet = await createKeyPairSignerFromBytes(new Uint8Array(key)); return this.wallet; } catch (error) { this.logger.debug(`Failed to decode as base58: ${error}`); } } // If it's an array, try to create from bytes if (Array.isArray(wallet)) { try { this.wallet = await createKeyPairSignerFromBytes(new Uint8Array(wallet)); return this.wallet; } catch (error) { this.logger.debug(`Failed to create from byte array: ${error}`); } } // If we get here, none of the conversion methods worked throw new Error('Unable to convert wallet to KeyPairSigner using any available method'); } catch (error) { throw new NosanaError(`Failed to convert wallet to KeyPairSigner: ${error instanceof Error ? error.message : 'Unknown error'}`, ErrorCodes.WALLET_CONVERSION_ERROR, error); } } async isValidFilePath(filePath) { // Only validate file paths in Node.js environment if (typeof window !== 'undefined') { return false; // Browser environment, no file system access } try { const [fs, path] = await Promise.all([ import('fs'), import('path') ]); if (!path.isAbsolute(filePath) && !filePath.startsWith('./') && !filePath.startsWith('../')) { return false; } const stats = await fs.promises.stat(filePath); return stats.isFile(); } catch { return false; } } } // Export types and configuration export * from './config/index.js'; export * from './errors/NosanaError.js'; export * from './logger/Logger.js'; // Export JobsProgram and related types export { JobsProgram, JobState, MarketQueueType } from './programs/JobsProgram.js'; // Export IPFS utilities export * from './ipfs/IPFS.js'; // Export all generated client types and functions export * from './generated_clients/jobs/index.js'; // Export dependencies export * from 'gill';