Add Acki Nacki to your backend
This document describes the various ways to accomplish the most important tasks of running a backend project that supports Acki Nacki
How to connect
Blockchain access may be set up through
the public endpoint
self-hosted Block Keeper GQL endpoint
self-hosted Block Manager GQL endpoint
Public endpoint
The public endpoint: https://shellnet.ackinacki.org/graphql
Setting up Self-Hosted Block Keeper
System Requirements
CPU (cores)
8c/16t
12c/24t
RAM (GiB)
64 GB
128 GB
Storage
1 TB NVMe
2 TB NVMe
Network (Gbit/s)
1 Gbit synchronous unmetered Internet connection
1 Gbit synchronous unmetered Internet connection
How to run: follow the instructions in Ackinacki repo.
After successfully provisioned Block Keeper the gql endpoint will be on localhost:3000/graphql
Setting up Self-Hosted Block Manager
Requirements and how-to-run guide are coming soon.
System Requirements
CPU
4c/8t
8c/16t
RAM
32 GB
64 GB
Storage
1 TB NVMe
2 TB NVMe
Network
1 Gbit synchronous unmetered Internet connection
1 Gbit synchronous unmetered Internet connection
How to run: guide is coming soon
After successfully provisioned Block Manager the gql endpoint will be on localhost:3000/graphql
Setting up Wallet Account
Soon the official multisig wallet files will be published here:https://github.com/ackinacki/ackinacki/tree/main/contracts/multisig.
This guide implies the latest wallet API and changes in the guide may be very small. So it is good to estimate the potential integration effort.
Using CLI tool
Build and install CLI tool
Now path to tvm-cli is publicly accessible. You can also add it to your ENVs
export PATH=$PATH:~/tvm-sdk/target/release/tvm-cli
Configure network connection
Get wallet account contract files
Soon the wallet files will be published here:https://github.com/ackinacki/ackinacki/tree/main/contracts/multisig
Generate wallet keys and get the address
Top up the new address from your sponsor wallet
Deploy the wallet account contract to blockchain
Use the following command for a simple one-owner account:
Using SDK
You may integrate above described process of wallet account deployment into your backend code.
Note, that similar to the CLI approach described above, you have to sponsor a user account before deploying contract code. The sample assumes you use Acki Nacki faucet, where you can request test tokens to the contract address generated by the sample. In a production environment you may set up a giver to sponsor your contract deployment operations.
Monitoring transactions
Lets assume we need to reliably know when customers receive or transfer funds from their wallets. Sample of transaction pagination is available below.
Pagination of all transactions
This sample queries and displays all transactions from the beginning. We can get all the transaction and filter by account addresses on the backend side.
Note: By default the Blockchain API queries, such as the one used here provide only data from the past 7 days. To retrieve older data, make sure to use the archive: true
flag, as shown in the sample:
Not all transactions that are successful are valid transfers and not all transactions that are aborted actually failed. Read below how to understand which transfers are successful transfers and which are not.
Pagination of account transactions
Simply replace the query used in the sample above with this one:
How to mitigate risks during transfers
Using CLI tool
The are two main cases regarding transfers to user accounts: a user may already have an active account to which they want to withdraw funds (set bounce to true), or they may want to withdraw funds to a completely new account, that doesn't exist at the time withdraw is requested (set bounce to false).
The status of the account provided by the user may be checked with the following Everdev command:
The possible results of this command are the following:
Doesn't exist
- account does not exist. It needs to be sponsored, then deployed, and only then will it be active.
Uninit
- account already has some funds on it but contract code has not been deployed yet. User needs to deploy it.
Active
- account already exists, and its code is deployed.
In the first to cases, the service might first transfer a small portion of the requested amount (~1 Shell) and request that the user deploys their contract. Upon the user's confirmation that the account is deployed, its status may be rechecked, and if it became active, the remaining amount of requested funds may be safely transferred.
Using SDK
Same way you can check it using Client Libraries:
Withdrawing from wallet accounts
Using CLI tool
This example shows how to generate a withdrawal transaction from the wallet, using its sendTransaction
method. Note, that if Wallet has multiple custodians, the transaction will have to be confirmed with the confirmTransaction
method.
In this example tokens are withdrawn from the user account to the account specified in dest
. In a proper implementation, the account given by user should be used instead.
Using SDK
You may integrate withdrawals from wallet account into your backend using SDK as well.
This example shows how to generate a withdrawal transaction from the wallet, using its sendTransaction
method. Note, that if Wallet has multiple custodians, the transaction will have to be confirmed with the confirmTransaction
method.
In this example tokens are withdrawn from the user account to the account specified in dest
. In a proper implementation, the account given by user should be used instead.
How to determine a successful transaction?
Not all aborted = true transactions are failed.
It depends on the account state before and after the transaction (fields orig_status
and end_status
):
If the account was already deployed, i.e. if
(tx.orig_status == tx.end_status == active)
then you can usetx.aborted
field. If it istrue
, then the transaction is not successful.If the account was not yet deployed then
if
(orig_status == nonExist && end_status == uninit && aborted == true)
then transaction is successful.All the transactions executed on non-deployed accounts are aborted by definition but if we see the state has changed to
uninit
, it means that the transfer was successfully received.if
(orig_status == uninit && end_status == uninit && aborted == true && in_message.bounce==false)
then transaction is successful.Non-bounced messages are successfully received by non-deployed accounts, though the transaction status is aborted.
Instead of checking
tx.in_message.bounce==false
you can check iftx.bounce.bounce_type<2
(tx.bounce.bounce_type==2(Ok) is equal to in_message.bounce==true)
Last updated