anya-core 1.2.0

Enterprise-grade Bitcoin Infrastructure Platform
Documentation
import { useState, useEffect, useCallback } from 'react';
import { Web5 } from '@web5/api';

// RGB protocol service for Bitcoin asset management in React
export interface RGBConfig {
  nodeEndpoint: string;
  network: 'mainnet' | 'testnet' | 'regtest';
  dataDir?: string;
}

export interface RGBAsset {
  assetId: string;
  name: string;
  description: string;
  supply: number;
  precision: number;
  genesis: string;
  metadata?: Record<string, any>;
}

export interface AssetTransfer {
  assetId: string;
  toAddress: string;
  amount: number;
  metadata?: Record<string, any>;
}

export interface RGBTransaction {
  id: string;
  assetId: string;
  amount: number;
  fromAddress: string;
  toAddress: string;
  status: 'pending' | 'confirmed' | 'failed';
  timestamp: number;
  txHash?: string;
}

export class RGBServiceError extends Error {
  constructor(message: string) {
    super(message);
    this.name = 'RGBServiceError';
  }
}

export class RGBService {
  private web5: Web5;
  private config: RGBConfig;

  constructor(web5: Web5, config: RGBConfig) {
    this.web5 = web5;
    this.config = config;
  }

  async createAsset(params: {
    name: string;
    description: string;
    supply: number;
    precision: string;
    metadata?: Record<string, any>;
  }): Promise<RGBAsset> {
    try {
      const response = await this.makeRequest('create_asset', {
        name: params.name,
        description: params.description,
        supply: params.supply,
        precision: params.precision,
        metadata: params.metadata,
      });

      return {
        assetId: response.asset_id,
        name: params.name,
        description: params.description,
        supply: params.supply,
        precision: parseInt(params.precision),
        genesis: response.genesis,
        metadata: params.metadata,
      };
    } catch (error) {
      throw new RGBServiceError(`Failed to create asset: ${error}`);
    }
  }

  async transferAsset(transfer: AssetTransfer): Promise<RGBTransaction> {
    try {
      const response = await this.makeRequest('transfer_asset', {
        asset_id: transfer.assetId,
        to_address: transfer.toAddress,
        amount: transfer.amount,
        metadata: transfer.metadata,
      });

      return {
        id: response.transfer_id,
        assetId: transfer.assetId,
        amount: transfer.amount,
        fromAddress: response.from_address,
        toAddress: transfer.toAddress,
        status: 'pending',
        timestamp: Date.now(),
        txHash: response.tx_hash,
      };
    } catch (error) {
      throw new RGBServiceError(`Failed to transfer asset: ${error}`);
    }
  }

  async getAsset(assetId: string): Promise<RGBAsset> {
    try {
      const response = await this.makeRequest('get_asset', {
        asset_id: assetId,
      });

      return {
        assetId: response.asset_id,
        name: response.name,
        description: response.description,
        supply: response.supply,
        precision: response.precision,
        genesis: response.genesis,
        metadata: response.metadata,
      };
    } catch (error) {
      throw new RGBServiceError(`Failed to get asset: ${error}`);
    }
  }

  async listAssets(): Promise<RGBAsset[]> {
    try {
      const response = await this.makeRequest('list_assets');
      return response.assets.map((asset: any) => ({
        assetId: asset.asset_id,
        name: asset.name,
        description: asset.description,
        supply: asset.supply,
        precision: asset.precision,
        genesis: asset.genesis,
        metadata: asset.metadata,
      }));
    } catch (error) {
      throw new RGBServiceError(`Failed to list assets: ${error}`);
    }
  }

  async getBalance(assetId: string): Promise<number> {
    try {
      const response = await this.makeRequest('get_balance', {
        asset_id: assetId,
      });
      return response.balance;
    } catch (error) {
      throw new RGBServiceError(`Failed to get balance: ${error}`);
    }
  }

  async getTransactionHistory(assetId?: string): Promise<RGBTransaction[]> {
    try {
      const response = await this.makeRequest('get_transaction_history', {
        asset_id: assetId,
      });

      return response.transactions.map((tx: any) => ({
        id: tx.id,
        assetId: tx.asset_id,
        amount: tx.amount,
        fromAddress: tx.from_address,
        toAddress: tx.to_address,
        status: tx.status,
        timestamp: tx.timestamp,
        txHash: tx.tx_hash,
      }));
    } catch (error) {
      throw new RGBServiceError(`Failed to get transaction history: ${error}`);
    }
  }

  async validateContract(contractId: string): Promise<boolean> {
    try {
      const response = await this.makeRequest('validate_contract', {
        contract_id: contractId,
      });
      return response.valid;
    } catch (error) {
      throw new RGBServiceError(`Failed to validate contract: ${error}`);
    }
  }

  async generateAddress(assetId: string): Promise<string> {
    try {
      const response = await this.makeRequest('generate_address', {
        asset_id: assetId,
      });
      return response.address;
    } catch (error) {
      throw new RGBServiceError(`Failed to generate address: ${error}`);
    }
  }

  private async makeRequest(method: string, params?: any): Promise<any> {
    const url = `${this.config.nodeEndpoint}/api/v1/${method}`;
    
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params || {}),
    });

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    return response.json();
  }
}

// React hook for RGB protocol operations
export function useRGBService(config: RGBConfig) {
  const [assets, setAssets] = useState<RGBAsset[]>([]);
  const [transactions, setTransactions] = useState<RGBTransaction[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const web5 = new Web5(); // Initialize Web5
  const rgbService = new RGBService(web5, config);

  const fetchAssets = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const assetList = await rgbService.listAssets();
      setAssets(assetList);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error');
    } finally {
      setLoading(false);
    }
  }, [rgbService]);

  const fetchTransactions = useCallback(async (assetId?: string) => {
    setLoading(true);
    setError(null);
    try {
      const txHistory = await rgbService.getTransactionHistory(assetId);
      setTransactions(txHistory);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error');
    } finally {
      setLoading(false);
    }
  }, [rgbService]);

  const createAsset = useCallback(async (params: {
    name: string;
    description: string;
    supply: number;
    precision: string;
    metadata?: Record<string, any>;
  }) => {
    setLoading(true);
    setError(null);
    try {
      const asset = await rgbService.createAsset(params);
      setAssets(prev => [...prev, asset]);
      return asset;
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error');
      throw err;
    } finally {
      setLoading(false);
    }
  }, [rgbService]);

  const transferAsset = useCallback(async (transfer: AssetTransfer) => {
    setLoading(true);
    setError(null);
    try {
      const transaction = await rgbService.transferAsset(transfer);
      setTransactions(prev => [...prev, transaction]);
      return transaction;
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error');
      throw err;
    } finally {
      setLoading(false);
    }
  }, [rgbService]);

  const getBalance = useCallback(async (assetId: string) => {
    setError(null);
    try {
      return await rgbService.getBalance(assetId);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error');
      throw err;
    }
  }, [rgbService]);

  useEffect(() => {
    fetchAssets();
    fetchTransactions();
  }, [fetchAssets, fetchTransactions]);

  return {
    assets,
    transactions,
    loading,
    error,
    rgbService,
    fetchAssets,
    fetchTransactions,
    createAsset,
    transferAsset,
    getBalance,
  };
}