跳到主要內容

交易支付

此範例展示了 DID Connect 一個常見且強大的使用案例:要求使用者簽署並提交一筆鏈上交易以進行支付。此模式非常適合電子商務結帳、服務訂閱、內容購買或任何需要轉移代幣或資產的場景。

我們將使用 signature 聲明來要求使用者簽署一筆預先建構好的代幣轉帳交易。

運作原理

此過程涉及應用程式建立一筆交易,然後要求使用者的錢包進行簽署。這確保了使用者對其資產保有完全的控制權,且應用程式絕不會經手使用者的私鑰。

以下是典型的流程:

  1. 交易建立

    應用程式的後端確定支付的詳細資訊(例如,金額、代幣類型、收款人地址),並使用像 @ocap/client 這樣的函式庫來建構一筆原始交易。

  2. 聲明請求

    應用程式啟動一個 DID Connect 會話,並向使用者請求一個 signature 聲明。原始交易資料被嵌入到此聲明請求中。

  3. 使用者批准

    使用者的 DID 錢包接收到請求,解碼交易,並顯示一個人類可讀的摘要(例如,「支付 100 ABC 代幣給『我的應用』」)。然後使用者可以選擇用他們的私鑰批准並簽署該交易。

  4. 回應處理

    一旦批准,錢包會將已簽署的交易傳回給應用程式。應用程式接著可以驗證簽名並將交易廣播到區塊鏈以完成支付。

整個過程是安全且非託管的,提供無縫的 Web3 支付體驗。

程式碼範例

讓我們建構一個範例,其中我們的應用程式向使用者請求支付 100 個原生代幣。

1. 設定 WalletAuthenticator

首先,使用您的應用程式詳細資訊和鏈資訊來設定 WalletAuthenticator。

Transaction Payment Authenticator Setup

javascript
import { WalletAuthenticator } from '@did-connect/lib';
import { fromRandom } from '@ocap/wallet';

// Your application's wallet
const appWallet = fromRandom();

const auth = new WalletAuthenticator({
  wallet: appWallet,
  baseUrl: 'https://yourapp.com',
  appInfo: {
    name: 'My Awesome App',
    description: 'An app that requires payment.',
    icon: 'https://yourapp.com/logo.png',
    link: 'https://yourapp.com',
  },
  chainInfo: {
    host: 'https://beta.abtnetwork.io/api',
    id: 'beta',
  },
});

2. 定義簽名聲明

接下來,定義要請求的 claims。我們將使用單一的 signature 聲明。在聲明函數內部,我們將建構交易。

這需要使用 @ocap/client 來對交易進行編碼,並使用 @ocap/util 將產生的緩衝區轉換為 Base58 字串,這是錢包所期望的格式。

Create Transaction Signature Claim

javascript
import Client from '@ocap/client';
import { fromPublicKey } from '@ocap/wallet';
import { toBase58 } from '@ocap/util';

const client = new Client('https://beta.abtnetwork.io/api');
const NATIVE_TOKEN_ADDRESS = 'z35nB2SA6xxBuoaiuUXUw6Gah2SNU3UzqdgEt'; // Native token on ArcBlock chains

// Define the claims for an Express.js handler
const claims = {
  signature: async ({ userDid, userPk }) => {
    // 1. Construct the transaction object
    const txPayload = {
      tx: {
        from: userDid,
        pk: userPk,
        itx: {
          to: appWallet.address, // Send payment to the app's address
          tokens: [
            {
              address: NATIVE_TOKEN_ADDRESS,
              value: '100000000000000000000', // 100 tokens (with 18 decimals)
            },
          ],
        },
      },
      wallet: fromPublicKey(userPk),
    };

    // 2. Encode the transaction into a buffer
    const encoded = await client.encodeTransferV2Tx(txPayload);

    // 3. Return the claim object for the wallet
    return {
      type: 'fg:t:transaction', // Specifies a native framework transaction
      data: toBase58(encoded.buffer), // The transaction data must be Base58 encoded
      description: '簽署此交易以完成您的 100 代幣支付。',
      // The requirement object is used by the wallet to display a clear summary to the user
      requirement: {
        tokens: [
          {
            address: NATIVE_TOKEN_ADDRESS,
            value: '100000000000000000000',
          },
        ],
      },
    };
  },
};

// In your route handler, you would then generate the request URL
// const signed = await auth.sign({ context: { userDid, userPk }, claims });

在此範例中:

  • userDid 和 userPk 是在使用者連接錢包後,由 DID Connect 會話上下文提供的。
  • 我們使用 client.encodeTransferV2Tx 來建立一個標準的代幣轉帳交易。
  • to 地址是我們應用程式的錢包地址,資金將被發送到此處。
  • requirement 物件對於良好的使用者體驗至關重要。它允許錢包解析交易並向使用者準確顯示他們被要求支付的內容,從而防止他們簽署惡意或不正確的交易。

3. 處理錢包的回應

在使用者於錢包中簽署交易後,您的應用程式的回呼端點將會收到已簽署的交易資料。然後您可以再次使用像 @ocap/client 這樣的函式庫將其廣播到區塊鏈。

有關設定處理器以處理錢包回應的完整指南,請參閱 處理錢包回應 指南。

此範例涵蓋了一個基礎的 Web3 互動。透過利用 signature 聲明,您可以安全地請求支付和其他鏈上操作,而無需託管使用者的金鑰。

要查看聲明的另一個實際應用,請查看 NFT 門控訪問 範例。