Managing accounts

Learn how to generate and review accounts
beginners
15 minutes

Introduction

This tutorial will walk you through the following steps:

  • Generating an account
  • Reviewing account info
  • Reviewing account history
  • Getting account balances

Requirements

You will need NodeJS 8.12.0 or higher to complete this tutorial. You can verify your installation by opening up your terminal and run the following command:

node --versionnode --version

Step 1: Installing libraries

First, install all the required libraries:

npm install --save @blockstack/stacks-transactions @stacks/blockchain-api-client cross-fetchnpm install --save @blockstack/stacks-transactions @stacks/blockchain-api-client cross-fetch

Step 2: Generating an account

To get started, let's generate a new, random Stacks 2.0 private key:

import fetch from 'cross-fetch'; const { makeRandomPrivKey, privateKeyToString, getAddressFromPrivateKey, TransactionVersion, } = require('@blockstack/stacks-transactions'); const { AccountsApi, FaucetsApi, Configuration } = require('@stacks/blockchain-api-client'); const apiConfig = new Configuration({ fetchApi: fetch, basePath: 'https://stacks-node-api.blockstack.org', }); const privateKey = makeRandomPrivKey();import fetch from 'cross-fetch';const { makeRandomPrivKey, privateKeyToString, getAddressFromPrivateKey, TransactionVersion,} = require('@blockstack/stacks-transactions');const { AccountsApi, FaucetsApi, Configuration } = require('@stacks/blockchain-api-client');const apiConfig = new Configuration({ fetchApi: fetch, basePath: 'https://stacks-node-api.blockstack.org',});const privateKey = makeRandomPrivKey();

Step 3: Reviewing account info

With the private key, you can review account details. First, we need to derive the Stacks address from the private key. Then, we can use the AccountsApi class to get the account details:

const stacksAddress = getAddressFromPrivateKey( privateKeyToString(privateKey), TransactionVersion.Testnet // remove for Mainnet addresses ); ... const accounts = new AccountsApi(apiConfig); const accountInfo = await accounts.getAccountInfo({ principal: stacksAddress }); console.log(accountInfo);const stacksAddress = getAddressFromPrivateKey( privateKeyToString(privateKey), TransactionVersion.Testnet // remove for Mainnet addresses);... const accounts = new AccountsApi(apiConfig); const accountInfo = await accounts.getAccountInfo({ principal: stacksAddress }); console.log(accountInfo);

The API will respond with a balance, nonce (starting at zero), and respective proofs:

{ balance: '0x00000000000000000000000000000000', nonce: 0, balance_proof: '', nonce_proof: '' }{ balance: '0x00000000000000000000000000000000', nonce: 0, balance_proof: '', nonce_proof: ''}

The balance property represents the Stacks token balance, as hex-encoded string of an unsigned 128-bit integer (big-endian). It is not easy to consume the balance property in this format. To simplify that, and to obtain all balances for all tokens (Stacks/STX, fungible, and non-fungible), check out step 5.

Disabling proofs

Proofs, provided as hex-encoded strings, can be removed from the responses by setting the proof parameter:

const accountInfo = await accounts.getAccountInfo({ principal: stacksAddress, proof: 0, });const accountInfo = await accounts.getAccountInfo({ principal: stacksAddress, proof: 0,});

Step 4: Reviewing account history

The following step make requires associated accounts transactions. For simplicity, let's run the faucet for the new account:

const faucets = new FaucetsApi(apiConfig); const faucetTx = await faucets.runFaucetStx({ address: stacksAddress, }); console.log(faucetTx);const faucets = new FaucetsApi(apiConfig);const faucetTx = await faucets.runFaucetStx({ address: stacksAddress,});console.log(faucetTx);

The API will respond with a new transaction ID and confirmation that the faucet run was successful:

{ success: true, txId: '0x5b3d9b47c8f0a3c161868c37d94977b3b0a507558a542fd9499b597bfc799d11', txRaw: '80800000000400164247d6f2b425ac5771423ae6c80c754f717...' }{ success: true, txId: '0x5b3d9b47c8f0a3c161868c37d94977b3b0a507558a542fd9499b597bfc799d11', txRaw: '80800000000400164247d6f2b425ac5771423ae6c80c754f717...'}

Assuming the faucet transaction was successfully processed, you can review the account history. We are expecting at least one transactions to show up in the account history.

const history = await accounts.getAccountTransactions({ principal: stacksAddress, }); console.log(history);const history = await accounts.getAccountTransactions({ principal: stacksAddress,});console.log(history);

The API will respond with a paginatable list of transactions associated with the account:

{ limit: 20, offset: 0, total: 1, results: [ { tx_id: '0x89ee63c0', tx_type: 'token_transfer', fee_rate: '180', sender_address: 'STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6', sponsored: false, post_condition_mode: 'deny', tx_status: 'success', block_hash: '0x167662a4e', block_height: 2951, burn_block_time: 1598910912, burn_block_time_iso: '2020-08-31T21:55:12.000Z', canonical: true, tx_index: 1, tx_result: {"hex":"0x03","repr":"true"}, token_transfer: { recipient_address:"STW617CAFYNFQG6G470DNWW4V56XAY7125S3Z6RK", amount:"500000", memo:"0x466175636574000000" }, events: [{ ... }] } ] }{ limit: 20, offset: 0, total: 1, results: [ { tx_id: '0x89ee63c0', tx_type: 'token_transfer', fee_rate: '180', sender_address: 'STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6', sponsored: false, post_condition_mode: 'deny', tx_status: 'success', block_hash: '0x167662a4e', block_height: 2951, burn_block_time: 1598910912, burn_block_time_iso: '2020-08-31T21:55:12.000Z', canonical: true, tx_index: 1, tx_result: {"hex":"0x03","repr":"true"}, token_transfer: { recipient_address:"STW617CAFYNFQG6G470DNWW4V56XAY7125S3Z6RK", amount:"500000", memo:"0x466175636574000000" }, events: [{ ... }] } ]}

Please review the API reference for property definitions and details.

Handling pagination

To make API responses more compact, lists returned by the API are paginated. For lists, the response body includes:

ParameterDescriptionDefault

limit

The number of list items returned

20

offset

The number of elements skipped

0

total

The number of all available list items

0

results

Array of list items (length of array equals the set limit)

[]

In order to paginate throughout the full result set, we can use the limit and offset request properties. Here is an example where we request transactions 50-100 for an account:

const history = await accounts.getAccountTransactions({ principal: stacksAddress, limit: 50, offset: 50, });const history = await accounts.getAccountTransactions({ principal: stacksAddress, limit: 50, offset: 50,});

Step 5: Getting account balances

As mentioned above, any Stacks address can have a variety of tokens and associated balances. In order to get balances for all Stacks, fungible, and non-fungible tokens, we can use the getAccountBalance method:

const balances = await accounts.getAccountBalance({ principal: stacksAddress, }); console.log(balances);const balances = await accounts.getAccountBalance({ principal: stacksAddress,});console.log(balances);

The API will respond with the following breakdown of token balances:

{ stx: { balance: '500000', total_sent: '0', total_received: '500000' }, fungible_tokens: {}, non_fungible_tokens: {} }{ stx: { balance: '500000', total_sent: '0', total_received: '500000' }, fungible_tokens: {}, non_fungible_tokens: {}}

We can see that the current Stacks (STX) balance is 500000 micro-STX, or 0.5 Stacks (STX) token.

Previous
Understand Stacking
Next
Sending tokens