/ src / lib / utils / wave / stellar.ts
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  }