Creating Your First BSV Transaction with createAction(): A Beginner's Guide

createAction() is the core method in the BSV SDK, allowing applications to describe transaction actions via a high-level interface while the wallet handles signing, fees, and broadcasting. This article explains its principles, parameters, and practical usage.

Ethan Lin

Ethan Lin

technical_editor

Published Jun 15, 20264 min read

In a Nutshell

createAction() is a high-level interface for creating a transaction action through a wallet: you tell the wallet which inputs and outputs to create, and the wallet takes care of signing, fees, change, and processing.

It is the most important method for beginners writing their first BSV transaction because it wraps "transaction construction" into an application action.

What Is an Action?

In the SDK context, an action can be thought of as a meaningful wallet operation. It's not just "transfer"; it can also be publishing data, creating a spendable output, spending an existing output, or writing state for an application protocol.

In other words, the application doesn't directly say to the wallet: "Please give me raw transaction bytes signed with a private key." Instead, it says: "I want to create an action: description is this, outputs are these, inputs to spend are these, processing options are these." The wallet then creates a transaction based on this information.

Key Parameters of createAction

In the official wallet reference, createAction() accepts CreateActionArgs. The core fields can be simplified as:

TypeScript
1{
2 description: string
3 inputBEEF?: string
4 inputs?: Array<...>
5 outputs?: Array<...>
6 lockTime?: number
7 version?: number
8 labels?: string[]
9 options?: {
10 signAndProcess?: boolean
11 acceptDelayedBroadcast?: boolean
12 returnTXIDOnly?: boolean
13 noSend?: boolean
14 sendWith?: string[]
15 randomizeOutputs?: boolean
16 }
17}

For beginners, the most commonly used are description and outputs.

  • description: A description of the operation for the user and wallet. Avoid meaningless strings; a real application should inform the user what the operation is about.
  • outputs: Describe the new outputs this transaction will create. Each output typically includes an amount, locking script, and output description.
  • inputs: Specify which existing outputs to spend. For a simple first transaction, you can often let the wallet automatically select inputs.
  • options: Control whether to sign and process, return only txid, not broadcast, etc. Beginners should not modify these arbitrarily until understanding the default flow.

Creating an OP_RETURN Data Output

The official first transaction tutorial uses Script.fromASM() to construct an OP_RETURN data output. The following is an example of the approach:

TypeScript
1import { WalletClient, Script } from '@bsv/sdk'
2
3async function createSimpleTransaction() {
4 const wallet = new WalletClient('auto', 'localhost')
5
6 const response = await wallet.createAction({
7 description: 'My first BSV transaction',
8 outputs: [{
9 satoshis: 100,
10 lockingScript: Script
11 .fromASM(`OP_RETURN ${Buffer.from('Hello BSV!').toString('hex')}`)
12 .toHex(),
13 outputDescription: 'My first data output'
14 }]
15 })
16
17 console.log(response)
18 return response
19}
20
21createSimpleTransaction().catch(console.error)

Key points in this code:

  • WalletClient handles the connection to the wallet.
  • Script.fromASM() converts a human-readable ASM script into a script object usable by the SDK.
  • Buffer.from('Hello BSV!').toString('hex') encodes text into hexadecimal data.
  • lockingScript is the script on the output. Here, OP_RETURN indicates it's a data output, not a regular payment address output.
  • The result from createAction() may include a txid and possibly more transaction processing information, depending on the wallet and options.

What createAction Does for You

  • If you don't manually specify inputs, the wallet will attempt to select sufficient inputs from available UTXOs.
  • If the target output amount plus fee is less than the total input amount, the wallet creates a change output.
  • If signing is required, the wallet uses its own key management system to sign, without handing over private keys to the application.
  • If the default processing flow includes broadcasting, the wallet or related service will attempt to submit the transaction to the network.
  • If processing fails, the application must read the error or status instead of assuming a successful call means the transaction has been accepted by miners.

Position in the BSV Technology Stack

Many user operations in BSV applications can be abstracted as actions.

  • Publishing content can be a data output.
  • Creating a credential can be a data output with protocol fields and signatures.
  • Transferring a token can involve spending the old token UTXO and creating a new token UTXO.
  • Updating business state can be a transaction that records new state.

The value of createAction() is that it allows applications to describe these actions with a unified interface. Underneath, it's still transactions, but the higher layer can speak in business terms.

When Not to Rely Solely on createAction

createAction() is great for first transactions and many wallet-driven applications, but it is not the end of the learning journey.

  • If you need to understand signature hash, manual fees, complex inputs/outputs, transaction chains, batch transactions, or low-level broadcasting, you should move to stage 8 and learn manual transaction construction.
  • If you are building protocol-level tools, wallet backends, or transaction processing services, you cannot stop at the high-level interface.

The right order is: first use createAction() to run a real transaction, then unpack each layer later.

Common Beginner Misconceptions

  • createAction() is not "writing to a database". It creates a Bitcoin transaction action; whether the transaction is accepted depends on the network and miner policies.
  • outputs is not an arbitrary array. The locking script of each output determines whether it can be spent in the future or if it's a data output.
  • description is not a decorative field. Real wallets use it to help users understand what they are authorizing.
  • Automatic signing does not mean no authorization. The wallet can require user confirmation or reject operations based on permission policies.
  • Getting a txid back does not mean you have completed application state management. You still need to consider broadcast status, confirmations, indexing, and subsequent queries.

References

  • First Transaction tutorial: https://bsv-blockchain.github.io/ts-sdk/tutorials/first-transaction/
  • Wallet reference: https://bsv-blockchain.github.io/ts-sdk/reference/wallet/
  • Wallet Integration concept: https://bsv-blockchain.github.io/ts-sdk/concepts/wallet-integration/

Recommended articles