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

Configuration
Minimum
Recommended

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

Configuration
Minimum
Recommended

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:

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 use tx.aborted field. If it is true, 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 if tx.bounce.bounce_type<2 (tx.bounce.bounce_type==2(Ok) is equal to in_message.bounce==true)

Last updated