stellar.ts
1 import * as StellarSdk from '@stellar/stellar-sdk'; 2 3 // USDC on Stellar Mainnet 4 const USDC_ASSET_CODE = 'USDC'; 5 const USDC_ISSUER = 'GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN'; 6 7 const HORIZON_URL = 'https://horizon.stellar.org'; 8 9 export interface TrustlineCheckResult { 10 exists: boolean; 11 isAuthorized: boolean; 12 hasCapacity: boolean; 13 availableLimit: number | null; 14 error: string | null; 15 } 16 17 /** 18 * Verifies if a Stellar account has a USDC trustline and is ready to receive USDC. 19 * @param accountId The Stellar public key (starts with G) 20 * @returns TrustlineCheckResult with details about the trustline status 21 */ 22 export async function verifyUsdcTrustline(accountId: string): Promise<TrustlineCheckResult> { 23 const server = new StellarSdk.Horizon.Server(HORIZON_URL); 24 25 try { 26 const account = await server.loadAccount(accountId); 27 28 // Find USDC balance in account balances 29 const usdcBalance = account.balances.find( 30 (balance): balance is StellarSdk.Horizon.HorizonApi.BalanceLineAsset => 31 balance.asset_type === 'credit_alphanum4' && 32 'asset_code' in balance && 33 'asset_issuer' in balance && 34 balance.asset_code === USDC_ASSET_CODE && 35 balance.asset_issuer === USDC_ISSUER, 36 ); 37 38 if (!usdcBalance) { 39 return { 40 exists: false, 41 isAuthorized: false, 42 hasCapacity: false, 43 availableLimit: null, 44 error: 'USDC trustline not found. Please enable the USDC trustline in your wallet.', 45 }; 46 } 47 48 // Check if trustline is authorized 49 const isAuthorized = usdcBalance.is_authorized === true; 50 51 if (!isAuthorized) { 52 return { 53 exists: true, 54 isAuthorized: false, 55 hasCapacity: false, 56 availableLimit: null, 57 error: 'USDC trustline exists but is not authorized.', 58 }; 59 } 60 61 // Calculate available limit 62 const limit = parseFloat(usdcBalance.limit); 63 const currentBalance = parseFloat(usdcBalance.balance); 64 const availableLimit = limit - currentBalance; 65 66 return { 67 exists: true, 68 isAuthorized: true, 69 hasCapacity: availableLimit > 0, 70 availableLimit, 71 error: null, 72 }; 73 } catch (err) { 74 // Handle account not found error 75 if (err instanceof StellarSdk.NotFoundError) { 76 return { 77 exists: false, 78 isAuthorized: false, 79 hasCapacity: false, 80 availableLimit: null, 81 error: 'Stellar account not found. Make sure the account is funded and active.', 82 }; 83 } 84 85 // Handle other errors 86 const message = err instanceof Error ? err.message : 'Unknown error verifying trustline'; 87 return { 88 exists: false, 89 isAuthorized: false, 90 hasCapacity: false, 91 availableLimit: null, 92 error: message, 93 }; 94 } 95 }