Skip to main content

Transferring Credits

The official currency of Aleo Network are called Aleo Credits. All fees paid for transactions, as well as rewards for staking and mining, are in the form of Aleo Credits. Please refer to the Fundamentals for more information.

Unlike other popular Blockchains like Ethereum, there is no special transfer transaction type. Instead, a native program called credits.aleo governs transfers, usage, and ownership of Aleo Credits. All value transfers on the Aleo Network are done by calling functions in the credits.aleo program via Execute transactions. As such, you can transfer credits using the same methods described in the Executing Programs guide

However, as credit transfers are some of the most common and fundamental functions on the network, the Provable SDK provides specialized functions for credit transfers via the ProgramManager class. There are two main methods for building credit transfer transactions: transfer() and buildTransferTransaction(). Calling transfer will build and submit the transaction to the Aleo network, while buildTransferTransaction() will only build the transaction and return it to the caller within Javascript.

Let's walk through an example:

note

The base unit for Aleo Credits is the microcredit. All functions expect and will return values in microcredits by default. 1 credit is equal to 1,000,000 microcredits.

Transfer Aleo Credits

Setup

Similar to the Deploying Programs guide, we'll need to initialize some fundamental objects if you haven't already done so:

import { Account, AleoNetworkClient, initThreadPool, NetworkRecordProvider, ProgramManager, AleoKeyProvider } from '@provablehq/sdk';

// If the threadpool has not been initialized, do so (this step can be skipped if it's been initialized elsewhere).
await initThreadPool();

const account = new Account({ privateKey: 'APrivateKey1...'});
const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");

const keyProvider = new AleoKeyProvider();
keyProvider.useCache(true);

const recordProvider = new NetworkRecordProvider(account, networkClient);

const programManager = new ProgramManager(networkClient, keyProvider, recordProvider);
programManager.setAccount(account);

NetworkRecordProvider

An observant eye will notice that we've added a new import and initialization above in the form of NetworkRecordProvider. This new code helps manage any records needed by the ProgramManager. As a reminder, records are the individual units of private state on the Aleo network. Records are generated by a program's functions and can be changed and updated by when a user runs various functions of the program. Check out the Records section in Fundamentals for more information.

When programs execute, they will often need to find records that belong to a user. The SDK provides an interface called the RecordProvider to enable developers to implement their own record storage and retrieval mechanism. The default implementation of the RecordProvider interface is the NetworkRecordProvider class which searches the Aleo network for records uniquely belonging to a user. The ProgramManager class is capable of taking in a RecordProvider implementaiton as an parameter. For more information on the RecordProvider interface and generally how to find records using the SDK, check out the Managing State guide.

Build the Transaction

Once everything's been intialized, we can build and submit the transaction, and await the results:

// Send a completely private transfer
const tx = await programManager.buildTransferTransaction(
amount : 1,
recipient: RECIPIENT_ADDRESS,
transferType: "transfer_private",
fee: 0.2
);
// Submit the transaction to the network.
const tx_id = await programManager.networkClient.submitTransaction(tx);

/// Send public transfer to another user
const tx_2 = await programManager.buildTransferTransaction(1, RECIPIENT_ADDRESS, "transfer_public", 0.2);
const tx_id_3 = await programManager.networkClient.submitTransaction(tx_2);

// Send a public transfer to another user using a private record as input
const tx_3 = await programManager.buildTransferTransaction(1, RECIPIENT_ADDRESS, "transfer_private_to_public", 0.2);
const tx_id_3 = await programManager.networkClient.submitTransaction(tx_3);

/// Create a private record from a public balance
const tx_4 = await programManager.buildTransferTransaction(1, RECIPIENT_ADDRESS, "transfer_public_to_private", 0.2);
const tx_id_4 = await programManager.networkClient.submitTransaction(tx_4);

/// Send a public transfer from the transaction signer's address / original transaction initiator.
const tx_5 = await programManager.buildTransferTransaction(1, RECIPIENT_ADDRESS, "transfer_public_as_signer", 0.2);
const tx_id_5 = await programManager.networkClient.submitTransaction(tx_5);


// Generally the transaction will need 1-3 blocks (3-9 seconds) to be confirmed on the network. When that time has
// elapsed the following function can be used to get the transaction details.
const transaction1 = await programManager.networkClient.getTransaction(tx_id);
const transaction2 = await programManager.networkClient.getTransaction(tx_id_2);
const transaction3 = await programManager.networkClient.getTransaction(tx_id_3);
const transaction4 = await programManager.networkClient.getTransaction(tx_id_4);
const transaction5 = await programManager.networkClient.getTransaction(tx_id_5);

Alternatively, we can just call the transfer() method to build and broadcast the transaction in one call:

const RECIPIENT_ADDRESS = "aleo1...";

const tx_id = await programManager.transfer(
amount : 1,
recipient: RECIPIENT_ADDRESS,
transferType: "transfer_private",
fee: 0.2
);
const tx_id_2 = await programManager.transfer(1, RECIPIENT_ADDRESS, "transfer_public", 0.2);
const tx_id_3 = await programManager.transfer(1, RECIPIENT_ADDRESS, "transfer_private_to_public", 0.2);
const tx_id_4 = await programManager.transfer(1, RECIPIENT_ADDRESS, "transfer_public_to_private", 0.2);
const tx_id_5 = await programManager.transfer(1, RECIPIENT_ADDRESS, "transfer_public_as_signer", 0.2);

const transaction1 = await programManager.networkClient.getTransaction(tx_id);
const transaction2 = await programManager.networkClient.getTransaction(tx_id_2);
const transaction3 = await programManager.networkClient.getTransaction(tx_id_3);
const transaction4 = await programManager.networkClient.getTransaction(tx_id_4);
const transaction5 = await programManager.networkClient.getTransaction(tx_id_5);

Checking Balances

Public Balances

A public balance of any address can be checked with getMappingValue() function of the NetworkClient.

const networkClient = new AleoNetworkClient("https://api.explorer.provable.com/v1");
const USER_ADDRESS = "aleo1...";
const public_balance = networkClient.getMappingValue("credits.aleo", USER_ADDRESS);

Private Balances

The private balance of an address is the sum of all unspent credits records owned by the address. Check out the next guide for more information regarding record finding.