Dijets is a JavaScript Library for interfacing with Dijets Ternary Chains of Value, Utility & Method. It is built using TypeScript and intended to support both browser and Node.js. This library allows one to issue commands to Dijets node APIs.
The APIs currently supported by default are:
- Admin API
- Auth API
- DJTXv API (for: Value Chain)
- DJTXu (for: Utility Chain)
- DJTXm API (for: Method Chain)
- Health API
- Info API
- Keystore API
- Metrics API
DijetsJS main purpose is to provide developers with an easy to integrate library. With this library, any Javascript developer is able to interact with a Dijets Node running on Dijets Primary Network provided that the API endpoints are enabled for the developer's consumption. Read more about the specifications hereDijetsJS Library.
DijetsJS - Features:
- Locally manage private keys
- Retrieve balances on addresses
- Get UTXOs for addresses
- Build and sign transactions
- Issue signed transactions to any of the Value Chain, Utility Chain or the Method Chain.
- Intra-Chain swaps to & fro - the Value Chain<->Method Chain and the Value Chain<->Utility Chain.
- Add Validators and Delegators by staking DJTX
- Test a local node setup
- Retrieve Dijets network information
Dijets requires Node.js LTS version 14.16.0 or higher to compile.
Dijets is available for installation via npm
:
npm install --save dijets
You can also pull the repo down directly and build it from scratch:
npm run build
Running this command will generate a pure Javascript Library i.e. "dijets.js" which is placed automatically in a folder named "web" in your project's root directory. The newly generated Javascript library "dijets.js" can then be integrated into any project simply by dropping it inside the project's workspace/folder as a pure javascript implementation of Dijets Network.
You can have the DijetsJS library at your Node.js project's disposal by importing it like so:
const dijets = require("dijets");
Or for your Typescript project you can import DijetsJS as follows:
import { Dijets } from "dijets"
import {
Dijets,
BN,
BinTools,
Buffer
} from "dijets"
const bintools = BinTools.getInstance();
The above lines import the libraries used in the tutorials. The libraries include:
- Dijets: Dijets javascript library module.
- BinTools: A collection of Binary Tool Utilities with a singleton built into Dijets. This library is used mainly to deal with binary data.
- BN: A bignumber module use by Dijets.
- Buffer: A Buffer library.
DijetsJS comes with a built-in Keychain. This KeyChain is primarily used during function calls to the API. The Keychain enables signed function calls by using keys it's registered. The first step in this process is to create an instance of DijetsJS connected to any of Dijets ternary chain's API endpoints.
import {
Dijets,
BinTools,
Buffer,
BN
} from "dijets"
const bintools = BinTools.getInstance();
const myNetworkID = 12345; // the network ID always defaults to 1. We specify the ID to override the defaults to run a local network instead.
const dijets = new Dijets("localhost", 9650, "http", myNetworkID);
const vchain = dijets.VChain(); //returns a reference to the Value-Chain used by DijetsJS
DijetsJS KeyChain is accessed through the Value Chain and can be referenced directly or through a reference variable.
const myKeychain = vchain.keyChain();
This exposes the instance of the class DJTXvKeyChain which is created when the Value Chain API is created. The function supports secp256k1 curve for ECDSA key pairs.
The KeyChain has the ability to create new KeyPairs for you and return the dijets address associated with the respective key pair.
const newAddress1 = myKeychain.makeKey(); // this will return an instance of the KeyPair class
You can also import your existing private key into the KeyChain using either a Buffer
const mypk = bintools.cb58Decode("DFjz6epjMrBKmUL4rkurfZnjqQHu9Eq287G1C5qpv2hr2tFCur"); // this will return a Buffer
const newAddress2 = myKeychain.importKey(mypk); // this will return an instance of the KeyPair class
... or a CB58 string instead:
const mypk = "DFjz6epjMrBKmUL4rkurfZnjqQHu9Eq287G1C5qpv2hr2tFCur";
const newAddress2 = myKeychain.importKey(mypk); // this will return an instance of the KeyPair class
The Value Chain KeyChain has built-in capabilities for general key management. The following operations are available in all the implementations of this KeyChain's interface.
const addressStrings = myKeychain.getAddressStrings(); // this will return an array of strings for the addresses
const addresses = myKeychain.getAddresses(); // this will return an array of Buffers for the addresses
const exists = myKeychain.hasKey(addresses[0]); // this will return true if the address is managed
const keypair = myKeychain.getKey(addresses[0]); // this will return the KeyPair class
The Value Chain KeyPair has standardized KeyPair functionality. The following operations are available in all the implementations of this KeyPair's instance.
const address = keypair.getAddress(); // this will return Buffer
const addressString = keypair.getAddressString(); // this will return string
const pubk = keypair.getPublicKey(); // this will return Buffer
const pubkstr = keypair.getPublicKeyString(); // this will return a CB58 encoded string
const privk = keypair.getPrivateKey(); // this will return Buffer
const privkstr = keypair.getPrivateKeyString(); //returns a CB58 encoded string
keypair.generateKey(); // creates a new random KeyPair
const mypk = bintools.cb58Decode("24jUJ9vZexUM6expyMcT48LBx27k1m7xpraoV62oSQAHdziao5");
const successul = keypair.importKey(mypk); // this will return boolean if private key imported successfully
const message = Buffer.from("Through consensus to the stars");
const signature = keypair.sign(message); // this will return a Buffer with the signature
const signerPubk = keypair.recover(message, signature); // this will return a Buffer
const isValid = keypair.verify(message, signature); // this will return a boolean
This example shows how to create a digital asset on Dijets Value Chain and declare it publicly within the Dijets Ecosystem. Just like in the previous example, the first step in this process is to create an instance of DijetsJS connected to a ternary chain endpoint of our choice.
import {
Dijets,
BinTools,
BN,
Buffer,
} from "dijets"
import {
InitialStates,
SECPTransferOutput
} from "dijets/dist/apis/DJTXv"
const myNetworkID = 12345; // NetworkID always defaults to 1, we need to override that for the local network
const dijets = new Dijets("localhost", 9650, "http", myNetworkID);
const vchain = dijets.VChain(); // this will return a reference to the Value Cain used by DijetsJS
The first steps in creating a new asset using DijetsJS library is to determine the relatively basic properties of the asset. Theese properties can be the digital asset's name, its ticker symbol, and its denomination.
// Giving a name to our new coin
const name = "PenXenOleFren";
// Giving a symbol to the coin
const symbol = "PXF";
// The coin's denomination indicates what the basic main unit of an asset is and where its fractional subunit begins from.
// For Example in Dijets case: 1 DJTX as the base unit has a denomination of 9. The smallest sub-unit of DJTX is a nanoDJTX (nDJTX) at 10^-9 DJTX
// NanoDijet = NanoDjtx = 1
// MicroDijet = MicroDjtx = 1000 * NanoDjtx
// Boson = 49*MicroDjtx + 463*NanoDjtx
// MesonDijet = MesonDjtx = 1000 * MicroDjtx
// Dijet = Djtx = 1000 * MesonDjtx
// PionDjtx uint64 = 1000 * Djtx
// ExaDjtx uint64 = 1000 * PionDjtx
const denomination = 9;
This example makes a value chain transfer to a single recipient address. The first step in this process is to create an instance of Dijets connected to our Ternary Chain API endpoint of choice.
import {
Dijets,
BinTools,
Buffer,
BN
} from "dijets"
const myNetworkID = 12345; // defaults to 1, override it to use local network
const dijets = new dijets.Dijets("localhost", 9650, "http", myNetworkID);
const vchain = dijets.VChain(); // this will return a reference to the v chain used by DijetsJS
Now, provided the keystore contains a list of addresses which will be used in this transaction, we can start the transfer process by getting the UTXOs
Dijets Value Chain stores all available balances for addresses in a datastore called the "Unspent Transaction Outputs (UTXOs)". A UTXO Set is the unique list of outputs produced by transactions, addresses that can spend those outputs, and other variables such as lockout times (a timestamp after which the output can be spent) and thresholds (how many signers are required to spend the output).
To keep the examples compact, we're going to create a simple transaction that spends x amount of available coins and sends it to a single address without any limitations.
Here's how to get the UTXOs for the addresses we'll be using in this example.
const myAddresses = vchain.keyChain().getAddresses(); // this will return an array of addresses the KeyChain manages as buffers
const addressStrings = xchain.keyChain().getAddressStrings(); // this will return an array of addresses the KeyChain manages as strings
const u = await vchain.getUTXOs(myAddresses);
const utxos = u.utxos
— Asset ID of the digital asset we wish to transfer. (For this example we are using a random AssetID)
— Helper function to send the digital asset => buildBaseTx()
— Available Balance of 400 coins
We can verify that we have the funds available for the transaction like so:
const assetid = "8pfG5CTyL5KBVaKrEnCvNJR95dUWAKc1hrffcVxfgi8qGhqjm"; // cb58 encoded string
const mybalance = utxos.getBalance(myAddresses, assetid); // this operation returns 400 as BN (Big Number)
Once we have verified the balance availability of 400 coins! We can go ahead and send 200 of those coins to our friend's address.
const sendAmount = new BN(200); // amount is in BN (Big Number) format
const friendsAddress = "dijets1k26annideya2ms95puxcczsa3lzwf5ftt0fjk"; // note the address format is in Bech32 as the transfer is being made on the Value Chain.
// The below returns an UnsignedTx
// Parameters sent are (in order of appearance):
// * The UTXO Set
// * The amount being sent as a BN
// * An array of addresses to send the funds
// * An array of addresses sending the funds
// * An array of addresses any leftover funds are sent
// * The AssetID of the funds being sent
const unsignedTx = await xchain.buildBaseTx(utxos, sendAmount, [friendsAddress], addressStrings, assetid);
const signedTx = vchain.signTx(unsignedTx);
const txid = await vchain.issueTx(signedTx);
The transfer is completed and the transaction is sent.
Now that we sent the transaction to the network, it takes a few seconds to determine if the transaction has gone through. We can get an updated status on the transaction using the TxID through the Value Chain.
// Expected responses for transactio: "Accepted", "Processing", "Unknown", and "Rejected"
const status = await vchain.getTxStatus(txid);
The statuses can be one of "Accepted", "Processing", "Unknown", and "Rejected":
- "Accepted" indicates that the transaction has been accepted as valid by the network and executed
- "Processing" indicates that the transaction is being voted on.
- "Unknown" indicates that node knows nothing about the transaction, indicating the node doesn't have it
- "Rejected" indicates the node knows about the transaction, but it conflicted with an accepted transaction