1.0.7 • Published 5 months ago

@frostr/bifrost v1.0.7

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

Bifrost

SDK and reference node for the FROSTR protocol.

Features

  • Communicates over nostr using end-to-end encrypted messaging.
  • Nodes will collaborate to sign messages and exchange ECDH secrets.
  • Run standalone or integrate into existing nostr clients.
  • Includes methods for creating and managing a group of FROSTR shares.

Installation

npm install @frostr/bifrost

Usage Examples

Creating a group of shares

The following example demonstrates how to create a set of commits and shares for a 2-of-3 threshold signing group.

import {
  encode_group_pkg,
  encode_share_pkg,
  generate_dealer_pkg
} from '@frostr/bifrost/lib'

const THRESHOLD  = 2  // Number of shares required to sign.
const MEMBERS    = 3  // Total number of shares to create.
const SECRET_KEY = 'your hex-encoded secret key'

// Generate a 2-of-3 threshold share package.
const { group, shares } = generate_dealer_pkg(THRESHOLD, MEMBERS, [ SECRET_KEY ])

// Encode the group and shares as bech32 strings.
const group_cred  = encode_group_pkg(group)
const share_creds = shares.map(encode_share_pkg)

Initializing a Bifrost Node

import { BifrostNode } from '@frostr/bifrost'

// List of relays to connect to.
const relays  = [ 'wss://relay.example.com' ]

const options = {
  // Provide an existing cache for storing data.
  cache : {
    // Cache for storing ECDH secrets.
    ecdh : new Map<string, string>
  },
  // Enables more verbose logging of errors.
  debug : false,
  // Middleware functions for handling incoming messages.
  middleware : {
    // This middleware will run before a ECDH request is accepted.
    ecdh : (node, msg) => SignedMessage<ECDHPackage>,
    // This middleware will run before a signature request is accepted.
    sign : (node, msg) => SignedMessage<SessionPackage>
  },
  // Specify a set of policies for each peer.
  policies : [
    // The format is [ pubkey, allow_send, allow_recv ].
    [ 'pubkey1', true,  true  ],
    // If allow_send is false, the node will not send requests to the peer.
    [ 'pubkey2', false, true  ],
    // If allow_recv is false, the node will not handle requests from the peer.
    [ 'pubkey3', false, false ]
  ]
}

// Initialize the node with the group and share credentials.
const node = new BifrostNode (group, share, relays, opt)

// Log when the node is ready.
node.on('ready', () => console.log('bifrost node is ready'))

// Connect to the relays.
await node.connect()

Signing Messages

// Optional parameters for the signature request.
const options = {
  content : null,      // optional payload for the signature request.
  peers   : [],        // array of peer public keys (overrides policies).
  stamp   : now(),     // specific timestamp for the request.
  type    : 'message', // optional type parameter for the signature request.
  tweaks  : []         // array of tweak values to apply to the signature.
}

// Request a partial signature from other group members.
const result = await node.req.sign(
  message, // message to sign.
  options  // optional parameters for the signature request.
)

if (result.ok) {
  // The final signature aggregated from all group members.
  const signature = result.data
}

ECDH Key Exchange

// Request a partial ECDH secret from other group members.
const result = await node.req.ecdh(
  ecdh_pk, // public key for the ECDH exchange.
  peer_pks // array of peer public keys (overrides policies).
)

if (result.ok) {
  // The final ECDH shared secret.
  const shared_secret = result.data
}

Listening for Events

The Bifrost node emits events during various stages of processing requests and responses.

interface BifrostNodeEvent {
  // Base events.
  '*'                 : [ string, ...any[]        ] // emits all events.
  'ready'             : BifrostNode                 // emits when the node is ready.
  'closed'            : BifrostNode                 // emits when the node is closed.
  'message'           : SignedMessage               // emits when a message is received.
  'bounced'           : [ string, SignedMessage   ] // emits when a message is rejected.
  // ECDH events.
  '/ecdh/sender/req'  : SignedMessage               // emits when a ECDH request is sent.
  '/ecdh/sender/res'  : SignedMessage[]             // emits when a ECDH request is fulfilled.
  '/ecdh/sender/rej'  : [ string, ECDHPackage     ] // emits when a ECDH request is rejected.
  '/ecdh/sender/sec'  : [ string, ECDHPackage[]   ] // emits when a ECDH share is aggregated.
  '/ecdh/sender/err'  : [ string, SignedMessage[] ] // emits when a ECDH share fails to aggregate.
  '/ecdh/handler/req' : SignedMessage               // emits when a ECDH request is received.
  '/ecdh/handler/res' : SignedMessage               // emits when a ECDH response is sent.
  '/ecdh/handler/rej' : [ string, SignedMessage   ] // emits when a ECDH rejection is sent.
  // Signature events.
  '/sign/sender/req'  : SignedMessage               // emits when a signature request is sent.
  '/sign/sender/res'  : SignedMessage[]             // emits when a signature response is received.
  '/sign/sender/rej'  : [ string, SessionPackage  ] // emits when a signature rejection is received.
  '/sign/sender/sig'  : [ string, SignedMessage[] ] // emits when a signature share is aggregated.
  '/sign/sender/err'  : [ string, SignedMessage[] ] // emits when a signature share fails to aggregate.
  '/sign/handler/req' : SignedMessage               // emits when a signature request is received.
  '/sign/handler/res' : SignedMessage               // emits when a signature response is sent.
  '/sign/handler/rej' : [ string, SignedMessage   ] // emits when a signature rejection is sent.
}

Development & Testing

The library includes comprehensive test suites organized into unit and end-to-end test suites.

Run specific test suites:

# Run all tests
npm test

# Build the project
npm run build

# Build a release candidate.
npm run release

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

1.0.7

5 months ago

1.0.6

5 months ago

1.0.5

5 months ago

1.0.4

5 months ago

1.0.3

5 months ago

1.0.2

5 months ago

1.0.1

5 months ago

1.0.0

6 months ago

0.3.1

7 months ago

0.3.0

7 months ago

0.2.6

7 months ago

0.2.5

8 months ago

0.2.4

8 months ago

0.2.3

8 months ago

0.2.2

8 months ago

0.2.0

8 months ago

0.1.3

8 months ago

0.1.2

8 months ago

0.1.0

8 months ago