You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Solana钱包交易失败问题求助

Solana钱包适配器转账问题修复指南

问题背景

使用solana_wallet_adapter调用Phantom、Solflare钱包进行SOL转账时遇到以下问题:

Phantom钱包问题

  • 能正常显示连接授权弹窗和交易批准弹窗,但点击「批准」后无响应,一段时间后控制台报错:
    E/flutter (28131): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: [JsonRpcException<dynamic>] -3 : sign request declined
    

Solflare钱包问题

  • 能成功连接钱包,但滑动批准交易时提示「发生未知错误」,控制台反复出现:
    E/flutter (29334): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method callAsyncJavaScript on channel com.pichillilorenzo/flutter_inappwebview_...)
    

原代码

final adapter = SolanaWalletAdapter(
              const AppIdentity(),
              cluster: Cluster.devnet,
            );

            final Cluster cluster = Cluster.devnet;

            var blockHash = await web3.Connection(cluster).getLatestBlockhash();

            final connection = web3.Connection(
              cluster,
            );


            AuthorizeResult result = await adapter.authorize();


            final connectedAccount = adapter.connectedAccount?.address;
            if (connectedAccount == null) throw Exception('Connect wallet before sending tx.');

            // Mobile wallet displays the address as base-58.
            final rcv = web3.PublicKey.fromBase58("<some-address-here>");

            // Mobile wallet adapter specification returns address as base-64
            final snd = web3.PublicKey.fromBase64(connectedAccount);

            print('creating transaction');

            // Get latest blockhash info.
            final blockhash = await connection.getLatestBlockhash();

            // Create transfer tx.
            final transaction = web3.Transaction(
              feePayer: snd, // The account that will sign the tx (and pay any fees).
              recentBlockhash: blockhash.blockhash,
              lastValidBlockHeight: blockhash.lastValidBlockHeight,
              instructions: [
                SystemProgram.transfer(
                  fromPublicKey: snd,
                  toPublicKey: rcv,
                  lamports: web3.solToLamports(1),
                ),
              ],
            );

            // Serialize tx.
            const config = web3.SerializeConfig(requireAllSignatures: false);
            final tt = transaction.serialize(config).getString(web3.BufferEncoding.base64);
            print('creating transaction string $tt');

            // Sign and send tx.
            final txresult = await adapter.signAndSendTransactions(transactions: [tt]);

            // Wait for confirmation.
            await connection.confirmTransaction(base64ToBase58(txresult.signatures.first!));

解决方案

针对Phantom钱包的修复

  1. 复用钱包适配器实例:不要每次点击按钮都新建SolanaWalletAdapter,重复创建会导致会话异常,建议将其作为类成员变量复用。
  2. 优化Blockhash获取时机:提前获取的blockhash可能过期,必须在创建交易前才获取最新的blockhash,确保交易有效性。
  3. 简化交易流程:移除冗余的blockHash变量,避免混淆。

针对Solflare钱包的修复

  1. 集成flutter_inappwebview插件:Solflare内部依赖该插件的callAsyncJavaScript方法,需在项目中添加依赖:
    • 在pubspec.yaml中添加:
      dependencies:
        flutter_inappwebview: ^6.0.0 # 版本建议与solana_wallet_adapter依赖的版本匹配
      
    • 执行flutter pub get后重新运行项目。
  2. 配置平台权限:
    • Android:在AndroidManifest.xml中添加网络权限:
      <uses-permission android:name="android.permission.INTERNET" />
      
    • iOS:在Info.plist中添加App Transport Security例外(若需要):
      <key>NSAppTransportSecurity</key>
      <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
      </dict>
      
  3. 清理缓存重建项目:执行flutter clean后重新构建,避免缓存导致的插件未加载问题。

修正后的代码示例

// 作为类成员变量,复用适配器实例
final SolanaWalletAdapter _adapter = SolanaWalletAdapter(
  const AppIdentity(),
  cluster: Cluster.devnet,
);
final Cluster _cluster = Cluster.devnet;
late final web3.Connection _connection;

@override
void initState() {
  super.initState();
  _connection = web3.Connection(_cluster);
}

// 按钮点击触发的转账方法
Future<void> _sendSol() async {
  try {
    // 授权连接钱包
    await _adapter.authorize();

    final connectedAccount = _adapter.connectedAccount?.address;
    if (connectedAccount == null) throw Exception('请先连接钱包');

    // 解析收款和付款地址
    final receiver = web3.PublicKey.fromBase58("<some-address-here>");
    final sender = web3.PublicKey.fromBase64(connectedAccount);

    // 创建交易前获取最新Blockhash
    final blockhashInfo = await _connection.getLatestBlockhash();

    // 构建转账交易
    final transaction = web3.Transaction(
      feePayer: sender,
      recentBlockhash: blockhashInfo.blockhash,
      lastValidBlockHeight: blockhashInfo.lastValidBlockHeight,
      instructions: [
        SystemProgram.transfer(
          fromPublicKey: sender,
          toPublicKey: receiver,
          lamports: web3.solToLamports(1),
        ),
      ],
    );

    // 序列化交易
    const serializeConfig = web3.SerializeConfig(requireAllSignatures: false);
    final serializedTx = transaction.serialize(serializeConfig).getString(web3.BufferEncoding.base64);

    // 签名并发送交易
    final txResult = await _adapter.signAndSendTransactions(transactions: [serializedTx]);

    // 确认交易
    if (txResult.signatures.isNotEmpty) {
      await _connection.confirmTransaction(txResult.signatures.first);
    }
  } catch (e) {
    print('转账失败:$e');
  }
}

内容的提问来源于stack exchange,提问作者Wilfred Almeida

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 15:14:53