New versions of the Qredo API and Signing Agent are now available! To get started, just contact us here.
Qredo Logo

Qredo API

Code examples

Overview

In this section you'll find code samples for onboarding with the Qredo API, which are used in Get started and other tutorials.

JavaScript examples

Get an authentication token

Before running the code, do the following:

  1. Install Node.js and crypto.js.

  2. Add these dependencies to your package.json config file:

    "dependencies": {
        "crypto-js": "^4.1.1"        
    }
    
  3. Make adjustments in the code:

    • apiKeyID, apiSecret: Specify your API key and secret.
    • workspaceID: Specify your Workspace ID.

Now you can use the example:

// include the crypto-js library
const CryptoJS = require("crypto-js")

// specify your API key, secret, and workspace ID
// for production usage, please secure and retrieve your API secret through a key management solution
let apiKeyID = "YOUR_API_KEY"
let apiSecret = "YOUR_API_SECRET"
let workspaceID = "YOUR_WORKSPACE_ID"

// get the current timestamp
let timestamp = String(Math.floor(Date.now() / 1000))

// set the method and URL of the request for getting the auth token
let method = "GET"
let url = `https://api-v2.qredo.network/api/v2/workspaces/${workspaceID}/token`

// create a message using the timestamp, method, and URL
let message = `${timestamp}${method}${url}`

// decode the API secret and use it to HMAC sign the message    
let buff = Buffer.from(apiSecret, "base64")
let secret = buff.toString("ascii")
let hmac = CryptoJS.HmacSHA256(message, secret)

// create a signature: base64 encode the signed message
let sig = CryptoJS.enc.Base64.stringify(hmac)
  .replace(/\+/g, "-")
  .replace(/\//g, "_")
  .replace(/=+$/, "")

// set headers for the request
let  headers = {
  "qredo-api-key": apiKeyID, // the API key
  "qredo-api-timestamp": timestamp, // the timestamp
  "qredo-api-signature": sig // the signature
}

// run the request with the required headers and get the token
fetch(url, {method, headers})
  .then(response => response.text())
  .then(text => console.log(text))

Generate BLS & EC keys

Before running the code, do the following:

  1. Install Node.js and crypto.js.
  2. Add these dependencies to your package.json config file:
"dependencies": {
    "crypto-js": "^4.1.1",
    "milagro-crypto-js": "github:apache/incubator-milagro-crypto-js",
    "secp256k1": "^5.0.0"
}

Now you can use the example:

// include the required modules
const crypto = require("crypto")
const milagro = require('milagro-crypto-js')
const bls381 = new milagro("BLS381")
const secp256k1 = require('secp256k1');

// a class for computing sha256 hashes
class Sha256 {
    async hash(data) {
        const result = await this.#getSubtle().digest('SHA-256', data)
        return new Uint8Array(result)
    }
    
    #getSubtle() {
        if (globalThis.window && globalThis.window.crypto) {
            return globalThis.window.crypto.subtle
        } else if (globalThis && globalThis.crypto) {
            return globalThis.crypto.subtle
        } else {
            return crypto.subtle
        }
    }
}

// a class for converting hex data
class Hex {
    hexToBytes(hex) {
        for (var bytes = [], c = 0; c < hex.length; c += 2)
            bytes.push(parseInt(hex.substr(c, 2), 16))
        return new Uint8Array(bytes)
    }

    bytesToString(bytes) {
        return String.fromCharCode(...bytes)
    }

    bytesToHex(bytes) {
        return [...new Uint8Array (bytes)]
        .map (b => b.toString (16).padStart (2, "0"))
        .join ("");    
    }
}

// a class for generating and using BLS keys
class BLS {
    #sha256 = undefined

    constructor() {
        this.#sha256 = new Sha256()
    }
    
    // generate a BLS private/public key pair
    async generateKey(seed) {
        const seed_array = new Uint8Array(seed)
        const hash = await this.#sha256.hash(seed_array)

        const rng = new bls381.RAND();
        rng.clean();
        rng.seed(seed.length, hash)

        let sk = [];
        let pk = [];

        bls381.BLS.KeyPairGenerate(rng, sk, pk);

        return {
            publicKey: pk,
            privateKey: sk
        }
    }

    // use a BLS private key to create a signature
    sign(data, private_key) {
        let sig = []

        bls381.BLS.sign(sig, data, private_key)

        return bls381.BLS.bytestostring(sig)
    }
}

// a class for generating EC keys
class EC {
    #sha256 = undefined
    #hex = undefined

    constructor() {
        this.#sha256 = new Sha256()
        this.#hex = new Hex()
    }

    // generate a BLS private/public key pair
    async generateKey(seed) {
        var ecdsa_x = [],
            ecdsa_y = []

        function hashfn(x, y) {
            ecdsa_x = x
            ecdsa_y = y

            const pubKey = new Uint8Array(33)
            pubKey[0] = (y[31] & 1) === 0 ? 0x02 : 0x03
            pubKey.set(x, 1)
            return pubKey
        }

        const hashed_seed = new Uint8Array(await this.#sha256.hash(new Uint8Array(seed)))
        const priv_key = new Uint8Array(await this.#sha256.hash(new Uint8Array(hashed_seed)))
        let pub_key = secp256k1.publicKeyCreate(priv_key)

        secp256k1.ecdh(pub_key, priv_key, {
            hashfn
        }, Buffer.alloc(33))
        pub_key = "04" + this.#hex.bytesToHex(ecdsa_x) + this.#hex.bytesToHex(ecdsa_y)

        return {
            publicKey: pub_key,
            privateKey: priv_key
        }
    }
}

// a function for base64 encoding
function base64Encode(buffer) {
    return btoa(Array.from(new Uint8Array(buffer), b => String.fromCharCode(b)).join(''))
}

// a function for generating BLS and EC keys
async function generateKeys() {

  const hex = new Hex()
  const bls = new BLS()
  const ec = new EC()

  // generate a seed for private keys
  const seed = crypto.randomBytes(48)

  // generate BLS and EC keys from the seed
  const blsKey = await bls.generateKey(seed)
  const ecKey = await ec.generateKey(seed)

  // extract public keys
  let blsPubKey = base64Encode(blsKey.publicKey)
  let ecPubKey = base64Encode(hex.hexToBytes(ecKey.publicKey))

  // build a request body for registering the public keys
  let body = {
    "blsPublicKey": blsPubKey,
    "ecPublicKey": ecPubKey
  }
  
  // print the private BLS key and the request body
  console.log("BLS KEYS – store privateKey!")
  console.log(blsKey)
  console.log("REQUEST BODY")
  console.log(JSON.stringify(body, null, 2))
}

// generate keys
generateKeys()

Create a signature

Before running the code, do the following:

  1. Install Node.js and crypto.js.

  2. Add these dependencies to your package.json config file:

    "dependencies": {
        "crypto-js": "^4.1.1",
        "milagro-crypto-js": "github:apache/incubator-milagro-crypto-js",
        "secp256k1": "^5.0.0"
    }
    
  3. Make adjustments in the code:

    • privateKey: Specify your BLS private key.
    • messages: Specify the message(s) to sign.

Now you can use the example:

// include the required modules
const crypto = require("crypto")
const milagro = require('milagro-crypto-js')
const bls381 = new milagro("BLS381")

// a class for computing sha256 hashes
class Sha256 {
    async hash(data) {
        const result = await this.#getSubtle().digest('SHA-256', data)
        return new Uint8Array(result)
    }
    
    #getSubtle() {
        if (globalThis.window && globalThis.window.crypto) {
            return globalThis.window.crypto.subtle
        } else if (globalThis && globalThis.crypto) {
            return globalThis.crypto.subtle
        } else {
            return crypto.subtle
        }
    }
}

// a class for converting hex data
class Hex {
    hexToBytes(hex) {
        for (var bytes = [], c = 0; c < hex.length; c += 2)
            bytes.push(parseInt(hex.substr(c, 2), 16))
        return new Uint8Array(bytes)
    }

    bytesToString(bytes) {
        return String.fromCharCode(...bytes)
    }

    bytesToHex(bytes) {
        return [...new Uint8Array (bytes)]
        .map (b => b.toString (16).padStart (2, "0"))
        .join ("");    
    }
}

// a class for generating and using BLS keys
class BLS {
    #sha256 = undefined

    constructor() {
        this.#sha256 = new Sha256()
    }
    
    // generate a BLS private/public key pair
    async generateKey(seed) {
        const seed_array = new Uint8Array(seed)
        const hash = await this.#sha256.hash(seed_array)

        const rng = new bls381.RAND();
        rng.clean();
        rng.seed(seed.length, hash)

        let sk = [];
        let pk = [];

        bls381.BLS.KeyPairGenerate(rng, sk, pk);

        return {
            publicKey: pk,
            privateKey: sk
        }
    }

    // use a BLS private key to create a signature
    sign(data, private_key) {
        let sig = []

        bls381.BLS.sign(sig, data, private_key)

        return bls381.BLS.bytestostring(sig)
    }
}

// a function for creating signatures
function createSignatures() {

  const hex = new Hex()
  const bls = new BLS()
  
  // specify your BLS private key 
  let privateKey = YOUR_BLS_PRIVATE_KEY

  // specify the messages to sign
  let messages = [
    "YOUR_MESSAGE"
  ]

  // convert and sign the messages
  let sigs = []
  for (let i in messages) {
      let msg = hex.bytesToString(hex.hexToBytes(messages[i]))
      let sig = bls.sign(msg, privateKey)            
      sigs.push(sig)
  }

  return sigs     
}

// create a signature
console.log(createSignatures())

Postman examples

Get an authentication token

To get an authentication token in Postman, take these steps:

  1. Create a collection and add the following collection variables:

    • apiKey and apiSecret: Specify your API key and Secret.
    • workspaceID: Specify your Workspace ID.
  2. Create a GET request with the following URL:

    GET https://api-v2.qredo.network/api/v2/workspaces/{{workspaceID}}/token
    
  3. Paste the code below in the Pre-request Script tab under your request URL.

  4. Click Send to make the call.

You can also follow this video tutorial:

Here is the script code:

// specify your API key and secret
// for production usage, please secure and retrieve your API secret through a key management solution 
let apiKey = pm.variables.get("apiKey")
let apiSecret = pm.variables.get("apiSecret")

// get the current timestamp
let timestamp = String(Math.floor(Date.now() / 1000))

// get the method and URL of the request
let method = pm.request.method
let url = pm.request.url.toString()
let resolvedUrl = pm.variables.replaceIn(url)

// create a message using the timestamp, method, and URL
let message = `${timestamp}${method}${resolvedUrl}`

// decode the API secret and use it to HMAC sign the message
let buff = Buffer.from(apiSecret, "base64")
let secret = buff.toString("ascii")
let hmac = CryptoJS.HmacSHA256(message, secret)

// create a signature: base64 encode the signed message
let sig = CryptoJS.enc.Base64.stringify(hmac)
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=+$/, "")

// add headers
pm.request.headers.add({key: "qredo-api-key", value: apiKey})
pm.request.headers.add({key: "qredo-api-timestamp", value: timestamp})
pm.request.headers.add({key: "qredo-api-signature", value: sig})
Previous
Security best practices