Skip to content

anataliocs/nestjs-typeorm-full-example

Repository files navigation

Nest Logo



Nestjs TypeORM Full Example for Web3 SDKs

Example of a NestJS application with PostgreSQL and Axios integrating into multiple Web3 SDKs to demonstrate how to handle complex integration scenarios where you are building on multiple chains and APIs including Ethereum, Solana and Bitcoin(WIP).

This project modularizes popular Web3 SDKs, handles the lifecycle management, abstracts away complexity, adds configuration mgmt and exposes simplified interfaces in REST API, GraphQL, Websocket and SSE(Server-Sent Events) endpoint formats.

These endpoints are consumed by ultra-lightweight, nano-clients including:

The resulting NestJS app will be a Dockerized, stateless, cloud-native, horizontal-scalable, microservice-oriented backend for a decentralized application.

Reactive, async, non-blocking, event-driven back-ends are very powerful for on-chain, blockchain-powered dApps.

Client Examples:

Endpoints and ultra light-weight clients for consuming data.


General Examples

REST API

GraphQL

Websockets

SSE


Ethereum logo
Ethers.js Examples

REST API

GraphQL

Websockets

SSE


Solana logo
Solana Kit Examples

REST API

GraphQL

Websockets

SSE


Bitcoin logo
Bitcoinjs-lib Examples

REST API

  • VanillaJS: WIP

GraphQL

  • VanillaJS: WIP

Websockets

  • VanillaJS: WIP
  • VanillaJS: WIP

SSE

  • VanillaJS: WIP

Tech Stack:

The SDKs used in this example:


Quick Start

Build/install and add Endor cli.

CLI used for running local PostgreSQL and other cloud services.

pnpm install
npm install -g @endorhq/cli

Start PostgreSQL:

ℹ️ NOTE: Start each in a separate terminal tab

This will start a local PostgreSQL instance using Endor CLI.

pnpm db

Start service:

Lint test and run dev.

pnpm dev

Set up Config

Setup .env file:

cp .env.example .env
REAP_BASE_URL=https://sandbox.api.caas.reap.global/
REAP_API_KEY=
REAP_DOCS=https://reap.readme.io/reference/test-environment
APP_URL=127.0.0.1
PEAQ_RPC_SERVER_URL=https://quicknode1.peaq.xyz
PEAQ_WSS_SERVER_URL=wss://quicknode1.peaq.xyz
ETH_DEV_SEED=
ETH_DEV_ADDRESS=

ETHERS_RPC_SERVER_URL=
ETHERS_RPC_API_KEY=

SOLKIT_RPC_SERVER_URL=
SOLKIT_WS_SERVER_URL=
SOLKIT_RPC_API_KEY=

BITCOIN_RPC_SERVER_URL=
BITCOIN_RPC_API_KEY=

Install Foundry CLI: Foundry is a CLI tool suite for working with Ethereum/Solidity smart contracts. We will use cast to create a new wallet.

curl -L https://foundry.paradigm.xyz | bash
foundryup

Create a new EVM wallet: Set this as your ETH_DEV_SEED. Only use this for dev. https://getfoundry.sh/cast/reference/wallet

cast wallet new

Run local eth node

anvil --fork-url https://reth-ethereum.ithaca.xyz/rpc

Faucets:

Open browser: After starting the service, open the following:


Run local PostgreSQL

The command pnpm db abstracts away the complexity of running a local PostgreSQL node.
Here are more details on how it's used.

https://docs.endor.dev/cli/services/postgres/

Endor CLI: A lightweight developer tool to run local cloud services (like PostgreSQL) with one command using reproducible containers. See docs: https://docs.endor.dev/cli/

Endor PostgreSQL

endor run postgres

Connect to PostgreSQL via CLI

psql -h localhost -U postgres -d postgres

Run the Project in Different Environments

# lint test and run dev
pnpm dev

# development
$ pnpm run start

# watch mode
$ pnpm run start:dev

# production mode
$ pnpm run start:prod

NestJS CLI Usage

https://docs.nestjs.com/cli/overview

Create a new resource:

  • Generate a module
  • Generate a controller
  • Generate a service
  • OPTIONAL: Generate an entity class/interface
  • OPTIONAL: Generate Data Transfer Objects
nest g resource new-resource

Create a new project:

Create a new project using

  • pnpm
  • Typescript
  • --strict flag

Optional: -c custom-schematic

nest n project-name -p pnpm -l TS --strict

Run tests

# unit tests
$ pnpm run test

# e2e tests
$ pnpm run test:e2e

# test coverage
$ pnpm run test:cov

Server Sent Events

In this example, we use ethers.js to check for new blocks and use an Observable to emit to blocks to a html file and display them with just a couple lines of vanilla JS.

We used the nest.js Server Sent Event controller functionality to create a SSE endpoint /ethers/sse/block-number/.

With html and vanilla.js

Minimal client using a SINGLE .html file: client/src/sse/ethers/block-number.html

Setting up an EventSource to the NestJS SSE Endpoint

const eventSource = new EventSource('http://127.0.0.1:3000/ethers/sse/block-number/', {
  withCredentials: false,
});

With HTMX

HTMX further abstracts away logic, using custom HTML tags to replace even the Javascript from the previous example with vanilla.js.

Minimal client using .htmx: client/src/sse/ethers/htmx-block-number.html

  • Raw HTML with htmx
  • Uses picocss delivered via public CDN for styling

Setting up SSE with htmx

<article id="messages" hx-ext="sse" sse-connect="http://127.0.0.1:3000/ethers/sse/block-number/"
         sse-swap="message"></article>

WebSocket

We use, ethers.js to poll for new blocks and use a rxjs Observable to emit blocks via a nest.js Websocket gateway, with the ws adapter and display the results using the vanilla.js Websocket API on the client side.

With html and vanilla.js

Example minimal client using .html file: client/src/ws/ethers/ws-block-number.html

Setting up a Websocket to the NestJS WS Gateway

// For Ethers
const ethersSocket = new WebSocket('ws://localhost:3000');
// For Solkit
const solkitSocket = new WebSocket('ws://localhost:3000');

GraphQL

We use, ethers.js to get a block-by-block number and use a rxjs Observable to emit the block via a nest.js GraphQL Resolver with an Apollo Server.

With html and vanilla.js

Example minimal client using .html file: client/src/graphql/ethers/graphql-block-query.html

Making a GraphQL request to the NestJS GraphQL Resolver

const res = await fetch('http://127.0.0.1:3000/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: query,
    variables: { blockNumber: blockNumber }
  })
});

Misc

Related info and links.

API URL Best Practices

Examples: Format /[version]/[domain]/[resource]/[resource_id]/[hiearchical_resource]/[hiearchical_resource_id]

  • [GET] /v1/treasury/customers/{customer_id}/orders
  • [POST] /v1/treasury/customers/{customer_id}/orders
  • [GET] /v1/treasury/customers/{customer_id}/orders/{order_id}
  • [PUT] /v1/treasury/customers/{customer_id}/orders/{order_id}
  • [DELETE] /v1/treasury/customers/{customer_id}/orders/{order_id}
  • [PATCH] /v1/treasury/customers/{customer_id}/orders/{order_id}
  1. Versioning (/v1/)
    • Allows backward compatibility when introducing breaking changes
  2. Domain (/treasury/)
    • Organizes APIs by business domain or bounded context
  3. Resource (/customers/)
    • Everything is a resource
    • collection → item → subcollection → subitem
  4. Hierarchical Resource (/orders/)
    • Parent-child relationships: customers ONEtoMANY orders
    • Child access in parent scope (Mirror database schema)

GOOD

# Clear hierarchy and context
GET /v1/treasury/customers/123/orders/456

BAD

# vs ambiguous flat structure
GET /v1/orders/456  // Which customer? No context.

Block Explorers

Related Articles


License

This project is licensed under the MIT License—see the LICENSE file for details.

Maintained by Hella Labs.


Nest Logo


🥚


Chris Anatalio

About

Nestjs TypeORM Full Example with PostgreSQL, Axios, Typescript that integrates with multiple Web3 SDKs/APIs including ethers.js and Solana kit with REST, GraphQL, Websocket and SSE endpoints

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors