UNPKG

irys-complete-toolkit

Version:

Complete Irys SDK toolkit supporting all chains, tokens, and features

429 lines (428 loc) 15.7 kB
"use strict"; /** * Irys Web SDK Toolkit * Comprehensive SDK for browser-based Irys operations */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.IrysWebSDK = void 0; const types_1 = require("../types"); class IrysWebSDK { constructor(config) { this.config = config; this.validateConfig(); } validateConfig() { if (!this.config.token || !types_1.SUPPORTED_TOKENS[this.config.token]) { throw new types_1.IrysError(`Unsupported token: ${this.config.token}. Supported tokens: ${Object.keys(types_1.SUPPORTED_TOKENS).join(', ')}`); } if (!this.config.provider) { throw new types_1.IrysError('Provider is required for Web SDK'); } if (!this.config.providerType) { throw new types_1.IrysError('Provider type is required for Web SDK'); } } /** * Initialize the web uploader with the specified token and provider */ async initialize() { try { const tokenConfig = types_1.SUPPORTED_TOKENS[this.config.token]; // Import required packages const { WebUploader } = await Promise.resolve().then(() => __importStar(require('@irys/web-upload'))); let uploader; // Handle different blockchain types if (this.config.token === 'solana' || this.config.token === 'usdc-solana') { await this.initializeSolana(); } else if (this.config.token === 'aptos') { await this.initializeAptos(); } else { // EVM-based tokens await this.initializeEVM(); } } catch (error) { throw new types_1.IrysError(`Failed to initialize Irys web uploader: ${error}`); } } async initializeEVM() { const { WebUploader } = await Promise.resolve().then(() => __importStar(require('@irys/web-upload'))); const webEthereumModule = await Promise.resolve().then(() => __importStar(require('@irys/web-upload-ethereum'))); const tokenConfig = types_1.SUPPORTED_TOKENS[this.config.token]; // Get the appropriate token class const TokenClass = webEthereumModule[`Web${tokenConfig.className}`] || webEthereumModule.WebEthereum; if (this.config.providerType === 'ethers-v5') { this.uploader = await WebUploader(TokenClass).withProvider(this.config.provider); } else if (this.config.providerType === 'ethers-v6') { const { EthersV6Adapter } = await Promise.resolve().then(() => __importStar(require('@irys/web-upload-ethereum-ethers-v6'))); this.uploader = await WebUploader(TokenClass).withAdapter(EthersV6Adapter(this.config.provider)); } else if (this.config.providerType === 'viem-v2') { const { ViemV2Adapter } = await Promise.resolve().then(() => __importStar(require('@irys/web-upload-ethereum-viem-v2'))); this.uploader = await WebUploader(TokenClass).withAdapter(ViemV2Adapter(this.config.provider, { publicClient: this.config.provider.publicClient })); } else { throw new types_1.IrysError(`Unsupported EVM provider type: ${this.config.providerType}`); } } async initializeSolana() { const { WebUploader } = await Promise.resolve().then(() => __importStar(require('@irys/web-upload'))); const { WebSolana } = await Promise.resolve().then(() => __importStar(require('@irys/web-upload-solana'))); this.uploader = await WebUploader(WebSolana).withProvider(this.config.provider); } async initializeAptos() { const { WebUploader } = await Promise.resolve().then(() => __importStar(require('@irys/web-upload'))); const { WebAptos } = await Promise.resolve().then(() => __importStar(require('@irys/web-upload-aptos'))); this.uploader = await WebUploader(WebAptos).withProvider(this.config.provider); } /** * Get the wallet address */ get address() { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } return this.uploader.address; } /** * Get current token */ get token() { return this.config.token; } /** * Get account balance */ async getBalance() { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } try { const balance = await this.uploader.getBalance(); return this.uploader.utils.fromAtomic(balance); } catch (error) { throw new types_1.IrysError(`Failed to get balance: ${error}`); } } /** * Fund the account */ async fund(amount) { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } try { const atomicAmount = this.uploader.utils.toAtomic(amount); const fundTx = await this.uploader.fund(atomicAmount); return { ...fundTx, humanReadableAmount: this.uploader.utils.fromAtomic(fundTx.quantity), token: this.config.token }; } catch (error) { throw new types_1.IrysError(`Failed to fund account: ${error}`); } } /** * Get upload price for data size */ async getPrice(bytes) { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } try { const price = await this.uploader.getPrice(bytes); return this.uploader.utils.fromAtomic(price); } catch (error) { throw new types_1.IrysError(`Failed to get price: ${error}`); } } /** * Upload data to Irys */ async upload(data, options = {}) { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } try { // Check if we have sufficient funds for larger uploads if (this.getDataSize(data) > 100 * 1024) { // > 100KB const price = await this.uploader.getPrice(this.getDataSize(data)); const balance = await this.uploader.getBalance(); if (balance.lt(price)) { throw new types_1.InsufficientFundsError(this.uploader.utils.fromAtomic(price), this.uploader.utils.fromAtomic(balance)); } } const receipt = await this.uploader.upload(data, options); return receipt; } catch (error) { if (error instanceof types_1.InsufficientFundsError) { throw error; } throw new types_1.IrysError(`Failed to upload data: ${error}`); } } /** * Upload a file (browser File object) */ async uploadFile(file, options = {}) { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } try { // Add Content-Type tag if not already present const tags = options.tags || []; const hasContentType = tags.some(tag => tag.name.toLowerCase() === 'content-type'); if (!hasContentType && file.type) { tags.push({ name: 'Content-Type', value: file.type }); } const receipt = await this.uploader.upload(file, { ...options, tags }); return receipt; } catch (error) { throw new types_1.IrysError(`Failed to upload file: ${error}`); } } /** * Upload multiple files */ async uploadFiles(files, options = {}) { const receipts = []; for (const file of files) { const receipt = await this.uploadFile(file, options); receipts.push(receipt); } return receipts; } /** * Create a balance approval */ async createApproval(options) { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } try { const atomicAmount = this.uploader.utils.toAtomic(options.amount); const approvalOptions = { amount: atomicAmount, approvedAddress: options.approvedAddress, ...(options.expiresInSeconds && { expiresInSeconds: options.expiresInSeconds }) }; const receipt = await this.uploader.approval.createApproval(approvalOptions); return receipt; } catch (error) { throw new types_1.IrysError(`Failed to create approval: ${error}`); } } /** * Revoke a balance approval */ async revokeApproval(approvedAddress) { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } try { const receipt = await this.uploader.approval.revokeApproval({ approvedAddress }); return receipt; } catch (error) { throw new types_1.IrysError(`Failed to revoke approval: ${error}`); } } /** * Get balance approvals */ async getApprovals(payingAddresses) { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } try { const options = payingAddresses ? { payingAddresses } : {}; const approvals = await this.uploader.approval.getApprovals(options); return approvals; } catch (error) { throw new types_1.IrysError(`Failed to get approvals: ${error}`); } } /** * Get created approvals */ async getCreatedApprovals(approvedAddresses) { if (!this.uploader) { throw new types_1.IrysError('SDK not initialized. Call initialize() first.'); } try { const options = approvedAddresses ? { approvedAddresses } : {}; const approvals = await this.uploader.approval.getCreatedApprovals(options); return approvals; } catch (error) { throw new types_1.IrysError(`Failed to get created approvals: ${error}`); } } /** * Create a mutable reference */ async createMutableReference(data, options = {}) { const receipt = await this.upload(data, options); const url = `https://gateway.irys.xyz/mutable/${receipt.id}`; return { receipt, url }; } /** * Update a mutable reference */ async updateMutableReference(rootTxId, data, options = {}) { const tags = [ { name: 'Root-TX', value: rootTxId }, ...(options.tags || []) ]; return this.upload(data, { ...options, tags }); } /** * Upload NFT metadata */ async uploadNFTMetadata(metadata, options = {}) { const tags = [ { name: 'Content-Type', value: 'application/json' }, { name: 'Application', value: 'NFT-Metadata' }, ...(options.tags || []) ]; return this.upload(JSON.stringify(metadata), { ...options, tags }); } /** * Utility function to get data size */ getDataSize(data) { if (typeof data === 'string') { return new Blob([data]).size; } else if (data instanceof File || data instanceof Blob) { return data.size; } else if (data instanceof ArrayBuffer) { return data.byteLength; } else if (data instanceof Uint8Array) { return data.length; } else { return new Blob([JSON.stringify(data)]).size; } } /** * Check if provider is connected */ async isConnected() { try { if (this.config.providerType === 'solana') { return this.config.provider.connected || false; } else if (this.config.providerType === 'aptos') { return this.config.provider.connected || false; } else { // For EVM providers, try to get the signer const signer = await this.config.provider.getSigner?.(); return !!signer; } } catch (error) { return false; } } /** * Request wallet connection (for applicable providers) */ async connect() { try { if (this.config.providerType === 'solana') { const provider = this.config.provider; if (provider.connect) { await provider.connect(); } } else if (this.config.providerType === 'aptos') { const provider = this.config.provider; if (provider.connect) { await provider.connect(); } } else { // For EVM providers if (typeof window !== 'undefined' && window.ethereum) { await window.ethereum.request({ method: 'eth_requestAccounts' }); } } } catch (error) { throw new types_1.IrysError(`Failed to connect wallet: ${error}`); } } /** * Disconnect wallet (for applicable providers) */ async disconnect() { try { if (this.config.providerType === 'solana') { const provider = this.config.provider; if (provider.disconnect) { await provider.disconnect(); } } else if (this.config.providerType === 'aptos') { const provider = this.config.provider; if (provider.disconnect) { await provider.disconnect(); } } } catch (error) { throw new types_1.IrysError(`Failed to disconnect wallet: ${error}`); } } } exports.IrysWebSDK = IrysWebSDK;