import type { IPurchaseAdapter, PurchaseContext, PurchaseResult } from '@namiml/sdk-core'; import type { NamiProductDetails } from '@namiml/sdk-core'; type ExpoNamiIapModule = { initConnection: () => Promise; getProducts: (skuIds: string[]) => Promise; purchase: (params: { skuId: string; offerId?: string; appAccountToken?: string; }) => Promise<{ transactionId: string; receipt?: string; skuId: string; }>; restorePurchases: () => Promise>; }; function getExpoNamiIap(): ExpoNamiIapModule { return require('@namiml/expo-nami-iap') as ExpoNamiIapModule; } type PurchaseContextWithAppAccountToken = PurchaseContext & { appAccountToken?: string; }; function getPurchaseErrorMessage(error: unknown): string { if (error instanceof Error && error.message) { return error.message; } if (typeof error === 'object' && error && 'message' in error) { const message = (error as { message?: unknown }).message; if (typeof message === 'string' && message.length > 0) { return message; } } return 'Purchase failed'; } export class ExpoPurchaseAdapter implements IPurchaseAdapter { async getProducts(skuIds: string[]): Promise { const { initConnection, getProducts } = getExpoNamiIap(); await initConnection(); return getProducts(skuIds); } async purchase(skuId: string, context?: PurchaseContext): Promise { const { initConnection, purchase } = getExpoNamiIap(); await initConnection(); try { const tx = await purchase({ skuId, offerId: context?.offerId, appAccountToken: (context as PurchaseContextWithAppAccountToken | undefined)?.appAccountToken, }); return { success: true, transactionId: tx.transactionId, receipt: tx.receipt, skuId: tx.skuId, }; } catch (error) { return { success: false, skuId, message: getPurchaseErrorMessage(error) }; } } async restorePurchases(): Promise { const { initConnection, restorePurchases } = getExpoNamiIap(); await initConnection(); const txs = await restorePurchases(); return txs.map((t) => ({ success: true, transactionId: t.transactionId, receipt: t.receipt, skuId: t.skuId })); } }