signAssociatedTransaction
Sign parent-child (associated) transactions using the wallet. The wallet constructs child transactions from a source transaction and signs them all together.
Usage
const { txraws } = await Turing.signAssociatedTransaction({
sourceTxraw,
sourceUtxos,
inputs,
outputs,
});Parameters
interface Input {
txId?: string; // Transaction ID (required for source transaction inputs)
script?: string; // Locking script, hex format only
satoshis?: number; // Satoshi value
outputIndex: number; // Output index
scriptSigType:
| "p2pkh"
| "tbc20" // Standard FT transfer unlock
| "tbc20_contract" // Standard FT unlock in contract / swap scenarios
| "tbc20_coin" // Stablecoin transfer unlock (FT.getFTunlock + isCoin)
| "tbc20_coin_contract" // Stablecoin unlock in contract / swap scenarios (FT.getFTunlockSwap + isCoin)
| "other"; // Custom script signature type
unfinishedScriptSig?: string; // For "other" type: custom script template (hex format), with the signature portion replaced by 097369676e6174757265
ftVersion?: 1 | 2 | 3; // FT version for "tbc20_contract" / "tbc20_coin_contract" types
contractTxId?: string; // Contract transaction ID for "tbc20_contract" / "tbc20_coin_contract" types
}
interface Output {
script: string; // Output locking script, hex format only
satoshis: number; // Output satoshi value
}
interface SignAssociatedTransactionRequestData {
sourceTxraw: string; // The source (parent) transaction raw hex
sourceUtxos: Input[]; // UTXOs from the source transaction
inputs?: Input[][]; // 2D array of child transaction inputs
outputs?: Output[][]; // 2D array of child transaction outputs
}| Parameter | Type | Required | Description |
|---|---|---|---|
sourceTxraw | string | Yes | Source transaction raw hex string |
sourceUtxos | Input[] | Yes | Array of UTXOs from the source transaction |
inputs | Input[][] | No | 2D array — each sub-array represents the inputs of a child transaction |
outputs | Output[][] | No | 2D array — each sub-array represents the outputs of a child transaction |
Returns
interface SignAssociatedTransactionResponse {
txraws: string[]; // Assembled transaction hex strings ready for broadcast
}| Field | Type | Description |
|---|---|---|
txraws | string[] | Signed parent-child transactions ready for broadcast |
Error Handling
try {
const { txraws } = await Turing.signAssociatedTransaction({
sourceTxraw,
sourceUtxos,
inputs,
outputs,
});
console.log("Signed transactions:", txraws);
} catch (error) {
console.error("Signing failed:", error);
}Example
FT transfer example with two child transactions:
const sourceUtxos: Input[] = [
{
txId: "",
outputIndex: 0,
satoshis: 500,
script: ftcode,
scriptSigType: "tbc20",
},
{
txId: "",
outputIndex: 2,
satoshis: 10000,
script: p2pkh,
scriptSigType: "p2pkh",
},
];
const inputs: Input[][] = [
[
{ outputIndex: 0, scriptSigType: "tbc20" },
{ outputIndex: 2, scriptSigType: "p2pkh" },
],
[
{ outputIndex: 0, scriptSigType: "tbc20" },
{ outputIndex: 2, scriptSigType: "p2pkh" },
],
];
const outputs: Output[][] = [
[
{
script: ftcode,
satoshis: 500,
},
{
script: fttape,
satoshis: 0,
},
{
script: p2pkh,
satoshis: 8000,
},
],
[
{
script: ftcode,
satoshis: 500,
},
{
script: fttape,
satoshis: 0,
},
{
script: p2pkh,
satoshis: 6000,
},
],
];
const { txraws } = await Turing.signAssociatedTransaction({
sourceTxraw,
sourceUtxos,
inputs,
outputs,
});Stablecoins (tbc20_coin / tbc20_coin_contract)
Stablecoins are a special kind of FT whose unlocking scripts differ from standard FT, so dedicated scriptSigType values are provided:
"tbc20_coin": Stablecoin standard transfer unlock"tbc20_coin_contract": Stablecoin unlock for contract / swap scenarios (also requirescontractTxIdandftVersion)
Child transactions (inputs / outputs)
Just mark the corresponding input's scriptSigType as "tbc20_coin" or "tbc20_coin_contract". All other fields are written exactly the same way as standard FT — you do not need to worry about sequence / nLockTime.
Source transaction (sourceTxraw)
sourceTxraw is a raw transaction the caller assembles themselves. If it contains stablecoin inputs, the caller must satisfy the following two conditions when building it:
- Set the
sequenceof every stablecoin input to0xFFFFFFFE. - Set the transaction's
nLockTimeto the maximumlockTimevalue found in the tape of all spent stablecoin UTXOs.
Reference implementation:
import { Transaction } from "tbc-lib-js";
import { stableCoin } from "tbc-contract";
const tx = new Transaction().from(coinUtxos).from(payUtxo);
// ...addOutput(...)
for (let i = 0; i < coinUtxos.length; i++) {
tx.setInputSequence(i, 0xFFFFFFFE);
}
let lockTimeMax = 0;
for (let i = 0; i < coinUtxos.length; i++) {
const lt = stableCoin.getLockTimeFromTape(
preTXs[i].outputs[coinUtxos[i].outputIndex + 1].script
);
lockTimeMax = Math.max(lockTimeMax, lt);
}
tx.setLockTime(lockTimeMax);
const sourceTxraw = tx.uncheckedSerialize();The corresponding entries in
sourceUtxosmust still be marked as"tbc20_coin"or"tbc20_coin_contract".
Stablecoin example
The parent transaction spends 1 stablecoin UTXO + 1 P2PKH UTXO and produces a new stablecoin UTXO (output 0/1 are code/tape, output 2 is the P2PKH change). The child transaction then spends that newly created stablecoin UTXO:
const sourceUtxos: Input[] = [
{
txId: coinUtxo.txId,
outputIndex: coinUtxo.outputIndex,
satoshis: 500,
script: coinCodeHex,
scriptSigType: "tbc20_coin",
},
{
txId: payUtxo.txId,
outputIndex: payUtxo.outputIndex,
satoshis: 10000,
script: p2pkhHex,
scriptSigType: "p2pkh",
},
];
const inputs: Input[][] = [
[
{ outputIndex: 0, scriptSigType: "tbc20_coin" },
{ outputIndex: 2, scriptSigType: "p2pkh" },
],
];
const outputs: Output[][] = [
[
{ script: newCoinCodeHex, satoshis: 500 },
{ script: newCoinTapeHex, satoshis: 0 },
{ script: p2pkhChangeHex, satoshis: 8000 },
],
];
const { txraws } = await Turing.signAssociatedTransaction({
sourceTxraw,
sourceUtxos,
inputs,
outputs,
});If the stablecoin needs to take the contract / swap path, change scriptSigType to "tbc20_coin_contract" and supply contractTxId and ftVersion:
{
outputIndex: 0,
scriptSigType: "tbc20_coin_contract",
contractTxId: "<contract transaction ID>",
ftVersion: 2,
}Live Example
Live Example
Turing.signAssociatedTransaction()
The active wallet network is Unknown. This method requires TBC. Switch networks and try again.
Includes sample data for preview. Clear it to use your own transaction data.