swap-bch-js
swap-bch-js is a JavaScript Library for building transactions for the Signal, Watch, and Pay (SWaP) Protocol. The library is a fork of bitcoinfilesjs and also supports the Bitcoin Files Protocol (BFP). Methods for uploading and downloading files are provided per the BFP specification. For convenience, SLP-SDK (Bitbox) functionality has been built into the library.
SWaP Protocol Reference
This library is reference code for the Signal, Watch, and Pay (SWaP) Protocol. The end-to-end examples in this repository contain the full code necessary for the SWaP Signal and Payment message classes and types described in the protocol specification. Please reference these examples when building or testing your own applications.
Installation
For node.js
npm install swap-bch-js
Example Signal Downloads
const SLPSDK = require('slp-sdk')
const bitbox = new SLPSDK({ restURL: 'https://rest.bitcoin.com/v2/' })
const swap = require('swap-bch-js')
const Swp = swap.swp;
const swp = new Swp(bitbox);
fs = require('fs');
let metadata;
(async function(){
try {
let exchangeMetadata = await swp.bitdb.getSignalMetadata(1, "3bebd6590b0870e13a65fbb6a59e891ec06cd2f1c162f2b3c034d8b1e1ae88b9");
console.log('exchange metadata: ', exchangeMetadata);
let exchangeByTokenMetadata = await swp.bitdb.getSignalMetadata(1, null, "c4b0d62156b3fa5c8f3436079b5394f7edc1bef5dc1cd2f9d0c4d46f82cca479");
console.log('exchange by token metadata: ', exchangeByTokenMetadata);
let escrowMetadata = await swp.bitdb.getSignalMetadata(2, "d7cbeaab6d02769464f9c71a6efd8cd2682d728d7e5de3ac278372b1b81c9d83");
console.log('escrow metadata: ', escrowMetadata);
let escrowByOracleMetadata = await swp.bitdb.getSignalMetadata(2, null, "974b3bf766b36434a21fe6f8782d8056f932d33ae401e92cf31a88204a21ea3e");
console.log('escrow by oracle metadata: ', escrowByOracleMetadata);
let crowdfundMetadata = await swp.bitdb.getSignalMetadata(3, "565c84990aacfbd006d4ed2ee14bfb0f3bb27a84a6c9adcabccb6fb8e17e64c5");
console.log('crowdfund metadata: ', crowdfundMetadata);
console.log('outputs to crowdfund', crowdfundMetadata.outputs)
} catch (e) {
console.error(e)
}
})();
Example Exchange Offer Signal Upload
Full exchange end-to-end example in examples directory
const SLPSDK = require('slp-sdk')
const bitbox = new SLPSDK({ restURL: 'https://rest.bitcoin.com/v2/' })
const swap = require('swap-bch-js')
const Swp = swap.swp;
const swp = new Swp(bitbox);
const network = swp.network;
(async function(){
try {
let fundingWif = 'L3TS24MB1RhG3tcod2se7ik59WQRsUFkDiG8S2QNaPsapby7DmjR'
let fundingEcpair = bitbox.ECPair.fromWIF(fundingWif)
let fundingAddress = bitbox.ECPair.toCashAddress(fundingEcpair)
let msgType = 1
const fileSize = 0
let config = {
tokenId: 'c4b0d62156b3fa5c8f3436079b5394f7edc1bef5dc1cd2f9d0c4d46f82cca479',
buyOrSell: 'BUY',
rate: 280000,
reserve: false,
exactUtxoTxId: '9a1a5be139ee12e487ea34e5ff62d90995946f876227be056d5d088a79a302ee',
exactUtxoIndex: 1,
minSatsToExchange: 140000
}
let uploadCost = Swp.calculateFileUploadCost(fileSize, config);
console.log('upload cost: ', uploadCost);
let fundingUtxos = await network.getUtxos(fundingAddress, false);
let availableSats = fundingUtxos.reduce(function (accumulator, currentValue) {
return accumulator + currentValue.satoshis
}, 0)
console.log('got funding Utxos')
console.log('available satoshis:', availableSats)
if(availableSats < uploadCost)
throw new Error('Insufficient funds in '+fundingAddress+' to send offer signal. Needed: '+uploadCost
let fileId = await swp.uploadSignal(msgType, fundingUtxos, fundingAddress, fundingWif, config);
console.log('Offer Signal Id: ', fileId);
} catch (e) {
console.log(e)
}
})();
Example Escrow Offer Signal Upload
Full escrow end-to-end example in examples directory
const BITBOXSDK = require('bitbox-sdk')
const bitbox = new BITBOXSDK.BITBOX({ restURL: 'https://rest.bitcoin.com/v2/' });
const swap = require('swap-bch-js')
const Swp = swap.swp;
const swp = new Swp(bitbox);
const network = swp.network;
(async function(){
try {
let fundingWif = 'L3TS24MB1RhG3tcod2se7ik59WQRsUFkDiG8S2QNaPsapby7DmjR'
let fundingEcpair = bitbox.ECPair.fromWIF(fundingWif)
let fundingAddress = bitbox.ECPair.toCashAddress(fundingEcpair)
let msgType = 2
const fileSize = 0
let config = {
oracleBfp: 'ee10994d61ae1318d6298975283509e44eeace497d30765cf1c7bc48a7410d2f',
contractTermsIndex: 0,
contractPartyIndex: 1,
compilerId: 'jeton',
compilerVersion: 'e01',
pubKey: '025d8a5fb65c9171946a17b791279862d85e7fe88ea194f85ff95de15388c7e666',
exactUtxoTxId: '3bebd6590b0870e13a65fbb6a59e891ec06cd2f1c162f2b3c034d8b1e1ae88b9',
exactUtxoIndex: 1,
appendedScriptPubKey: '76a91410c1db6f3076e020974ef540199e7ae4b76fbafa88ac',
appendedSats: 2000
}
let uploadCost = Swp.calculateFileUploadCost(fileSize, config);
console.log('upload cost: ', uploadCost);
let fundingUtxos = await network.getUtxos(fundingAddress, false);
let availableSats = fundingUtxos.reduce(function (accumulator, currentValue) {
return accumulator + currentValue.satoshis
}, 0)
console.log('got funding Utxos')
console.log('available satoshis:', availableSats)
if(availableSats < uploadCost)
throw new Error('Insufficient funds in '+fundingAddress+' to send offer signal. Needed: '+uploadCost)
let fileId = await swp.uploadSignal(msgType, fundingUtxos, fundingAddress, fundingWif, config);
console.log('Offer Signal Id: ', fileId);
} catch (e) {
console.error(e)
}
})();
Example Crowdfund Offer Signal Upload
Full threshold crowdfunding end-to-end example in examples directory
const SLPSDK = require('slp-sdk')
const bitbox = new SLPSDK({ restURL: 'https://rest.bitcoin.com/v2/' })
const swap = require('swap-bch-js')
const Swp = swap.swp;
const swp = new Swp(bitbox);
const network = swp.network;
const utils = swap.utils
function outputArrayToBuffer (outputObject) {
let bufArray = []
}
(async function(){
try {
let fundingWif = 'L3TS24MB1RhG3tcod2se7ik59WQRsUFkDiG8S2QNaPsapby7DmjR'
let fundingEcpair = bitbox.ECPair.fromWIF(fundingWif)
let fundingAddress = bitbox.ECPair.toCashAddress(fundingEcpair)
let msgType = 3
let outputArray= [
{
script: Buffer.from('76a914da74026d67264c0acfede38e8302704ef7d8cfb288ac', 'hex'),
value: 100000
},
{
script: Buffer.from('76a914ac656e2dd5378ca9c45fd5cd44aa7da87c7bfa8288ac', 'hex'),
value: 150000
}
]
let outputsBuf = utils.outputsArrayToBuffer(outputArray)
const fileSize = 0
let config = {
msgClass: 1,
msgType: msgType,
campaignUri: 'https://swapcrowdfund.com/somecampaign',
outputs: outputsBuf,
}
let uploadCost = Swp.calculateFileUploadCost(fileSize, config);
console.log('upload cost: ', uploadCost);
let fundingUtxos = await network.getUtxos(fundingAddress, false);
let availableSats = fundingUtxos.reduce(function (accumulator, currentValue) {
return accumulator + currentValue.satoshis
}, 0)
console.log('got funding Utxos')
console.log('available satoshis:', availableSats)
if(availableSats < uploadCost)
throw new Error('Insufficient funds in '+fundingAddress+' to send offer signal. Needed: '+uploadCost)
let fileId = await swp.uploadSignal(msgType, fundingUtxos, fundingAddress, fundingWif, config);
console.log('fileId: ', fileId);
} catch (e) {
console.error(e)
}
})();