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 🙏

© 2025 – Pkg Stats / Ryan Hefner

nem-voting

v2.2.9

Published

nem voting

Readme

NEM Voting

npm version Build Status Coverage Status License: MIT

nem-voting is a typescript / node.js module for using the NEM voting functionalities easily on any project. Created using NEM-library.

  1. Installation
  2. Examples
  3. Definitions
  4. Technical specification

Installation

to install the npm module on your typescript or node project run:

npm install nem-voting --save

the module is made to work together with nem-library, so you should install that too:

npm install [email protected] --save

it is important that 1.0.5 is installed since it needs to be the same version than the one in nem-voting

Examples

The module exports two main classes: UnbroadcastedPoll and BroadcastedPoll. They represent polls that exist only locally and polls that exist in the blockchain, respectively.

It also exports a PollConstants object with various usefull constants for voting and a PollIndex object for handling indexes other than the public one (public and private), along with some useful functions specified below.

Creating and Broadcasting a Poll to the blockchain

import { PollConstants, UnbroadcastedPoll, BroadcastedPoll } from "nem-voting";
import { NEMLibrary, NetworkTypes, Account, TransactionHttp } from "nem-library";
import { Observable } from "rxjs";

// This function will bootstrap both the internal nem-library for nem-voting and the local one
// if the local version of nem-library and the one in nem-voting don't match then this will give problems
NEMLibrary.bootstrap(NetworkTypes.TEST_NET); // Change to NetworkTypes.MAIN_NET for main net
const testPrivateKey = "c195d7699662b0e2dfae6a4aef87a082d11f74d2bd583f7dec5663a107823691"; // introduce the poll creator private key

const formData = {
    title: "test poll 2.0",
    doe: Date.now() + (60 * 1000 * 60), // Date of ending as timestamp in milliseconds
    type: PollConstants.POI_POLL, // type of vote counting
    multiple: false, // true if multiple votes are allowed
};
const description = "This is the description for the poll";
const options = ["option 1", "option 2"];

// Create poll object
const poll = new UnbroadcastedPoll(formData, description, options);
const account = Account.createWithPrivateKey(testPrivateKey);

// We get the broadcasted poll data, including the poll address and the option addresses
const broadcastData = poll.broadcast(account.publicKey);
// Now we sign and broadcast the transactions
const transactionHttp = new TransactionHttp();
Observable.merge(...(broadcastData.transactions.map((t) => {
    const signed = account.signTransaction(t);
    return transactionHttp.announceTransaction(signed);
})))
    .last()
    .subscribe(() => {
        // The poll is now broadcasted, but we need to wait for all the transactions to be confirmed
        console.log(broadcastData.broadcastedPoll);
    });

Fetching a Poll from the blockchain

import { BroadcastedPoll, NEMVoting } from "nem-voting";
import { NEMLibrary, Address, NetworkTypes } from "nem-library";

// This function will bootstrap both the internal nem-library for nem-voting and the local one
// if the local version of nem-library and the one in nem-voting don't match then this will give problems
NEMLibrary.bootstrap(NetworkTypes.TEST_NET); // Change to NetworkTypes.MAIN_NET for main net
const pollAddress = new Address("TCX6LT3Y43IQL3DKU6FAGDMWJFROQGFPWSJMUY7R");

BroadcastedPoll.fromAddress(pollAddress)
    .map((poll) => {
        return poll;
    })
    .subscribe((data) => {
        console.log(data);
    });

Getting the results for a broadcasted poll

import { BroadcastedPoll, NEMVoting } from "nem-voting";
import { NEMLibrary, Address, NetworkTypes } from "nem-library";

// This function will bootstrap both the internal nem-library for nem-voting and the local one
// if the local version of nem-library and the one in nem-voting don't match then this will give problems
NEMLibrary.bootstrap(NetworkTypes.TEST_NET); // Change to NetworkTypes.MAIN_NET for main net
const pollAddress = new Address("TCX6LT3Y43IQL3DKU6FAGDMWJFROQGFPWSJMUY7R");

BroadcastedPoll.fromAddress(pollAddress)
    .switchMap((poll) => {
        return poll.getResults();
    })
    .subscribe((results) => {
        console.log(results);
    });

Voting on a poll

import { BroadcastedPoll } from "nem-voting";
import { NEMLibrary, Address, NetworkTypes, Account, TransactionHttp } from 'nem-library';

// This function will bootstrap both the internal nem-library for nem-voting and the local one
// if the local version of nem-library and the one in nem-voting don't match then this will give problems
NEMLibrary.bootstrap(NetworkTypes.TEST_NET); // Change to NetworkTypes.MAIN_NET for main net
const pollAddress = new Address("TBW2PIAVJPW7QRHWJ74PA4E36B6FNE7QWGOI3JAF"); // Poll Address
const testPrivateKey = "c195d7699662b0e2dfae6a4aef87a082d11f74d2bd583f7dec5663a107823691"; // Voter private key
const account = Account.createWithPrivateKey(testPrivateKey);

BroadcastedPoll.fromAddress(pollAddress)
    .switchMap((poll) => {
        // It is important to validate that a poll is valid before voting
        if (!poll.validate()) {
            throw new Error("Invalid Poll");
        }
        const voteTransaction = poll.vote(poll.data.options[0]); // get vote transaction
        const signed = account.signTransaction(voteTransaction); // sign transaction
        const transactionHttp = new TransactionHttp();
        return transactionHttp.announceTransaction(signed); // broadcast transaction
    })
    .subscribe((announceResult) => {
        console.log(announceResult);
    });

Definitions

UnbroadcastedPoll

interface IFormData {
    /**
     * Title of the poll
     */
    title: string;
    /**
     * date of ending, as milliseconds from UNIX epoch
     */
    doe: number;
    /**
     * True if multiple votes are accepted
     */
    multiple: boolean;
    /**
     * type of the poll
     */
    type: number;
}
interface IPollData {
    /**
     * General information abount the poll
     */
    formData: IFormData;
    /**
     * Detailed description for the poll
     */
    description: string;
    /**
     * Options of the poll
     */
    options: string[];
    /**
     * (optional) Array of Addresses to be whitelisted. Only for whitelist polls
     */
    whitelist?: Address[];
}
interface IBroadcastData {
    /**
     * Transactions that need to be sent and confirmed for the poll to be broadcasted
     */
    transactions: TransferTransaction[];
    /**
     * Broadcasted Poll object. Can not be used until the transactions have been broadcasted and confirmed
     */
    broadcastedPoll: BroadcastedPoll;
}
/**
 * Abstract class that represents a poll
 */
declare abstract class Poll {
    readonly data: IPollData;
}
/**
 * An unbroadcasted poll. Exists only locally and not on the blockchain yet
 */
declare class UnbroadcastedPoll extends Poll {
    constructor(formData: IFormData, description: string, options: string[], whitelist?: Address[]);
    /**
     * Broadcasts an unbroadcasted poll and returns the resulting broadcasted poll object (as a promise)
     * @param creatorPublicKey - public key of the poll creator
     * @param pollIndex - optionally provide the poll index to send the poll to.
     *                    If not specified the default public index is used
     * @return {pollAddress: Address, transactions: TransferTransaction[]} - returns the poll address
     * and the transactions that need to be sent for it to be broadcasted
     */
    broadcast: (creatorPublicKey: string, pollIndex?: PollIndex | undefined) => IBroadcastData;
}

BroadcastedPoll

/**
 * A broadcasted poll. Represents a Poll that exists in the blockchain.
 */
declare class BroadcastedPoll extends Poll {
    /**
     * The poll address
     */
    readonly address: Address;
    /**
     * Map from option to option address
     */
    private optionAddresses;
    /**
     * Fetches a Broadcasted Poll from the blockchain by its address
     * @param pollAddress - The poll's NEM Address
     * @return Promise<BroadcastedPoll>
     */
    private static fromAddressPromise;
    /**
     * Fetches a Broadcasted Poll from the blockchain by its address
     * @param pollAddress - The poll's NEM Address
     * @return Observable<BroadcastedPoll>
     */
    static fromAddress: (pollAddress: Address) => Observable<BroadcastedPoll>;
    /**
     * Gets the option address for a given option
     * @param option - The option
     * @return Address | null
     */
    getOptionAddress: (option: string) => Address | null;
    /**
     * Gets the results for the poll
     * @param pollAddress - The poll's NEM Address
     * @return Observable<IResults>
     */
    getResults: () => Observable<IResults>;
    /**
     * Gets the results for the poll as a csv string
     * @param pollAddress - The poll's NEM Address
     * @return Observable<string>
     */
    getCsvResults: () => Observable<string>;
    /**
     * Gets the results for the poll as an array of vote objects
     * @param pollAddress - The poll's NEM Address
     * @return Observable<IResults>
     */
    getVoters: () => Observable<IVote[]>;
    /**
     * validates a poll's structure and returns wether it is correct or not
     * @return boolean
     */
    validate: () => boolean;
    /**
     * Votes on the poll from a given account, returns the vote transaction result
     * @param option - The option to vote
     * @return TransferTransaction - the transaction that needs to be sent to vote
     */
    vote: (option: string) => TransferTransaction;
    /**
     * Votes on the poll from a multisig account, returns the vote transaction result
     * @param multisigAccount - The public account of the multisig account that votes
     * @param option - The option to vote
     * @return MultisigTransaction - the transaction that needs to be sent to vote
     */
    voteMultisig: (multisigAccount: PublicAccount, option: string) => MultisigTransaction;
    /**
     * Gets the votes that an address has sent to the poll, if it has not voted returns null
     * @param address - The address of the voter
     * @return Observable<Transaction[] | null>
     */
    getVotes: (address: Address) => Observable<Transaction[] | null>;
}

Constants

export const PollConstants = {
    /**
     * Poll Types
     */
    POI_POLL: 0,
    WHITELIST_POLL: 1,

    /**
     * Poll Indexes
     */
    TESTNET_POLL_INDEX: "TAVGTNCVGALLUPZC4JTLKR2WX25RQM2QOK5BHBKC",
    MAINNET_POLL_INDEX: "NAZN26HYB7C5HVYVJ4SL3KBTDT773NZBAOMGRFZB",
};

Poll Indexes

/**
 * Represents the info from a poll header sent to an index
 */
interface IPollHeader {
    title: string;
    type: number;
    doe: number;
    address: Address;
    whitelist?: Address[];
}
/**
 * Contains the info for a poll index, public or private
 */
declare class PollIndex {
    /**
     * Poll Index Address
     */
    address: Address;
    /**
     * true if the index is private. On private indexes only the creator can send valid polls
     */
    isPrivate: boolean;
    /**
     * the creator of the poll, only needed for private indexes
     */
    creator?: Address;
    /**
     * array of broadcasted header polls for the index
     */
    headers: IPollHeader[];
    /**
     * Gets a poll index from its address with all of its broadcasted polls
     * @param address - the index account address
     * @return Observable<PollIndex>
     */
    static fromAddress: (address: Address) => Observable<PollIndex>;
    /**
     * Creates a new poll Index
     * @param isPrivate - will create a private index if true
     * @param creatorAddress - needed only if the index is private
     * @return Observable<PollIndex>
     */
    static create: (isPrivate: boolean, creatorAddress?: Address | undefined) => {
        address: Address;
        transaction: TransferTransaction;
    };
}
/**
 * Gets the addresses for all the poll indexes created by an address
 * @param creator - the address of the creator of the indexes we want
 * @return Observable<Address[]>
 */
declare const getCreatedIndexAddresses: (creator: Address) => Observable<Address[]>;

Technical specification

A Detailed Technical description of the NEM voting Standard is mantained at https://github.com/shierve/NEM-voting-specifications