|
| 1 | +/** |
| 2 | + * TON WASM adapter for abstract-wasm-coin. |
| 3 | + * |
| 4 | + * Wraps @bitgo/wasm-ton and exposes: |
| 5 | + * - deriveAddress — normalizes a raw TON address to bounceable EQ... form |
| 6 | + * - parseTransaction — decodes a base64-encoded TON transaction into normalized outputs/inputs |
| 7 | + * |
| 8 | + * Explain logic, verification policy, and product semantics stay in sdk-coin-ton. |
| 9 | + * This adapter is a thin translation layer only. |
| 10 | + */ |
| 11 | +import { Transaction as WasmTonTransaction, parseTransaction, decode as wasmDecode, encode as wasmEncode } from '@bitgo/wasm-ton'; |
| 12 | +import type { WasmCoinAdapter, WasmCoinCapability, WasmDerivedAddress, WasmParsedTransaction } from '../types'; |
| 13 | + |
| 14 | +// ============================================================================= |
| 15 | +// Adapter-specific param/result types |
| 16 | +// ============================================================================= |
| 17 | + |
| 18 | +export interface TonAddressParams { |
| 19 | + /** Raw address string (any TON format: EQ..., UQ..., workchain:hash hex). */ |
| 20 | + address: string; |
| 21 | + /** When true (default), return the bounceable EQ... address. */ |
| 22 | + bounceable?: boolean; |
| 23 | +} |
| 24 | + |
| 25 | +export interface TonDerivedAddress extends WasmDerivedAddress { |
| 26 | + raw: { workchainId: number; addressHash: Uint8Array }; |
| 27 | +} |
| 28 | + |
| 29 | +export interface TonParseParams { |
| 30 | + /** Base64-encoded TON transaction bytes. */ |
| 31 | + txBase64: string; |
| 32 | + /** When true (default), return bounceable EQ... destination addresses. */ |
| 33 | + toAddressBounceable?: boolean; |
| 34 | +} |
| 35 | + |
| 36 | +export interface TonParsedTransaction extends WasmParsedTransaction { |
| 37 | + raw: ReturnType<typeof parseTransaction>; |
| 38 | +} |
| 39 | + |
| 40 | +// ============================================================================= |
| 41 | +// Adapter implementation |
| 42 | +// ============================================================================= |
| 43 | + |
| 44 | +export const tonAdapter: WasmCoinAdapter<TonAddressParams, TonDerivedAddress, TonParseParams, TonParsedTransaction> = { |
| 45 | + coin: 'ton', |
| 46 | + capabilities: new Set<WasmCoinCapability>(['deriveAddress', 'parseTransaction']), |
| 47 | + |
| 48 | + deriveAddress(params: TonAddressParams): TonDerivedAddress { |
| 49 | + const bounceable = params.bounceable !== false; |
| 50 | + const decoded = wasmDecode(params.address); |
| 51 | + const address = wasmEncode(decoded.workchainId, decoded.addressHash, bounceable); |
| 52 | + return { |
| 53 | + address, |
| 54 | + raw: { workchainId: decoded.workchainId, addressHash: decoded.addressHash }, |
| 55 | + }; |
| 56 | + }, |
| 57 | + |
| 58 | + parseTransaction(params: TonParseParams): TonParsedTransaction { |
| 59 | + const toAddressBounceable = params.toAddressBounceable !== false; |
| 60 | + const tx = WasmTonTransaction.fromBytes(Buffer.from(params.txBase64, 'base64')); |
| 61 | + const parsed = parseTransaction(tx); |
| 62 | + |
| 63 | + const outputs: Array<{ address: string; amount: string }> = []; |
| 64 | + const inputs: Array<{ address: string; amount: string }> = []; |
| 65 | + |
| 66 | + for (const action of parsed.sendActions) { |
| 67 | + const address = toAddressBounceable ? action.destinationBounceable : action.destination; |
| 68 | + const amount = String(action.jettonTransfer ? action.jettonTransfer.amount : action.amount); |
| 69 | + outputs.push({ address, amount }); |
| 70 | + } |
| 71 | + |
| 72 | + // TON is account-model: inputs mirror total output from the sender. |
| 73 | + const totalAmount = outputs.reduce((sum, o) => sum + BigInt(o.amount), 0n); |
| 74 | + if (outputs.length > 0) { |
| 75 | + // Sender address not available from the parsed payload at this layer; |
| 76 | + // callers that need it should use the raw field. |
| 77 | + inputs.push({ address: '', amount: String(totalAmount) }); |
| 78 | + } |
| 79 | + |
| 80 | + return { id: tx.id, inputs, outputs, raw: parsed }; |
| 81 | + }, |
| 82 | +}; |
0 commit comments