Skip to content

taller2-grupo5-rostov-1c2022/payments-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Production pipeline codecov Fastify

Spotifiuby Payments Server

Dependencies

This project is based on Taller 2 - Basic Payment SC. To install the project we recommend that you use NVM and install the node version defined in .nvmrc (v12.18.1) or nvm use

Once you have that in place, you can install the dependencies with npm through npm i

Alternatively, you can use docker-compose up --build command in the project root.

Check out the SC in Etherscan 🚀

Docker

You need docker-compose and docker to run the following containers and commands.

Developing with container and database

$ sudo docker-compose up --build

Running tests within container

You can run a container which will run the app and will provide the database. In one terminal run:

$ sudo docker-compose up --build

Then in other terminal run docker ps and copy the container ID from the sc_spotifiuby_payments-server image:

$ docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS          PORTS                                       NAMES
f0d1f3905aa9   sc_spotifiuby_payments-server   "docker-entrypoint.s…"   49 seconds ago   Up 48 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   sc_spotifiuby_payments-server_1
7abd82e44f98   postgres:14.2                   "docker-entrypoint.s…"   2 weeks ago      Up 48 seconds   0.0.0.0:5438->5432/tcp, :::5438->5432/tcp   sc_spotifiuby_postgres_1

Finally, enter the container with docker exec -it [container-id] bash and run the tests within the container using npm run test:

$ docker exec -it [container-id] bash
$ root@f0d1f3905aa9:/app# ls
Dockerfile  artifacts  contracts  coverage.json  deployments         hardhat.config.ts  heroku-Dockerfile  package-lock.json  postgres-data  src   tsconfig.json
README.md   cache      coverage   deploy         docker-compose.yml  heroku             node_modules       package.json       scripts        test  typechain
$ root@b1e9c7c4e040:/code# npm run test

API Documentation

The following endpoints are available:

Keep in mind that all endpoints needs a api_key header with the API key value defined in the .env (see below).

  • Create wallet
    • POST api/v1/wallets/{userId}
      • Path: userId is the id of the user.
      • Body: empty
      • Example: POST /wallets/asd123
      • Response: the address property is the address of the wallet for that particular user.
{
    "id": 5,
    "user_id": "asd123",
    "private_key": "0x8082e5c8b45ce5698af26a51b314503eb0488d239d49c225e59405373aa1bda9",
    "address": "0x00Bd8EbEeBEE720cF3Cabe401bc4b96E362B9C61"
}
  • Get wallets
    • GET api/v1/wallets
      • Path: empty
      • Body: empty
      • Example: GET /wallets
      • Response: the address property is the address of the wallet for that particular user.
[
    {
        "id": 1,
        "user_id": "1",
        "private_key": "0x8cd44b554456c3185ba845388b10943a2f36e4f5d9e9ddcfc217f55aa083f18b",
        "address": "0x95B883F075d438CEA5952c5a7163EF1ED49c4Eda"
    },
    {
        "id": 2,
        "user_id": "8f4g5f6g",
        "private_key": "0x2cd9e69a82aa14c796cfdfc499cc429d8ff6ebfdc5994f25cef30ca223da9d51",
        "address": "0xCe52D4545A36c1366e21B86Cf8040Bd307b6318F"
    },
    {
        "id": 3,
        "user_id": "facu1",
        "private_key": "0xafd5ea47258633c390cfbe9235720423495c03900101e083b4bfb2c19caa2653",
        "address": "0xaa994f63f812A136158aC937aCC806E40b85739d"
    },
    {
        "id": 5,
        "user_id": "asd123",
        "private_key": "0x8082e5c8b45ce5698af26a51b314503eb0488d239d49c225e59405373aa1bda9",
        "address": "0x00Bd8EbEeBEE720cF3Cabe401bc4b96E362B9C61"
    }
]
  • Get wallet from specific user
    • GET api/v1/wallets/{userId}
      • Path: userId is the id of the user.
      • Body: empty
      • Example: GET /wallets/asd123
      • Response: the address property is the address of the wallet for that particular user.
{
    "id": 5,
    "user_id": "asd123",
    "private_key": "0x8082e5c8b45ce5698af26a51b314503eb0488d239d49c225e59405373aa1bda9",
    "address": "0x00Bd8EbEeBEE720cF3Cabe401bc4b96E362B9C61"
}
  • Deposit ethers into the Smart contract
    • POST api/v1/deposit/{userId}
      • Path: userId is the id of the user.
      • Body: amountInEthers is the amount of ethers to deposit as a string. { "amountInEthers": "0.0001" }
      • Example: POST /deposit/asd123
      • Response: transaction receipt. from property should be the address of the wallet for that userId
{
    "nonce": 2,
    "gasPrice": {
        "type": "BigNumber",
        "hex": "0x4190ab08"
    },
    "gasLimit": {
        "type": "BigNumber",
        "hex": "0x6d78"
    },
    "to": "0xE9f7F026355d691238F628Cd8BCBb39Bf7F4f8E2",
    "value": {
        "type": "BigNumber",
        "hex": "0x5af3107a4000"
    },
    "data": "0xd0e30db0",
    "chainId": 4,
    "v": 43,
    "r": "0xc8fc145f611e8e5552374c3dedc2f588458d7214a523b095d70f5478bf06bdf8",
    "s": "0x0ff83c7c81028bfa59aa8375b489daaa77787aa80ba4d7421a1ea09621abc607",
    "from": "0xaa994f63f812A136158aC937aCC806E40b85739d",
    "hash": "0xcc9c8acb976d44bc96e4a10f6c89d7431ab5e08fc681db5a6e682c213ab5c101"
}
  • Get transactions
    • GET api/v1/transactions
      • Path: empty
      • Body: empty
      • Headers: role with the role value of admin, artist or listener.
      • Example: GET /transactions
      • Response example: id represents the tx's hash.
[
    {
        "id": "0x8d9f054f2bae4c5a3a243c6878a47e31dc5e63d55dfa144964ccb59711e5653d",
        "user_id": "facu1",
        "receiver_address": "0xE9f7F026355d691238F628Cd8BCBb39Bf7F4f8E2",
        "sender_address": "0xaa994f63f812A136158aC937aCC806E40b85739d",
        "amount": 0.0001,
        "day": 28,
        "month": 5,
        "year": 2022
    },
    {
        "id": "0xcc9c8acb976d44bc96e4a10f6c89d7431ab5e08fc681db5a6e682c213ab5c101",
        "user_id": "facu1",
        "receiver_address": "0xE9f7F026355d691238F628Cd8BCBb39Bf7F4f8E2",
        "sender_address": "0xaa994f63f812A136158aC937aCC806E40b85739d",
        "amount": 0.0001,
        "day": 28,
        "month": 5,
        "year": 2022
    }
]
  • Get transactions from specific user
    • GET api/v1/transactions/{userId}
      • Path: userId is the id of the user.
      • Body: empty
      • Headers: role with the role value of admin, artist or listener.
      • Example: GET /transactions/asd123
      • Response example: id represents the tx's hash.
[
    {
        "id": "0x8d9f054f2bae4c5a3a243c6878a47e31dc5e63d55dfa144964ccb59711e5653d",
        "user_id": "asd123",
        "receiver_address": "0xE9f7F026355d691238F628Cd8BCBb39Bf7F4f8E2",
        "sender_address": "0xaa994f63f812A136158aC937aCC806E40b85739d",
        "amount": 0.0001,
        "day": 28,
        "month": 5,
        "year": 2022
    }
]
  • Make payment to specific user
    • POST api/v1/pay/{userId}
      • Path: userId is the id of the user.
      • Body: amountInEthers is the amount of ethers to deposit as a string. {"amountInEthers": "0.0001"}
      • Headers: role with the role value of admin, artist or listener.
      • Example: POST /pay/asd123
      • Response example: id represents the tx's hash, to is the address of the receiver, from is the address of the sender.
{
    "nonce": 9,
    "gasPrice": {
        "type": "BigNumber",
        "hex": "0x3c6b6cca"
    },
    "gasLimit": {
        "type": "BigNumber",
        "hex": "0x919f"
    },
    "to": "0xaa994f63f812A136158aC937aCC806E40b85739d",
    "value": {
        "type": "BigNumber",
        "hex": "0x00"
    },
    "data": "0x935f4c18000000000000000000000000aa994f63f812a136158ac937acc806e40b85739d000000000000000000000000000000000000000000000000002386f26fc10000",
    "chainId": 4,
    "v": 44,
    "r": "0x757a11857014df7a6efcc444e6857891c8a3a74e575361e442208c227c7c57ba",
    "s": "0x68929ce2f7b530535a813b6aeb2a1da630efa842e359e4ec4c6480f4ad9a736c",
    "from": "0xE9f7F026355d691238F628Cd8BCBb39Bf7F4f8E2",
    "hash": "0x342d49c9ee513ffefebdb9120abce0eb9045bb5040ce337a228cba2851b3a53e"
}
  • Get balance from a wallet for a specific user (Header)
    • GET api/v1/balances/
      • Headers: uid is the id of the user formatted as a string.
      • Response example: balance represents the balance of the user in ethers.
{
    "balance": "0.05156058679858502"
}
  • Get balance from a wallet for a specific user (Path)
    • GET api/v1/balances/{userId}
      • Path: userId is the id of the user formatted as a string.
      • Headers: role with the role value of admin, artist or listener.
      • Response example: balance represents the balance of the user in ethers.
{
    "balance": "0.05156058679858502"
}
  • Get balance from SC
    • GET api/v1/balances/system
      • Headers: role with the role value of admin, artist or listener.
      • Response example: balance represents the balance of the SC in ethers. systemAddress represents the address of the SC.
{
    "balance": "0.05156058679858502",
    "systemWallet": "0x112312f15f1f51f8e"
}

Heroku

You'll need to set the following actions secrets to deploy the project to Heroku:

  • HEROKU_APP_NAME: App name
  • HEROKU_EMAIL: Account email
  • HEROKU_API_KEY: Account API key

Datadog

The heroku Dockerfile includes the DataDog agent. Create a new DataDog API Key from here. Also, you need to set the following config vars in Heroku (you can use Heroku CLI if you want):

DD_API_KEY=<api_key_from_datadog>
DD_DYNO_HOST=false
HEROKU_APP_NAME=<app_name>
DD_TAGS=service:<meaningful_tag_for_datadog>

Upload Coverage to Codecov

The pipeline automatically generates a coverage report and uploads it to codecov

You'll need to set the following actions secrets:

  • CODECOV_TOKEN: Repo Token. Can be obtained on codecov when setting up or on settings

Usage

Environment variables

Keep in mind that you have to set the following variables in a .env file in the root of the project:

  • INFURA_API_KEY: The API key for the Infura node, you can get it from the Infura dashboard
  • MNEMONIC: The mnemonic for the wallet, you can get it from MetaMask.
  • PORT: The port to run the server on. The default port is 3000.
  • API_KEY: The API key value for API authentication.
  • ETHERSCAN_API_KEY: The API key for the Etherscan node, you can get it from the Etherscan dashboard

This repository already contains these variables set as actions secrets and the deployment pipeline generates a .env file with those secrets.

Testing

To run the tests, after you installed the dependencies, just run npm run test

Linting

To run the linter, after you installed the dependencies, just run npm run lint

Coverage

To create a coverage report, after you installed the dependencies, just run npm run coverage

SC Deployment

To deploy the smart contract just run npm run deploy-rinkeby or npm run deploy-local for local development.