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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qvote/zilliqa-sdk

v1.1.6

Published

Quadratic Voting smart contract SDK for Zilliqa

Readme

QVoteZilliqaSDK :sunglasses: :nail_care:

Quadratic Voting smart contract SDK for Zilliqa

Part of the Zillacracy grant initiative.

Zillacracy x QVote

Docs Here

Quadratic Voting - very oversimplified

Quadratic Voting is a better way of voting. It allows you to express more than simply your favourite choice. You are given a number of credits you can distribute to the options according to how you feel about them. You can also give negative credits to the options you don't like. The effective number of votes you cast for a given amount of credits is the square root of the absolute number of credits. This encourages you to vote for multiple options instead of piling all your credits on one choice. In this way you effectively get to rank the options according to your preference, and also express the extent to which you like or dislike an option.

There's actually much more to quadratic voting. Read up about it here. https://vitalik.ca/general/2019/12/07/quadratic.html https://www.radicalxchange.org/concepts/quadratic-voting/

The basics

This sdk is designed to help build applications that use quadratic voting. It's functionality handles these smart contracts for you at a high level. Low level blockchain interactions are abstracted away.

Install

Make sure you have Zilliqa-js installed like so npm i @zilliqa-js/zilliqa

Then install the QVote Zilliqa SDK npm i @qvote/zilliqa-sdk

Example walkthrough with Injected Zilliqa

const TESTNET = {
  url: "https://dev-api.zilliqa.com",
  protocol: { chainId: 333, msgVersion: 1 },
};
const zil = new Zilliqa(TESTNET.url);
zil.wallet.setDefault(deployerAddress);
const qv = new QVoteZilliqa(zil, TESTNET.protocol);

/**
 * Get current block number (think of it as a timestamp)
 * Get current minimum gasPrice (price you pay for computation on the blockchain)
 */
const txblock = await zil.blockchain.getLatestTxBlock();
const curBlockNumber = parseInt(txblock.result!.header!.BlockNum);

/* Deploy a contract */
const [qvotingAddress, qvInstance, deployTx] = await qv.deploy(
  {
    name: "Test hi",
    description: "Hello hi",
    options: ["opt1", "opt2", "opt3", "opt4"],
    creditToTokenRatio: "1000",
    //can register for next 0 min
    registrationEndTime: qv.futureTxBlockNumber(curBlockNumber, 60 * 0),
    //can vote in 0 min and voting is open for 15 min
    expirationBlock: qv.futureTxBlockNumber(curBlockNumber, 60 * 15),
    tokenId: "DogeCoinZilToken",
  },
  deployerAddress
);

/* Register addressses */
const registerTx = await qv.ownerRegister(qvInstance, {
  addresses: [deployerAddress, voterAddress],
  creditsForAddresses: [100, 100],
});

/* Vote as deployer (we registered this qvotingAddress) */
const voteTx1 = await qv.vote(qvInstance, {
  // ["opt1", "opt2", "opt3", "opt4"] so we are giving
  // 20 cred to opt1, and -80 to opt2 0 to opt3, 0 to opt4
  creditsToOption: ["20", "-80", "0", "0"],
});

/* Vote as voter (we registered this qvotingAddress) */
zil.wallet.setDefault(voterAddress);
const voteTx2 = await qv.vote(qvInstance, {
  creditsToOption: ["50", "-30", "-20", "0"],
});

/**
 * Getting contract immutable initial state variables
 * Getting contract mutable state variables
 */
const contractState = await qv.getContractState(qvotingAddress);

/**
 * Adding qv contract qvotingAddress to a queue
 */

/**
 * Deploying queue
 */
zil.wallet.setDefault(deployerAddress);
const queue = new QueueZilliqa(zil, BLOCKCHAINS.CURRENT.protocol);

const [address1, queueInstance, deployTx1] = await queue.deploy(
  {
    maxQueueSize: "3",
  },
  deployerAddress
);

/**
 * we can also get the instance from a deployed address
 */
const regeneratedQueueInstance = queue.getInstance(address1);

/**
 * Pushing address to queue
 */
const pushTx = await queue.push(regeneratedQueueInstance, {
  addressToPush: qvotingAddress,
});

/**
 * Pushing address to queue2
 */
const pushTx2 = await queue.push(regeneratedQueueInstance, {
  addressToPush: voterAddress,
});
/**
 * Getting queue state
 */
const queueState = await queue.getContractState(address1, 14);

Example walkthrough

Create the QVote object. With this we can pretty much do everything. Fetch, deploy, interact with the quadratic voting smart contracts.

Get the transaction block, the current blocknumber and the gas price. We will need these to deploy the contracts.

const txblock = await zil.blockchain.getLatestTxBlock();
const curBlockNumber = parseInt(txblock.result!.header!.BlockNum);
const gasPrice = await qv.handleMinGas(zil.blockchain.getMinimumGasPrice());

Deploy a QVote election

Create the payload with qvote and create a new contract instance, then deploy it with QVote.

zil.wallet.setDefault(deployerAddress);
const contract = zil.contracts.new(
  ...qv.payloadQv({
    payload: {
      name: "Test hi",
      description: "Hello hi",
      options: ["opt1", "opt2", "opt3", "opt4"],
      creditToTokenRatio: "1000",
      //can register for next 0 min
      registrationEndTime: qv.futureTxBlockNumber(curBlockNumber, 60 * 0),
      //can vote in 0 min and voting is open for 15 min
      expirationBlock: qv.futureTxBlockNumber(curBlockNumber, 60 * 15),
      tokenId: "DogeCoinZilToken",
    },
    ownerAddress: deployerAddress,
  })
);
const [qvotingAddress, instance, deployTx] = await qv.handleDeploy(
  contract.deploy(...qv.payloadDeploy({ gasPrice }))
);
console.log(qvotingAddress);

Registering and voting

To vote on a QVote smart contract you have to first register (prevents double voting). You pass to the payload a list of addresses that will be allowed to vote, and the number of credits they have. NOTE: this is a temporary solution. As you can see, the owner can set the credits of every voter, so effectively control the election in a very centralized manner. The credit values should be proportional to the balances of tokens for each of the users (as explained in the smart contracts). As soon as we are able to access the state of another smart contract form within scilla, users will be able to register themselves and the smart contracts will take care of credit assigning.

const registerTx = await instance.call(
  ...qv.payloadOwnerRegister({
    payload: {
      addresses: [deployerAddress, voterAddress],
      creditsForAddresses: [100, 100],
    },
    gasPrice,
  })
);
printEvents(registerTx);

some example votes

const voteTx1 = await instance.call(
  ...qv.payloadVote({
    payload: {
      // ["opt1", "opt2", "opt3", "opt4"] so we are giving
      // 20 cred to opt1, and -80 to opt2 0 to opt3, 0 to opt4
      creditsToOption: ["20", "-80", "0", "0"],
    },
    gasPrice,
  })
);
printEvents(voteTx1);

/* Vote as voter (we registered this qvotingAddress) */
zil.wallet.setDefault(voterAddress);
const voteTx2 = await instance.call(
  ...qv.payloadVote({
    payload: {
      creditsToOption: ["50", "-30", "-20", "0"],
    },
    gasPrice,
  })
);
printEvents(voteTx2);

/**
 * Getting contract immutable initial state variables
 * Getting contract mutable state variables
 */
const init = await instance.getInit();
const state = await instance.getState();
const contractState = qv.parseInitAndState(init, state);
console.log(contractState);

Decision Queue

There is another contract called DecisionQueue. This contract stores the addresses to deployed decision contracts so that they can be found in the blockchain by web apps. No databases, everything is onchain. Pushing to this queue is optional. You can always share the address to the deployed decision contract 'manually' to all your users. You can also deploy your own queue, for your own community. This way you can reference this queue in your web app, and display the decisions relevant to your community.

/**
 * Deploying queue
 */
zil.wallet.setDefault(deployerAddress);
const queue = new QueueZilliqa();

const queueContract = zil.contracts.new(
  ...queue.payloadQueue({
    payload: {
      maxQueueSize: "3",
    },
    ownerAddress: deployerAddress,
  })
);
const [address1, queueInstance, deployTx1] = await queue.handleDeploy(
  queueContract.deploy(...queue.payloadDeploy({ gasPrice }))
);

/**
 * Pushing address to queue
 */
const pushTx = await queueInstance.call(
  ...queue.payloadPushQueue({
    payload: {
      addressToPush: qvotingAddress,
    },
    gasPrice,
  })
);
printEvents(pushTx);

/**
 * Pushing address to queue2
 */
await queueInstance.call(
  ...queue.payloadPushQueue({
    payload: {
      addressToPush: voterAddress,
    },
    gasPrice,
  })
);

/**
 * Pushing address to queue3
 */
await queueInstance.call(
  ...queue.payloadPushQueue({
    payload: {
      addressToPush: deployerAddress,
    },
    gasPrice,
  })
);

/**
 * Pushing address to queue4
 */
await queueInstance.call(
  ...queue.payloadPushQueue({
    payload: {
      addressToPush: zil.wallet.create(),
    },
    gasPrice,
  })
);

/**
 * Getting queue state
 */
const queueState = await queueInstance.getState();
console.log(queueState);