@hashgraph/stablecoin-npm-backend
v1.16.0
Published
<div align="center">
Downloads
7
Maintainers
Keywords
Readme
Stablecoin Studio - Backend
Table of Contents
- Context
- Architecture
- Overview
- Technologies
- Installation
- Build
- Run
- Configuration
- Testing
- Contributing
- Code of conduct
- License
Context
The backend module is meant to be used in combination with the Hedera StableCoin Studio.
Its purpose is to enable multisignatures for stable coins management operations.
Only single level multikeys are supported for now. Keys lists/Threshold keys associated to accounts cannot contain key lists/threshold keys themselves as keys.
Whenever users need to submit to the DLT network a transaction (Cash In, Freeze, ...) associated to an account that has multiple keys (key list or threshold keys) they will have the possibility to interact with the backend in the following way:
- They will first add the "raw transaction" (unsigned string of bytes) to the backend's database using the backend's api.
- After the transaction is created, key owners will have the possibility to asyncronously sign the transaction.
- Once all the required keys have signed the transaction, anyone can retrieve the transaction and its signatures, concatenate them and submit it to the Hedera network.
Architecture
The backend is made of two components:
- API: the api interacts with the underlying database and exposes 4 functionalities
- Add a transaction: allows for a new, unsigned transaction to be added to the database.
- Sign a transaction: allows for a transaction to be signed by one of the keys associated to the account the transaction belongs to.
- Remove a transaction: allows for a transaction to be removed from the database.
- Retrieve transactions: allows for transactions to be retrieved, either all of them or those that are associated to a given public key.
- Database: the db where transactions are stored waiting to be signed by all account's keys before submitting them to the Hedera DLT. It has one table with the following columns.
- id: Every transaction has UUID that uniquely identifies it within the database.
- transactionMessage: The content of the unsigned raw transaction submitted when creating a new transaction.
- description: Description of what the transactionMessage does. This is useful so that users know what the transaction is supposed to do before signing it.
- hederaAccountId: The hedera account the transaction belongs to.
- signatures: List of signatures already added to the transaction.
- keyList: List of public keys associated to the account the transaction belongs to. These are the keys that have the right to sign the transaction.
- signedKeys: List of public keys that have already signed the transaction (their signatures have been added to signatures).
- status: Current status of the transaction. There are two options:
- PENDING: transaction signature is still in progress.
- SIGNED: all required keys have already signed the transaction, we can submit it to the Hedera DLT.
- threshold: minimum number of keys that must sign the transaction before we can submit to the network (update its status to SIGNED).
Overview
Add a transaction
- Path : /v1/transactions
- HTTP Method : POST
- Body :
{
"payload": "transaction_raw_message",
"description": "transaction_short_description",
"accountId": "your_account_id",
"keyList": ["PK1", "PK2", ...],
"threshold": "number"
}
Logic :
- Action : transaction is added to the DB.
Status code :
- 201 Created: Transaction added successfully.
- 400 Bad Request: Invalid request payload.
- 500 Internal Server Error: An error occurred during the process.
Response :
{
"transactionId": "generated_transaction_ID"
}
Sign a transaction
- Path : /v1/transactions/{transactionId}
- HTTP Method : PUT
- Body :
{
"signedTransactionMessage": "transaction_signed_message",
"publicKey": "public_key_used_for_signing"
}
- Logic :
- Success :
- transaction id exists
- public key is part of the remaining key list (has the right to sign)
- body’s signatures matches the provided public key
- the signature added to the body is indeed associated to the provided public key (compare with the current transaction body)
- Action :
- updates the Body of the transaction in the DB
- removes the public key from the list of “Remaining keys”
- Updates the threshold
- Success :
- Status code :
- 204 No content: Transaction updated successfully.
- 400 Bad Request: Invalid transactionId format.
- 401 Unauthorized: Unauthorized key.
- 404 Not Found: transactionId could not be found.
- 409 Conflict: transactionId already signed by the provided key.
- 500 Internal Server Error: An error occurred during the process.
Delete a transaction
- Path : /v1/transactions/{transactionId}
- HTTP Method : DELETE
Logic :
- Success :
- transaction id exists
- Action : removes transaction from the DB.
- Success :
- Status code :
- 204 No content: Transaction removed successfully.
- 400 Bad Request: Invalid transactionId format.
- 404 Not Found: transactionId could not be found.
- 500 Internal Server Error: An error occurred during the process.
Retrieve All transactions
- Path : /v1/transactions
- HTTP Method : GET
Logic :
- Action : returns all the transaction from the DB (paginated response).
- Status code :
- 200 OK.
- 500 Internal Server Error: An error occurred during the process.
- Response :
[
{
"id" :"transaction_id",
"transaction_message": "hexadecimal_array_of_bytes",
"description": "transaction_short_description",
"hedera_account_id": "your_account_id",
"signatures": ["signature_1", "signature_2", ...],
"key_list": ["PK1", "PK2", ...],
"signed_keys": ["PK1", "PK2", ...],
"status": "transaction_status",
"threshold":"number"
},
{...}
]
Retrieve transactions for public Key
- Path : /v1/transactions/{publicKey}
- HTTP Method : GET
Logic :
- Action : returns all the transaction from the DB for a specific public Key and type (PENDING/SIGNED) (paginated response).
- Status code :
- 200 OK.
- 500 Internal Server Error: An error occurred during the process.
- Response :
[
{
"id" :"transaction_id",
"transaction_message": "hexadecimal_array_of_bytes",
"description": "transaction_short_description",
"hedera_account_id": "your_account_id",
"signatures": ["signature_1", "signature_2", ...],
"key_list": ["PK1", "PK2", ...],
"signed_keys": ["PK1", "PK2", ...],
"status": "transaction_status",
"threshold":"number"
},
{...}
]
Technologies
- Typescript
- NestJS
- TypeORM
- Winston
- Postgres
- Docker
Installation
The command below can be used to install the official release from the NPM repository. This version may not reflect the most recent changes to the main branch of this repository.
npm install -g @hashgraph/stablecoin-npm-backend
Build
Run npm install
. This will create and populate node_modules
and build the project and dependencies.
Then run npm run build
. This will create and populate the dist
folder with the transpiled javascript files.
Run
In order to run the backend you will need to execute the docker compose yaml file that defines the entire application (DB + API).
Run docker compose up -d --build
. This will start two containers (one for the API, another one for the DB), their respectives volumes and the network for them to communicate with each other.
The application will use two ports (defined in the .env file):
- Port
SERVER_PORT
: This is the API port, it can be accessed from outside the docker project. - Port
DB_PORT
: This is the DB port, it is only accessible from within the docker network.
Configuration
There is a .env
file that must be used to configure the backend. These are the configuration parameters:
COMPOSE_PROJECT_NAME
: Name of the docker compose project.CONTAINER_BACK_NAME
: Name of the container running the NestJS API.CONTAINER_DB_NAME
: Name of the container running the postgres DB.DOCKER_NETWORK_NAME
: Name of the docker compose network.SERVER_HOST
: API server name.SERVER_PORT
: API port. This port will be exposed outside of the docker network so that anyone can reach it.DB_HOST
: DB server name.DB_PORT
: DB port. This port will not be exposed outside of the docker network, which means that it is only accessible to the API.DB_USER
: DB admin user name.DB_PASSWORD
: DB admin user password.DB_NAME
: DB name.ORIGIN
: List of urls that are accepted in the HTTP header "Origin". If the API endpoints are invoked from a different url, the request will fail.MAX_LOG_FILESIZE
: Max size of the logging files used by the Winston file rotation policy. If a log file reaches this size, it will be zipped and a new file will be created.LOG_LEVEL
: Minimum log level to be included in the loging files.FILE_NAME
: Log file name pattern and localtion.DATE_PATTERN
: Log file date pattern.
Testing
Jest
The project uses Jest for testing.
Run
Tests may be run using the following command
npm run test
Contributing
Contributions are welcome. Please see the contributing guide to see how you can get involved.
Code of conduct
This project is governed by the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to [email protected].