Wallet Interaction
On the Ergo Platform, one of the most common ways to interact with wallets and the Ergo blockchain is through the dApp Connector protocol, also known as EIP-12. It is the main wallet interaction protocol for browser extension wallets like Nautilus or SAFEW.
API overview
The EIP-12 API is divided into two parts, the Connection and Context APIs. All methods defined in EIP-12 are promise-based asynchronous methods. This means that they return a Promise
. As a result, calling any EIP-12 method requires either an await
keyword or Promise.then()
method to wait for them to finish.
Connection API
The Connection API is responsible for all connection and wallet information related methods, such as access requesting and connection state checking.
EIP-12 compatible browser wallets on Ergo will automatically inject the Connection API into every active page so that any JavaScript context can interact with it directly through the ergoConnector
object.
Multi-wallet support
The Connection API is structured to allow support for multiple wallets. To connect to a wallet, you can use ergoConnector.{walletName}.connect()
method, where {walletName}
is the wallet of your choice.
Examples
Asking for Nautilus Wallet connection
await ergoConnector.nautilus.connect();
Asking for SAFEW Wallet connection
await ergoConnector.safew.connect();
Note that the API remains the same. Only the wallet name changes.
Context API
The Context API is responsible for wallet interactions, such as balance fetching, transaction signing, et cetera.
Once the connection request is accepted by the user, this API will be injected in the same way as the Connection API, and you can interact with it through the ergo
object.
Example
await ergo.get_balance();
Interacting with a wallet
Step. 1: Check for a wallet
To check if the user has an EIP-12 wallet installed and running, check for the presence of the ergoConnector
object and then for the desired wallet.
if (ergoConnector) { // check if Connection API is injected
if (ergoConnector.nautilus) { // check if Nautilus Wallet is available
console.log("Nautilus Wallet is ready to use");
} else {
console.log("Nautilus Wallet is not active");
}
} else {
console.log("No wallet available");
}
INFO
For the sake of simplicity, the Nautilus Wallet will be used for all examples. But this guide is suitable for any other EIP-12 compatible wallet. Please, refer to the Connection API topic for more information.
Step. 2: Request access
To interact with the user's wallet, you need to request wallet access.
const connected = await ergoConnector.nautilus.connect();
if (connected) {
console.log("Connected!");
} else {
console.log("Not connected!");
}
When you call ergoConnector.nautilus.connect()
for the first time a wallet window will pop-up asking the user to allow access to the selected wallet. If the user rejects the prompt, it will return false
otherwise, it will return true
and inject the Context API, which will make the ergo
object available for direct use.
Step. 3: Get balance
Now that you have access to the Context API you can interact with the connected wallet.
Let's start by getting the wallet's balance. For that, use the ergo.get_balance()
method.
Get ERG balance
The following code will return a string
with the total of NanoErgs
owned by the connected wallet.
await ergo.get_balance("ERG");
Get balance by Token ID
Given a Token ID
, the following code will return a string
with the total of token units owned by the connected wallet.
await ergo.get_balance(
"03faf2cb329f2e90d6d23b58d91bbb6c046aa143261cc21f52fbe2824bfcbf04"
);
Get balance for all assets
The following code will return an array
with the balance of all assets owned by the connected wallet.
await ergo.get_balance("all");
The returned array is structured as follows:
[{ tokenId: string, balance: string }];
Step. 4: Get addresses
There are three methods to get user addresses:
Get the change/default address
The following code will return a string
containing the wallet's default change address.
await ergo.get_change_address();
Get unused addresses
The following code will return an array
of strings containing all wallet's unused addresses. By unused, read addresses that never sent or received any transaction.
await ergo.get_unused_addresses();
Get used addresses
The following code will return an array
of strings containing all the wallet's used addresses.
await ergo.get_used_addresses();
Step. 5: Fetch boxes
Boxes are UTxOs on steroids, they play a crucial role in the Ergo blockchain by holding assets and data protected by a contract.
You can use the ergo.get_utxos()
method to fetch unspent boxes owned by the selected wallet.
Get all unspent boxes
The following code will return an array of all unspent boxes owned by the selected wallet.
await ergo.get_utxos();
Filter unspent boxes
Unspent boxes can be also filtered by specific assets.
Example: Fetching all unspent boxes containing SigUSD tokens
await ergo.get_utxos({
tokens: [
{
tokenId:
"03faf2cb329f2e90d6d23b58d91bbb6c046aa143261cc21f52fbe2824bfcbf04"
}
]
});
If needed, a target amount can be specified, so that the wallet will only return unspent boxes until the target is met.
await ergo.get_utxos({
tokens: [
{
tokenId:
"03faf2cb329f2e90d6d23b58d91bbb6c046aa143261cc21f52fbe2824bfcbf04",
amount: "100"
}
]
});
TIP
Note that the tokens
field is an array
, which means you can filter by various tokens in the same call.
Step. 6: Get the current height
The current height stands for the latest block number included in the blockchain. This is necessary for transaction building.
You can make use of ergo.get_current_height()
to get it.
await ergo.get_current_height();
Step. 7: Sign a transaction
The next step after building a transaction is signing it, for that you can call ergo.sign_tx()
to ask the user to sign a previously built transaction.
const unsignedTransaction = new TransactionBuilder(creationHeight)
.from(inputs)
.to(new OutputBuilder(1000000n, recipientAddress))
.sendChangeTo(changeAddress)
.payMinFee()
.build()
.toEIP12Object();
const signedTransaction = await ergo.sign_tx(unsignedTransaction);
When ergo.sign_tx()
is called a pop-up window will be displayed to the user asking to review and sign the transaction. If the user signs it successfully, then it will return a signed transaction object
that can be submitted to the blockchain otherwise, it will throw an exception.
Step. 8: Submit a transaction
Now you have a signed transaction you can submit it to the blockchain using the ergo.submit_tx()
method.
const transactionId = await ergo.submit_tx(signedTransaction);
If the transaction is successfully accepted by the mempool, a string
containing the Transaction ID
will be returned otherwise, it will throw an exception.