# 低階 API

低階 API 提供了對整個交易生命週期的細粒度控制。與抽象化細節的[高階 API](./api-reference-transaction-helpers.md)不同，這些方法允許您手動建構、編碼、簽署和傳送交易。這對於進階情境非常理想，例如多重簽署工作流程，其中不同方需要在交易廣播前簽署交易。

此 API 分為四個主要的方法群組，每個群組對應交易生命週期中的一個階段：

1. **編碼**：準備一筆交易並將其序列化為二進位緩衝區。
2. **簽署**：為已編碼的交易新增數位簽名。
3. **多重簽署**：為一筆交易新增多個數位簽名。
4. **傳送**：將已簽署的交易廣播到區塊鏈。


## 編碼交易

編碼是建立交易的第一步。`encode[Type]Tx` 方法會接收核心交易資料（`itx`）並將其包裝在標準交易結構中，新增如 `chainId` 和 `nonce` 等必要細節。結果是一個可供人類讀取的交易物件和一個準備好簽署的二進位緩衝區。

鏈上支援的每種交易類型都有一個對應的 `encode` 方法。您可以透過呼叫 `client.getTxEncodeMethods()` 來獲取完整列表。

### `encode[Type]Tx(payload)`

編碼一筆交易但不進行簽署。

**參數**

<x-field-group>
  <x-field data-name="tx" data-type="object" data-required="true">
    <x-field-desc markdown>交易資料物件。</x-field-desc>
    <x-field data-name="itx" data-type="object" data-required="true" data-desc="特定於交易類型的內部交易物件。"></x-field>
    <x-field data-name="from" data-type="string" data-required="false" data-desc="傳送者地址。若未提供，則從錢包推導得出。"></x-field>
    <x-field data-name="nonce" data-type="number" data-required="false" data-desc="交易 nonce。若未設定，預設為 `Date.now()`。"></x-field>
    <x-field data-name="chainId" data-type="string" data-required="false" data-desc="鏈 ID。若未提供，則從連接的節點獲取。"></x-field>
  </x-field>
  <x-field data-name="wallet" data-type="WalletObject" data-required="true" data-desc="用於推導傳送者地址和公鑰的錢包物件。"></x-field>
  <x-field data-name="delegator" data-type="string" data-required="false" data-desc="委派權限的帳戶地址（如果適用）。"></x-field>
</x-field-group>

**回傳值**

<x-field data-name="Promise<object>" data-type="Promise<object>" data-desc="一個 promise，其解析為包含已編碼交易的物件。">
  <x-field data-name="object" data-type="object" data-desc="可供人類讀取的交易物件。"></x-field>
  <x-field data-name="buffer" data-type="Buffer" data-desc="已序列化的交易二進位緩衝區，可供簽署。"></x-field>
</x-field>

**範例**

```javascript TransferV2Tx icon=logos:javascript
const { encodeTransferV2Tx } = client;
const senderWallet = fromRandom();
const receiverAddress = 'z1...';

const { object, buffer } = await encodeTransferV2Tx({
  tx: {
    itx: {
      to: receiverAddress,
      value: await client.fromTokenToUnit(10), // 轉移 10 個原生代幣
    },
  },
  wallet: senderWallet,
});

console.log('Encoded TX Object:', object);
console.log('Buffer to Sign:', buffer.toString('hex'));
```


## 簽署交易

`sign[Type]Tx` 方法建立在編碼步驟之上，增加了數位簽名。這些方法會編碼交易，然後使用提供的錢包來簽署產生的二進位緩衝區。

您可以透過呼叫 `client.getTxSignMethods()` 來獲取所有可用的簽署方法完整列表。

### `sign[Type]Tx(payload)`

編碼並簽署一筆交易。

**參數**

<x-field-group>
  <x-field data-name="tx" data-type="object" data-required="true" data-desc="交易資料物件，與編碼時相同。"></x-field>
  <x-field data-name="wallet" data-type="WalletObject" data-required="true" data-desc="用於簽署交易的錢包。"></x-field>
  <x-field data-name="delegator" data-type="string" data-required="false" data-desc="委派者地址（如果適用）。"></x-field>
  <x-field data-name="encoding" data-type="string" data-required="false" data-desc="輸出的可選編碼（'base16'、'hex'、'base58'、'base64'）。若省略，則回傳交易物件。"></x-field>
</x-field-group>

**回傳值**

<x-field data-name="Promise<object|string>" data-type="Promise<object|string>" data-desc="一個 promise，其解析為已簽署的交易物件，或在指定 `encoding` 時解析為編碼後的字串。"></x-field>

**範例**

```javascript TransferV2Tx icon=logos:javascript
const { signTransferV2Tx } = client;
const senderWallet = fromRandom();
const receiverAddress = 'z1...';

const signedTx = await signTransferV2Tx({
  tx: {
    itx: {
      to: receiverAddress,
      value: await client.fromTokenToUnit(10),
    },
  },
  wallet: senderWallet,
});

console.log('Signed TX:', signedTx);
```


## 傳送交易

`send[Type]Tx` 方法負責將交易廣播到區塊鏈。如果提供的是未簽署的交易和一個錢包，這些方法可以隱式地執行簽署步驟；或者它們也可以傳送一個已經簽署過的交易。

可透過 `client.getTxSendMethods()` 獲取傳送方法的完整列表。

### `send[Type]Tx(payload)`

簽署（如有必要）並將交易傳送到鏈上。

**參數**

<x-field-group>
  <x-field data-name="tx" data-type="object" data-required="true" data-desc="交易物件。可以是已簽署或未簽署的。"></x-field>
  <x-field data-name="wallet" data-type="WalletObject" data-required="true" data-desc="用於簽署交易的錢包。即使交易已預先簽署，仍需此錢包來識別傳送者。"></x-field>
  <x-field data-name="signature" data-type="string" data-required="false" data-desc="交易的預先計算簽名。若提供此簽名，將不會再次使用錢包進行簽署。"></x-field>
  <x-field data-name="delegator" data-type="string" data-required="false" data-desc="委派者地址（如果適用）。"></x-field>
  <x-field data-name="commit" data-type="boolean" data-default="false" data-required="false" data-desc="是否等待交易被提交到區塊後才完成 promise。"></x-field>
</x-field-group>

**回傳值**

<x-field data-name="Promise<string>" data-type="Promise<string>" data-desc="一個解析為交易雜湊值的 promise。"></x-field>

**範例：自動簽署**

```javascript TransferV2Tx icon=logos:javascript
const { sendTransferV2Tx } = client;
const senderWallet = fromRandom();
const receiverAddress = 'z1...';

// 客戶端將在傳送前使用 senderWallet 簽署此交易。
const txHash = await sendTransferV2Tx({
  tx: {
    itx: {
      to: receiverAddress,
      value: await client.fromTokenToUnit(10),
    },
  },
  wallet: senderWallet,
});

console.log('Transaction sent with hash:', txHash);
```

**範例：傳送預先簽署的交易**

```javascript TransferV2Tx icon=logos:javascript
// 假設 signedTx 來自 sign[Type]Tx 範例
const { sendTransferV2Tx } = client;

const txHash = await sendTransferV2Tx({
  tx: signedTx, // 傳入整個已簽署的交易物件
  wallet: senderWallet,
});

console.log('Pre-signed transaction sent with hash:', txHash);
```


## 多重簽署交易

對於需要多個簽名（如原子交換）的工作流程，會使用 `multiSign[Type]Tx` 方法。此過程涉及一方先簽署交易（使用標準的 `sign[Type]Tx` 方法），然後後續的參與方使用對應的 `multiSign[Type]Tx` 方法新增他們的簽名。

您可以透過 `client.getTxMultiSignMethods()` 獲取支援多重簽名的交易列表。

### `multiSign[Type]Tx(payload)`

為一個已經有一個或多個簽名的交易新增一個簽名。

**參數**

<x-field-group>
  <x-field data-name="tx" data-type="object" data-required="true" data-desc="交易物件，應已包含至少一個簽名。"></x-field>
  <x-field data-name="wallet" data-type="WalletObject" data-required="true" data-desc="當前簽署者的錢包。"></x-field>
  <x-field data-name="delegator" data-type="string" data-required="false" data-desc="當前簽署者的委派者地址（如果適用）。"></x-field>
  <x-field data-name="data" data-type="any" data-required="false" data-desc="可隨簽名包含的選用資料。"></x-field>
  <x-field data-name="encoding" data-type="string" data-required="false" data-desc="輸出的可選編碼（'base16'、'hex'、'base58'、'base64'）。"></x-field>
</x-field-group>

**回傳值**

<x-field data-name="Promise<object|string>" data-type="Promise<object|string>" data-desc="一個 promise，其解析為已新增新簽名的交易物件。"></x-field>

**範例：原子交換 (`ExchangeV2Tx`)**

```javascript ExchangeV2Tx icon=logos:javascript
// 兩方的錢包
const aliceWallet = fromRandom();
const bobWallet = fromRandom();

// 1. Alice 準備並簽署初始交換交易
const exchangeTx = {
  itx: {
    to: bobWallet.address,
    sender: {
      value: await client.fromTokenToUnit(10), // Alice 提供 10 個代幣
    },
    receiver: {
      value: await client.fromTokenToUnit(5), // Alice 要求 5 個代幣
    },
  },
};

const signedByAlice = await client.signExchangeV2Tx({
  tx: exchangeTx,
  wallet: aliceWallet,
});

// 2. Alice 將 `signedByAlice` 傳送給 Bob。Bob 加入他的簽名。
const signedByBoth = await client.multiSignExchangeV2Tx({
  tx: signedByAlice,
  wallet: bobWallet,
});

// 3. Bob 將 `signedByBoth` 傳回給 Alice。Alice 傳送最終的交易。
const txHash = await client.sendExchangeV2Tx({
  tx: signedByBoth,
  wallet: aliceWallet, // 使用傳送者錢包來提交
});

console.log('Atomic swap transaction sent:', txHash);
```
