Skip to content
This repository has been archived by the owner on Mar 5, 2024. It is now read-only.

p2ppsr/babbage-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@babbage/sdk

This package has been deprecated.

To build Babbage apps in Typescript or JavaScript please use:

New Typescript or Javascript NPM Package

New Typescript or Javascript GitHub Repository

Installation

This package has been deprecated.

npm i @babbage/sdk

Please use this package instead.

npm i @babbage/sdk-ts

By Example

There are a few example projects you can check out which implement the Babbage SDK:

  • 🎵Tempo: A platform for creating and sharing music, and empowering artists with micropayments
  • âś…Simple ToDo List: An app that demonstrates the basics of Bitcoin tokenization and identity

Documentation

đź“’ The JavaScript API is documented below the examples, in the API section

The đź“šBabbage Learn website hosts the concepts, guides and reference materials that show you how the SDK works.

Example Usage

Encryption

const { encrypt, decrypt } = require('@babbage/sdk')

// Encrypt and decrypt data using the Babbage SDK
const encryptedData = await encrypt({
  plaintext: Buffer.from('some data'),
  protocolID: [0, 'Hello World'],
  keyID: '1'
})

// The same protocol and key ID is needed for decryption
const decryptedData = await decrypt({
  ciphertext: encryptedData,
  protocolID: [0, 'Hello World'],
  keyID: '1',
  returnType: 'string'
})

Creating and Redeeming Bitcoin tokens

This example also uses PushDrop

const { createAction } = require('@babbage/sdk')
const { create, redeem } = require('pushdrop')

const bitcoinOutputScript = await create({
  fields: [ // The "fields" are the data payload to attach to the token.
    Buffer.from('My First Token'),
    Buffer.from('My name is Ty') // Tokens can represent anything!
  ],
  // The "first token" protocol and key ID can be used to sign and 
  // lock this new Bitcoin PushDrop token.
  protocolID: 'first token',
  keyID: '1'
})

const newToken = await createAction({
  // The Bitcoin transaction ("Action" with a capital A) has an output, 
  // because it has led to the creation of a new Bitcoin token.
  outputs: [{
    // The output amount is how much Bitcoin (measured in "satoshis") 
    // this token is worth. Let's use 1000 satoshis.
    satoshis: 1000,
    // The output script for this token was created by the PushDrop library, 
    // which you can see above.
    script: bitcoinOutputScript
  }],
  // Finally, we'll describe the Action for the user
  description: 'Create my first token'
})

// Here, we're using the PushDrop library to unlcok / redeem the PushDrop 
// token that was previously created. By providing this information, 
// PushDrop can "unlock" and spend the token. When the token gets spent, 
// the user gets their 1000 satoshis back.
const unlockingScript = await pushdrop.redeem({
  // To unlock the token, we need to use the same "first token" protocol 
  // and key ID as when we created the token before. Otherwise, the 
  // key won't fit the lock and the Bitcoins won't come out.
  protocolID: 'first token',
  keyID: '1',
  // We're telling PushDrop which previous transaction and output we want to
  // unlock, so that the correct unlocking puzzle can be prepared.
  prevTxId: newToken.txid,
  outputIndex: 0, // The first output from the transaction
  // We also give PushDrop a copy of the locking puzzle ("script") that 
  // we want to open, which is helpful in preparing to unlock it.
  lockingScript: bitcoinOutputScript,
  // Finally, the number of satoshis we are expecting to unlock when the 
  // puzzle gets solved.
  outputAmount: 1000
})

// Now, we're going to use the unlocking puzle that PushDrop has prepared for us,
// so that the user can get their Bitcoins back. This is another "Action", which
// is just a Bitcoin transaction.
// The amount the user gets back will be slightly less, because of transaction fees.
await createAction({
  inputs: { // These are inputs, which unlock Bitcoin tokens.
    // The input comes from the token which we're completing
    [newToken.txid]: {
      ...newToken,
      // The output we want to redeem is specified here, and we also give 
      // the unlocking puzzle ("script") from PushDrop.
      outputsToRedeem: [{
        index: 0, // The first output of the transaction
        unlockingScript
      }]
    }
  },
  // Let the user know why they're getting some Bitcoins back
  description: 'Redeem my first token'
})

🏆 After reading the above two examples, could you implement a token with encrypted data? 🏆

API

Table of Contents

createAction

Creates and broadcasts a BitCoin transaction with the provided inputs and outputs.

Parameters

  • obj Object All parameters for this function are provided in an object

    • obj.inputs Object? Input scripts to spend as part of this Action. This is an object whose keys are TXIDs and whose values are BRC-8 transaction envelopes that contain an additional field called outputsToRedeen. This additional field is an array of objects, each containing index and unlockingScript properties (with an optional sequenceNumber). The index property is the output number in the transaction you are spending, and unlockingScript is the hex-encoded Bitcoin script that unlocks and spends the output (the sequenceNumber is applied to the input). Any signatures should be created with SIGHASH_NONE | ANYONECANPAY so that additional modifications to the resulting transaction can be made afterward without invalidating them. You may substitute SIGHASH_NONE for SIGHASH_SINGLE if required for a token contract, or drop ANYONECANPAY if you are self-funding the Action and the outputs require no other funding inputs.
    • obj.outputs Array<Object>? The array of transaction outputs (amounts and scripts) that you want in the transaction. Each object contains "satoshis" and "script", which can be any custom locking script of your choosing.
    • obj.lockTime Number? The lock time of the created transaction.
    • obj.description string A present-tense description of the user Action being facilitated or represented by this BitCoin transaction.
    • obj.labels Array<String> An array of transaction labels to apply to the Action
    • obj.dangerouslyDisableMapi Boolean Disables returning mAPI responses with created transaction, dramatically improving performance while removing the ability of recipients to check for double-spends by checking mAPI signatures. (optional, default false)

Returns Promise<Object> An Action object containing "txid", "rawTx" "mapiResponses" and "inputs".

createHmac

Creates a SHA-256 HMAC with a key belonging to the user.

Parameters

  • args Object All parameters are passed in an object.

    • args.data (Uint8Array | string) The data to HMAC. If given as a string, it must be in base64 format.
    • args.protocolID (Array | string) Specify an identifier for the protocol under which this operation is being performed.
    • args.keyID string An identifier for the message. During verification, the same message ID will be required. This can be used to prevent key re-use, even when the same user is using the same protocol to HMAC multiple messages.
    • args.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed. (optional, default '')
    • args.counterparty (Uint8Array | string) If specified, the user with this identity key will also be able to verify the HMAC, as long as they specify the current user's identity key as their counterparty. Must be a hexadecimal string representing a 33-byte or 65-byte value, "self" or "anyone". (optional, default self)
    • args.privileged string This indicates whether the privileged keyring should be used for the HMAC, as opposed to the primary keyring. (optional, default false)

Returns Promise<Uint8Array> The SHA-256 HMAC of the data.

getWindowVersion

Obtains the version by using the local window.CWI instance. Fails of no CWI instance exists within the local window.

getXDMVersion

Uses cross-document messaging to obtain a substrate connection. Fails after 200ms if no version response is received.

getHTTPVersion

Uses the HTTP local port 3301 API to request the version. Fails if HTTP errors are encountered, or no server is running.

promiseWithTimeout

Provides a timedout promise.

Parameters

  • obj Object All parameters for this function are provided in an object

    • obj.timeout Number Timeout in milliseconds, promise interupted, control returned, if not completed after timeout milliseconds.
    • obj.promise Function The promised function to be run to completion or interupted, control returned, after timeout milliseconds.
    • obj.error Error The error that is thrown if the time expires.

createSignature

Creates a digital signature with a key belonging to the user. The SHA-256 hash of the data is used with ECDSA.

To allow other users to externally verify the signature, use getPublicKey with the same protocolID, keyID and privileged parameters. The signature should be valid under that public key.

Parameters

  • args Object All parameters are passed in an object.

    • args.data (Uint8Array | string) The data to sign. If given as a string, it must be in base64 format.
    • args.protocolID (Array | string) Specify an identifier for the protocol under which this operation is being performed.
    • args.keyID string An identifier for the message being signed. During verification, or when retrieving the public key used, the same message ID will be required. This can be used to prevent key re-use, even when the same user is using the same protocol to sign multiple messages.
    • args.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed. (optional, default '')
    • args.counterparty (Uint8Array | string) If specified, the user with this identity key will also be able to verify the signature, as long as they specify the current user's identity key as their counterparty. Must be a hexadecimal string representing a 33-byte or 65-byte value, "self" or "anyone". (optional, default self)
    • args.privileged string This indicates whether the privileged keyring should be used for signing, as opposed to the primary keyring. (optional, default false)

Returns Promise<Uint8Array> The ECDSA message signature.

decrypt

Decrypts data with a key belonging to the user. The same protocolID, keyID, counterparty and privileged parameters that were used during encryption must be used to successfully decrypt.

Parameters

  • args Object All parameters are passed in an object.

    • args.ciphertext (string | Uint8Array) The encrypted data to decipher. If given as a string, it must be in base64 format.
    • args.protocolID (Array | string) Specify an identifier for the protocol under which this operation is being performed. It should be the same protocol ID used during encryption.
    • args.keyID string This should be the same message ID used during encryption.
    • args.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed. (optional, default '')
    • args.counterparty (Uint8Array | string) If a foreign user used the local user's identity key as a counterparty when encrypting a message, specify the foreign user's identity key and the message can be decrypted. Must be a hexadecimal string representing a 33-byte or 65-byte value, "self" or "anyone". (optional, default self)
    • args.privileged Boolean This indicates which keyring should be used when decrypting. Use the same value as was used during encryption. (optional, default false)
    • args.returnType string Specify the data type for the returned plaintext. Available types are string (binary) and Uint8Array. (optional, default Uint8Array)

Returns Promise<(string | Uint8Array)> The decrypted plaintext.

encrypt

Encrypts data with a key belonging to the user. If a counterparty is provided, also allows the counterparty to decrypt the data. The same protocolID, keyID, counterparty and privileged parameters must be used when decrypting.

Parameters

  • args Object All parameters are passed in an object.

    • args.plaintext (string | Uint8Array) The data to encrypt. If given as a string, it must be in base64 format.
    • args.protocolID (Array | string) Specify an identifier for the protocol under which this operation is being performed.
    • args.keyID string An identifier for the message being encrypted. When decrypting, the same message ID will be required. This can be used to prevent key re-use, even when the same two users are using the same protocol to encrypt multiple messages. It can be randomly-generated, sequential, or even fixed.
    • args.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed. (optional, default '')
    • args.counterparty (Uint8Array | string) If specified, the user with this identity key will also be able to decrypt the message, as long as they specify the current user's identity key as their counterparty. Must be a hexadecimal string representing a 33-byte or 65-byte value, "self" or "anyone". (optional, default self)
    • args.privileged Boolean When true, the data will be encrypted with the user's privileged keyring instead of their primary keyring. (optional, default false)
    • args.returnType string Specify the data type for the returned ciphertext. Available types are string (binary) and Uint8Array. (optional, default Uint8Array)

Returns Promise<(string | Uint8Array)> The encrypted ciphertext.

getNetwork

Returns the current network (main or test)

Returns Promise<String> The current network (e.g. "main")

getPublicKey

Returns the public key. If identityKey is specified, returns the current user's identity key. If a counterparty is specified, derives a public key for the counterparty.

Parameters

  • args Object All parameters are passed in an object.

    • args.protocolID (Array | string)? Specify an identifier for the protocol under which this operation is being performed.
    • args.keyID string? An identifier for retrieving the public key used. This can be used to prevent key re-use, even when the same user is using the same protocol to perform actions.
    • args.privileged string This indicates whether the privileged keyring should be used, as opposed to the primary keyring. (optional, default false)
    • args.identityKey string If true, the identity key will be returned, and no key derivation will be performed (optional, default false)
    • args.reason string? The reason for requiring access to the user's privilegedKey (optional, default 'No reason provided.')
    • args.counterparty string The counterparty to use for derivation. If provided, derives a public key for this counterparty, who can derive the corresponding private key. (optional, default self)
    • args.forSelf boolean Whether the derived child public key corresponds to a private key held by the current user. (optional, default false)
    • args.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed.

Returns Promise<Object> An object containing the user's public key

getVersion

Returns the current version of the kernal

Returns Promise<String> The current kernel version (e.g. "0.3.49")

isAuthenticated

Checks if a user is currently authenticated.

Returns Promise<Object> Returns an object indicating whether a user is currently authenticated.

verifyHmac

Verifies that a SHA-256 HMAC was created with a key that belongs to the user.

Parameters

  • args Object All parameters are passed in an object.

    • args.data (Uint8Array | string) The data to verify. If given as a string, it must be in base64 format.
    • args.hmac (Uint8Array | string) The hmac created from the data. If given as a string, it must be in base64 format.
    • args.protocolID (Array | string) Specify an identifier for the protocol under which the HMAC operation was performed.
    • args.keyID string An identifier for the message. This should be the same message ID that was used when creating the HMAC.
    • args.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed. (optional, default '')
    • args.counterparty (Uint8Array | string) If specified, allows verification where the user with this identity key has created the HMAC, as long as they had specified the current user's identity key as their counterparty during creation. Must be a hexadecimal string representing a 33-byte or 65-byte value or "self". Note that signatures created with counterparty = "anyone" are verifiable by anyone, and do not need user keys through the kernel. (optional, default self)
    • args.privileged string This indicates whether the privileged keyring was used for the HMAC, as opposed to the primary keyring. (optional, default false)

Returns Promise<Boolean> Whether the HMAC has been erified.

verifySignature

Verifies that a digital signature was created with a key belonging to the user.

Parameters

  • args Object All parameters are passed in an object.

    • args.data (Uint8Array | string) The data that was signed. If given as a string, it must be in base64 format.
    • args.signature (Uint8Array | string) The signature to verify, in the same format returned when it was created.
    • args.protocolID (Array | string) Specify the identifier for the protocol under which the data was signed.
    • args.keyID string An identifier for the message that was signed. This should be the same message ID that was used when creating the signature.
    • args.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed. (optional, default '')
    • args.counterparty (Uint8Array | string) If specified, allows verification where the user with this identity key has created the signature, as long as they had specified the current user's identity key as their counterparty during creation. Must be a hexadecimal string representing a 33-byte or 65-byte value or "self". Note that signatures created with counterparty = "anyone" are verifiable by anyone, and do not need user keys through the kernel. (optional, default self)
    • args.privileged string This indicates whether the privileged keyring was used for signing, as opposed to the primary keyring. (optional, default false)
    • args.reason string? The reason shown to the user for using the privileged key (optional, default '')

Returns Promise<Object> An object indicating whether the signature was successfully verified.

waitForAuthentication

Waits for a user to be authenticated.

Returns Promise<Object> An object containing a boolean indicating that a user is authenticated

createCertificate

Creates a signed certificate

Parameters

  • obj Object All parameters for this function are provided in an object

    • obj.certificateType string The type of certificate to create
    • obj.fieldObject Object The fields to add to the certificate
    • obj.certifierUrl string The URL of the certifier signing the certificate
    • obj.certifierPublicKey string The public identity key of the certifier signing the certificate

Returns Promise<Object> A signed certificate

getCertificates

Returns found certificates

Parameters

  • obj Object All parameters for this function are provided in an object

    • obj.certifiers Array<string>? The certifiers to filter certificates by
    • obj.types Object? The certificate types to filter certificates by, given as an object whose keys are types and whose values are arrays of fields to request from certificates of the given type.

Returns Promise<Object> An object containing the found certificates

proveCertificate

Creates certificate proof specifically for verifier

Parameters

  • obj Object All parameters for this function are provided in an object

    • obj.certificate Object The certificate to prove
    • obj.fieldsToReveal Array<string>? The names of the fields to reveal to the verifier
    • obj.verifierPublicIdentityKey string The public identity key of the verifier

Returns Promise<Object> A certificate for presentation to the verifier for field examination

submitDirectTransaction

Submits a transaction directly to a ninja

Parameters

  • obj Object All parameters for this function are provided in an object

    • obj.protocol string Specify the transaction submission payment protocol to use. Currently, the only supported protocol is that with BRFC ID "3241645161d8"
    • obj.transaction Object The transaction envelope to submit, including key derivation information
    • obj.senderIdentityKey string Provide the identity key for the person who sent the transaction
    • obj.note string Human-readable description for the transaction
    • obj.amount Number Amount of satoshis associated with the transaction
    • obj.labels Array<String>? Labels to apply to the submitted transaction
    • obj.derivationPrefix string? A derivation prefix used for all outputs. If provided, derivation prefixes on all outputs are optional.

Returns Promise<Object> Object containing reference number, status=success, and human-readable note acknowledging the transaction

getTransactionOutputs

Returns a set of transaction outputs that Dojo has tracked

Parameters

  • obj Object All parameters are given in an object

    • obj.basket String? If provided, indicates which basket the outputs should be selected from.
    • obj.tracked Boolean? If provided, only outputs with the corresponding tracked value will be returned (true/false).
    • obj.spendable Boolean? If given as true or false, only outputs that have or have not (respectively) been spent will be returned. If not given, both spent and unspent outputs will be returned.
    • obj.tags Array<String>? If provided, only outputs that are tagged with one of the given tags will be returned (depending on the tagQueryMode which defaults to all).
    • obj.includeEnvelope Boolean? If provided, returns a structure with the SPV envelopes for the UTXOS that have not been spent. (optional, default false)
    • obj.includeBasket Boolean? If provided, returns the basket a UTXO is a member of, or undefined if it is not in a basket. (optional, default false)
    • obj.includeTags Boolean? If provided, returns one or more tags a UTXO is tagged with. (optional, default false)
    • obj.includeCustomInstructions Boolean? If provided, returns custom instructions providing the necessary key derivation associated with one or more UTXOs. (optional, default false)
    • obj.tagQueryMode String? If provided, will return outputs that match either all the tags, or any of them.
    • obj.type String? If provided, only outputs of the specified type will be returned. If not provided, outputs of all types will be returned.
    • obj.limit Number? Provide a limit on the number of outputs that will be returned. (optional, default 25)
    • obj.offset Number? Provide an offset into the list of outputs. (optional, default 0)

Returns Promise<Array<TransactionOutputDescriptor>> A set of outputs that match the criteria

listActions

Returns a list of Actions with a given label

Parameters

  • obj Object All parameters are given in an object

    • obj.label String The label for the transactions to return
    • obj.limit Number Provide a limit on the number of outputs that will be returned. (optional, default 25)
    • obj.offset Number Provide an offset into the list of outputs. (optional, default 0)
    • obj.addInputsAndOutputs Boolean? Optional. If true, include the list of transaction inputs and outputs when retrieving transactions. Enabling this option adds the 'inputs' and 'outputs' properties to each transaction, providing detailed information about the transaction's inputs and outputs. (optional, default false)
    • obj.includeBasket Boolean? Optional. If true, the basket for each input and output will be included. (optional, default false)
    • obj.includeTags Boolean? Optional. If true, the tags on each input and output will be included. (optional, default false)

Returns Promise<Array<TransactionOutputDescriptor>> A set of outputs that match the criteria

revealKeyLinkage

Reveals the linkage between a key held by this user and a key held by another user. In one mode, reveals all keys associated with a counterparty, in the other mode reveals only the linkage of a specific interaction. Encrypts the linkage value so that only the specified verifier can access it. Refer to BRC-72 for full details.

Parameters

  • args Object All parameters are passed in an object.

    • args.mode string When "counterparty" it will reveal all keys for the counterparty. When "specific" it will reveal only the linkage for the specific protocolID and keyID provided
    • args.counterparty string The identity of the person who is associated with the linked key to reveal. Must be a hexadecimal string representing a 33-byte or 65-byte value.
    • args.verifier string The identity key of the person to whom this revelation is being made. The linkage will be encrypted so that only the verifier can access it.
    • args.protocolID string BRC-43 Protocol ID under which the linkage is to be revealed
    • args.keyID string BRC-43 Key ID under which the linkage is to be revealed
    • args.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed.
    • args.privileged Boolean This indicates which keyring should be used. (optional, default false)

Returns Promise<object> The revealed linkage payload, as described in BRC-72.

requestGroupPermission

Requests group permissions for an application.

Returns Promise<void> Resolves after group permissions are completed by the user.

unbasketOutput

Returns a set of transaction outputs that Dojo has tracked

Parameters

  • obj Object All parameters are given in an object

    • obj.basket String? If provided, indicates which basket the outputs should be selected from.
    • obj.tracked Boolean? If provided, only outputs with the corresponding tracked value will be returned (true/false).
    • obj.includeEnvelope Boolean? If provided, returns a structure with the SPV envelopes for the UTXOS that have not been spent.
    • obj.spendable Boolean? If given as true or false, only outputs that have or have not (respectively) been spent will be returned. If not given, both spent and unspent outputs will be returned.
    • obj.type String? If provided, only outputs of the specified type will be returned. If not provided, outputs of all types will be returned.
    • obj.limit Number? Provide a limit on the number of outputs that will be returned.
    • obj.offset Number? Provide an offset into the list of outputs.
    • obj.txid
    • obj.vout

Returns Promise<Array<TransactionOutputDescriptor>> A set of outputs that match the criteria

discoverByIdentityKey

Resolves identity information by identity key from the user's trusted certifiers.

Parameters

  • obj Object All parameters are provided in an object

    • obj.identityKey String The identity key to resolve information for
    • obj.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed.

Returns Promise<Array<Object>>

discoverByAttributes

Resolves identity information by attributes from the user's trusted certifiers.

Parameters

  • obj Object All parameters are provided in an object

    • obj.attributes Object An object containing key value pairs to query for (ex. { firstName: 'Bob' } )
    • obj.description string? Describe the high-level operation being performed, so that the user can make an informed decision if permission is needed.

Returns Promise<Array<Object>>

SDK Connection Substrates

The Babbage SDK connects to a running Computing with Integrity (CWI) kernel instance, allowing applications to plug into user-owned identities. There are currently three substrates (connection modes) that the SDK can use to link an application to a MetaNet identity provider:

  1. Window API: In a web browser, the SDK will first try to use a window.CWI interface for communicating with the kernel.
  2. Babbage XDM: In a browser or iframe window, the SDK will next try to use XDM (cross-document messaging) to communicate with a running kernel instance.
  3. Cicada API: Lastly, the SDK will attempt to communicate over localhost:3301 to a running HTTP MetaNet service. This Port 3301 Substrate is named Cicada, in honor of Cicada 3301.

License

The license for this library, which is a wrapper for the proprietary Babbage API, is the Open BSV License. It can only be used on the BSV blockchain. The Babbage API itself, including the rights to create and host Babbage software or any other related infrastructure, is not covered by the Open BSV License and remains proprietary and restricted. The Open BSV License only extends to the code in this repository, and you are not permitted to host Babbage software, servers or create copies or alternative implementations of the proprietary Babbage API without other permission.