Signature Algorithm

General Steps for Signature Generation

All requests should include a signature named Sign in the request header. You should sign all the request parameters with ECDSA algorithm, the private key used for signing corresponds to the wallet address registered on BitPocket OpenAPI platform.

[!IMPORTANT] The private key of the wallet is sensitive information, NEVER EXPOSE THE WALLET PRIVATE KEY TO ANY THIRD PARTIES.

Follow these steps to perform the signature generation:

Step 1

Collect all parameters from the following sources into a set M:

  • API-Key, Timestamp, and Nonce parameters from the Header
  • All Query parameters
  • All Body parameters

Sort the non-empty parameters in set M by their parameter names in ascending ASCII order (lexicographical order). Then concatenate them into a string stringA using URL key-value pair format (i.e., key1=value1&key2=value2...).

Important Rules:

  • Parameter names must be sorted in ascending ASCII order (lexicographical order)
  • Parameters with empty values are not included in the signature
  • Parameter names are case-sensitive

Step 2

Sign stringA with the private key privateKeyByteArray (a 32-byte byte array) of the wallet address uploaded to the platform. This produces a signature byte array signByteArray (a 64-byte byte array). Convert signByteArray to a base64 encoded string SignStr and place it in the Sign parameter of the Header.

Sign Example

Following is an example of signing a message with ECDSA algorithm using Node.js. You can also refer to the Java Demo for signing a message with ECDSA algorithm using Java.

const { networks } = require('bitcoinjs-lib');
const ecc = require('tiny-secp256k1');
const {ECPairFactory } =require('ecpair')
const bitcoinMessage = require('bitcoinjs-message')
const {mnemonicToSeedSync }  = require('bip39')
const { BIP32Factory} = require( 'bip32')
const bip32 = BIP32Factory(ecc);
const ecpair = ECPairFactory(ecc)

// sign message with ECDSA algorithm
//networks.bitcoin/networks.regtest/networks.testnet
const network = networks.bitcoin
const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
const coinType =  network === networks.bitcoin ? 0:1
const message = "hello world~"

//we'll use the private key generated with the following path to sign the message
let path = "m/86'/" + coinType +"'/0'/0/0"

//generate see from mnemonic
const seed = mnemonicToSeedSync(mnemonic)
const child = bip32.fromSeed(seed, network).derivePath(path)

//get key pair
const keyPair = ecpair.fromPrivateKey(child.privateKey, {network});

//sign the message with keypair
const signature = bitcoinMessage.sign(message, keyPair.privateKey, keyPair.compressed);

//base64 encode
const signedBase64 = signature.toString('base64')

console.log('signed string is:', signedBase64)

//signed result with networks.regtest & networks.testnet: 
//H3AWawcJzgWu41bIWDqGdnJpscJbdSQw+1OrAzs4ouFGGOvXHee8qrFXy9WBQlpDlgTTXFGYTew0jcmOvvEdCrs=

//signed result with networks.bitcoin:
//IPPpwB7TGuH+cjiF9YTG8hnSD2LYIUQLWSlyv0FcRaHkAou4jJ7hU2E02s3l3IF//4ZzXd37xeoP70/fOTAT11s=

Java Demo

results matching ""

    No results matching ""