Browser Extension
Description: aelf Web Extension is a tool for DApp developers to interact with the aelf blockchain.
Purpose: This guide provides instructions for both users and developers on the installation, usage, and implementation of the aelf Web Extension.
aelf-web-extension
Introduction
aelf Web Extension provides an interface for DApp developers to interact with the aelf blockchain. This guide outlines the usage and implementation details for both users and developers.
For Users
Release Version
Please wait for the official release.
Development Version
dev version For those using QQ Browser and similar, you can add the extension manually.
Notice
- Note: Using File:/// protocol may can not use the extenstion //. You must opt in to file access for each extension that requests it. For more details, visit the Chrome Developer Documentation.
For DApp Developers
Interaction Flow
- Ensure the user has installed the extension.
- Connect to the blockchain.
- Initialize the contract.
- Call contract methods.
How to Use
To access the complete data structure, click here. For an extension demo, refer to the provided examples.
- aelf-web-extension
- Data Format
- Demo of Checking the Extension
- GET_CHAIN_STATUS
- CALL_AELF_CHAIN
- LOGIN
- INIT_AELF_CONTRACT
- CALL_AELF_CONTRACT / CALL_AELF_CONTRACT_READONLY
- CHECK_PERMISSION
- SET_CONTRACT_PERMISSION
- REMOVE_METHODS_WHITELIST
- For Extension Developers
- Project Information
Data Format
{
"histories": [],
"keychain": {
"keypairs": [
{
"name": "your keypairs name",
"address": "your keypairs address",
"mnemonic": "your keypairs mnemonic",
"privateKey": "your keypairs privateKey",
"publicKey": {
"x": "your keypairs publicKey",
"y": "your keypairs publicKey"
}
}
],
"permissions": [
{
"chainId": "AELF",
"contractAddress": "contract address",
"contractName": "contract name",
"description": "contract description",
"github": "contract github",
"whitelist": {
"Approve": {
"parameter1": "a",
"parameter2": "b",
"parameter3": "c"
}
}
}
]
}
}
Demo of Checking the Extension
let nightElfInstance = null;
class NightElfCheck {
constructor() {
const readyMessage = 'NightElf is ready';
let resolveTemp = null;
this.check = new Promise((resolve, reject) => {
if (window.NightElf) {
resolve(readyMessage);
}
setTimeout(() => {
reject({
error: 200001,
message: 'timeout / cannot find NightElf / please install the extension'
});
}, 1000);
resolveTemp = resolve;
});
document.addEventListener('NightElf', result => {
console.log('Checking the status of extension named NightElf: ', result);
resolveTemp(readyMessage);
});
}
static getInstance() {
if (!nightElfInstance) {
nightElfInstance = new NightElfCheck();
return nightElfInstance;
}
return nightElfInstance;
}
}
const nightElfCheck = NightElfCheck.getInstance();
nightElfCheck.check.then(message => {
// connectChain -> Login -> initContract -> call contract methods
});
GET_CHAIN_STATUS
You can see the demo ./devDemos/test.html. [demo.js just a draft]
Token Transfer
If you want to check Token Transfer Demo. You can Click Here
The methods calls act the same as the methods call of the aelf-sdk.js
Note: ...
stands for omitted data.
const aelf = new window.NightElf.AElf({
httpProvider: ['http://192.168.197.56:8101/chain'],
appName: 'Test'
});
aelf.chain.getChainStatus((error, result) => {
console.log('Chain Status:', error, result);
});
Expected Result :
result = {
ChainId: "AELF"
GenesisContractAddress: "61W3AF3Voud7cLY2mejzRuZ4WEN8mrDMioA9kZv3H8taKxF"
}
CALL_AELF_CHAIN
Example of retrieving a transaction result:
const txid = 'c45edfcca86f4f528cd8e30634fa4ac53801aae05365cfefc3bfe9b652fe5768';
aelf.chain.getTxResult(txid, (err, result) => {
console.log('Transaction Result:', err, result);
});
Expected Result :
result = {
Status: "NotExisted"
TransactionId: "ff5bcd126f9b7f22bbfd0816324390776f10ccb3fe0690efc84c5fcf6bdd3fc6"
}
LOGIN
Example login call:
aelf.login({
appName: 'hzzTest',
chainId: 'AELF',
payload: {
method: 'LOGIN',
contracts: [
{
chainId: 'AELF',
contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
contractName: 'token',
description: 'token contract',
github: ''
},
{
chainId: 'AELF TEST',
contractAddress: '2Xg2HKh8vusnFMQsHCXW1q3vys5JxG5ZnjiGwNDLrrpb9Mb',
contractName: 'TEST contractName',
description: 'contract description',
github: ''
}
]
}
}, (error, result) => {
console.log('Login Result:', result);
});
// keychain = {
// keypairs: [{
// name: 'your keypairs name',
// address: 'your keypairs address',
// mnemonic: 'your keypairs mnemonic',
// privateKey: 'your keypairs privateKey',
// publicKey: {
// x: 'f79c25eb......',
// y: '7fa959ed......'
// }
// }],
// permissions: [{
// appName: 'hzzTest',
// address: 'your keyparis address',
// contracts: [{
// chainId: 'AELF',
// contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
// contractName: 'token',
// description: 'token contract',
// github: ''
// }],
// domain: 'Dapp domain'
// }]
// }
INIT_AELF_CONTRACT
Example of initializing a contract:
// In aelf-sdk.js wallet is the realy wallet.
// But in extension sdk, we just need the address of the wallet.
const tokenContract;
const wallet = {
address: '2JqnxvDiMNzbSgme2oxpqUFpUYfMjTpNBGCLP2CsWjpbHdu'
};
// It is different from the wallet created by Aelf.wallet.getWalletByPrivateKey();
// There is only one value named address;
aelf.chain.contractAtAsync(
'4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
wallet,
(error, result) => {
console.log('>>>>>>>>>>>>> contractAtAsync >>>>>>>>>>>>>');
console.log(error, result);
tokenContract = result;
}
);
Expected Result :
result = {
Approve: ƒ (),
Burn: ƒ (),
ChargeTransactionFees: ƒ (),
ClaimTransactionFees: ƒ (),
....
}
CALL_AELF_CONTRACT / CALL_AELF_CONTRACT_READONLY
Example contract method calls:
tokenContract.GetBalance.call(
{ symbol: 'AELF', owner: '65dDNxzcd35jESiidFXN5JV8Z7pCwaFnepuYQToNefSgqk9' },
(err, result) => {
console.log('Get Balance Result:', result);
}
);
tokenContract.Approve(
{ symbol: 'AELF', spender: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc', amount: '100' },
(err, result) => {
console.log('Approve Result:', result);
}
);
// If you use tokenContract.GetBalance.call this method is only applicable to queries that do not require extended authorization validation.(CALL_AELF_CONTRACT_READONLY)
// If you use tokenContract.Approve this requires extended authorization validation (CALL_AELF_CONTRACT)
// tokenContract.GetBalance.call(payload, (error, result) => {})
// result = {
// symbol: "AELF",
// owner: "65dDNxzcd35jESiidFXN5JV8Z7pCwaFnepuYQToNefSgqk9",
// balance: 0
// }
CHECK_PERMISSION
Example permission check:
aelf.checkPermission({
appName: 'hzzTest',
type: 'address',
address: '4WBgSL2fSem9ABD4LLZBpwP8eEymVSS1AyTBCqXjt5cfxXK'
}, (error, result) => {
console.log('Check Permission Result:', result);
});
Expected Result :
result = {
...,
permissions:[
{
address: '...',
appName: 'hzzTest',
contracts: [{
chainId: 'AELF',
contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
contractName: 'token',
description: 'token contract',
github: ''
},
{
chainId: 'AELF TEST',
contractAddress: 'TEST contractAddress',
contractName: 'TEST contractName',
description: 'contract description',
github: ''
}],
domian: 'Dapp domain'
}
]
}
SET_CONTRACT_PERMISSION
Example of removing methods whitelist:
aelf.removeContractPermission({
appName: 'hzzTest',
chainId: 'AELF',
payload: {
contractAddress: '2Xg2HKh8vusnFMQsHCXW1q3vys5JxG5ZnjiGwNDLrrpb9Mb'
}
}, (error, result) => {
console.log('removeContractPermission>>>>>>>>>>>>>>>>>>>', result);
});
Expected Result
keychain = {
keypairs: {...},
permissions: [{
appName: 'hzzTest',
address: 'your keyparis address',
contracts: [{
chainId: 'AELF',
contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
contractName: 'token',
description: 'token contract',
github: ''
}],
domain: 'Dapp domain'
}]
}
REMOVE_METHODS_WHITELIST
Example of removing contract permission:
aelf.removeContractPermission({
appName: 'hzzTest',
chainId: 'AELF',
payload: {
contractAddress: '2Xg2HKh8vusnFMQsHCXW1q3vys5JxG5ZnjiGwNDLrrpb9Mb'
}
}, (error, result) => {
console.log('Remove Contract Permission Result:', result);
});
Expected Result
keychain = {
keypairs: {...},
permissions: [{
appName: 'hzzTest',
address: 'your keyparis address',
contracts: [{
chainId: 'AELF',
contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
contractName: 'token',
description: 'token contract',
github: '',
whitelist: {}
}],
domain: 'Dapp domain'
}]
}
For Extension Developers
- Download the code:
git clone https://github.com/hzz780/aelf-web-extension.git
- Install dependencies:
npm install
- Run webpack:
webpack -w
- Add to the browser:
open development mode, add the webpack output app/public.
Project Information
We use ECDH` to use public key to encryt data and private key to decrypt data.