Ethereum (ETH)
Welcome to the Ctrl Wallet Ethereum integration guide. This guide will help you to integrate your Ethereum-based DApp with Ctrl Wallet.
Detect Ctrl Wallet with Ethereum Base Chain
To detect whether your browser is running Ctrl Wallet, you can use the following code:
if (
(typeof window.ethereum !== "undefined" && window.ethereum?._XDEFI) ||
window.xfi
) {
console.log("Ctrl Wallet detected");
// Your code here
}Notice: window.ethereum is a standard Ethereum provider object, and window.ethereum._XDEFI is a property added by Ctrl Wallet. If window.ethereum is not available, you can also check window.xfi which is a global object added by Ctrl Wallet.
The Ctrl Wallet on Ethereum JavaScript provider API is specified by EIP-1193 and EIP-6963. Support window.ethereum only and removal window.web3
Connect/Disconnect to Ctrl Wallet
To connect to Ctrl Wallet (access the user's [blockchain - like Ethereum] account(s)), you can use the following code:
// Connect & get accounts
window.ethereum.request({method: 'eth_accounts'});
// Alias for connection
window.ethereum.request({method: 'eth_requestAccounts'});
// Check if dapp connected
window.ethereum.isConnected();
// Check if the caller's current permissions
window.ethereum.request({method: 'wallet_getPermissions'});
// Check if request the given permissions
window.ethereum.request({method: 'wallet_requestPermissions'});To disconnect from Ctrl Wallet, please use:
window.ethereum.disconnect();Experience functions
When your account is connected to Ctrl Wallet, let's start experiencing more functions.
Get the current account
window.ethereum.request({ method: "eth_accounts" }).then((accounts) => {
if (accounts.length > 0) {
console.log("Current account:", accounts[0]);
// Do something with the account
} else {
console.log("No account connected");
// Do something else
}
});Above code will return Promise<Array[String]> with the current account address. If wallet can not be found, return [] instead of throw Error
Check wallet whether it is connected(exists) or not
window.ethereum
.request({ method: "has_wallet", params: ["ethereum"] })
.then(() => {
// Wallet is connected
})
.catch((e) => {
// Wallet not found (not exist)
});Above code will return Promise<Boolean> with the current account address. If wallet can not be found, return false instead of throw Error
Sign Transaction
// Example Sign Transactionconst
const signature = window.ethereum.request({
method: 'eth_signTransaction',
params: [
"from": "string",
"to": "string",
"gas": "string",
"gasPrice": "string",
"value": "string",
"data": "string",
"nonce": "string"
]
});Above code will return Promise<Signature | RPC: 2.0>
Transfer
window.ethereum.request({
method: "eth_sendTransaction",
params: [
{
from: "string",
to: "string",
gas: "string",
gasPrice: "string",
value: "string",
data: "string",
nonce: "string",
},
],
});Return Promise<String> with the transaction hash
Decrypt Message
window.ethereum
.request({ method: "eth_decrypt", params: [encryptedMessage, accounts[0]] })
.then((decryptedMessage) =>
console.log("The decrypted message is:", decryptedMessage),
)
.catch((error) => console.log(error.message));Above code will return Promise<String> with the decrypted message
Get Encryption Public Key
Return Promise<String> with the public key
let encryptionPublicKey;
window.ethereum
.request({
method: "eth_getEncryptionPublicKey",
params: [accounts[0]], // You must have access to the specified account
})
.then((result) => {
encryptionPublicKey = result;
})
.catch((error) => {
if (error.code === 4001) {
// EIP-1193 userRejectedRequest error
console.log("Can't encrypt anything without the key.");
} else {
console.error(error);
}
});Encrypt Message
const ethUtil = require('ethereumjs-util');
const encryptedMessage = ethUtil.bufferToHex(
Buffer.from(
JSON.stringify(
sigUtil.encrypt(
{
publicKey: encryptionPublicKey,
data: 'Hello, World!,
version: 'x25519-xsalsa20-poly1305',
}
)
),
'utf8'
)
);Add Ethereum Chain
window.ethereum.request
interface AddEthereumChainParameter {
chainId: string; // A 0x-prefix hex string
chainName: string;
nativeCurrency: {
name: string;
symbol: string; // 2-6 characters long
decimals: 18;
};
rpcUrls: string[];
blockExplorerUrls?: string[];
iconUrls?: string[]; // Currently ignored
}Return Promise<void> with the result
Switch Ethereum Chain
Return Promise<void> with the result, and an error otherwise
try {
await window.await ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0xf00' }],
});
} catch (switchError) {
if (switchError.code === 4902) {
try {
await ethereum.request({
method: 'wallet_addEthereumChain',
params: [
{
chainId: '0xf00',
chainName: '...',
rpcUrls: ['https://...'] /* ... */,
},
],
});
} catch (addError) {
// handle "add" error
}
}
// handle other "switch" errors
}Watch Asset
Return true if the token was added, false otherwise
window.ethereum
.request({
method: "wallet_watchAsset",
params: {
type: "ERC20",
options: {
address: "0x1234567890123456789012345678901234567890",
symbol: "FOO",
decimals: 18,
image: "https://example.com/token-image.png",
},
},
})
.then((success) => {
if (success) {
console.log("FOO successfully added to wallet!");
} else {
throw new Error("Something went wrong.");
}
})
.catch(console.error);RPC Request
Return Promise<Ethereum RPC> Currently only support HTTP(s) method Reference: RPC Method
window.ethereum.request({method: '<Method>', params: [args1,....]})Subscription
Support subscribe using JSON-RPC notifications. This allows clients to wait for events instead of polling for them. All results will be released at data event.
Methods
// For Subscribe
window.ethereum
.request({
method: "eth_subscribe",
params: ["<type>", "<options>"],
})
.then((subscriptionId) => {
console.log("Subscription ID:", subscriptionId);
// Do something with the subscription ID
});
// For Unsubscribe
window.ethereum.request({
method: "eth_unsubscribe",
params: ["<Subscription ID>"],
});Example
// Subscribe for event
const subscriptionID = window.ethereum.request({method: 'eth_subscribe', params: ["logs", {
address: "0x1234567890123456789012345678901234567890",
topics: ["0x1234567890123456789012345678901234567890123456789012345678901234"]
})
// You can listen for incoming notifications by
window.ethereum.on("data", data => {
// Do the rest of your work with data
})Events
Currently we only support some action events from Wallet
window.ethereum.on('event_name', callback);
//Example
window.ethereum.on('close', () => window.location.reload());
window.ethereum.on('accountsChanged', () => window.location.reload());Events supported
| Events | Trigger |
|---|---|
accountsChanged | Receive when active account changed in Wallet |
networkChanged | Receive when active network changed in Wallet |
chainChanged | Receive when active chain changed in Wallet |
close | Alias for disconnect event |
disconnect | Receive when disconnecting from Wallet |
Methods supported
| Methods | Description |
|---|---|
on(event, callback) | Add event listener |
off(event, callback) | Remove event listener |