npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

boost-zil

v1.1.15

Published

# Overview

Downloads

10

Readme

:fire: boost-zil :fire:

Overview

Welcome to your single stop solution to development on Zilliqa.

boost-zil features:

  • :hammer: smart contract isolated server docker testing
  • :robot: fully automated typescript smart contract typesafe SDK generation
  • :sunglasses: a suite of convenience methods that allow you to go from idea to working app in a matter of hours
  • :rocket: SDK works with node and zilpay in the browser out of the box

Q: Why is it 10 times better?

A: The SDK is typed, that means that with an IDE you will be asked to put the parameters that the contract requires AND the parameters will be formatted for you to be consumed by the blockchain.

Docs Here

:package: Package breakdown

  • boost-zil/lib/testing -> testing related methods
  • boost-zil -> convenience methods and smart contract SDK types
  • boost-zil-build -> bash script that builds the smart contracts in the current directory
  • boost-zil-project -> bash script that initializes a boost-zil project in the current directory

Q: Why are imports separate for testing?

A: So that the package convienience methods can be used in the browser!

Quick start

npm i boost-zil@latest -g

Make your project dir go to it and init:

mkdir myProject && cd myProject && boost-zil-project

✨ Congrats ✨

This is that simple.

You just created a scilla dev project that can build your contract, and test it on an isolated ziliqa blockchain server.

If you want to deploy to mainnet production you are just a step away.

Read through the code and get started!

Examples

EXAMPLES

Build a Scilla smart contract

With boost-zil.json already defined in your directory:

{
  // relative path from current directory to all the contracts you want to build
  "contracts": ["./test/SlotMachine/SlotMachine.scilla"],
  // if you want to make signers for meta transactions
  // experimental
  "makeSigners": false
}

In your terminal:

boost-zil-build

✨ Bam! ✨

You are done your contracts are built.

You can import your contract SDK from ../path/to/contract/build/bind.ts

Have a read through the bind to understand how it works.

Deploy a contract using the SDK

import {SDKResolvers, Uint128} from 'boost-zil'
import {SlotMachine} from './test/SlotMachine/build/bind'
import {Zilliqa, Long} from "@zilliqa-js/zilliqa";

const runtimeconfig = {
  "nodeUrl": "https://api.zilliqa.com/",
  "version": 65537,
  "networkName": "mainnet"
}


/**
 * The best concept about this sdk are resolvers
 * why?
 * you can provide and change them in any environment with ease,
 * so you can test the same code you use in production for instance
 * on an isolated server that is integrated into this framework
 * */
const resolvers: SDKResolvers = {
  getZil: async (
    // this will be true if the sdk requires a signer to make a transaction
    // otherwise it means that the sdk is just getting state of the contract for instance
    requireSigner
  ) => {
    // your custom teardown zil function
    // you might need this if your services are using the same private key in multiple places
    // for instance you have a meta transaction submitting service and you neeed an arbitrary
    // private key to submit, but only one process can use it at a time
    // you can make an aquire submitter private key mechanism and then release ownership over
    // the private key when teardown is called
    let teardown = async () => {};
    const zil = new Zilliqa(runtimeconfig.nodeUrl);
    if (signer) {
      zil.wallet.addByPrivateKey(a.privateKey);
      teardown = async () => {};
    }
    return { zil, teardown };
  }
  // version of the blockchain protocol
  getVersion: () => runtimeconfig.version;
  // the name of the network used by the logger to give you viewblock links
  getNetworkName: () => runtimeconfig.networkName;
  // optional to provide custom transaction logging logic
  // example if you are runnning this on google cloud functions
  // you might want to write your custom transaction logging function
  // however on default you have a logging function that gives you viewblock links
  // prints the events errors and if transaction was successsfull (included in the blockchain)
  /* txLog?: (t: Transaction, msg: string) => void; */
}


(async () => {
  const limit = Long.fromString("20000");
  const slotMachine = SlotMachine(resolvers);
  const { address, tx } = await slotMachine
    // deploy always takes the gas limit and the contract init parameters after it
    .deploy(
      limit,
      // now the contract parameters
      // THESE ARE TYPED, JUST HOVER OVER THE FUNCTION IN VS CODE :sunglasses:
      adminPubKey,
      // the admin of the
      fundingAccount.address,
      // will just return the corresponsing number to 10.12 zil
      // which is 10.12 * 10^12
      Uint128.fromFraction("10.12", 12),
      // just "1000" wrapped in Uint128 type
      new Uint128("1000")
    )
    .send();

})()

Make a call to a smart contract

import {Uint128, ByStr20} from 'boost-zil'
import {SlotMachine} from './test/SlotMachine/build/bind'
import {Zilliqa, Long} from "@zilliqa-js/zilliqa";


(async () => {
  const limit = Long.fromString("20000");]
  // checkout deploy section to know how to get resolvers
  const slotMachine = SlotMachine(resolvers);
  // just put a bech32 or bystr20 address everything is formatted under the hood :)
  const address = new ByStr20("")
  // all calls that are available for that smart contract will be here
  const slotMachineCall = slotMachine.calls(address)(limit);
  // :sparkles: bam easiest call of my life
  // thats how you can send it directly
  // the sdk AUTOMAGICALLY detects if a transition accepts ZIL
  // the how much ZIL should be sent will be always the first param if the contract accepts
  const {tx} = await slotMachineCall.AddFunds(Uint128.zil("34")).send();
  // but check this out
  // you can also get the json representing the transaction
  const asJson = slotMachineCall.AddFunds(Uint128.zil("45")).toJSON();
  // with the json you can show it to the user, save to db for later, anything!
  // to rejenerate and send a transaction from the json:
  const {tx} = await slotMachine.dangerousFromJSONCall(asJson, limit);

})()

Complex params call to a smart contract

import { List, Pair, ScillaString, ByStr20 } from "boost-zil";
import { SlotMachine } from "./test/SlotMachine/build/bind";
import { Zilliqa, Long } from "@zilliqa-js/zilliqa";

(async () => {
  // consider the ignite dao global config contract
  // with the following transition
  // transition UpdateByStrConfig(conf: List (Pair String ByStr20))
  //   IsAdmin;
  //   forall conf UpdateByStr
  // end
  // when you have the config contract sdk the call reduces to:
  await configContract
    .UpdateByStrConfig(
      new List(
        Object.entries(conf.config.config.bystr20).map(
          ([k, v]) => new Pair(new ScillaString(k), new ByStr20(v))
        )
      )
    )
    .send();
})();

Get partial state of a contract (example: GZIL)

import { createAccount } from "boost-zil";

const transferTarget = createAccount();
const gzilCall = gzil.calls(address)(limit);
const twoGzil = Uint128.fromFraction("2", 15);
const twoThirdGzil = Uint128.fromFraction("0.66", 15);
await gzilCall.Transfer(transferTarget.address, twoGzil).send();
const mintTarget = createAccount();
await gzilCall.Mint(mintTarget.address, twoThirdGzil).send();

const [state] = await gzil
  .state(
    {
      total_supply: "*",
      balances: {
        // will surgically get the state of mintTarget address and
        // transfer target address
        // remember to use lowerCase() this is how addresses are stored on the
        // blockchain
        [mintTarget.address.lowerCase()]: "*",
        [transferTarget.address.lowerCase()]: "*",
      },
      // you can get other fields too
    },
    // set to true if you want to get the initial state too
    "false"
  )
  .get(address);

expect(state.balances[mintTarget.address.lowerCase()]).to.be.eq(
  twoThirdGzil.toSend()
);
expect(state.balances[transferTarget.address.lowerCase()]).to.be.eq(
  twoGzil.toSend()
);

Get partial state of a contract without the sdk (example: fungible token balance)

You can do that but using sdks is recommended. (the sdks use this under the hood, you can check it out, by generating a sdk and reading the code)

const addr = new ByStr20("some address");
const tokens = ["fungible token 1", "fungible token 2", "fungible token 3"]
.map(t => new ByStr20(t))

const states = await partialState(async () => getNoSignerZil())(
          ...tokens.map((t) => ({
              contractAddress: t,
              includeInit: "false" as "false",
              query: {
                  balances: { [addr]: "*" as "*" },
              },
          })),
      );

Get partial state for multiple contracts as map

const stateGetter = mappedPartialState(getMainnetResolvers().getZil);
const state = await stateGetter(
  {
    contractAddress: ssn,
    query: { deposit_amt_deleg: { [someAddr.lowerCase()]: "*" } },
    includeInit: "false",
  },
  {
    contractAddress: gzil,
    query: { balances: { [bigGzilHodler.lowerCase()]: "*" } },
    includeInit: "true",
  },
  {
    contractAddress: zilswap,
    query: { pools: { [gzil.lowerCase()]: "*" } },
    includeInit: "false",
  }
);
expect(
  typeof state[ssn.toBech32()].deposit_amt_deleg[someAddr.lowerCase()] !=
    "undefined"
).to.be.true;
expect(
  typeof state[gzil.toBech32()].balances[bigGzilHodler.lowerCase()] !=
    "undefined"
).to.be.true;
expect(
  typeof state[zilswap.toBech32()].pools[gzil.lowerCase()] != "undefined"
).to.be.true;

Test smart contracts

You need to run docker desktop and then checkout the test directory of this project:

Test directory

consider that you will have everything setup if you just use in your commandline:

boost-zil-project

to setup a project for you.

Transaction logging

On an isolated server (if you would be sending to mainnet you would have viewblock links too):

Deploy 🔥
Success.
Transfer 🔥
Success.
Events🕵️‍♀️
TransferSuccess
sender: 
"0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82"
recipient: 
"0x06c586241ae6c6fe02de96b4683b4f45e6868643"
amount: 
"2000000000000000"
Mint 🔥
Success.
Events🕵️‍♀️
Minted
minter: 
"0xd90f2e538ce0df89c8273cad3b63ec44a3c4ed82"
recipient: 
"0x97a89084fe8bacdc2e8e7298c0c3d27bae4f92e5"
amount: 
"660000000000000"

SDK types

import {Uint128,ByStr20} from 'boost-zil'

/**
 * Any sdk type like Uint128 and ByStr20 
 * List Pair 
 * Custom ADT 
 * Exist so that they streamline formatting and sending transactions
 * to the blockchain.
 * There are many quirks when it comes to the transactions, such as custom user ADTs
 * the formatting on the addresses across the entire stack.
 * that is why the sdk types corresponding to Scilla types exist.
 * Also it allows for static typing in typescript if you passed the right types to the
 * transaction which is epic!
 * */

// every type class exposes a .toSend() which recursively formats the message to the //// blockchain in conjunction with the contract sdks

const addr = new ByStr20("any address as long as it is an address bech32 or bystr20").toSend();

// addr now will be a formatted address and will be interpreted by the blockchain 
// correctly! same goes for any other type

// since gzil has 15 decimals to get 2.1 gzil all you have to do is:
const twoGzil = Uint128.fromFraction("2.1", 15);
// now twoGzil can be used in a transfer transaction to the GZIL contract !

// if you want a formatted human readable string for a frontend:
const humanReadableTwoGzil = Uint128.fromStringtoFraction(twoGzil.toSend(), 15, 3);
// humanReadableTwoGzil is now "2.100"

// more advanced but pays off :)
const twoGzil = Uint128.fromFraction("2", 15);
twoGzil.setTokenInfo({ symbol: "GZIL", decimals: 15, precision: 3 });

const threeGzil = Uint128.fromFractionUint128(twoGzil, "3.5");

expect(threeGzil.toSend()).to.be.equal("3500000000000000");
expect(threeGzil.getReadable()).to.be.equal("3.500");
expect(twoGzil.getReadable()).to.be.equal("2.000");

Full project examples

EXAMPLES

Zilmorphs (successfull NFT project source code)