UNPKG

defarm-sdk

Version:

DeFarm SDK - On-premise blockchain data processing and tokenization engine for agriculture supply chain

400 lines (345 loc) 10.5 kB
import type { Asset } from '../types'; interface BlockchainConfig { enabled: boolean; network: 'stellar' | 'ethereum' | 'polygon'; endpoint?: string; credentials?: { publicKey?: string; privateKey?: string; apiKey?: string; }; } interface BlockchainResult { transactionId: string; blockNumber: number; timestamp: Date; } export interface SignedTransaction { source: string; fee: string; operations: any[]; sequence: string; timeBounds?: { minTime: number; maxTime: number; }; signatures: Array<{ hint: string; signature: string; }>; } // New interfaces for tokenization export interface TokenizationBlockchainConfig { network: 'stellar' | 'ethereum' | 'polygon'; rpcUrl: string; contractAddresses: { nft: string; ipcm: string; valuechains: string; }; } export interface MintNFTParams { to: string; valuechainId: string; metadataUrl: string; asset: Asset; } export interface MintNFTResult { success: boolean; tokenId?: string; contractAddress?: string; transactionHash?: string; error?: string; } export interface NFTInfo { tokenId: string; contractAddress: string; owner: string; metadataUrl: string; valuechainId: string; } /** * Service for blockchain integration * Enhanced with tokenization capabilities using DeFarm backbone contracts */ export class BlockchainService { private config: BlockchainConfig; private tokenizationConfig?: TokenizationBlockchainConfig; private initialized = false; constructor(config: BlockchainConfig, tokenizationConfig?: TokenizationBlockchainConfig) { this.config = config; this.tokenizationConfig = tokenizationConfig; } async initialize(): Promise<void> { if (!this.config.enabled) { return; } // In real implementation, would initialize blockchain connection console.log(`Initializing blockchain service for ${this.config.network}`); // Verify credentials if (!this.config.credentials?.publicKey) { throw new Error('Blockchain public key required'); } this.initialized = true; } async submitAsset(asset: Asset): Promise<BlockchainResult> { if (!this.initialized) { throw new Error('Blockchain service not initialized'); } // Create hash of asset data const assetHash = this.createAssetHash(asset); // In real implementation, would submit to blockchain console.log(`Submitting asset ${asset.dfid} to ${this.config.network} blockchain`); // Simulate blockchain submission return { transactionId: `tx_${Date.now()}_${Math.random().toString(36).substring(7)}`, blockNumber: Math.floor(Math.random() * 1000000), timestamp: new Date() }; } async verifyAsset(dfid: string, transactionId: string): Promise<boolean> { if (!this.initialized) { throw new Error('Blockchain service not initialized'); } // In real implementation, would verify on blockchain console.log(`Verifying asset ${dfid} with transaction ${transactionId}`); // Simulate verification return true; } async disconnect(): Promise<void> { if (this.initialized) { console.log('Disconnecting blockchain service'); this.initialized = false; } } private createAssetHash(asset: Asset): string { // In real implementation, would use proper hashing const data = { dfid: asset.dfid, name: asset.name, category: asset.category, ownership: asset.ownership.ownerId, created: asset.metadata.created }; // Simple hash simulation return Buffer.from(JSON.stringify(data)).toString('base64'); } /** * Mint NFT using DeFarm's smart contract (for tokenization) */ async mintNFT(params: MintNFTParams): Promise<MintNFTResult> { if (!this.tokenizationConfig) { return { success: false, error: 'Tokenization not configured' }; } try { // Call DeFarm's tokenization API (uses backbone smart contracts) const response = await fetch(`${this.getDeFarmAPIUrl()}/tokenization/mint`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.getDeFarmAPIKey()}` }, body: JSON.stringify({ to: params.to, valuechainId: params.valuechainId, metadataUrl: params.metadataUrl, contractId: this.tokenizationConfig.contractAddresses.nft, rpcUrl: this.tokenizationConfig.rpcUrl, assetData: { dfid: params.asset.dfid, category: params.asset.category, subcategory: params.asset.subcategory, name: params.asset.name } }) }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(`Mint API failed: ${response.status} ${errorData.error || response.statusText}`); } const result = await response.json(); return { success: result.success, tokenId: result.tokenId, contractAddress: this.tokenizationConfig.contractAddresses.nft, transactionHash: result.transactionHash, error: result.error }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Unknown blockchain error' }; } } /** * Map CID to blockchain using IPCM contract */ async mapCIDToBlockchain(key: string, cid: string): Promise<{ success: boolean; transactionHash?: string; error?: string; }> { if (!this.tokenizationConfig) { return { success: false, error: 'Tokenization not configured' }; } try { // Call DeFarm's CID mapping API (uses backbone IPCM contract) const response = await fetch(`${this.getDeFarmAPIUrl()}/tokenization/map-cid`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.getDeFarmAPIKey()}` }, body: JSON.stringify({ key, cid, contractId: this.tokenizationConfig.contractAddresses.ipcm, rpcUrl: this.tokenizationConfig.rpcUrl }) }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(`CID mapping API failed: ${response.status} ${errorData.error || response.statusText}`); } const result = await response.json(); return { success: result.success, transactionHash: result.transactionHash, error: result.error }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Unknown CID mapping error' }; } } /** * Query NFTs owned by an address */ async queryNFTByOwner(ownerAddress: string): Promise<NFTInfo[]> { if (!this.tokenizationConfig) { return []; } try { const response = await fetch(`${this.getDeFarmAPIUrl()}/tokenization/query-nfts?owner=${ownerAddress}`, { method: 'GET', headers: { 'Authorization': `Bearer ${this.getDeFarmAPIKey()}` } }); if (!response.ok) { throw new Error(`NFT query failed: ${response.status} ${response.statusText}`); } const result = await response.json(); return result.nfts || []; } catch (error) { console.warn('Failed to query NFTs:', error); return []; } } /** * Get wallet balance */ async getBalance(address: string): Promise<string> { if (!this.tokenizationConfig) { return '0'; } try { const response = await fetch(`${this.getDeFarmAPIUrl()}/blockchain/balance?address=${address}&network=${this.tokenizationConfig.network}`, { method: 'GET', headers: { 'Authorization': `Bearer ${this.getDeFarmAPIKey()}` } }); if (!response.ok) { throw new Error(`Balance query failed: ${response.status} ${response.statusText}`); } const result = await response.json(); return result.balance || '0'; } catch (error) { console.warn('Failed to get balance:', error); return '0'; } } /** * Get DeFarm API URL from environment */ private getDeFarmAPIUrl(): string { return process.env.DEFARM_API_URL || 'https://api.defarm.com'; } /** * Get DeFarm API key from environment */ private getDeFarmAPIKey(): string { return process.env.DEFARM_API_KEY || 'defarm_sdk_default_key'; } /** * Submit signed transaction to blockchain */ async submitSignedTransaction(signedTx: SignedTransaction): Promise<{ hash: string; success: boolean; error?: string; }> { if (!this.tokenizationConfig) { return { hash: '', success: false, error: 'Tokenization not configured' }; } try { const response = await fetch(`${this.getDeFarmAPIUrl()}/blockchain/submit-transaction`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.getDeFarmAPIKey()}` }, body: JSON.stringify({ network: this.tokenizationConfig.network, signedTransaction: signedTx }) }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(`Transaction submission failed: ${response.status} ${errorData.error || response.statusText}`); } const result = await response.json(); return { hash: result.transactionHash || result.hash, success: result.success, error: result.error }; } catch (error) { return { hash: '', success: false, error: error instanceof Error ? error.message : 'Unknown submission error' }; } } /** * Get blockchain explorer URL for a transaction */ getExplorerUrl(transactionId: string): string { const network = this.tokenizationConfig?.network || this.config.network; switch (network) { case 'stellar': return `https://stellar.expert/explorer/testnet/tx/${transactionId}`; case 'ethereum': return `https://etherscan.io/tx/${transactionId}`; case 'polygon': return `https://polygonscan.com/tx/${transactionId}`; default: return ''; } } }