The Bhojpur Wallet is a platform-as-a-service product used as a Wallet Engine based on the Bhojpur.NET Platform for application delivery.

Bhojpur Wallet - Data Processing Engine

The Bhojpur Wallet is a platform-as-a-service used as a Service Engine based on the Bhojpur.NET Platform. It leverages PostgreSQL database for storage.

Bounded Contexts

The application uses the following bounded contexts:

  1. Admin
  2. Agent
  3. Merchant
  4. Subscriber
  5. Transaction
  6. Account
  7. Statement
  8. Tariff
  9. Auth
  10. Customer
1. Admin Context

The application needs some form of administration by a super user in-charge with the responsibility of running and maintaining the application to ensure reliability and stability. This user is an admin and is given their own bounded context. Some responsibilities/actions of this user are:

  1. Can login to system or register.
  2. Can assign float to a Super Agent.
  3. Can configure tariff
  4. Can suspend/change status of a customer account
  5. Can view/edit/delete customer accounts

As the application grows and scales the administrator context would have more responsibilities.

  1. The application would need more than one administrator and more so more than one category of administrators. Some examples of administrators with their roles include:

    i. Customer Care - is a part admin who would assist customers with information about the system and troubleshoot problems.

    ii. Finance - is a part admin whose responsibilities would be financial and accounting aspect in the system.

    iii. IT - an admin whose responsible for the infrastructure that the system runs on.

2. Agent Context

We have developed a wallet and money transfer service for a Telco and we have been given the go ahead by the Central Bank to deploy the application and get some customers to use our system. There are however some initial steps the business has to perform to start onboarding new customers. The system should be able to have some level of autonomy when it comes to the flow of money. That is where agents come in.

The initial obstacle in the pilot is gaining the Agentโ€™s trust and encouraging them to process cash withdrawals and agent training.

Our first initial steps before we can roll out a Payment Wallet service

  1. Acquire a business entity licensed to hold public money (i.e. a Bank).
  2. Create a Super Agent(s) whose task would be depositing money to our bank account.
  3. Once a Super Agent deposits to our account, we assign them with an equivalent amount of float they can sell to other agents.
  4. When we onboard an ordinary Agent, they will have a balance of zero, and they will approach the Super Agent to get float.

The Agents are important customers to the system. They can also have various categories depending on the business use case. For example, we have two types of agents:

  1. Super Agent
  2. Ordinary Agent
3. Merchant Context

Our system has two kinds of Merchants.

  1. A merchant to provides utility services to their customers
  2. A merchant that sells goods and services to end customers

Both the merchants have unique ways of how customers pay for their good and services. However, both the merchants have an account number.

  1. Pay bill number as an Account number for a merchant - Customer provides the pay bill number, a customer account number and the amount.
  2. Till number as an account number for a merchant - Customer provides the till number and amount.

Pay bill number is usually given to utility companies that need to identify from whom the payment is coming from by the customer account number.

Till number is usually given to small scale traders that want to accept payment via our system from their customers.

For example, we stick to one general Merchant that accepts payments.

4. Subscriber Context

A subscriber does not have much going on. They can authenticate and perform a transaction.

5. Transaction Context

Contains all business logic in regard to transactions happening in the system. It enforces the transaction rules and business policy.

Business Policies:

  1. A transaction cannot happen between identical customers i.e. a customer cannot transact with themselves
  2. A deposit cannot be done by customer none other than an Agent
  3. A customer cannot perform a withdrawal with no other customer than an Agent
  4. A super agent is however only allowed to do deposits for other agents only
  5. Customers are not allowed to deposit, withdraw or transfer money below the minimum amount allowed
  6. Apply transaction fee as per the tariff configured
6. Account Context

The main responsibility of this context is managing customer accounts/wallets. Responsibilities:

  1. Updating account balances, credit/debit accounts
  2. Updating system ledger after changing account balances
7. Statement Context

The main responsibility of this context is managing the system ledger. If we scale the system, we can view this ledger as the statements/transactions event store. Borrowing from event sourcing design, our statement context is a record of every event with customer transactions.

8. Tariff Context

This context has a responsibility of configuring and maintaining the tariff used in various transactions.

9. Auth Context

The system has four different types of users, admin, agent, subscriber and merchant. The auth context is responsible for authenticating and authorizing these users into the system.

10. Customer Context

This context is mainly an aggregator of the agent, merchant and subscriber contexts. It exposes common functionality for, which can be used in other core contexts.

Installation

To begin with, the application uses PostgreSQL database as the backend database.

Database Installation

The application uses PostgreSQL as the database server. To setup PostgreSQL on local your machine using Docker.

Get the official PostgreSQL docker image.

$ docker pull postgres

then create a container from the image with the following variables

$ docker create \
--name mpesa-db \
-e POSTGRES_USER=bhojpur \
-e POSTGRES_PASSWORD=bhojpur \
-p 5432:5432 \
postgres

Run the following command to start the container

$ docker start bhojpur-db

Application Installation

Running the application is very simple. First, we need to copy and create our configuration.

Lets begin. Cloning ...

$ git clone https://github.com/bhojpur/wallet.git

Configuring

$ cd wallet
$ cp config.yml.example config.yml

This configuration file looks something like this

database:
  host: "127.0.0.1"
  port: "5432"
  user: "bhojpur"
  password: "bhojpur"
  dbname: "bhojpur"

app_secret_key: "eQig7GS4cHO2su"

You can change the config variables depending on your database setup. I have followed the default setup shown at database installation step.

Building and running

Using the Binary
$ mkdir bin
$ go build -o bin/wallet-server 
$ ./bin/wallet-server

It will install all dependencies required and produce a binary for your platform.

Using the Dockerfile

Make sure you have docker installed and working properly.

$ docker build -t bhojpur-wallet:latest .
$ docker container create --network=host --name wallet-server --restart unless-stopped wallet-server
$ docker container start wallet-server

The server will start at port 6700.

Enjoy.

API Usage

A description of the RESTful Web Services APIs.

Endpoints

All the routes exposed in the application are defined in this function

func apiRouteGroup(api fiber.Router, domain *registry.Domain, config app.Config) {

	api.Post("/login/:user_type", user_handlers.Authenticate(domain, config))
	api.Post("/user/:user_type", user_handlers.Register(domain))

	// create group at /api/admin
	admin := api.Group("/admin", middleware.AuthByBearerToken(config.Secret))
	admin.Post("/assign-float", user_handlers.AssignFloat(domain.Admin))
	admin.Post("/update-charge", user_handlers.UpdateCharge(domain.Tariff))
	admin.Get("/get-tariff", user_handlers.GetTariff(domain.Tariff))
	admin.Put("/super-agent-status", user_handlers.UpdateSuperAgentStatus(domain.Agent))

	// create group at /api/account
	account := api.Group("/account", middleware.AuthByBearerToken(config.Secret))
	account.Get("/balance", account_handlers.BalanceEnquiry(domain.Account))
	account.Get("/statement", account_handlers.MiniStatement(domain.Statement))

	// create group at /api/transaction
	transaction := api.Group("/transaction", middleware.AuthByBearerToken(config.Secret))
	transaction.Post("/deposit", transaction_handlers.Deposit(domain.Transactor))
	transaction.Post("/transfer", transaction_handlers.Transfer(domain.Transactor))
	transaction.Post("/withdraw", transaction_handlers.Withdraw(domain.Transactor))
}

The routes are mounted on the prefix /api so your requests should point to

POST /api/login/<user_type>                     <-- user_type can be either of agent, admininistrator, merchant, subscriber
POST /api/user/<user_type> # for registration   <-- user_type can be either of agent, admininistrator, merchant, subscriber
POST /api/admin/assign-float
POST /api/admin/update-charge
GET /api/admin/get-tariff
PUT /api/admin/super-agent-status
GET /api/account/balance
POST /api/account/statement
POST /api/transaction/deposit
POST /api/transaction/transfer
POST /api/transaction/withdraw

To Register

The APIs can be used to register four types of users: admin, agent, merchant and subscriber

Admin Registration

An admin can be registered to the API with the following POST parameters

firstName, lastName, email, password

Curl request example

curl --request POST \
  --url http://localhost:6700/api/user/administrator \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data firstName=Admin \
  --data lastName=Batua \
  --data [email protected] \
  --data password=welcome

Response example

{
  "status": "success",
  "message": "user created",
  "data": {
    "userID": "bc8f933b-b0aa-4049-9caf-dfe73008bc24",
    "userType": "administrator"
  }
}
Agent Registration

At minimum, you need to create two agents, one of which will become a super agent. An agent can be registered to the APIs with the following POST parameters

firstName, lastName, email, phoneNumber, password

Curl request example

curl --request POST \
  --url http://localhost:6700/api/user/agent \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data firstName=Agent \
  --data lastName=Batua \
  --data [email protected] \
  --data phoneNumber=16282004199 \
  --data password=welcome

Response example

{
  "status": "success",
  "message": "user created",
  "data": {
    "userID": "cca4d238-74ae-4d47-aae8-b0ab952aac28",
    "userType": "agent"
  }
}
Merchant Registration

A merchant can be registered to the api with the following POST parameters

firstName, lastName, email, phoneNumber, password

Curl request example

curl --request POST \
  --url http://localhost:6700/api/user/merchant \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data firstName=Merchant \
  --data lastName=Batua \
  --data [email protected] \
  --data phoneNumber=16282004199 \
  --data password=welcome

Response example

{
  "status": "success",
  "message": "user created",
  "data": {
    "userID": "c3a71820-ef66-74d9-adc8-f365a234ed5c",
    "userType": "merchant"
  }
}
Subscriber Registration

A subscriber can be registered to the api with the following POST parameters

firstName, lastName, email, phoneNumber, password

Curl request example

curl --request POST \
  --url http://localhost:6700/api/user/subscriber \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data firstName=Subscriber \
  --data lastName=Batua \
  --data [email protected] \
  --data phoneNumber=16282004199 \
  --data password=welcome

Response example

{
  "status": "success",
  "message": "user created",
  "data": {
    "userID": "cf8d7f25-367e-4ac7-8b5f-eaa7608e6c3f",
    "userType": "subscriber"
  }
}

To Login

You can use the following POST parameters for login with any of the four users email, password

Curl request example for subscriber login

curl --request POST \
  --url http://localhost:6700/api/login/subscriber \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data [email protected] \
  --data password=welcome

Response example

{
  "userId": "cf8d7f25-367e-4ac7-8b5f-eaa7608e6c3f",
  "userType": "subscriber",
  "token": "eyJhbGciOiJIUzI1NiIsInR4cCI6IkpXVCJ8.eyJ1c2VyIjp7InVzZXJJZCI6ImNmOWQ5ZjI4LTM1N2UtNGFjNy05YjVmLWVhYTg2MDllNmMyZiIsInVzZXJUeXBlIjoic3Vic2NyaWJlciJ9LCJleHAiOjE2MDU0MTYwNjAsImlhdCI6MTYwNTM5NDQ2MH0.lAJ4WpF2Mnfg52iuTOoPV8nvbHV3JrMQOC-5xXrQ5EE"
}

NOTE: The remaining endpoints require the token acquired above for authentication

Initial Steps Before Transacting

There are some initial setups that need to be done before you can begin doing transactions.

1. Creating a Super Agent

Before you can start transacting, you need to login as an administrator and create a Super Agent by changing the status of an existing agent. When registering an Agent, you ought to have created at minimum two agents. It is now that we need make one of those agents a Super Agent.

The following endpoint is used to update the super agent status of an Agent.

PUT /api/admin/super-agent-status requires the following post parameters: email

Curl request example

curl --request PUT \
  --url http://localhost:6700/api/admin/super-agent-status \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6Ijc2YmM0YWEzLTAyNWQtNGQ1YS1hNWZiLWY1NDk1NTdmNjM0YSIsInVzZXJUeXBlIjoiYWRtaW5pc3RyYXRvciJ9LCJleHAiOjE2MDU0NTE4MDUsImlhdCI6MTYwNTQzMDIwNX0.8lTWl9hGr9GTST7WpEpzKdm_gqhMkf4qUellLx4o5bw' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data [email protected]

Response example

{
  "status": "success",
  "message": "Super Agent Status updated"
}
2. Assigning Float

Login as an Administrator, you need to assign float to your super-agent using the following endpoint

POST /api/admin/assign-float

Curl request example

curl --request POST \
  --url http://localhost:6700/api/admin/assign-float \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6ImE3OGVjNjNhLTA0ZWItNDAzNC1iZmVkLTBhNmMwMjU3ZTJlNCIsInVzZXJUeXBlIjoiYWRtaW5pc3RyYXRvciJ9LCJleHAiOjE2MDUzMjExNzUsImlhdCI6MTYwNTI5OTU3NX0.4fGlMJQB-eylKwOAwa4d16nVQQt3uYgwPbUjYt7j9zA' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data [email protected] \
  --data amount=100000

Response example

{
  "status": "success",
  "message": "Float has been assigned.",
  "data": {
    "balance": 100000
  }
}
3. Transfer Float to Agents

The super-agent is limited to depositing to Agents only. You will need to transfer the acquired float to other Agents you have registered.

4. Configure Tariff

The default tariff in the system is set to zero amount for all chargeable transactions. You could begin testing transactions using the default tariff and later choose to configure your own tariff. Choose your poison :-).

You can configure a tariff by updating the available charges. The system doesn't allow you to add any other charge band.

GET /api/admin/get-tariff - use this endpoint to get the available configured transaction charges

Response example

{
  "status": "success",
  "message": "Tariff retrieved",
  "data": [
    {
      "id": "acf3e6bf-c9de-45b4-a8b6-bf97f92b783a",
      "txnOperation": "WITHDRAW",
      "srcUserType": "subscriber",
      "destUserType": "agent",
      "fee": 0
    },
    {
      "id": "0e5a4aaa-135a-4464-96c9-d021f769bdb7",
      "txnOperation": "WITHDRAW",
      "srcUserType": "merchant",
      "destUserType": "agent",
      "fee": 0
    },
    {
      "id": "243e7ecc-c2dd-41bb-9953-1278050bfb64",
      "txnOperation": "WITHDRAW",
      "srcUserType": "agent",
      "destUserType": "agent",
      "fee": 0
    },
    {
      "id": "f8835176-316c-49de-b001-687e2c4a338d",
      "txnOperation": "TRANSFER",
      "srcUserType": "agent",
      "destUserType": "agent",
      "fee": 0
    },
    {
      "id": "4edeb6d0-37cd-4c67-997a-0b3fa93b722d",
      "txnOperation": "TRANSFER",
      "srcUserType": "subscriber",
      "destUserType": "subscriber",
      "fee": 0
    },
    {
      "id": "94c0ae8b-a131-41b9-b5af-5235b8926fa4",
      "txnOperation": "TRANSFER",
      "srcUserType": "merchant",
      "destUserType": "subscriber",
      "fee": 0
    },
    {
      "id": "450e4baa-58c3-41b3-abe5-a55555492e0c",
      "txnOperation": "TRANSFER",
      "srcUserType": "subscriber",
      "destUserType": "merchant",
      "fee": 0
    },
    {
      "id": "3623a89f-c496-41c8-b6c9-73429cc4ef9d",
      "txnOperation": "TRANSFER",
      "srcUserType": "agent",
      "destUserType": "merchant",
      "fee": 0
    }
  ]
}

POST /api/admin/update-charge - use this endpoint to update a charge using its id.

You need the following POST parameters

amount, chargeId - The amount should be in cents.

Curl request example

curl --request POST \
  --url http://localhost:6700/api/admin/update-charge \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6Ijc2YmM0YWEzLTAyNWQtNGQ1YS1hNWZiLWY1NDk1NTdmNjM0YSIsInVzZXJUeXBlIjoiYWRtaW5pc3RyYXRvciJ9LCJleHAiOjE2MDU0NTE4MDUsImlhdCI6MTYwNTQzMDIwNX0.8lTWl9hGr9GTST7WpEpzKdm_gqhMkf4qUellLx4o5bw' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data amount=1050 \
  --data chargeId=acf3e6bf-c9de-45b4-a8b6-bf97f92b783a

Response example

{
  "status": "success",
  "message": "charge configured"
}

Performing Transactions

While configuring a charge requires you to provide the amount in paisas, performing transactions requires the amount to be in whole units i.e. rupees

Transacting also requires you to provide an accountNo, use the email of the customer as the accountNo

customerType can be either of agent, merchant or subscriber

1. To Deposit

A deposit is only done by an agent. You need an agent token to perform this transaction.

You need the following POST parameters

amount, accountNo and customerType

Curl request example

curl --request POST \
  --url http://localhost:6700/api/transaction/deposit \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6ImNjYTdkMjI3LTc0YWUtNGQ0Ny1hYWU4LWEwYWI5NTJhYWMyOCIsInVzZXJUeXBlIjoiYWdlbnQifSwiZXhwIjoxNjA1MzIxODEyLCJpYXQiOjE2MDUzMDAyMTJ9.jFLfjScuvHaOV68n11sRticy2ntzQRhwbNq5E4sPmQI' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data amount=400 \
  --data [email protected] \
  --data customerType=subscriber

Response example

{
  "status": "success",
  "message": "Success",
  "data": {
    "message": "Transaction under processing. You will receive a message shortly."
  }
}
2. To Withdraw

You need the following POST parameters

amount, agentNumber

Use agent email for agentNumber

Curl request example

curl --request POST \
  --url http://localhost:6700/api/transaction/withdraw \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6ImNmOWQ4ZjI4LTM1N2UtNGFjNy05YjVmLWVhYTg2MDllNmMyZiIsInVzZXJUeXBlIjoic3Vic2NyaWJlciJ9LCJleHAiOjE2MDU0MTYwNjAsImlhdCI6MTYwNTM5NDQ2MH0.lAJ4WpF2Mnfg52iuTOoPV8nvbHV3JrMQOC-5xXrQ5EE' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data amount=40 \
  --data [email protected]

Response example

{
  "status": "success",
  "message": "Success",
  "data": {
    "message": "Transaction under processing. You will receive a message shortly."
  }
}
3. To Transfer

You need the following POST parameters

amount, accountNo and customerType

Curl request example

curl --request POST \
  --url http://localhost:6700/api/transaction/transfer \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6ImNmOWQ4ZjI4LTM1N2UtNGFjNy05YjVmLWVhYTg2MDllNmMyZiIsInVzZXJUeXBlIjoic3Vic2NyaWJlciJ9LCJleHAiOjE2MDUzMjE5MDMsImlhdCI6MTYwNTMwMDMwM30.vLiHdNTr4onTVqUZbLbdpwgbH98VYzHJJU-JKtFOHVg' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data amount=30 \
  --data [email protected] \
  --data customerType=merchant

Response example

{
  "status": "success",
  "message": "Success",
  "data": {
    "message": "Transaction under processing. You will receive a message shortly."
  }
}

To Query Balance

This is just a GET request, no params

Curl request example

curl --request GET \
  --url http://localhost:6700/api/account/balance \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6ImNmOWQ4ZjI4LTM1N2UtNGFjNy05YjVmLWVhYTg2MDllNmMyZiIsInVzZXJUeXBlIjoic3Vic2NyaWJlciJ9LCJleHAiOjE2MDUzNjY3NTMsImlhdCI6MTYwNTM0NTE1M30.-Piib6bXzYqb0S8nLo76SBTyGmWi7UPUMExptIcqBZI'

Response example

{
  "status": "success",
  "message": "Your current balance is 690",
  "data": {
    "userID": "cf8d7f25-367e-4ac7-8b5f-eaa7608e6c3f",
    "balance": 690
  }
}

To Get Mini Statement

This is just a GET request, no params

Curl request example

curl --request GET \
  --url http://localhost:6700/api/account/statement \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6Ijk4YmNmMmY1LWRiY2ItNDk1NS04NTU0LTc0OWYxMTVhZjU5OCIsImVtYWlsIjoiIn0sImV4cCI6MTYwNDA2OTE0MywiaWF0IjoxNjA0MDQ3NTQzfQ.IYyclrC66aweehs_A4Sigmc83a27udmPofM2yOeut9Q'

Response example

{
  "status": "success",
  "message": "mini statement retrieved for the past 5 transactions",
  "data": {
    "message": "mini statement retrieved for the past 5 transactions",
    "userID": "cf8d7f25-367e-4ac7-8b5f-eaa7608e6c3f",
    "transactions": [
      {
        "transactionId": "97c3ff6d-72d5-479d-8838-85a5c32985a2",
        "transactionType": "DEPOSIT",
        "createdAt": "2020-11-14T01:59:28.613007+03:00",
        "creditedAmount": 400,
        "debitedAmount": 0,
        "userId": "cf8d7f25-367e-4ac7-8b5f-eaa7608e6c3f",
        "accountId": "63978e26-9c0d-40eb-a24b-d1ae51e21942"
      },
      {
        "transactionId": "4be4a008-b18e-4d4b-95d3-58b660d5b931",
        "transactionType": "TRANSFER",
        "createdAt": "2020-11-14T01:59:05.949066+03:00",
        "creditedAmount": 0,
        "debitedAmount": 30,
        "userId": "cf9d8f28-357e-4ac7-9b5f-eaa8609e6c2f",
        "accountId": "63978e26-9c0d-40eb-a24b-d1ae51e21942"
      },
      {
        "transactionId": "45da6c6a-03d8-4d58-849a-fd80bbfabbb4",
        "transactionType": "TRANSFER",
        "createdAt": "2020-11-14T01:57:04.622507+03:00",
        "creditedAmount": 0,
        "debitedAmount": 40,
        "userId": "cf9d8f28-357e-4ac7-9b5f-eaa8609e6c2f",
        "accountId": "63978e26-9c0d-40eb-a24b-d1ae51e21942"
      }
    ]
  }
}

Testing

Tests have been written for the application.

An approach to testing this application would be something in the following lines.

  1. Test the code in the interactor files
  2. Test the code in the repository files

The above files carry the bulk of the behaviour of the whole application, they are the business logic of the application. The rest of the files are just implementation details that could change rapidly and the tests written for them would certainly fail after change.

e.g. the HTTP handler functions in the application uses gofiber, writing unit tests for them is good but not desired, because gofiber can be replaced with mux easily and that would break your tests.

Owner
Bhojpur Consulting
A software developer building enterprise grade solutions
Bhojpur Consulting
Similar Resources

API wrapper over high-load TON wallet

highload-wallet-api API wrapper over high-load TON wallet smart contract. Can be

Nov 4, 2022

Minilotus - A simple wallet manager of lotus

A simple wallet manager of lotus. Refer to https://github.com/filecoin-project/l

Jan 5, 2022

A simple ticket-wallet API. It is fully dockerized

Ticket Wallet This is a simple ticket-wallet API. It is fully dockerized. Table of contents 1 Response Data format 2 API โ€ƒ2.1 Get layout โ€ƒ2.2 Start se

Jan 23, 2022

Blockcain - Trust Wallet token repository - A comprehensive, up-to-date collection of information about several thousands (!) of crypto tokens

Blockcain - Trust Wallet token repository - A comprehensive, up-to-date collection of information about several thousands (!) of crypto tokens

Trust Wallet Assets Info Overview Trust Wallet token repository is a comprehensi

Feb 14, 2022

Akroma GO client - Akroma is an EVM based application development platform (smart-contracts).

Akroma Akroma is an EVM based application development platform (smart-contracts). Akroma will utilize a Masternode system, and build out an Oracle pla

Dec 11, 2022

Powerful Blockchain streaming data engine, based on StreamingFast Firehose technology.

Substreams - A streaming data engine for The Graph - by StreamingFast DEVELOPER PREVIEW OF SUBSTREAMS Think Fluvio for deterministic blockchain data.

Dec 30, 2022

Cross-platform application for easy encrypted sharing of files, folders, and text between devices.

Cross-platform application for easy encrypted sharing of files, folders, and text between devices.

wormhole-gui Wormhole-gui is a cross-platform application that lets you easily share files, folders and text between devices. It uses the Go implement

Dec 30, 2022

A fast and lightweight interactive terminal based UI application for tracking cryptocurrencies ๐Ÿš€

A fast and lightweight interactive terminal based UI application for tracking cryptocurrencies ๐Ÿš€

cointop is a fast and lightweight interactive terminal based UI application for tracking and monitoring cryptocurrency coin stats in real-time.

Jan 6, 2023

The Fabric Smart Client is a new Fabric Client that lets you focus on the business processes and simplifies the development of Fabric-based distributed application.

Fabric Smart Client The Fabric Smart Client (FSC, for short) is a new Fabric client-side component whose objective is twofold. FSC aims to simplify th

Dec 14, 2022
Related tags
Ethereum-vanity-wallet - A fork of https://github.com/meehow/ethereum-vanity-wallet but the key can be exported to a JSON keystore file

ethereum-vanity-wallet See https://github.com/meehow/ethereum-vanity-wallet This version: doesn't display the private key let's you interactively expo

Jan 2, 2022
Scp-wallet-api - Backend for SCP Wallet app

SCP Wallet API Backend for SCP Wallet app. It exposes a simplified REST API whic

Jan 31, 2022
Personal-Solana-Wallet - Create your personal wallet on Solana blockchain

Personal Wallet on Solana using Go โ™พ๏ธ Setting up environment Installation of Cob

Nov 9, 2022
A simple, secure self-destructing message service, using HashiCorp Vault product as a backend
A simple, secure self-destructing message service, using HashiCorp Vault product as a backend

sup3rS3cretMes5age! A simple, secure self-destructing message service, using Has

Mar 5, 2022
SwissWallet is a deterministic cryptocurrency wallet generator heavily based on MindWallet and MemWallet

SwissWallet SwissWallet is a deterministic cryptocurrency wallet generator heavily based on MindWallet and MemWallet but using argon2 and scrypt by de

Jul 28, 2022
An easy to setup local crypto wallet based on Geth

CryptoWallet An easy to setup local crypto wallet based on Geth To run. go run CrytoWallet This will expose a set a api's. To Create new Wallet curl

Oct 15, 2021
A work-in-progress Bitcoin wallet based on Output Descriptors

go-wallet A work-in-progress Bitcoin wallet Descriptors go-wallet is designed around Bitcoin Descriptors. It implements a Output Script Descriptors la

May 4, 2022
A phoenix Chain client based on the go-ethereum fork,the new PoA consensus engine is based on the VRF algorithm.

Phoenix Official Golang implementation of the Phoenix protocol. !!!The current version is for testing and developing purposes only!!! Building the sou

Apr 28, 2022
A plugin that turn hashicorp vault into blockchain wallet.
A plugin that turn hashicorp vault into blockchain wallet.

dq-vault - Hashicorp vault BTC/ETH plugin This vault plugin stores a user's mnemonic inside vault in an encrypted manner. The plugin uses this stored

Dec 7, 2022
Simple and useful principle of wallet in blockchain
Simple and useful principle of wallet in blockchain

Blockchain wallet utiles Development export GOPROXY=https://goproxy.io,direct go run *.go Build go build -o ./bin/app *.go About wallet in blockchain

Aug 11, 2022