Skip to content

acekyd/tbdex-pfi-exemplar

 
 

Repository files navigation

Example tbDEX implementation

This is a starter kit for building a Participating Financial Institution (PFI) gateway to provide liquidity services on the tbDEX network. You can fork this and use it (or use it as inspiration!). Contains mock implementations of some features of a PFI, as well as a Verifiable Credential (VC) issuer using a Decentralized Identifier (DID).

Mock TypeScript PFI implementation for example purposes using:

Running in codesandbox

You can run try this example in codesandbox, or locally.

To run in codesandbox, use the link below and then open a terminal. Then continue on from the preparing server section below.

Open sandbox

Local Development Prerequisites

node and npm

This project is using node v20.3.1 and npm >=v7.0.0. You can verify your node and npm installation via the terminal:

$ node --version
v20.3.1
$ npm --version
9.6.7

If you don't have node installed, feel free to choose whichever installation approach you feel the most comfortable with.

We recommend using nvm (aka node version manager) since it allows you to run multiple versions of node and select the appropriate runtime for your specific project via nvm use. This ensures what you're running locally matches what we've tested against ourselves. Follow installation instructions for nvm here.

Once you have installed nvm, install the desired node version with nvm install, defined in the .nvmrc file in the root of the project.

Docker

Docker is used to spin up a local PostgreSQL container. Most major platforms are supported and you can find the installation instructions here .

dbmate

dbmate is used to run database migrations.

Follow these install instructions based on your OS' package manager.

Preparing the server database (one time)

Important

Make sure you have all the prerequisites

  1. Clone the repo and cd into the project directory
  2. ./db/scripts/start-pg from your command line to start a psql container by running.
  3. ./db/scripts/migrate to perform database migrations
    • This only needs to be done once and then whenever changes are made in db/migrations.
  4. npm install to install all project dependencies
  5. cp .env.example .env.
    • This is where you can set any necessary environment variables. .env.example contains all environment variables that you can set.
  6. npm run server and ensure this is running

Running end-to-end PFI tutorial

In this tutorial we will set up an issuer to issue Sanction Check VCs, as well as create a customer called "Alice" to interact with the PFI server.

Step 1: Local development is setup

Ensure prerequisites are installed and check the database prepared and running).

Step 2: Create a VC issuer

npm run example-create-issuer

Creates a new VC issuer, which will be needed by the PFI.

Note

issuer.json stores the private info for the issuer

Step 3: Configure the PFI database with offerings and VC issuer

Replace these lines in seed-offerings.ts with the appropriate issuer info.

https://github.com/TBD54566975/tbdex-pfi-exemplar/blob/11bc1ede3d326259a2dae4fe23470e1a47303e4e/src/seed-offerings.ts#L87-L95

npm run seed-offerings

Prepares the PFI with the issuer DID and the offerings it will provide

Step 4: Create the identity for customer "Alice"

npm run example-create-customer

Create a new "customer" DID (customer is called Alice, think of it as her wallet). Take note of her DID which will be used in the next step.

Note

Alice's private wallet info is stored in alice.json.

Step 5: Issue a sanctions check VC to "Alice"

Issue the credential to Alice, which ensures Alice is a non-sanctioned individual. Use the DID from in Step 4. Take note of the signed VC that is returned.

npm run example-issue-credential $customer_did

Step 6: Run the PFI server

Run the server (or restart it) in another terminal window:

npm run server

Note

The server prints out the DID for the server after it starts, take a copy of this for the next step.

Step 7: Run a tbDEX exchange

Run a tbDEX transaction (or exchange):

Take the PFI DID string and the signed VC string (both long) and run:

npm run example-e2e-exchange $pfi_server_did $signed_vc

With the values from Step 5 and Step 6. You will see the server print out the interaction between the customer and the PFI. This will look up offers, ask for a quote, place an order, and finally check for status.

Each interaction happens in the context of an "Exchange" which is a record of the interaction between the customer and the PFI.

Implementing a PFI

The PFI server

Start the server with

npm run server

The server business logic (such as it is!) is in src/main.ts which you can see, doesn't do a lot, but it is something you can start with. Also look in src/db/exchange-repository.ts which out of the box has some simple built in functionality.

For server implementers _ExchangeRepository is an interesting class to lookup: getExchange or getExchanges is how order statuses and quotes can be exposed to the client.

Some interesting example parts of the code are getOfferings which returns what offers the PFI currently has, and rfq which creates a message to send to the PFI to request a quote for a particular offering (with the issuer saying that the customer 'Alice' is not a sanctioned individual). getExchanges shows the current state of the interaction between Alice and the PFI.

seed-offerings.ts also sets up the PFI with the offerings and requirements for the client to be able to make a request for a quote.

You also should use a non-ephemeral DID (using the env vars config as described above).

TODO: more content needed here...

DB stuff

Contains sections that highlight convenience scripts that'll help start a PostgreSQL, create/run migration scripts, and a psql shell that's useful for debugging.

Convenience Scripts

Script Description
./db/scripts/start-pg Starts dockerized psql if it isn't already running.
./db/scripts/stop-pg Stops dockerized psql if it is running. Passing -rm will delete the container as well.
./db/scripts/use-pg Drops you into a psql shell.
./db/scripts/new-migration Creates a new migration file.
./db/scripts/migrate Runs DB migrations.

Migration files

Migration files live in the db/migrations directory. This is where all of our database schemas live.

Adding a migration file

To create a new migration file, run the following command from the command line:

./db/scripts/new-migration replace_with_file_name

This will generate a barebones migration template file for you.

Note

The above example assumes you're in the root directory of the project. adjust the path to the script if you're not in the root.

Tip

for replace_with_file_name, our convention is <action>_<tblname>_table (e.g. if you're wanting to create a migration file to create a quotes table it would be create_quotes_table.sql as the filename. dbmate prefixes these with a timestamp so they can be applied linearly.

Running migrations

Migrations can be applied by running ./db/scripts/migrate from the command line.

Running Manual Queries & Debugging

From the command line, run:

./db/scripts/use-pg

This will drop you into an interactive db session.

Configuration

Configuration can be set using environment variables. Defaults are set in src/config.ts.

Project Resources

Resource Description
CODEOWNERS Outlines the project lead(s)
CODE_OF_CONDUCT.md Expected behavior for project contributors, promoting a welcoming environment
CONTRIBUTING.md Developer guide to build, test, run, access CI, chat, discuss, file issues
GOVERNANCE.md Project governance
LICENSE Apache License, Version 2.0

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 85.3%
  • Shell 11.3%
  • JavaScript 3.4%