irys-complete-toolkit
Version:
Complete Irys SDK toolkit supporting all chains, tokens, and features
429 lines (428 loc) • 15.7 kB
JavaScript
"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;