1.0.0 • Published 2 years ago

@dewebjs/akash-js v1.0.0

Weekly downloads
-
License
ISC
Repository
github
Last release
2 years ago

AkashJS - Akash JavaScript API

AkashJS implements much of the Akash command-line functionality in JavaScript (with TypeScript support) to enable JavaScript based deployment clients to be built. An example of this is the Akash Deploy Website that interacts with the Keplr wallet browser extension to allow visitors to quickly deploy to Akash.

Getting Started

Installation

This library is still highly experimental, and has not been published to a registry yet. For now, install in your project using:

npm install @dewebjs/akash-js

Proxy Server

A proxy server implementation is included in the proxy directory that can proxy RPC requests and Provider Gateway requests. It's needed in a browser setting because: 1) The public Akash RPC nodes are not CORS enabled. One way to get around this is to run your own node and enable CORS. Another is to start a CORS enabled server that proxies all browser requests to the public RPC nodes. 2) The main reason is that there's no way to perform any requests to a Provider Gateway from the Chrome browser today (which is the only officially supported browser by the Keplr wallet today). This is because the X.509 certificate generated by the Akash command-line contains "keyUsage = keyEncipherment, dataEncipherment", which leads to an "ERR_SSL_KEY_USAGE_INCOMPATIBLE" error in Chrome upon connection attempt (see also https://superuser.com/questions/1451895/err-ssl-key-usage-incompatible-solution). Having a proxy server that sits between the client's browser and the Provider solves this problem.

We may be able to do away with the proxy server completely if the provider certificate issue gets resolved in the future. A proxy for RPC is not strictly necessary because one can run their own CORS enabled nodes.

For now, to start the server, first navigate inside the proxy directory and install dependencies:

cd proxy
npm install

Edit the whitelist array in index.js to whitelist your frontend's domain (can be http://localhost:PORT during development), and anything else such as PORT if desired, and start the server:

node index.js

Akash in JS

To begin, initialize an instance of Akash with and RPC endpoint, and an offline signer. The offline signer can be any instance that implements the OfflineDirectSigner interface. This means it can be Keplr's OfflineSigner, CosmJS's DirectSecp256k1HdWallet, or something custom.

The following shows some semi-pseudo code to give you an idea. It's certainly non-exhaustive, and it's best to dig through the source code and examine the Typescript. But in general, the JavaScript API maps directly to the Akash command-line,

e.g. the command-line

akash query cert list --owner ADDRESS --serial SERIAL

in equivalent JavaScript is

akash.query.cert.list.params({ owner: ADDRESS, serial: SERIAL });
import { Akash, SDL, findDeploymentSequence } from 'akashjs';

// Simplified example using Keplr's offlineSigner:
const CHAIN_ID = 'akashnet-2';
await window.keplr.enable(CHAIN_ID);
const offlineSigner = window.getOfflineSigner(CHAIN_ID);
const accounts = await offlineSigner.getAccounts();
const address = accounts[0].address;

const RPC = 'http://localhost:8888/rpc';
const PROVIDER_GATEWAY = 'http://localhost:8888/provider'

const akash = await Akash.connect(RPC, offlineSigner);

// Create certificate
const response = await akash.tx.cert.create.client.params();

// Query certificate
const response = await akash.query.cert.list.params({
  owner: address,
  serial: serial
})

// Revoke certificate
const response = await akash.tx.cert.revoke.params({ serial: serial });

// Create deployment
const sdlString = 'BLAH';
const sdl = new SDL(sdlString);
const response = akash.tx.deployment.create.params({
  sdl: sdl
});
const {
  dseq, gseq, oseq
} = findDeploymentSequence(response);

// Query bids
const response = await akash.query.market.bid.list.params({
  owner: account.address,
  dseq: dseq
});

// Create lease
const response = await akash.tx.market.lease.create.params({
  dseq: dseq,
  oseq: oseq,
  gseq: gseq,
  provider: provider
});

// Send Manifest
await akash.provider.sendManifest.params({
  sdl: sdl,
  dseq: dseq,
  provider: provider,
  proxy: PROVIDER_GATEWAY
});

// Query lease status and access details
const response = await akash.provider.leaseStatus.params({
  dseq: dseq,
  oseq: oseq,
  gseq: gseq,
  provider: provider,
  proxy: PROVIDER_GATEWAY
});

Stargate

An instance of SigningAkashClient, which extends SigningStargateClient, is accessible from the instance of Akash. This means methods such as sendTokens(), delegateTokens(), signAndBroadcast(), etc. are also available:

const akash = await Akash.connect(RPC, offlineSigner);
const signingClient = akash.signingClient;

signingClient.sendTokens(address, recipientAddress, amount, fee, memo);

Note on HTTPS

  • Since the client's certificate private key will be sent to the proxy server, it's highly recommended that the proxy server is HTTPS enabled in production.
  • If certificate generation on the client is necessary, the client also needs to be HTTPS enabled. This is because the certificate generation code utilizes the Web Crypto API, which requires an HTTPS context.

Known Limitations

  • This library is highly experimental, and the general API is not finalized yet.
  • Note that not every single command-line command is implemented in JavaScript yet--I've only implemented the required ones for deployments so far. Notably, JavaScript equivalents to commands such as akash provider service-logs and akash provider service-status are not implemented yet, mostly because I haven't found time to decipher Akash's Golang WebSockets code yet. You can view the Akash command-line commands here.
  • The query APIs currently don't support pagination.

Disclaimer

We are not liable for any damages or loss, whether direct or indirect, in any way related to the usage of this library. Please use at your own risk.