Skip to content

Wallet Transferring

This guide provides instructions for transferring assets between wallets and contracts using the SDK. It includes methods to validate balances and initiate and configure transfer requests.

Transferring Assets Between Accounts

The transfer method initiates a transaction request that transfers an asset from one wallet to another. This method requires three parameters:

  1. The receiver's wallet address
  2. The amount of the asset to be transferred
  3. The ID of the asset to be transferred (optional - defaults to the base asset ID)

Upon execution, this function returns a promise that resolves to a transaction response. To wait for the transaction to be processed, call response.waitForResult().

Example

Here is an example of how to use the transfer function:

ts
import { BN, Wallet } from 'fuels';

const sender = Wallet.fromPrivateKey('...');
const destination = Wallet.generate({
  provider: sender.provider,
});
const amountToTransfer = 500;

const baseAssetId = sender.provider.getBaseAssetId();

const response = await sender.transfer(destination.address, amountToTransfer, baseAssetId);

await response.wait();

// Retrieve balances
const receiverBalance = await destination.getBalance(baseAssetId);

// Validate new balance
expect(new BN(receiverBalance).toNumber()).toEqual(amountToTransfer);
See code in context

In the previous example, we used the transfer method which creates a ScriptTransactionRequest, populates its data with the provided transfer information and submits the transaction.

However, there may be times when you need the Transaction ID before actually submitting it to the node. To achieve this, you can simply call the createTransfer method instead.

This method also creates a ScriptTransactionRequest and populates it with the provided data but returns the request object prior to submission.

ts
const transactionRequest = await sender.createTransfer(
  destination.address,
  amountToTransfer,
  assetId
);

const chainId = provider.getChainId();

const transactionId = transactionRequest.getTransactionId(chainId);

const response = await sender.sendTransaction(transactionRequest);

const { id } = await response.wait();

// The transaction id should is the same as the one returned by the transaction request
expect(id).toEqual(transactionId);
See code in context

Note: Any changes made to a transaction request will alter the transaction ID. Therefore, you should only get the transaction ID after all modifications have been made.

ts
const transactionRequest = await sender.createTransfer(
  destination.address,
  amountToTransfer,
  assetId
);

const chainId = provider.getChainId();

const transactionId = transactionRequest.getTransactionId(chainId);

transactionRequest.maturity = 1;

const { maxFee } = await provider.estimateTxGasAndFee({ transactionRequest });

transactionRequest.maxFee = maxFee;

const response = await sender.sendTransaction(transactionRequest);

const { id } = await response.wait();

expect(id).not.toEqual(transactionId);
See code in context

Transferring Assets To Multiple Wallets

To transfer assets to multiple wallets, use the Account.batchTransfer method:

ts
const myWallet = Wallet.fromPrivateKey(privateKey, provider);

const recipient1 = Wallet.generate({ provider });
const recipient2 = Wallet.generate({ provider });

const transfersToMake: TransferParams[] = [
  { amount: 100, destination: recipient1.address, assetId: provider.getBaseAssetId() },
  { amount: 200, destination: recipient2.address, assetId: provider.getBaseAssetId() },
  { amount: 300, destination: recipient2.address, assetId: someOtherAssetId },
];

const tx = await myWallet.batchTransfer(transfersToMake);
const { isStatusSuccess } = await tx.waitForResult();
See code in context

Transferring Assets To Contracts

When transferring assets to a deployed contract, we use the transferToContract method, which shares a similar parameter structure with the transfer method.

However, instead of supplying the target wallet's address, as done in destination.address for the transfer method, we need to provide an instance of Address created from the deployed contract id.

If you have the Contract instance of the deployed contract, you can simply use its id property. However, if the contract was deployed with forc deploy or not by you, you will likely only have its ID in a hex string format. In such cases, you can create an Address instance from the contract ID using Address.fromAddressOrString('0x123...').

Here's an example demonstrating how to use transferToContract:

ts
import { BN, Wallet } from 'fuels';

const sender = Wallet.fromPrivateKey('...');

const amountToTransfer = 400;
const assetId = provider.getBaseAssetId();
const contractId = deployedContract.id;

const contractBalance = await deployedContract.getBalance(assetId);

const tx = await sender.transferToContract(contractId, amountToTransfer, assetId);
await tx.waitForResult();

expect(new BN(contractBalance).toNumber()).toBe(0);
expect(new BN(await deployedContract.getBalance(assetId)).toNumber()).toBe(amountToTransfer);
See code in context

Note: Use transferToContract exclusively for transfers to a contract. For transfers to an account address, use transfer instead.

Transferring Assets To Multiple Contracts

Similar to the Account.batchTransfer method, you can transfer multiple assets to multiple contracts using the Account.batchTransferToContracts method. Here's how it works:

ts
const baseAssetId = provider.getBaseAssetId();
const assetA = TestAssetId.A.value;

const contractTransferParams: ContractTransferParams[] = [
  {
    contractId: contract1.id,
    amount: 999,
    assetId: baseAssetId,
  },
  {
    contractId: contract1.id,
    amount: 550,
    assetId: assetA,
  },
  {
    contractId: contract2.id,
    amount: 200,
    assetId: assetA,
  },
];

const submit = await sender.batchTransferToContracts(contractTransferParams);
const txResult = await submit.waitForResult();
See code in context

Always remember to call the waitForResult() function on the transaction response. That ensures the transaction has been mined successfully before proceeding.

Note: Use batchTransferToContracts solely for transferring assets to contracts. Do not use account addresses with this method. For multiple account transfers, use batchTransfer instead.

Checking Balances

Before you transfer assets, please make sure your wallet has enough funds. Attempting a transfer without enough funds will result in the error: The transaction does not have enough funds to cover its execution.

You can see how to check your balance at the checking-balances page.