Searchโ€ฆ
BifrostJS

Github

1
git clone https://github.com/bifrost-finance/bifrost.js.git
Copied!
1
cd bifrost.js
2
# https://www.npmjs.com/package/ts-node
3
# Locally in your project.
4
npm install -D typescript
5
npm install -D ts-node
6
# Globally with TypeScript.
7
npm install -g typescript
8
npm install -g ts-node
9
โ€‹
10
yarn
11
# yarn update-metadata
12
# yarn generate-full-definitions
Copied!

Extension

Installation

1
yarn add @polkadot/extension-dapp
Copied!
Browser extensions are also required: Downloadโ€‹

Usage

1
import {
2
web3Accounts,
3
web3Enable,
4
web3FromAddress,
5
} from "@polkadot/extension-dapp";
6
import { ApiPromise, WsProvider } from "@polkadot/api";
7
import { options } from "@bifrost-finance/api";
8
โ€‹
9
// returns an array of all the injected sources
10
// (this needs to be called first, before other requests)
11
const allInjected = await web3Enable('my cool dapp');
12
โ€‹
13
// returns an array of { address, meta: { name, source } }
14
// meta.source contains the name of the extension that provides this account
15
const allAccounts = await web3Accounts();
16
โ€‹
17
// the address we use to use for signing, as injected
18
const SENDER = '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE';
19
โ€‹
20
// finds an injector for an address
21
const injector = await web3FromAddress(SENDER);
22
โ€‹
23
// create instance
24
const wsProvider = new WsProvider("wss://bifrost-rpc.testnet.liebi.com");
25
const api = await ApiPromise.create(options({ provider: wsProvider }));
26
โ€‹
27
// sign and send our transaction - notice here that the address of the account
28
// (as retrieved injected) is passed through as the param to the `signAndSend`,
29
// the API then calls the extension to present to the user and get it signed.
30
// Once complete, the api sends the tx + signature via the normal process
31
api.tx.balances
32
.transfer("gGT6EDq2igApbW68wgKCjwDi12Vu3CZG4NBLWiNJGRrUUrk", 22000000000000)
33
.signAndSend(SENDER, { signer: injector.signer }, (status) => { console.log(status) });
Copied!

API

Installation

1
yarn add @bifrost-finance/api
2
// or
3
npm i @bifrost-finance/api
Copied!

Create an instance

A little different from polkadot.jsโ€‹
1
// Import
2
import { ApiPromise, WsProvider } from '@polkadot/api';
3
import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
4
import { options } from '@bifrost-finance/api';
5
โ€‹
6
// Construct
7
const wsProvider = new WsProvider('wss://bifrost-rpc.testnet.liebi.com');
8
const api = await ApiPromise.create(options({ provider: wsProvider, rpc: jsonrpc }));
9
โ€‹
10
// Do something
11
console.log(api.genesisHash.toHex());
Copied!

Keyring & Crypto Utilities

Create mnemonic

The following example shows how to create and generate mnemonics using BIP39.
1
const {
2
mnemonicGenerate,
3
mnemonicToMiniSecret,
4
mnemonicValidate,
5
naclKeypairFromSeed
6
} = require('@polkadot/util-crypto');
7
โ€‹
8
async function main () {
9
// Create mnemonic string for Alice using BIP39
10
const mnemonicAlice = mnemonicGenerate();
11
โ€‹
12
console.log(`Generated mnemonic: ${mnemonicAlice}`);
13
โ€‹
14
// Validate the mnemic string that was generated
15
const isValidMnemonic = mnemonicValidate(mnemonicAlice);
16
โ€‹
17
console.log(`isValidMnemonic: ${isValidMnemonic}`);
18
โ€‹
19
// Create valid Substrate-compatible seed from mnemonic
20
const seedAlice = mnemonicToMiniSecret(mnemonicAlice);
21
โ€‹
22
// Generate new public/secret keypair for Alice from the supplied seed
23
const { publicKey, secretKey } = naclKeypairFromSeed(seedAlice);
24
}
25
โ€‹
26
main().catch(console.error).finally(() => process.exit());
Copied!

Adding a pair & Generic address

ed25519
1
import { mnemonicGenerate } from '@polkadot/util-crypto';
2
import { Keyring } from '@polkadot/keyring';
3
โ€‹
4
// create a keyring with some non-default values specified
5
const keyring = new Keyring({ type: 'ed25519', ss58Format: 6 });
6
โ€‹
7
// generate a mnemonic with default params (we can pass the number
8
// of words required 12, 15, 18, 21 or 24, less than 12 words, while
9
// valid, is not supported since it is more-easily crackable)
10
const mnemonic = mnemonicGenerate();
11
โ€‹
12
// create & add the pair to the keyring with the type and some additional
13
// metadata specified
14
const pair = keyring.addFromUri(mnemonic, { name: 'first pair' }, 'ed25519');
15
โ€‹
16
// the pair has been added to our keyring
17
console.log(keyring.pairs.length, 'pairs available');
18
โ€‹
19
// log the name & address (the latter encoded with the ss58Format)
20
console.log(pair.meta.name, 'has address', pair.address);
Copied!
sr25519
There is one caveat with the different crypto types. The underlying @polkadot/util-crypto libraries makes use of WASM with JS fallbacks. However sr25519 there is only a WASM interface. This means that before adding any keypair with sr25519, we first need to ensure the WASM is initialized.
1
import { cryptoWaitReady, mnemonicGenerate } from '@polkadot/util-crypto';
2
import { Keyring } from '@polkadot/keyring';
3
โ€‹
4
// create a keyring with some non-default values specified
5
const keyring = new Keyring({ type: 'sr25519', ss58Format: 6 });
6
โ€‹
7
// generate a mnemonic with default params (we can pass the number
8
// of words required 12, 15, 18, 21 or 24, less than 12 words, while
9
// valid, is not supported since it is more-easily crackable)
10
const mnemonic = mnemonicGenerate();
11
โ€‹
12
await cryptoWaitReady();
13
// create & add the pair to the keyring with the type and some additional
14
// metadata specified
15
const pair = keyring.addFromUri(mnemonic, { name: 'first pair' });
16
โ€‹
17
// the pair has been added to our keyring
18
console.log(keyring.pairs.length, 'pairs available');
19
โ€‹
20
// log the name & address (the latter encoded with the ss58Format)
21
console.log(pair.meta.name, 'has address', pair.address);
Copied!

Validate address

This function will return true if the address is a legitamate Polkadot address and false if it is not Works both with Ed25519 and Sr25519 key types
1
const { decodeAddress, encodeAddress } = require('@polkadot/keyring');
2
const { hexToU8a, isHex } = require('@polkadot/util');
3
โ€‹
4
const address = '5GrpknVvGGrGH3EFuURXeMrWHvbpj3VfER1oX5jFtuGbfzCE';
5
โ€‹
6
const isValidAddressPolkadotAddress = () => {
7
try {
8
encodeAddress(
9
isHex(address)
10
? hexToU8a(address)
11
: decodeAddress(address)
12
);
13
โ€‹
14
return true;
15
} catch (error) {
16
return false;
17
}
18
};
19
โ€‹
20
const isValid = isValidAddressPolkadotAddress();
21
โ€‹
22
console.log(isValid);
Copied!

Extension

Installation

1
yarn add @polkadot/extension-dapp
Copied!
Browser extensions are also required: Downloadโ€‹

Usage

1
import {
2
web3Accounts,
3
web3Enable,
4
web3FromAddress,
5
} from "@polkadot/extension-dapp";
6
import { ApiPromise, WsProvider } from "@polkadot/api";
7
import { options } from "@bifrost-finance/api";
8
โ€‹
9
// returns an array of all the injected sources
10
// (this needs to be called first, before other requests)
11
const allInjected = await web3Enable('my cool dapp');
12
โ€‹
13
// returns an array of { address, meta: { name, source } }
14
// meta.source contains the name of the extension that provides this account
15
const allAccounts = await web3Accounts();
16
โ€‹
17
// the address we use to use for signing, as injected
18
const SENDER = '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE';
19
โ€‹
20
// finds an injector for an address
21
const injector = await web3FromAddress(SENDER);
22
โ€‹
23
// create instance
24
const wsProvider = new WsProvider("wss://bifrost-rpc.testnet.liebi.com");
25
const api = await ApiPromise.create(options({ provider: wsProvider }));
26
โ€‹
27
// sign and send our transaction - notice here that the address of the account
28
// (as retrieved injected) is passed through as the param to the `signAndSend`,
29
// the API then calls the extension to present to the user and get it signed.
30
// Once complete, the api sends the tx + signature via the normal process
31
api.tx.balances
32
.transfer("gGT6EDq2igApbW68wgKCjwDi12Vu3CZG4NBLWiNJGRrUUrk", 22000000000000)
33
.signAndSend(SENDER, { signer: injector.signer }, (status) => { console.log(status) });
Copied!

Traverse events

Query the system events and extract information from them. This example runs until exited via Ctrl-C
1
// Import the API
2
import { ApiPromise, WsProvider } from '@polkadot/api';
3
import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
4
import { options } from '@bifrost-finance/api';
5
โ€‹
6
async function main() {
7
// Construct
8
const wsProvider = new WsProvider('wss://bifrost-rpc.testnet.liebi.com');
9
const api = await ApiPromise.create(options({ provider: wsProvider, rpc: jsonrpc }));
10
โ€‹
11
// Subscribe to system events via storage
12
api.query.system.events((events) => {
13
// Loop through the Vec<EventRecord>
14
events.forEach((record) => {
15
// Extract the phase, event and the event types
16
const { event, phase } = record;
17
const types = event.typeDef;
18
โ€‹
19
// Filter events that are not Transfer of balances pallet
20
if (`${event.section}:${event.method}` !== 'balances:Transfer') { return }
21
// Show what we are busy with
22
console.log(`\t${event.section}:${event.method}:: (phase=${phase.toString()})`);
23
console.log(`\t\t${event.meta.documentation.toString()}`);
24
โ€‹
25
// Loop through each of the parameters, displaying the type and data
26
event.data.forEach((data, index) => {
27
console.log(`\t\t\t${types[index].type}: ${data.toString()}`);
28
});
29
});
30
});
31
}
32
โ€‹
33
main().catch((error) => {
34
console.error(error);
35
process.exit(-1);
36
});
Copied!

Bifrost Metadata

Events

Events are emitted for certain operations on the runtime. The following sections describe the events that are part of the default Bifrost runtime.
  • balances
balances
BalanceSet(AccountId, Balance, Balance)
  • interface: api.events.balances.BalanceSet.is
  • summary: A balance was set by root. [who, free, reserved]
    Deposit(AccountId, Balance)
  • interface: api.events.balances.Deposit.is
  • summary: Some amount was deposited (e.g. for transaction fees). [who, deposit]
    DustLost(AccountId, Balance)
  • interface: api.events.balances.DustLost.is
  • summary: An account was removed whose balance was non-zero but below ExistentialDeposit, resulting in an outright loss. [account, balance]
    Endowed(AccountId, Balance)
  • interface: api.events.balances.Endowed.is
  • summary: An account was created with some free balance. [account, free_balance]
    Reserved(AccountId, Balance)
  • interface: api.events.balances.Reserved.is
  • summary: Some balance was reserved (moved from free to reserved). [who, value]
    ReserveRepatriated(AccountId, AccountId, Balance, BalanceStatus)
  • interface: api.events.balances.ReserveRepatriated.is
  • summary: Some balance was moved from the reserve of the first account to the second account. Final argument indicates the destination balance type. [from, to, balance, destination_status]
    Transfer(AccountId, AccountId, Balance)
  • interface: api.events.balances.Transfer.is
  • summary: Transfer succeeded. [from, to, value]
    Unreserved(AccountId, Balance)
  • interface: api.events.balances.Unreserved.is
  • summary: Some balance was unreserved (moved from reserved to free). [who, value]
Last modified 1mo ago