Fetching data from the network
Fetching the network config
import { DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const networkProvider = entrypoint.createNetworkProvider();
const networkConfig = await networkProvider.getNetworkConfig();
}
Fetching the network status
import { DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const networkProvider = entrypoint.createNetworkProvider();
const metaNetworkStatus = await networkProvider.getNetworkStatus(); // fetches status from metachain
const shardOneNetworkStatus = await networkProvider.getNetworkStatus(1); // fetches status from shard one
}
Fetching a Block from the Network
To fetch a block, we first instantiate the required arguments and use its hash. The API only supports fetching blocks by hash, whereas the PROXY allows fetching blocks by either hash or nonce.
When using the PROXY, keep in mind that the shard must also be specified in the arguments.
Fetching a block using the API
import { ApiNetworkProvider } from "@multiversx/sdk-core";
{
const api = new ApiNetworkProvider("https://devnet-api.multiversx.com");
const blockHash = "1147e111ce8dd860ae43a0f0d403da193a940bfd30b7d7f600701dd5e02f347a";
const block = await api.getBlock(blockHash);
}
Additionally, we can fetch the latest block from the network:
import { ApiNetworkProvider } from "@multiversx/sdk-core";
{
const api = new ApiNetworkProvider("https://devnet-api.multiversx.com");
const latestBlock = await api.getLatestBlock();
}
Fetching a block using the PROXY
When using the proxy, we have to provide the shard, as well.
import { ProxyNetworkProvider } from "@multiversx/sdk-core";
{
const proxy = new ProxyNetworkProvider("https://devnet-gateway.multiversx.com");
const blockHash = "1147e111ce8dd860ae43a0f0d403da193a940bfd30b7d7f600701dd5e02f347a";
const block = await proxy.getBlock({ blockHash, shard: 1 });
}
We can also fetch the latest block from the network. By default, the shard will be the metachain, but we can specify a different shard if needed.
import { ProxyNetworkProvider } from "@multiversx/sdk-core";
{
const proxy = new ProxyNetworkProvider("https://devnet-gateway.multiversx.com");
const latestBlock = await proxy.getLatestBlock();
}
Fetching an Account
To fetch an account, we need its address. Once we have the address, we create an Address object and pass it as an argument to the method.
import { Address, DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const account = await api.getAccount(alice);
}
Fetching an Account's Storage
We can also fetch an account's storage, allowing us to retrieve all key-value pairs saved for that account.
import { Address, DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const account = await api.getAccountStorage(alice);
}
If we only want to fetch a specific key, we can do so as follows:
import { Address, DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const account = await api.getAccountStorageEntry(alice, "testKey");
}
Waiting for an Account to Meet a Condition
There are times when we need to wait for a specific condition to be met before proceeding with an action. For example, let's say we want to send 7 EGLD from Alice to Bob, but this can only happen once Alice's balance reaches at least 7 EGLD. This approach is useful in scenarios where you're waiting for external funds to be sent to Alice, enabling her to transfer the required amount to another recipient.
To implement this, we need to define the condition to check each time the account is fetched from the network. We create a function that takes an AccountOnNetwork object as an argument and returns a bool.
Keep in mind that this method has a default timeout, which can be adjusted using the AwaitingOptions class.
import { Address, DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const condition = (account) => {
return account.balance >= 7000000000000000000n; // 7 EGLD
};
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const account = await api.awaitAccountOnCondition(alice, condition);
}
Sending and Simulating Transactions
To execute transactions, we use the network providers to broadcast them to the network. Keep in mind that for transactions to be processed, they must be signed.
Sending a Transaction
import { Address, DevnetEntrypoint, Transaction } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const bob = Address.newFromBech32("erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx");
const transaction = new Transaction({
sender: alice,
receiver: bob,
gasLimit: 50000n,
chainID: "D",
});
// set the correct nonce and sign the transaction ...
const transactionHash = await api.sendTransaction(transaction);
}
Sending multiple transactions
import { Address, DevnetEntrypoint, Transaction } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const bob = Address.newFromBech32("erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx");
const firstTransaction = new Transaction({
sender: alice,
receiver: bob,
gasLimit: 50000n,
chainID: "D",
nonce: 2n,
});
const secondTransaction = new Transaction({
sender: bob,
receiver: alice,
gasLimit: 50000n,
chainID: "D",
nonce: 1n,
});
const thirdTransaction = new Transaction({
sender: alice,
receiver: alice,
gasLimit: 60000n,
chainID: "D",
nonce: 3n,
data: new Uint8Array(Buffer.from("hello")),
});
// set the correct nonce and sign the transaction ...
const [numOfSentTxs, hashes] = await api.sendTransactions([
firstTransaction,
secondTransaction,
thirdTransaction,
]);
}
Simulating transactions
A transaction can be simulated before being sent for processing by the network. This is primarily used for smart contract calls, allowing you to preview the results produced by the smart contract.
import { Address, DevnetEntrypoint, Transaction } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const contract = Address.newFromBech32("erd1qqqqqqqqqqqqqpgqccmyzj9sade2495w78h42erfrw7qmqxpd8sss6gmgn");
const transaction = new Transaction({
sender: alice,
receiver: contract,
gasLimit: 5000000n,
chainID: "D",
data: new Uint8Array(Buffer.from("add@07")),
});
const transactionOnNetwork = await api.simulateTransaction(transaction);
}
Estimating the gas cost of a transaction
Before sending a transaction to the network for processing, you can retrieve the estimated gas limit required for the transaction to be executed.
import { Address, DevnetEntrypoint, Transaction } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const contract = Address.newFromBech32("erd1qqqqqqqqqqqqqpgqccmyzj9sade2495w78h42erfrw7qmqxpd8sss6gmgn");
const nonce = await entrypoint.recallAccountNonce(alice);
const transaction = new Transaction({
sender: alice,
receiver: contract,
gasLimit: 5000000n,
chainID: "D",
data: new Uint8Array(Buffer.from("add@07")),
nonce: nonce,
});
const transactionCostResponse = await api.estimateTransactionCost(transaction);
}
Waiting for transaction completion
After sending a transaction, you may want to wait until it is processed before proceeding with another action. Keep in mind that this method has a default timeout, which can be adjusted using the AwaitingOptions class.
import { DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const txHash = "exampletransactionhash";
const transactionOnNetwork = await api.awaitTransactionCompleted(txHash);
}
Waiting for a Transaction to Satisfy a Condition
Similar to accounts, we can wait until a transaction meets a specific condition.
import { DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const condition = (txOnNetwork) => txOnNetwork.status.isSuccessful();
const txHash = "exampletransactionhash";
const transactionOnNetwork = await api.awaitTransactionOnCondition(txHash, condition);
}
Waiting for transaction completion
After sending a transaction, you may want to wait until it is processed before proceeding with another action. Keep in mind that this method has a default timeout, which can be adjusted using the AwaitingOptions class.
import { DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const txHash = "exampletransactionhash";
const transactionOnNetwork = await api.awaitTransactionCompleted(txHash);
}
Fetching Transactions from the Network
After sending a transaction, we can fetch it from the network using the transaction hash, which we receive after broadcasting the transaction.
import { DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const txHash = "exampletransactionhash";
const transactionOnNetwork = await api.getTransaction(txHash);
}
Fetching a token from an account
We can fetch a specific token (ESDT, MetaESDT, SFT, NFT) from an account by providing the account's address and the token identifier.
import { Address, DevnetEntrypoint, Token } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
let token = new Token({ identifier: "TEST-ff155e" }); // ESDT
let tokenOnNetwork = await api.getTokenOfAccount(alice, token);
token = new Token({ identifier: "NFT-987654", nonce: 11n }); // NFT
tokenOnNetwork = await api.getTokenOfAccount(alice, token);
}
Fetching all fungible tokens of an account
Fetches all fungible tokens held by an account. Note that this method does not handle pagination, but it can be achieved using doGetGeneric.
import { Address, DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const fungibleTokens = await api.getFungibleTokensOfAccount(alice);
}
Fetching all non-fungible tokens of an account
Fetches all non-fungible tokens held by an account. Note that this method does not handle pagination, but it can be achieved using doGetGeneric.
import { Address, DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const nfts = await api.getNonFungibleTokensOfAccount(alice);
}
Fetching token metadata
If we want to fetch the metadata of a token (e.g., owner, decimals, etc.), we can use the following methods:
import { DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
// used for ESDT
const fungibleTokenDefinition = await api.getDefinitionOfFungibleToken("TEST-ff155e");
// used for METAESDT, SFT, NFT
const nonFungibleTokenDefinition = await api.getDefinitionOfTokenCollection("NFTEST-ec88b8");
}
Querying Smart Contracts
Smart contract queries, or view functions, are endpoints that only read data from the contract. To send a query to the observer nodes, we can proceed as follows:
import { Address, DevnetEntrypoint, SmartContractQuery } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const query = new SmartContractQuery({
contract: Address.newFromBech32("erd1qqqqqqqqqqqqqpgqqy34h7he2ya6qcagqre7ur7cc65vt0mxrc8qnudkr4"),
function: "getSum",
arguments: [],
});
const response = await api.queryContract(query);
}
Custom Api/Proxy calls
The methods exposed by the ApiNetworkProvider or ProxyNetworkProvider are the most common and widely used. However, there may be times when custom API calls are needed. For these cases, we’ve created generic methods for both GET and POST requests.
Let’s assume we want to retrieve all the transactions sent by Alice in which the delegate function was called.
import { Address, DevnetEntrypoint } from "@multiversx/sdk-core";
{
const entrypoint = new DevnetEntrypoint();
const api = entrypoint.createNetworkProvider();
const alice = Address.newFromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th");
const url = `accounts/${alice.toBech32()}/transactions?function=delegate`;
const response = await api.doGetGeneric(url);
}