sendTransaction method

  1. @override
Future<TonSendTransactionResponse> sendTransaction(
  1. TonTransactionRequest request, [
  2. 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);
}