Git Product home page Git Product logo

crowdnode.js's Introduction

CrowdNode allows you to become a partial MNO - staking Dash to earn interest, participate in voting, etc.

The CrowdNode Node.js SDK enables you to build Web-based flows and cross-platform CLI tools to privately manage staking using CrowdNode's KYC-free Blockchain API.

Install

Node.js

You must have node.js installed:

Mac & Linux

curl https://webinstall.dev/node | bash
export PATH="${HOME}/.local/opt/node:$PATH"

Windows

curl.exe -A MS https://webinstall.dev/node | powershell
PATH %USERPROFILE%\.local\opt\node;%PATH%

CrowdNode SDK

npm install --save crowdnode@v1

CrowdNode Browser SDK

<script src="https://unpkg.com/@root/[email protected]/urequest.js"></script>
<script src="https://unpkg.com/[email protected]/dashrequest.js"></script>
<script src="https://unpkg.com/[email protected]/dashsight.js"></script>
<script src="https://unpkg.com/[email protected]/dashsocket.js"></script>
<script src="https://unpkg.com/@dashevo/[email protected]"></script>
<script src="https://unpkg.com/[email protected]/dashapi.js"></script>
<script src="https://unpkg.com/[email protected]/crowdnode.js"></script>
(async function () {
  let dashsight = window.DashSight.create({
    baseUrl: "https://insight.dash.org",
  });

  // ...

  await window.DashSocket.listen(
    "https://insight.dash.org",
    function finder(evname, data) {
      console.log(evname, data);
    },
    { debug: true },
  );
})();

API

The SDK also provides Type Hinting via JSDoc (compatible with TypeScript / tsc without any transpiling).

IMPORTANT

The CLI is denominated in Dash and Percent because those are the units most customers are familiar with and can easily calculate in their heads without making "careless" mistakes.

HOWEVER, the SDK and CrowdNode API are denominated in Duffs (Satoshis) and Permil (Permille) because those are the whole units that are easiest to compute.

QuickStart

The CrowdNode SDK uses Dashcore to create raw transactions and broadcasts them as Instant Send via the Dash Insight API. It uses Dash Insight WebSockets to listen for responses from the CrowdNode hotwallet.

A simple CrowdNode application may look like this:

"use strict";

let Fs = require("fs").promises;
let CrowdNode = require("crowdnode");

async function main() {
  let keyfile = process.argv[2];

  // a wallet pre-loaded with about Đ0.01
  let wif = await Fs.readFile(keyfile, "utf8");
  wif = wif.trim();

  // Initializes API info, such as hotwallets
  await CrowdNode.init({ insightBaseUrl: "https://insight.dash.org/" });

  let hotwallet = CrowdNode.main.hotwallet;
  await CrowdNode.signup(wif, hotwallet);
  await CrowdNode.accept(wif, hotwallet);
  await CrowdNode.deposit(wif, hotwallet);

  console.info("Congrats! You're staking!");
}

main().catch(function (err) {
  console.error("Fail:");
  console.error(err.stack || err);
  process.exit(1);
});

There are also a number of utility functions which are not exposed as public APIs, but which you could learn from in crowdnode-cli.

Constants

CrowdNode.offset = 20000;
CrowdNode.duffs = 100000000;
CrowdNode.depositMinimum = 100000;

CrowdNode.requests = {
  acceptTerms: 65536,
  offset: 20000,
  signupForApi: 131072,
  toggleInstantPayout: 4096,
  withdrawMin: 1,
  withdrawMax: 1000,
};

CrowdNode.responses = {
  PleaseAcceptTerms: 2,
  WelcomeToCrowdNodeBlockChainAPI: 4,
  DepositReceived: 8,
  WithdrawalQueued: 16,
  WithdrawalFailed: 32,
  AutoWithdrawalEnabled: 64,
  AutoWithdrawalDisabled: 128,
};

Usage

Manage Stake

await CrowdNode.init({ insightBaseUrl: "https://insight.dash.org" });

CrowdNode.main.baseUrl; // "https://app.crowdnode.io"
CrowdNode.main.hotwallet; // "XjbaGWaGnvEtuQAUoBgDxJWe8ZNv45upG2"

await CrowdNode.status(pubAddress, hotwallet);
/*
 * {
 *   signup: 0, // seconds since unix epoch
 *   accept: 0,
 *   deposit: 0,
 * }
 */

await CrowdNode.signup(wif, hotwallet);
/** @type SocketPayment
 * {
 *   "address": "Xj00000000000000000000000000000000",
 *   "satoshis": 20002, // PleaseAcceptTerms
 *   "timestamp": 1655634136000,
 *   "txid": "xxxx...",
 *   "txlock": true
 * }
 */

await CrowdNode.accept(wif, hotwallet);
/** @type SocketPayment
 * {
 *   "address": "Xj00000000000000000000000000000000",
 *   "satoshis": 20004, // WelcomeToCrowdNodeBlockChainAPI
 *   "timestamp": 1655634138000,
 *   "txid": "xxxx...",
 *   "txlock": true
 * }
 */

// amount given in DUFFs
await CrowdNode.deposit(wif, hotwallet, (amount = 0));
/** @type SocketPayment
 * {
 *   "address": "Xj00000000000000000000000000000000",
 *   "satoshis": 20008, // DepositReceived
 *   "timestamp": 1655634142000,
 *   "txid": "xxxx...",
 *   "txlock": true
 * }
 */

// permil is 1/10 percent, 500 permil = 50.0 percent
await CrowdNode.withdraw(wif, hotwallet, permil);
/** @type SocketPayment
 * {
 *   "address": "Xj00000000000000000000000000000000",
 *   "satoshis": 20016, // WithdrawalQueued
 *   "timestamp": 1657634142000,
 *   "txid": "xxxx...",
 *   "txlock": true
 * }
 */

HTTP RPC

await CrowdNode.http.GetBalance(pubAddr);
/** @type CrowdNodeBalance
 * {
 *   "DashAddress": "Xj00000000000000000000000000000000",
 *   "TotalBalance": 0.01292824,
 *   "TotalActiveBalance": 0,
 *   "TotalDividend": 0,
 *   "UpdatedOn": "2022-06-19T08:06:19.11",
 *   "UpdateOnUnixTime": 1655625979
 * }
 */

await CrowdNode.http.GetFunds(pubAddr);
await CrowdNode.http.GetFundsFrom(pubAddr, secondsSinceEpoch);
/*
 *  [
 *    {
 *      "FundingType": 1,
 *      "Amount": 0.00810218,
 *      "Time": 1655553336,
 *      "TimeReceived": 1655553336,
 *      "TxId": "e5a...",
 *      "Status": 32,
 *      "Comment": null,
 *      "TimeUTC": "2022-06-18T11:55:36",
 *      "Id": 3641556,
 *      "UpdatedOn": "2022-06-18T12:04:15.1233333"
 *    }
 *  ]
 */

await CrowdNode.http.IsAddressInUse(pubAddr);
/**
 * {
 *   "inUse": true,
 *   "DashAddress": "Xj00000000000000000000000000000000"
 * }
 */

Messages (Voting, etc)

await CrowdNode.http.GetMessages(pubAddr);
/**
 * []
 */

await CrowdNode.http.SetEmail(wif, email, sig);
await CrowdNode.http.Vote(wif, gobjectHash, vote, sig);
await CrowdNode.http.SetReferral(wif, referralId, sig);
await CrowdNode.http.FundsOpen(pub);
/* ${baseUrl}/FundsOpen/${pub} */

await CrowdNode.http.VotingOpen(pub);
/* ${baseUrl}/VotingOpen/${pub} */

Glossary

Term Description
addr your Dash address (Base58Check-encoded Pay-to-PubKey Address)
amount the integer value of "Duffs" (Đ/100000000)
permil 1/1000, 1‰, or 0.1% - between 1 and 1000 (0.1% to 100.0%)
./privkey.wif the file path to your staking key in WIF (Base58Check) format

CLI Documentation

See https://github.com/dashhive/crowdnode-cli.

Official CrowdNode Docs

https://knowledge.crowdnode.io/en/articles/5963880-blockchain-api-guide

crowdnode.js's People

Contributors

jojobyte avatar

Stargazers

Ghawas avatar Rion Daniel Gull avatar  avatar AJ ONeal avatar Niek avatar

Watchers

Rion Daniel Gull avatar  avatar

crowdnode.js's Issues

Show timestamps for dividends

It'd be nice to see

  • a timestamp on deposits
  • days since deposit

Get a better positive feedback loop on "Wow, it's only been 2 weeks and I've already earned more than my savings account has given me in... the last 6 years!!"

Complete types.js

From the API docs you can see that there a just few types that aren't in types.js yet.

  • Enumerate the responses that are missing a type in the README
  • Add those to types.js
  • Add the types to the appropriate return value

Request API from CrowdNode

Re: https://discord.com/channels/484546513507188745/501115691634786339/986453482343125004

Plain Text

curl -X GET https://test.crowdnode.io/odata/apifundings/HotWallet \
    -H 'Accept: text/plain'
yMY5bqWcknGy5xYBHSsh2xvHZiJsRucjuy

JSON

curl -X GET https://test.crowdnode.io/odata/apifundings/HotWallet \
    -H 'Accept: application/json'
{ "PubKeyHash": "yMY5bqWcknGy5xYBHSsh2xvHZiJsRucjuy" }

Alternate

v1.5.0 Release Notes

git log v1.3.1 --oneline -- |
    sd '^(\w+) (.*)' '| $1 | $2 |'
ceffbde 1.5.0
9118b5a refactor: lift some arg and state mangement
9d9d10f feat+fixes: add stake command, await all-the-things, lift process.exit()
d4be0b4 refactor!: signal that the user chose to not have a passphrase with 'NONE' as the shadow file contents
1d30756 fix: don't re-run encrypt, delete shadow on decrypt
601b2a8 fix: use correct prompt for existing passhprases
0261969 1.4.0
25294a8 chore: update submodules
20c6ad9 feat: add 'mini' (double quad-blocks) ascii QR output
1fad82b feat: update to 'micro' (quad-block) QR terminal output
2e6154a fix: use DASH, not DUFF for QR amount
6136ca4 docs: update links
4a6565d chore: move cli to submodule
28d28c2 chore: remove cli (for submodule)
8fb0580 docs: simplify intro instructions
761583f docs: update README.md
473b044 docs: remove optional keyfile

See also: dashhive/crowdnode-cli#4

Create Browser Demo

Replicate basic functionality of crowdnode-cli, but in the browser.

Try to move/copy code into ./lib here and use it rather than framework-ify-ing where possible.

  • Generate Private Key (WIF) (lib)
  • Store in localStorage (vue)
  • Show QR (qr-svg)
  • Signup (crowdnode)
  • Agree to Terms (crowdnode)
  • Deposit (crowdnode)
  • Show Balance (crowdnode and dashsight)
  • Withdraw (crowdnode)
  • Transfer (dashsight instant send)

Later: abstract storage and encryption.

Move `cli` out to submodule

The SEO is better when the CLI and the SDK are in different GitHub Repos.

We could create a new repo for crowdnode-cli and then submodule it here.

(plus, then npm version would work correctly for both modules)

v1.7.0 Release Notes

Works in browsers as Vanilla JS, Vite, Webpack... (and more?)

d9882fd v1.7.0
3bd851c fix(browser): crowdnode init with CORS url
ab6e7f6 feat(qr): separate node from plain js
0515dfa 1.7.0-2
39c0b84 chore: add 'index.js' to package.json.files (weird...)
1608267 1.7.0-1
56cc095 feat: hardcode crowdnode wallet address
c4d3044 feat: make browser-friendly
58e46ee feat: prep for more browser friendliness
3e08ac3 chore: move require.main test block
9b2f085 fix: use require shim for dashcore
da664f2 docs: add knowledge base url override
d355d1e fix: remove broken comment tsconfig.json
5977947 1.7.0-0
51af5d7 feat(browser): use browser-compatible dashsight, (re)move non-browser cruft
f58b3ef Fix decimal placement in holdings total
f01db9f chore: update submodule ./cli/
836030c docs(types): explicitly type vout.some(fn)

v1.6.1 Release Notes

a1a1e5c 1.6.1
39117c9 chore: bump cli submodule
9697687 fix: transfer should work with a single address and an amount
754490e doc: add 'version' subcommand to docs
1bba7a6 fix(http-rpc): workaround for beyond-duff precision
76f5e7d doc(http-rpc): remove unused 'baseUrl' from param lists
c0309ad fix(balance): don't duplicate Stakings for Holdings
d33aa5c doc+fix: withdraw is now spelled correctly
d53d9bd fix: updating wording and process as per user feedback

Also:

Process overview

We need tools that allow us to manually send transactions without a full node anyway.

Might as well build the tools for and document the process of staking with crowd node.

  1. How to get UTXOs:
  2. How to sign via JS
    var utxo = {
      txId: '115e8f72f39fad874cfab0deed11a80f24f967a84079fb56ddf53ea02e308986',
      outputIndex: 0,
      address: '17XBj6iFEsf8kzDMGQk5ghZipxX49VXuaV',
      script: '76a91447862fe165e6121af80d5dde1ecb478ed170565b88ac',
      satoshis: 50000,
    };
    // https://github.com/dashevo/dashcore-lib/blob/master/docs/examples.md#create-a-transaction
    var transaction = new Transaction()
      .from(utxos) // Feed information about what unspent outputs one can use
      .to(address, amount) // Add an output with the given amount of satoshis
      .change(address) // Sets up a change address where the rest of the funds will go
      .sign(privkeySet); // Signs all the inputs it can
    curl -X POST https://insight.dash.org/insight-api-dash/tx/sendix \
        --data-urlencode 'rawtx=xxxxxxxx'
  3. Load up the API address with Đash and send the amounts designated by the API https://knowledge.crowdnode.io/en/articles/5963880-blockchain-api-guide

--config option

I'd like to have a separate account for developing vs my personal account.

Issue with CLI - `Error: unknown protocol: 'null'` in v1.7.0, v1.7.0-1 & v1.7.0-2

@coolaj86 The latest versions of crowdnode (v1.7.0, v1.7.0-1 & v1.7.0-2) throw this error for many of the calls that access services through @root/request

j@crux:~$ crowdnode status
Selected default staking key <KEY>
Fail:
Error: unknown protocol: 'null'
    at urequestHelper (~/.local/opt/node-v16.18.1/lib/node_modules/crowdnode/node_modules/@root/request/request.js:478:16)
    at urequest (~/.local/opt/node-v16.18.1/lib/node_modules/crowdnode/node_modules/@root/request/request.js:626:16)
    at ~/.local/opt/node-v16.18.1/lib/node_modules/crowdnode/node_modules/@root/request/request.js:637:17
    at new Promise (<anonymous>)
    at ~/.local/opt/node-v16.18.1/lib/node_modules/crowdnode/node_modules/@root/request/request.js:636:20
    at request (~/.local/opt/node-v16.18.1/lib/node_modules/crowdnode/node_modules/dashsight/lib/request.js:16:20)
    at Object.insight.getTxs (~/.local/opt/node-v16.18.1/lib/node_modules/crowdnode/node_modules/dashsight/dashsight.js:113:26)
    at Object.CrowdNode.status (~/.local/opt/node-v16.18.1/lib/node_modules/crowdnode/crowdnode.js:107:44)
    at getCrowdNodeStatus (~/.local/opt/node-v16.18.1/lib/node_modules/crowdnode/bin/crowdnode.js:581:32)
    at getStatus (~/.local/opt/node-v16.18.1/lib/node_modules/crowdnode/bin/crowdnode.js:1783:21)

While this error seems connected to this chunk of code in request.js https://github.com/therootcompany/request.js/blob/main/request.js#L467-L480

It is likely due to the baseUrl set to empty 👇🏼

CrowdNode._insightApi = Insight.create({ baseUrl: "" });

Not positive that is the issue, but that's my suspicion at this point.

Rolling back to [email protected] appears to get the CLI working again

Store staking key in .config?

We could store the staking key in ~/.config/crowdnode/stake.wif.

The big questions are:

  • how to integrate with MacOS et al for OS key management
  • what crypto algo is used by wallets? (we probably want to use the same)

Todo list

  • Generate a Dash Wallet
  • Send monies to Dash Address #1 the boring way
  • Check UTXOs
  • Check SmartSendRate
  • Calculate ideal few inputs (not all inputs)
  • Sign Message to Dash Address #2
  • Send RawTx to Dash Address #2
  • Send from #2 to Hot Wallet to Sign Up
  • Send from #2 to Hot Wallet to Agree
  • Send deposit
  • Commands to check stats
  • Listen for payment events via WebSocket
  • limit debug output with debug: true option
  • Whilst command is running, auto-forward new payments to Hot Wallet
  • Withdrawal rewards
  • Unstake

Finishing Touches

  • ditch insightApi.getBalance for txes-based utxo checking
  • Keep enough change to run a withdrawal (prime the pump)
  • Show amounts when sending all-the-money
  • Documentation
  • Do-all-the-things-at-once command?
  • Publish to npm

Other

  • PR bad JSDoc in dashcore-lib/lib/transaction/transaction.js

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.