import type { TonConnect } from '@tonconnect/sdk' import type { TonNativeTransferRequest, TransactionResult, SignatureType, TonSignDataPayload } from '@meshconnect/uwc-types' import { WalletConnectorError } from '@meshconnect/uwc-types' import { buildSignDataPayload, executeSignData, unwrapBoc, bocToHash, TON_CONNECT_INJECTED_STORAGE_PREFIX, withWalletResponseTimeout } from '@meshconnect/uwc-ton-connector' import { extractTonSdkErrorMessage, parseError } from '../../utils/error-utils' import { TonTransactionBuilder } from './ton-transaction-builder' /** * Service for handling TON transaction operations */ export class TonTransactionService { private builder: TonTransactionBuilder constructor() { this.builder = new TonTransactionBuilder() } /** * Send a native TON transfer */ async sendTransaction( request: TonNativeTransferRequest, sdk: TonConnect, UserRejectsError?: (new (...args: never[]) => Error) | null ): Promise { try { const txRequest = this.builder.buildNativeTransfer( request, sdk.account?.address ) const result = await withWalletResponseTimeout( sdk.sendTransaction(txRequest), TON_CONNECT_INJECTED_STORAGE_PREFIX ) const boc = unwrapBoc(result) return await bocToHash(boc) } catch (error) { this.toWalletError(error, UserRejectsError) } } /** * Sign a message via TonConnect signData */ async signMessage( message: string, sdk: TonConnect, UserRejectsError?: (new (...args: never[]) => Error) | null, payloadOverride?: TonSignDataPayload ): Promise { if (typeof sdk.signData !== 'function') { throw new Error( 'Connected TON wallet does not support message signing (signData)' ) } try { const payload = buildSignDataPayload(message, payloadOverride) return await withWalletResponseTimeout( executeSignData(sdk, payload), TON_CONNECT_INJECTED_STORAGE_PREFIX ) } catch (error) { this.toWalletError(error, UserRejectsError) } } private toWalletError( error: unknown, UserRejectsError?: (new (...args: never[]) => Error) | null ): never { // Already-typed connector errors (e.g. the `expired` timeout) must pass // through — the normalization below would downgrade them. if (error instanceof WalletConnectorError) { throw error } const isRejected = UserRejectsError != null && error instanceof UserRejectsError const message = extractTonSdkErrorMessage(error) || 'TON wallet operation failed' parseError({ code: isRejected ? 4001 : undefined, message }) } }