sendTransaction method
Future<TonSendTransactionResponse>
sendTransaction(
- TonTransactionRequest request, [
- TonNetwork? network
override
Builds, signs, and submits a TON transaction.
Implementation
@override
Future<TonSendTransactionResponse> sendTransaction(TonTransactionRequest request, [TonNetwork? network]) async {
Future<TonSendTransactionResponse> instrumentationOperation() async {
final operationScope = _state.flowScope.capture(replace: false);
await operationScope.ready();
operationScope.check();
final configured = _tonService.getNetworks((_state.projectSettings?.networks?.map((networkGroup) => (networkGroup.chainName == "ton" ? networkGroup.networks?.map((networkConfiguration) => NetworkData(chain: "TON", networkId: networkConfiguration.networkId, name: networkConfiguration.name, displayName: (networkConfiguration.vanityName == "" ? networkConfiguration.name : (networkConfiguration.vanityName ?? networkConfiguration.name)), rpcUrls: NetworkRpcUrls(http: [...(networkConfiguration.privateCustomerRpcUrls ?? <String>[]), ...networkConfiguration.rpcUrls]), blockExplorerUrls: (networkConfiguration.blockExplorerUrls ?? <String>[]), iconUrl: firstOrNull(networkConfiguration.iconUrls), nativeCurrency: networkConfiguration.nativeCurrency, cluster: networkConfiguration.cluster, genesisHash: networkConfiguration.genesisHash, testnet: (networkConfiguration.testnet ?? false))).toList() ?? const [] : <NetworkData>[])).toList() ?? const []).expand((items) => items).toList(), (_tonState.tonNetworks ?? <TonNetwork>[]));
operationScope.check();
final resolvedNetwork = (network ?? firstOrNull(configured));
if (resolvedNetwork == null) {
throw DynamicStateException("no TON networks configured; provide one with useTon");
}
final publicKeys = _state.user?.verifiedCredentials?.map((credential) => (credential.walletAdditionalAddresses == null ? null : firstWhereOrNull<WalletAdditionalAddress>(credential.walletAdditionalAddresses!, (item) => item.address == request.from))?.publicKey).where((v) => v != null).map((v) => v!).toList() ?? const [];
final publicKeyHex = firstOrNull(publicKeys);
if (publicKeyHex == null) {
throw DynamicStateException("no public key is available for this TON wallet");
}
operationScope.check();
final prepared = await _tonService.prepareTransaction(request, publicKeyHex, resolvedNetwork);
operationScope.check();
final signerCredential = firstOrNull(_state.user?.verifiedCredentials?.map((signerCandidate) => (((signerCandidate.format == "blockchain") && ((switch ((signerCandidate.chain ?? "")) { "eip155" => "EVM", "solana" => "SOL", "bip122" => "BTC", _ => (signerCandidate.chain ?? "").toUpperCase() }) == "TON")) && ((("TON" == "EVM" ? (signerCandidate.address ?? "").toLowerCase() : (signerCandidate.address ?? "")) == ("TON" == "EVM" ? request.from.toLowerCase() : request.from)) || (firstOrNull(signerCandidate.walletAdditionalAddresses?.map((additionalAddress) => (("TON" == "EVM" ? additionalAddress.address.toLowerCase() : additionalAddress.address) == ("TON" == "EVM" ? request.from.toLowerCase() : request.from) ? additionalAddress : null)).where((v) => v != null).map((v) => v!).toList() ?? const []) != null)) ? signerCandidate : null)).where((v) => v != null).map((v) => v!).toList() ?? const []);
final embeddedSigner = _client.findCapability<EmbeddedWalletSigner>();
final externalSigner = _client.findCapability<ExternalWalletSigner>();
if (!((signerCredential != null) || !((embeddedSigner != null) && (externalSigner != null)))) {
throw DynamicStateException("wallet ownership is unknown; cannot choose between embedded and external signers");
}
final WalletSigner? selectedSigner = signerCredential != null ? (signerCredential?.walletProvider == "embeddedWallet" ? embeddedSigner : externalSigner) : _client.findCapability<WalletSigner>();
final signer = selectedSigner;
if (signer == null) {
throw DynamicStateException("no WalletSigner installed to sign with (e.g. useWaas) — add one first");
}
operationScope.check();
final signature = await signer.signTransaction("TON", request.from, prepared.hashToSign, null, null, null);
operationScope.check();
operationScope.check();
final response = await _tonService.broadcastTransaction(prepared, signature, resolvedNetwork);
operationScope.check();
return response;
}
return await _api.instrumentation.runAsync("ton.sendTransaction", instrumentationOperation);
}