logo

Browser 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.

  • Check Extension Demo
  • 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
  • Data Format#

    1
    {
    2
    "histories": [],
    3
    "keychain": {
    4
    "keypairs": [
    5
    {
    6
    "name": "your keypairs name",
    7
    "address": "your keypairs address",
    8
    "mnemonic": "your keypairs mnemonic",
    9
    "privateKey": "your keypairs privateKey",
    10
    "publicKey": {
    11
    "x": "your keypairs publicKey",
    12
    "y": "your keypairs publicKey"
    13
    }
    14
    }
    15
    ],
    16
    "permissions": [
    17
    {
    18
    "chainId": "AELF",
    19
    "contractAddress": "contract address",
    20
    "contractName": "contract name",
    21
    "description": "contract description",
    22
    "github": "contract github",
    23
    "whitelist": {
    24
    "Approve": {
    25
    "parameter1": "a",
    26
    "parameter2": "b",
    27
    "parameter3": "c"
    28
    }
    29
    }
    30
    }
    31
    ]
    32
    }
    33
    }

    Demo of Checking the Extension#

    1
    let nightElfInstance = null;
    2
    3
    class NightElfCheck {
    4
    constructor() {
    5
    const readyMessage = 'NightElf is ready';
    6
    let resolveTemp = null;
    7
    this.check = new Promise((resolve, reject) => {
    8
    if (window.NightElf) {
    9
    resolve(readyMessage);
    10
    }
    11
    setTimeout(() => {
    12
    reject({
    13
    error: 200001,
    14
    message: 'timeout / cannot find NightElf / please install the extension'
    15
    });
    16
    }, 1000);
    17
    resolveTemp = resolve;
    18
    });
    19
    document.addEventListener('NightElf', result => {
    20
    console.log('Checking the status of extension named NightElf: ', result);
    21
    resolveTemp(readyMessage);
    22
    });
    23
    }
    24
    25
    static getInstance() {
    26
    if (!nightElfInstance) {
    27
    nightElfInstance = new NightElfCheck();
    28
    return nightElfInstance;
    29
    }
    30
    return nightElfInstance;
    31
    }
    32
    }
    33
    34
    const nightElfCheck = NightElfCheck.getInstance();
    35
    nightElfCheck.check.then(message => {
    36
    // connectChain -> Login -> initContract -> call contract methods
    37
    });

    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.

    1
    const aelf = new window.NightElf.AElf({
    2
    httpProvider: ['http://192.168.197.56:8101/chain'],
    3
    appName: 'Test'
    4
    });
    5
    6
    aelf.chain.getChainStatus((error, result) => {
    7
    console.log('Chain Status:', error, result);
    8
    });
    Expected Result :#
    1
    result = {
    2
    ChainId: "AELF"
    3
    GenesisContractAddress: "61W3AF3Voud7cLY2mejzRuZ4WEN8mrDMioA9kZv3H8taKxF"
    4
    }

    CALL_AELF_CHAIN#

    Example of retrieving a transaction result:

    1
    const txid = 'c45edfcca86f4f528cd8e30634fa4ac53801aae05365cfefc3bfe9b652fe5768';
    2
    aelf.chain.getTxResult(txid, (err, result) => {
    3
    console.log('Transaction Result:', err, result);
    4
    });
    Expected Result :#
    1
    result = {
    2
    Status: "NotExisted"
    3
    TransactionId: "ff5bcd126f9b7f22bbfd0816324390776f10ccb3fe0690efc84c5fcf6bdd3fc6"
    4
    }

    LOGIN#

    Example login call:

    1
    aelf.login({
    2
    appName: 'hzzTest',
    3
    chainId: 'AELF',
    4
    payload: {
    5
    method: 'LOGIN',
    6
    contracts: [
    7
    {
    8
    chainId: 'AELF',
    9
    contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
    10
    contractName: 'token',
    11
    description: 'token contract',
    12
    github: ''
    13
    },
    14
    {
    15
    chainId: 'AELF TEST',
    16
    contractAddress: '2Xg2HKh8vusnFMQsHCXW1q3vys5JxG5ZnjiGwNDLrrpb9Mb',
    17
    contractName: 'TEST contractName',
    18
    description: 'contract description',
    19
    github: ''
    20
    }
    21
    ]
    22
    }
    23
    }, (error, result) => {
    24
    console.log('Login Result:', result);
    25
    });
    26
    27
    // keychain = {
    28
    // keypairs: [{
    29
    // name: 'your keypairs name',
    30
    // address: 'your keypairs address',
    31
    // mnemonic: 'your keypairs mnemonic',
    32
    // privateKey: 'your keypairs privateKey',
    33
    // publicKey: {
    34
    // x: 'f79c25eb......',
    35
    // y: '7fa959ed......'
    36
    // }
    37
    // }],
    38
    // permissions: [{
    39
    // appName: 'hzzTest',
    40
    // address: 'your keyparis address',
    41
    // contracts: [{
    42
    // chainId: 'AELF',
    43
    // contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
    44
    // contractName: 'token',
    45
    // description: 'token contract',
    46
    // github: ''
    47
    // }],
    48
    // domain: 'Dapp domain'
    49
    // }]
    50
    // }

    INIT_AELF_CONTRACT#

    Example of initializing a contract:

    1
    // In aelf-sdk.js wallet is the realy wallet.
    2
    // But in extension sdk, we just need the address of the wallet.
    3
    const tokenContract;
    4
    const wallet = {
    5
    address: '2JqnxvDiMNzbSgme2oxpqUFpUYfMjTpNBGCLP2CsWjpbHdu'
    6
    };
    7
    // It is different from the wallet created by Aelf.wallet.getWalletByPrivateKey();
    8
    // There is only one value named address;
    9
    aelf.chain.contractAtAsync(
    10
    '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
    11
    wallet,
    12
    (error, result) => {
    13
    console.log('>>>>>>>>>>>>> contractAtAsync >>>>>>>>>>>>>');
    14
    console.log(error, result);
    15
    tokenContract = result;
    16
    }
    17
    );
    Expected Result :#
    1
    result = {
    2
    Approve: ƒ (),
    3
    Burn: ƒ (),
    4
    ChargeTransactionFees: ƒ (),
    5
    ClaimTransactionFees: ƒ (),
    6
    ....
    7
    }

    CALL_AELF_CONTRACT / CALL_AELF_CONTRACT_READONLY#

    Example contract method calls:

    1
    tokenContract.GetBalance.call(
    2
    { symbol: 'AELF', owner: '65dDNxzcd35jESiidFXN5JV8Z7pCwaFnepuYQToNefSgqk9' },
    3
    (err, result) => {
    4
    console.log('Get Balance Result:', result);
    5
    }
    6
    );
    7
    8
    tokenContract.Approve(
    9
    { symbol: 'AELF', spender: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc', amount: '100' },
    10
    (err, result) => {
    11
    console.log('Approve Result:', result);
    12
    }
    13
    );
    14
    15
    // If you use tokenContract.GetBalance.call this method is only applicable to queries that do not require extended authorization validation.(CALL_AELF_CONTRACT_READONLY)
    16
    // If you use tokenContract.Approve this requires extended authorization validation (CALL_AELF_CONTRACT)
    17
    18
    // tokenContract.GetBalance.call(payload, (error, result) => {})
    19
    // result = {
    20
    // symbol: "AELF",
    21
    // owner: "65dDNxzcd35jESiidFXN5JV8Z7pCwaFnepuYQToNefSgqk9",
    22
    // balance: 0
    23
    // }

    CHECK_PERMISSION#

    Example permission check:

    1
    aelf.checkPermission({
    2
    appName: 'hzzTest',
    3
    type: 'address',
    4
    address: '4WBgSL2fSem9ABD4LLZBpwP8eEymVSS1AyTBCqXjt5cfxXK'
    5
    }, (error, result) => {
    6
    console.log('Check Permission Result:', result);
    7
    });
    Expected Result :#
    1
    result = {
    2
    ...,
    3
    permissions:[
    4
    {
    5
    address: '...',
    6
    appName: 'hzzTest',
    7
    contracts: [{
    8
    chainId: 'AELF',
    9
    contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
    10
    contractName: 'token',
    11
    description: 'token contract',
    12
    github: ''
    13
    },
    14
    {
    15
    chainId: 'AELF TEST',
    16
    contractAddress: 'TEST contractAddress',
    17
    contractName: 'TEST contractName',
    18
    description: 'contract description',
    19
    github: ''
    20
    }],
    21
    domian: 'Dapp domain'
    22
    }
    23
    ]
    24
    }

    SET_CONTRACT_PERMISSION#

    Example of removing methods whitelist:

    1
    aelf.removeContractPermission({
    2
    appName: 'hzzTest',
    3
    chainId: 'AELF',
    4
    payload: {
    5
    contractAddress: '2Xg2HKh8vusnFMQsHCXW1q3vys5JxG5ZnjiGwNDLrrpb9Mb'
    6
    }
    7
    }, (error, result) => {
    8
    console.log('removeContractPermission>>>>>>>>>>>>>>>>>>>', result);
    9
    });
    Expected Result#
    1
    keychain = {
    2
    keypairs: {...},
    3
    permissions: [{
    4
    appName: 'hzzTest',
    5
    address: 'your keyparis address',
    6
    contracts: [{
    7
    chainId: 'AELF',
    8
    contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
    9
    contractName: 'token',
    10
    description: 'token contract',
    11
    github: ''
    12
    }],
    13
    domain: 'Dapp domain'
    14
    }]
    15
    }

    REMOVE_METHODS_WHITELIST#

    Example of removing contract permission:

    1
    aelf.removeContractPermission({
    2
    appName: 'hzzTest',
    3
    chainId: 'AELF',
    4
    payload: {
    5
    contractAddress: '2Xg2HKh8vusnFMQsHCXW1q3vys5JxG5ZnjiGwNDLrrpb9Mb'
    6
    }
    7
    }, (error, result) => {
    8
    console.log('Remove Contract Permission Result:', result);
    9
    });
    Expected Result#
    1
    keychain = {
    2
    keypairs: {...},
    3
    permissions: [{
    4
    appName: 'hzzTest',
    5
    address: 'your keyparis address',
    6
    contracts: [{
    7
    chainId: 'AELF',
    8
    contractAddress: '4rkKQpsRFt1nU6weAHuJ6CfQDqo6dxruU3K3wNUFr6ZwZYc',
    9
    contractName: 'token',
    10
    description: 'token contract',
    11
    github: '',
    12
    whitelist: {}
    13
    }],
    14
    domain: 'Dapp domain'
    15
    }]
    16
    }

    For Extension Developers#

  • Download the code:
  • 1
    git clone https://github.com/hzz780/aelf-web-extension.git
  • Install dependencies:
  • 1
    npm install
  • Run webpack:
  • 1
    webpack -w
  • Add to the browser:
  • 1
    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.

    Edited on: 15 July 2024 07:08:01 GMT+0