Quick Start

Install

npm i @bsv/sdk

We're using node.js and npm on a local machine, once you're ready to start, initialize a project with npm init -y and install the BSV Blockchain official SDK.

Build Your First Transaction

To create your first transcation you need to send some BSV into a locking script you control. Let's set up our local node.js environment with a key we can use.

// createKey.js
const { PrivateKey } = require('@bsv/sdk')
const { readFile, writeFile, chmod } = require('fs/promises')
const crypto = require('crypto')
global.self = { crypto }

async function createKey() {
    try {
        const WIF = await readFile('.wif')
        const key = PrivateKey.fromWif(WIF.toString())
        console.error('You already have a key file, delete .wif manually if you know what you\'re doing.')
        console.log({ address: key.toAddress() })
    } catch (error) {
        const key = PrivateKey.fromRandom()
        const WIF = key.toWif()
        await writeFile('.wif', WIF)
        await chmod('.wif', 0o400)
        console.log({ address: key.toAddress() })
    }
}

createKey()

Run the above code by copying it into createKey.js and running node createKey.js

Now you should get something in your console which looks like this:

{ address: '1E7ZM72qRDSa0rqUhZoMCMb5MAFYFEaKQp' }

To continue developing and testing, this address will require some funding. This can be done by sending BSV to this wallet, and due the low cost of transactions only a few satoshis will suffice ($0.01 equivalent is recommended). This way, you also ensure that you're not affected if you would lose access to the keys.

If you don't have any BSV, you can find out how to buy it here, or ask the BSV community on X or Discord to send you some funding.

Once you've sent an initial funding transaction to this address, grab the whole transaction from Whats On Chain by pasting in the txid to the search box.

Once mined, a green button which says "Raw Tx" will be visible, which allows you to download the full transaction bytes as a hex string file. That's going to be our sourceTransaction which will fund the transaction we are going to define with the SDK. Copy the hex string into a file in the working directory called .transactions. The file contents should look something like this:

0100000001270ec3f7d507e2593b02297b57f27e8950a7d1df8247efb8203bb4989ef404f0000000006b483045022100a193f3cf1b65910fcf8535318725947fe3d483b80792a7671ca723276aa1999b022039d478124ce96a8bae0fb8da3ed8eeeb8b300b8810407f6665ce7eee8fdf19cb4121030ca32438b798eda7d8a818f108340a85bf77fefe24850979ac5dd7e15000ee1affffffff0310270000000000001976a914d01b0b702ee90e00944342f97c772a8be83e42a288acbc0b0000000000001976a914bc72926a0f5c078fa666bef3105af7a368a8146a88acb81a0000000000001976a914c4bf2c1f5cbc500c38083ca19b99cefba05e583988ac00000000

You can then construct your first transaction by copying the code below into createTx.js and running node createTx.js.

const { readFile, appendFile } = require('fs/promises')
const { Transaction, PrivateKey, P2PKH } = require('@bsv/sdk')
const crypto = require('crypto')
global.self = { crypto }

async function createTx () {
    const WIF = await readFile('.wif')
    const key = PrivateKey.fromWif(WIF.toString())
    const txsFile = await readFile('.transactions')
    const transactions = txsFile.toString().split('\n').filter(x => !!x)
    const sourceTransaction = Transaction.fromHex(transactions.pop())

    const tx = new Transaction()

    tx.addInput({
        sourceTransaction,
        sourceOutputIndex: 0,
        unlockingScriptTemplate: new P2PKH().unlock(key)
    })

    tx.addOutput({
        change: true,
        lockingScript: new P2PKH().lock(key.toAddress())
    })

    await tx.fee()
    await tx.sign()
    console.log(tx.toHex())

    const response = await tx.broadcast()

    console.log(response)

    // append new transaction
    await appendFile('.transactions', '\n' + tx.toHex())
}

createTx()

You should see a response like this:

01000000016dd14cc825fdd4239bae03cd2f7299a7f31f5a4286eac62c47ded0d5c0cd6738000000006a47304402207ce3bddd233f0b2ad04f25e836e69d699d1ad51bd1fdde3c65dab0f7cc13cd94022015c3fc8409145cb60baa483faead2867ac84149b6005a42c1518eb7a77912ba5412102cc6cf85c531f8a27d0d92662c5326d1ddf2941eb0df5fff1921addd37dfc6303ffffffff0150180000000000001976a91421087d3e223806a8c2bea4a1bdaf629a1a3d7efb88ac00000000
{
    "status": "success",
    "txid": "d9c4369a6beec556bec9c5aa3b09e913e91cf8cf2a8fcfd34a10fa3b33296326",
    "message": "SEEN_ON_NETWORK"
}

Congratulations

You're a BSV Developer.

You can keep running the same script - it will keep appending new transactions to the .transactions file until you run out of funds. BSV is so cheap that this could be a few thousand transactions later.

In the mean time, you can create your own Bitcoin ScriptTemplates by defining your own classes like so:

const { LockingScript, UnlockingScript, OP } = require('@bsv/sdk')

class SumScript {
    lock(sum) {
        const ls = new LockingScript()
        ls.writeOpCode(OP.OP_ADD)
        ls.writeNumber(sum)
        ls.writeOpCode(OP.OP_EQUAL)
        return ls
    }

    unlock(a, b) {
        const sign = async () => {
            const us = new UnlockingScript()
            us.writeNumber(a)
            us.writeNumber(b)
            return us
        }
        return { sign, estimateLength: async () => 6 }
    }
}

To create this output you simply add the class to an output:

tx.addOutput({
    satoshis: 3,
    lockingScript: new SumScript().lock(41)
})

Unlocking it in a future transaction you can simply do:

tx.addInput({
    sourceTransaction,
    sourceOutputIndex: 0,
    unlockingScriptTemplate: new SumScript.unlock(21, 20)
})

To check that the script works you can then run:

await tx.verify('scripts only')

Ask the AI if you want to learn more, or join our discord if you need help from a human. If you want to contribute new ScriptTemplates of your own design there's a repo for that here.

For more guidance from the documentation - jump here.

Guides

Last updated