GithubHelp home page GithubHelp logo

helium / helium-js Goto Github PK

View Code? Open in Web Editor NEW
110.0 27.0 29.0 5 MB

Official TypeScript packages for interacting with the Helium blockchain

License: Apache License 2.0

TypeScript 99.97% JavaScript 0.03%

helium-js's Introduction

Helium JS SDK

Build Status Coverage Status Renovate

Please view the Documentation for usage and examples.

⚠️ These libraries are currently in active development and are provided as-is. Helium makes no claims or guarantees about the correctness, reliability or security of this code. PRs welcome, see CONTRIBUTING.

This SDK is a collection of TypeScrypt libraries for interacting with the Helium blockchain. For additional documentation about the Helium network, visit the Developer Site.

Package NPM Version What it's for
@helium/crypto npm Cryptography utilities including keypairs, mnemonics and base58-check encoding
@helium/crypto-react-native npm Cryptography utilities following the same interface as @helium/crypto but for React Native
@helium/transactions npm Construct and serialize transaction primitives from their protobuf definitions
@helium/proto npm Protobuf definitions for Helium transactions
@helium/proto-ble npm Protobuf definitions for Helium Hotspot ble transactions
@helium/http npm An HTTP client for the blockchain REST API
@helium/currency npm Utilities for representing amounts of the different currencies supported by Helium
@helium/onboarding npm An HTTP client for interfacing with an Onboarding Server
@helium/address npm Utilities for Helium Addresses
@helium/wallet-link npm Utilities for linking a 3rd party app to the Helium Wallet

Installation

Each package can be installed independently depending on what utility you need. For example:

$ yarn add @helium/crypto @helium/transactions @helium/http
# or
$ npm install @helium/crypto @helium/transactions @helium/http

Usage

The following examples demonstrate some of the more common use cases and show how these packages can be used in combination to accomplish common tasks.

Creating and submitting a payment transaction

A payment from an owned keypair initialized with a 12 word mnemonic to an address specified by its base58 representation. The transaction is serialized to binary and submitted to the blockchain API.

import { Keypair, Address } from '@helium/crypto'
import { PaymentV1, Transaction } from '@helium/transactions'
import { Client } from '@helium/http'

const client = new Client()

// the transactions library needs to be configured
// with the latest chain vars in order to calcluate fees
const vars = await client.vars.get()
Transaction.config(vars)

// initialize an owned keypair from a 12 word mnemonic
const bob = await Keypair.fromWords(['one', 'two', ..., 'twelve'])

// initialize an address from a b58 string
const alice = Address.fromB58('148d8KTRcKA5JKPekBcKFd4KfvprvFRpjGtivhtmRmnZ8MFYnP3')

// get the speculative nonce for the keypair
const account = await client.accounts.get(bob.address.b58)

// construct a payment txn
const paymentTxn = new PaymentV1({
  payer: bob.address,
  payee: alice,
  amount: 10,
  nonce: account.speculativeNonce + 1,
})

// an appropriate transaction fee is calculated at initialization
console.log('transaction fee is:', paymentTxn.fee)

// sign the payment txn with bob's keypair
const signedPaymentTxn = await paymentTxn.sign({ payer: bob })

// submit the serialized txn to the Blockchain HTTP API
client.transactions.submit(signedPaymentTxn.toString())

Creating an advanced payment transaction

PaymentV2 transactions allow for specifying multiple recipients in the same transaction.

import { Keypair, Address } from '@helium/crypto'
import { PaymentV2, Transaction } from '@helium/transactions'
import { Client } from '@helium/http'

const client = new Client()

// the transactions library needs to be configured
// with the latest chain vars in order to calcluate fees
const vars = await client.vars.get()
Transaction.config(vars)

// initialize an owned keypair from a 12 word mnemonic
const bob = await Keypair.fromWords(['one', 'two', ..., 'twelve'])

// get the speculative nonce for the keypair
const account = await client.accounts.get(bob.address.b58)

// initialize recipient addresses from b58 strings
const alice = Address.fromB58('148d8KTRcKA5JKPekBcKFd4KfvprvFRpjGtivhtmRmnZ8MFYnP3')
const charlie = Address.fromB58('13JoEpkGQUd8bzn2BquFZe1CbmfzhL4cYpEohWH71yxy7cEY59Z')

// construct a PaymentV2 txn
const paymentTxn = new PaymentV2({
  payer: bob.address,
  payments: [
    {
      payee: alice,
      amount: 20,
    },
    {
      payee: charlie,
      amount: 10,
    },
  ],
  nonce: account.speculativeNonce + 1,
})

// an appropriate transaction fee is calculated at initialization
console.log('transaction fee is:', paymentTxn.fee)

// sign the payment txn with bob's keypair
const signedPaymentTxn = await paymentTxn.sign({ payer: bob })

// submit the serialized txn to the Blockchain HTTP API
client.transactions.submit(signedPaymentTxn.toString())

Sending an Account's full balance

Sending the maximum amount from an account (leaving a 0 HNT balance) requires taking into account the transaction fee. All fees are denominated in Data Credits (DC), which is equal to $0.00001 USD, meaning 35,000 DC equals $0.35 USD. DC are obtained by burning HNT, permanently removing it from circulation. If you do not already have DC in your account, the appropriate amount of HNT will be burned to cover the fee.

The general formula is: amountToSend = balance - feeInHNT

The packages in helium-js provide utility functions to calculate the above:

import { Keypair, Address } from '@helium/crypto'
import { PaymentV2, Transaction } from '@helium/transactions'
import { Client } from '@helium/http'
import { Balance, CurrencyType } from '@helium/currency'

const client = new Client()

// the transactions library needs to be configured
// with the latest chain vars in order to calcluate fees
const vars = await client.vars.get()
Transaction.config(vars)

// assuming bob has a balance of 100 HNT
const bob = await Keypair.fromWords(['one', 'two', ..., 'twelve'])

// initialize an address from a b58 string
const alice = Address.fromB58('148d8KTRcKA5JKPekBcKFd4KfvprvFRpjGtivhtmRmnZ8MFYnP3')

// get the speculative nonce for the keypair
const account = await client.accounts.get(bob.address.b58)

// construct a PaymentV2 txn for the purpose
// of calculating the fee
const paymentTxnForFee = new PaymentV2({
  payer: bob.address,
  payments: [
    {
      payee: alice,
      amount: account.balance.integerBalance,
    },
  ],
  nonce: account.speculativeNonce + 1,
})

// calculate max sendable amount
const feeInDC = new Balance(paymentTxnForFee.fee, CurrencyType.dataCredit)
const oracle = await client.oracle.getCurrentPrice()
const feeInHNT = feeInDC.toNetworkTokens(oracle.price)
const amountToSend = account.balance.minus(feeInHNT).integerBalance

// construct a PaymentV2 txn to sign
const paymentTxnForFee = new PaymentV2({
  payer: bob.address,
  payments: [
    {
      payee: alice,
      amount: amountToSend,
    },
  ],
  nonce: account.speculativeNonce + 1,
})

// sign the payment txn with bob's keypair
const signedPaymentTxn = await paymentTxn.sign({ payer: bob })

// submit the serialized txn to the Blockchain HTTP API
client.transactions.submit(signedPaymentTxn.toString())

⚠️ Note that oracle prices change over time. It's possible for a transaction to fail if the oracle price changes in between the time the transaction is constructed and when it is absorbed by the consensus group. The API exposes what the next oracle price will be at https://api.helium.io /v1/oracle/predictions. See https://developer.helium.com/blockchain/api/oracle for more details. To avoid failed transactions, it may be worth querying both the oracle predictions, and the current oracle value, and taking the greatest of those values.

Sending payment from multi-signature wallet

Sending a payment from a multi-signature wallet requires collecting the minimum number of required signatures from the addresses associated with the multi-signature address in question. Below is an example of creating and signing a 1 of 2 multi-signature address transaction.

import { Keypair, MultisigSignature } from '@helium/crypto'
import Address, { MultisigAddress } from '@helium/address'
import { PaymentV2, Transaction } from '@helium/transactions'
import { Client } from '@helium/http'

const client = new Client()

// the transactions library needs to be configured
// with the latest chain vars in order to calcluate fees
const vars = await client.vars.get()
Transaction.config(vars)

// initialize a keypair available for signing
const bob = await Keypair.fromWords(['one', 'two', ..., 'twelve'])

// initialize an address from a b58 string
const alice = Address.fromB58('148d8KTRcKA5JKPekBcKFd4KfvprvFRpjGtivhtmRmnZ8MFYnP3')

// initialize multisig address with the full set of addreses and required number of signatures
const multisigAddress = await MultisigAddress.create([bob.address, alice], 1)

// get the speculative nonce for the multisig keypair
const account = await client.accounts.get(multisigAddress.b58)

// create random payee address
const payeeAddress = Address.fromB58('13dSybmfNofup3rBGat2poGfuab4BhYZNKUJFczSi4jcwLmoXvD')

// construct a PaymentV2 txn to sign
const paymentTxn = new PaymentV2({
  payer: multisigAddress,
  payments: [
    {
      payee: payeeAddress,
      amount: amountToSend,
    },
  ],
  nonce: account.speculativeNonce + 1,
})

// Create signatures payload, a map of address to signature, and finally a KeySignature list
const bobSignature = (await paymentTxn.sign({ payer: bob })).signature || new Uint8Array()
const signatureMap = new Map([[bob.address, await bob.sign(paymentTxn.serialize())]])
const signatures = KeySignature.fromMap([bob.address, aliceAddress], signatureMap)

// Construct multisig signature using the address, the full set of all addresses, and the required signatures
const multisigSig = new MultisigSignature([bob.address, aliceAddress], signatures)

// Update signature on payment trasnaction
await paymentTxn.sign({payer: multisigSig})

// submit the serialized txn to the Blockchain HTTP API
client.transactions.submit(paymentTxn.toString())

helium-js's People

Contributors

addressxception avatar allenan avatar chewingglass avatar danielcolinjames avatar davetapley avatar dependabot[bot] avatar jcronyn avatar madninja avatar matthewcarlreetz avatar perronef5 avatar radrob1 avatar renovate-bot avatar renovate[bot] avatar tyler-whitman avatar vulet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

helium-js's Issues

Expose raw json from API resources

It would be useful to store and expose the raw json that @helium/http gets back from the API, as well as parsing it into typescript classes.

For example, we could do:

const client = new Client()
const list = client.hotspots.list
const [hotspot] = list.take(1)

console.log(hotspot.toJSON())

Currently the workaround is to parse/stringify the class, but then you need to delete the client reference out of it: https://github.com/helium/explorer/blob/master/jobs/sync_hotspots.js#L16-L17

How to get DC

I want to transfer some HNT,but i don`t have any DC to be fee,How to get DC

[http] support natural language min time in sums

endpoint: https://api.helium.io/v1/hotspots/${address}/rewards/sum/?min_time=-${numBack}%20${bucketType}

min_time is currently expected to be a Date, but it should allow a string like -30 day in addition

[@helium/transactions] Setting unsigned PaymentV2.toString() and then recreating with .fromString() creates a bad signatures when memo isn't present

I'm currently working on an implementation that takes unsigned transactions, signs them in an offline environment, and then takes the signed txn and submits it online again.

I've been running into an inexplicable issue where the PaymentV2 transaction behaves strangely when the unsigned transaction is serialized + encoded in base64, and then decoded and unserialized. Short example below where keypair is a Keypair derived from words:

const brokenTxn: PaymentV2 = PaymentV2.fromString(unsignedPaymentV2Txn.toString());
const signedBrokenTxn: PaymentV2 = await brokenTxn.sign({payer: keypair});
const pendingBrokenTxn: PendingTransaction = await client.transactions.submit(signedBrokenTxn.toString());

Eventually, the pendingBrokenTxn will fail with the failure reason of {invalid,bad_signature}.

To be clear, this only happens in two cases:

  • If the memo field is undefined
  • If the memo field is preemptively filled with the string "AAAAAAAAAAA="

When the memo field is populated, the signed transaction will clear (based on my testing so far).

Allow hotspot(address).rewards.sum.get to take natural language dates

https://github.com/helium/helium-js/blob/master/packages/http/src/resources/Sums.ts#L51

Right now .list allows a string like "-1 day" but .get only takes Date objects as input:

.list:

  async list(params: ListRewardsParams): Promise<ResourceList<Sum>> {
    if (!params.bucket) {
      throw new Error('missing bucket param')
    }
    const {
      data: { data: rewards, cursor },
    } = await this.client.get(this.baseUrl, {
      cursor: params.cursor,
      min_time: params.minTime instanceof Date ? params.minTime?.toISOString() : params.minTime,
      max_time: params.maxTime instanceof Date ? params.maxTime?.toISOString() : params.maxTime,
      bucket: params.bucket,
    })
    const data = rewards.map((d: HTTPSum) => new Sum(this.client, d))
    return new ResourceList(data, this.list.bind(this), cursor)
  }

.get:

async get(minTime: Date, maxTime: Date): Promise<Sum> {
    const { data: { data } } = await this.client.get(this.baseUrl, {
      min_time: minTime.toISOString(),
      max_time: maxTime.toISOString(),
    })
    return new Sum(this.client, data)
  }

Possible bug on signing a TokenBurnV1 transaction

Description
The bug happens on signing TokenBurnV1 transactions with an empty memo field, possibly during the encoding transaction process.

Platform
NodeJS 12.16.1
Ubuntu 16.04

Packages versions
@helium/crypto: 3.7.0
@helium/http: 3.22.0
@helium/proto: 1.2.0
@helium/transactions: 3.20.0

Test code

const crypto = require("@helium/crypto")
const http = require("@helium/http")
const { TokenBurnV1, Transaction } = require("@helium/transactions")

async function test() {
    const client = new http.Client();

    const vars = await client.vars.get()
    
    Transaction.config(vars)

    const account1 = await crypto.Keypair.fromWords([ /* hidden */])

    const account = await client.accounts.get(account1.address.b58)

    const txn = new TokenBurnV1({
        payer: account1.address,
        payee: account1.address,
        amount: 5000000,
        nonce: account.speculativeNonce ? account.speculativeNonce + 1 : 1,
        memo: "AAAAAAAAAAA=" // It is equals than an empty string 
    });

    const signedTx = await txn.sign({ payer: account1 }); // <-- The bug happens here

    const pendingTx = await client.transactions.submit(signedTx.toString());
    
    console.log(pendingTx.hash);
}

test().catch(console.log)

Using txn.toString(), it generates the next transaction:

igGWAQohAdV4yDJv/K1vfRCF3rYv+BdC/mvTKICco0/Rl6vzJWfMEiEB1XjIMm/8rW99EIXeti/4F0L+a9MogJyjT9GXq/MlZ8wYwJaxAiCQASpA6nFBqDFxGfDDlGgCmgJYe4e5O/iaHGP0qmzK7/TRQb4JiJECSCxol0fLMAwVL5gddtv3pL8ylxBQiKb3oXQ+DzC4kQI4AA==

Submitting the transaction to the network, fails and gives an invalid signature error. (Failed transaction link)

But, changing the memo field with another value different than an empty string, it works.

const crypto = require("@helium/crypto")
const http = require("@helium/http")
const { TokenBurnV1, Transaction } = require("@helium/transactions")

async function test() {
    const client = new http.Client();

    const vars = await client.vars.get()
    
    Transaction.config(vars)

    const account1 = await crypto.Keypair.fromWords([ /* hidden */ ])

    const account = await client.accounts.get(account1.address.b58)

    const txn = new TokenBurnV1({
        payer: account1.address,
        payee: account1.address,
        amount: 5000000,
        nonce: account.speculativeNonce ? account.speculativeNonce + 1 : 1,
        memo: Buffer.from("Hello World!").toString("base64")
    });

    const signedTx = await txn.sign({ payer: account1 });

    const pendingTx = await client.transactions.submit(signedTx.toString());
    
    console.log(pendingTx.hash);
}

test().catch(console.log)

It generates the next transaction and the node accepted it (Sucessfully transaction link)

igGeAQohAdV4yDJv/K1vfRCF3rYv+BdC/mvTKICco0/Rl6vzJWfMEiEB1XjIMm/8rW99EIXeti/4F0L+a9MogJyjT9GXq/MlZ8wYwJaxAiCQASpAemuJqI/Y8j1Kl3tmkojk5jNb4HnnjM9Z9McTPFzSfeCO/AczudVBYcob0qMiHuTxX6vzXlDKxHE2AZiwlQV7AzC4kQI4yMqx4/aNyKtv

Using the Helium CLI Wallet, it generates and submits perfectly the transaction (Successfully transaction link)

./helium-wallet --format json burn --amount 0.05 --payee 14Zm2aMFGXuHBuCDKLLgWS1wNkWxBndFEAuhyWiCd8KpFJSzQEE
Password: [hidden]
{
"amount": 0.05,
"fee": 35000,
"hash": null,
"memo": "AAAAAAAAAAA=",
"nonce": 144,
"payee": "14Zm2aMFGXuHBuCDKLLgWS1wNkWxBndFEAuhyWiCd8KpFJSzQEE",
"txn": "igGUAQohAdV4yDJv/K1vfRCF3rYv+BdC/mvTKICco0/Rl6vzJWfMEiEB1XjIMm/8rW99EIXeti/4F0L+a9MogJyjT9GXq/MlZ8wYwJaxAiCQASpAGLlwNd+DPM98VW7uL7vRUOrW8Mp6bh6LaJJekgjcJR4WD5Mtv4OcoTvdptpHV5Ujo7rohH8SLiEll1B5aPUABTC4kQI="
}

Extra
Yesterday, a user named Jerm helped me a lot by giving additional information:

Rust:

CiEB1XjIMm/8rW99EIXeti/4F0L+a9MogJyjT9GXq/MlZ8wSIQHVeMgyb/ytb30Qhd62L/gXQv5r0yiAnKNP0Zer8yVnzBjAlrECII8BMLiRAjgA

Field #1: 0A String Length = 33, Hex = 21, UTF8 = "��x�2o��o}��޶/�� ..." (total 31 chars)
Field #2: 12 String Length = 33, Hex = 21, UTF8 = "��x�2o��o}��޶/�� ..." (total 31 chars)
Field #3: 18 Varint Value = 5000000, Hex = C0-96-B1-02
Field #4: 20 Varint Value = 143, Hex = 8F-01
Field #6: 30 Varint Value = 35000, Hex = B8-91-02
Field #7: 38 Varint Value = 0, Hex = 00

HeliumJS:

CiEB1XjIMm/8rW99EIXeti/4F0L+a9MogJyjT9GXq/MlZ8wSIQHVeMgyb/ytb30Qhd62L/gXQv5r0yiAnKNP0Zer8yVnzBjAlrECII8BMLiRAg==

Field #1: 0A String Length = 33, Hex = 21, UTF8 = "��x�2o��o}��޶/�� ..." (total 31 chars)
Field #2: 12 String Length = 33, Hex = 21, UTF8 = "��x�2o��o}��޶/�� ..." (total 31 chars)
Field #3: 18 Varint Value = 5000000, Hex = C0-96-B1-02
Field #4: 20 Varint Value = 143, Hex = 8F-01
Field #6: 30 Varint Value = 35000, Hex = B8-91-02

Jerm's conclusion:

The missing field, #7, is the memo field.
there's a protobuf encoding problem in the signature function.
My hunch is that HeliumJS is unable to properly encode any transaction in which one of the elements is the integer zero. You wouldn't notice this in most transactions, though, because they'd be nonsense.
blockchain_txn_transfer_hotspot_v1 is one that could potentially be visible. If you transfer without requesting HNT payment, it would have an amount_to_seller field of 0.
and it's treating "0" as "empty" instead of null as empty.

Return toNetworkTokens function for stakingFee in add_gateway_v1 and assert_location_v1 transactions

It would be great if the stakingFee field could return data in the same way as the regular fee field returns (i.e. including the .toNetworkTokens() function)

This would extend the functionality of the "Show fees in HNT" toggle when doing a CSV export, and it was requested here: helium/explorer#120 (comment)

Relevant code in Explorer here:
https://github.com/helium/explorer/blob/master/components/ExportCSV/utils.js#L141-L142

All UnknownTransaction fields should be camelCased

I think we should make UnknownTransactions have all camelCased fields so we can better prepare for when the type is fully supported in helium-js, and avoid re-writing any frontend code (e.g. challenger_owner will eventually have to be updated to challengerOwner)

there are some examples of us doing this with camelCaseKeys() in helium-js

and this may be a separate issue, and I haven't thought it all the way through, but we could probably also convert some or all transactions to automatically return all camelCased keys so that when a new field gets added to hotspot for example, it'll automatically start showing up instead of needing to be manually added to the hotspot definition

[http] add locations

data/txns.js:
  13      const geoRes = await fetch(
  14:       `https://api.helium.io/v1/locations/${txn.location}`,
  15      )

Erori

Hello, I also have a problem with the Bobcat 300 Swift Vinyl Badger

ObBobcat

15 dBi

38 m

112WdFa ... mYjWqQC13ZffnR ...

StatisticsActivityWitnessedNearby

It is broadcast on explorer and in the bober app and I don't know dc ??

Inaccurate encodings with Webpack.

I was having a weird issue with helium-js earlier this week. I was taking an account's bin and putting it to a b58 address. I realized that it didn't match my bin to b58 address using another library. Investigating further it seems that this is an issue caused by webpack and its handling of checksumBytes of bs58CheckEncode(). I encountered this issue while running a simple React app, using react-scripts.

Integration of Helium Wallet and Explorer with BSC based Trading System

Hello Team,

Is it possible to Integrate the Helium Blockchain Wallet and Block Explorer with Binance Smart Chain based Trading System. Could you please advise if there are reference implementations or any documentations available on this. Thank you so much in advance for the support!

Mnemonic phrase should BIP39 compliant (generate a real checksum)

The current mobile wallet generates a 12-word mnemonic phrase that always has a 0000 checksum. This isn't BIP39 compliant. I noticed this while adding support for real BIP39 phrases into helium-wallet-rs. As the Helium ecosystem gets bigger, and we include things like ledger wallet I can see this being more and more of an issue. IMO, it is reasonable to expect a mnemonic phrase for a crypto wallet to be BIP39 compliant.

Right now, the CLI wallet supports importing both mobile and CLI, and I have a PR for exporting a mnemonic phrase for an existing wallet. Both of these code paths, have to support "mobile" and "bip39" checksums in order to not surprise users.

Having to support two paths seems like a bad way forward. But, we have to be careful about the upgrade path. A suggestion from Discord:

  • Fix this library (and then update the mobile wallet) so it always output only a BIP39-compliant mnemonic phrase, rather than a phrase with a 0000 checksum.
  • It has to be backwards compatible, so that users of "old mobile wallets" can still import their phrases. I don't think notifying users and expecting all will "update" their offline copy of their phrase is good enough. So, on import, the mobile wallet (using this library) should converting both mobile and BIP39 phrases into entropy.

Then eventually maybe the CLI wallet can drop support for importing mobile phrases and only import BIP39 phrases. Or at the very least, the CLI wallet will not output mobile-type phrases on output (there's a PR on helium-wallet-rs to optionally output phrases in the verify subcommand)

One note, I'm not 100% sure, but AFAICT, a given secret can output both a mobile-type and BIP39 type phrase. Re-importing either into the mobile wallet will result in the same secret, which results in the same wallet and same public address. To put it another way, the mnemonic phrase checksum isn't part of the entropy stored that makes up the keypair. So changing just the checksum calculation and using that when showing the phrase to the user should not (again AFAICT) change the actual keypair that gets derived from that phrase on import.

To make this more transparent to the mobile app user the entropyFromMnemonic() path could just do (pseudocode)

If foundChecksum ==  '0000' or foundChecksum == bip39CalcChecksum:
   create entropy from this phrase.

This weakens the bip39 checksum verification a bit, but...maybe doesn't matter?

Note: I commented on #120 because I thought it was about this issue. But I don't think it is.

Validators endpoint

Is there a discussion regarding implementing the Validators endpoint in this library?

Can not find a way to restore a keypair created from Keypair.makeRandom()

Hi, I created a KeyPair from:
let keypair = await Keypair.makeRandom();
then I have the pubilcKey, privateKey and address saved, later on I need to restore the keypair object so I can use it when sign:
const signedPaymentTxn = await paymentTxn.sign({ payer: keypair });

it seems I can not find a way to restore the keypair from the pubilcKey, privateKey and address I saved.

Any clues?
Thanks in advance

Private Key size invalid

Hello, I'm working on a project that needs to generate keys, then sign a message and verify a message. The function signatures are below:

{publicKey, privateKey} keygen()
string signMessage(string message, string privateKey)
bool verifyMessage(string message, string signature, string publicKey)

When I use @helium/crypto to generate the key pair I get the privateKey.length = 64, and publicKey.length = 32. However, when I try to recreate the keypair object using FromEntropy, I would expect to pass the private key, but I need to pass a 32 byte string array.

Where is this seed generated? Is there a missing method to collect this or some other way to derive the seed from the private key? Thanks!

Possible incorrect README.md documenation?

Hi,

I could not get this async iterator block (from the README.md) to work locally:

The asynchronous iterator can be used directly via the for-await-of syntax:

for await (const account of client.accounts.list()) {
  account //= Account
  // do something with account

  // after some condition is met, stop iterating
  if (someConditionMet)
    break
}

client.accounts.list() returns a Promise<ResourceList<Account>> which is not iterable due to the wrapper promise. Adding an await in front of client.accounts.list unwrapped it and made it work.

for await (const account of await client.accounts.list()) {
  account //= Account
  // do something with account

  // after some condition is met, stop iterating
  if (someConditionMet)
    break
}

Single JS file?

Hi there,
would it be possible to compile the TypeScript files into a single js file (e.g. helium-js-min.js) for convenient inclusion into html directly?
Thanks!

*hasMore* attribute of list is always set to true even when list is empty.

While working on the issue helium/explorer#216, I found out that hasMore attribute of the list is always set to true even when the list is empty and also when there is no more data to show.

helium_resource_list

To check the bug, we only need to add console.log(this.list) statement as shown below in ActivityList.js component in Explorer.

load_more

This is the code snippet that is used create a list.

make_list

Hey @danielcolinjames and @allenan. I would love to know your suggestions on this issue.

Erors

failed to get peer book. Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.39/containers/1dd755fd378876bf689711f9f06f09af06bcd34b55d9b4d33e0af537cb735e74/exec": context deadline exceeded

[http] add network rewards sum

data/rewards.js:
   72  export const getNetworkRewardsBuckets = async (numBack, bucketType) => {
   73:   const rewards = await fetchAll('/rewards/sum', {
   74      min_time: `-${numBack} ${bucketType}`,

[http] add order to cities list params

data/stats.js:
  36    const citiesResOnline = await fetch(
  37:     'https://api.helium.io/v1/cities?order=online_count',
  38    )

  44    const citiesResTotal = await fetch(
  45:     'https://api.helium.io/v1/cities?order=hotspot_count',
  46    )

The Transactions ListParams does not work

        let block = await await client.blocks.get(blockHeight);
        let res = await block.transactions.list({
            filterTypes: ['payment_v2','payment_v1' ], // this filterTypes is invalid
        })

also when i use limit:10, but the rerturn data is 50 size

Dependency Dashboard

This issue provides visibility into Renovate updates and their statuses. Learn more

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.


  • Check this box to trigger a request for Renovate to run again on this repository

???

what a shit you did, you killed Bobocat300, I know I'm not the only one, shit all that means hilium, dust and lumps, who can help me know if my guest Swift Vinyl Badger from Romania is more threatening or not, dead for 24 hours, may be canceled by someone in the validatorsHilium experts, let me know if I can mine Hilium or not, what the fuck is this, please insist on clarifying me too.

Usage Documentation

Hi,

there seems to be a big lack of documentation about the usage of the libraries etc...

At least neither this repo nor docs.helium.com have any documentation about this lib whatsoever...

The few README.mds that there are barely cover anything to be honest...

For most people the simplest things such as show me the rewards for hotspot XYZ seem very opaque

Furthermore what I believe is the correct way does not seem to yield any data such as:

c = new Client()
console.log(c.network.endpoint) // 'https://api.helium.io/v1'
h = await c.hotspots.get('112KJt2aU2iRcFJ4irQXGEppejvk7vRcjrL2QxXFSsBSy1mury8t') // Hotspot address taken at random
r = await h.rewards.list({min_time:"2021-08-03T00:00:00.000Z",max_time:"2021-08-04T00:00:00.000Z"})

r yields:

ResourceList {
  data: [],
  fetchMore: [Function: bound list] AsyncFunction,
  cursor: undefined
}

This suggests that there isnt any rewards but a quick curl reveals the exact opposite:

curl -qs https://api.helium.io/v1/hotspots/112KJt2aU2iRcFJ4irQXGEppejvk7vRcjrL2QxXFSsBSy1mury8t/rewards\?min_time\=2021-08-03T00%3A00%3A00.000Z\&max_time\=2021-08-04T00%3A00%3A00.000Z | jq .
{
  "data": [],
  "cursor": "eyJlbmRfYmxvY2siOjk0OTYxOSwiYmxvY2siOjk1MTAwMCwiYW5jaG9yX2Jsb2NrIjo5NTEwMDB9"
}
curl https://api.helium.io/v1/hotspots/112KJt2aU2iRcFJ4irQXGEppejvk7vRcjrL2QxXFSsBSy1mury8t/rewards\?min_time\=2021-08-03T00%3A00%3A00.000Z\&max_time\=2021-08-04T00%3A00%3A00.000Z\&cursor\=eyJlbmRfYmxvY2siOjk0OTYxOSwiYmxvY2siOjk1MTAwMCwiYW5jaG9yX2Jsb2NrIjo5NTEwMDB9 | jq .
{
  "data": [
    {
      "timestamp": "2021-08-03T22:32:32.000000Z",
      "hash": "hFwYP8LGL--yNE-y1WvKaK-kMnKLAc67LvQGk1bQ2sg",
      "gateway": "112KJt2aU2iRcFJ4irQXGEppejvk7vRcjrL2QxXFSsBSy1mury8t",
      "block": 950952,
      "amount": 1312042,
      "account": "13yfG77dATNdJQu5fSon5Yyg7R6U3CRuhS4aVQUxus95fe6nZ5m"
    },
   ....
  ]
}

So what's up with that?

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

[http] add activity counts

components/Makers/utils.js:
  49          const txnCountsRes = await fetch(
  50:           `https://api.helium.io/v1/accounts/${maker.address}/activity/count?filter_types=add_gateway_v1,assert_location_v1,token_burn_v1`,
  51          )

Transfer 1 HNT with 0 HNT in wallet to another can be completed successfully

Hi all, I am curious why with the following code, I can execute the transaction of transferring 1 HNT to another with a transaction hash returned successfully even the wallet has 0 HNT, also is there a way to check the status of the transaction from an exchange or from Helium network?

async function make_transaction(){

  const client = new Client();
  
  console.log("make_transaction the client: ", client);
  
  // the transactions library needs to be configured
  // with the latest chain vars in order to calculate fees
  const vars = await client.vars.get();
  console.log("make_transaction the vars: ", vars);

  Transaction.config(vars);
  const entropy = await crypto.randomBytes(32); 
console.log("make_transaction entropy is: ", entropy);
let entropyStr = entropy.toString("hex");
console.log("make_transaction entropyStr: ", entropyStr); 
let bob = await Keypair.fromEntropy(entropy); 

  console.log("make_transaction bob is: ", bob);
  console.log("make_transaction the bob.address: ", bob.address);
  // initialize an address from a b58 string
  const alice = Address.fromB58('148d8KTRcKA5JKPekBcKFd4KfvprvFRpjGtivhtmRmnZ8MFYnP3');
  console.log("make_transaction the alice: ", alice);
  //let mnemonic = alice.mnemonic;
  //console.log("make_transaction the mnemonic: ", mnemonic);
  // get the speculative nonce for the keypair
  console.log("make_transaction the bob.address.b58: ", bob.address.b58);
 // let publicKey = bob.publicKey;
  //console.log("make_transaction the publicKey: ", publicKey);
  //let publicKeyString = Base64.fromUint8Array(publicKey);
  //console.log("make_transaction publicKeyString: ", publicKeyString);
 // let publicKeyBack = Base64.toUint8Array(publicKeyString);
  //console.log("make_transaction publicKeyBack: ", publicKeyBack);
  //const account = await client.accounts.get(bob.address.b58);

  //console.log("make_transaction the balance.floatBalance: ", account.balance.floatBalance); 

  //console.log("make_transaction the account: ", account);
  // construct a payment txn
  const paymentTxn = new PaymentV1({
      payer: bob.address,
      payee: alice,
      amount: 1,
      nonce: alice.speculativeNonce + 1,
  });
  
  console.log("nonce is: ", paymentTxn);
  console.log('transaction fee is:', paymentTxn.fee);
  
  const signedPaymentTxn = await paymentTxn.sign({ payer: bob });
  
  console.log("make_transaction the serialized transaction: ", signedPaymentTxn.toString());
  let txHash = await client.transactions.submit(signedPaymentTxn.toString())
  console.log("make_transaction the transaction hash: ", txHash);

}

Thanks in advance!

Validator info is not populated when using any of the validators methods

I tried fetching info regarding validators using
this.heliumClient.validators.fromAddress(:address)
this.heliumClient.validator(:address)

Both methods return the structure of the validator info but with no values to it.

Example:

{versionHeartbeat: undefined, status: { height: 0, online: '', listenAddrs: [] }, stakeStatus: undefined, stake: Balance { type: NetworkTokens { ticker: 'HNT', decimalPlaces: [BigNumber], coefficient: [BigNumber] }, integerBalance: 0, bigInteger: BigNumber { s: 1, e: 0, c: [Array] }, bigBalance: BigNumber { s: 1, e: 0, c: [Array] }, floatBalance: 0 }, penalty: undefined, penalties: undefined, owner: undefined, name: undefined, lastHeartbeat: undefined, consensusGroups: undefined, blockAdded: undefined, block: undefined, address: ':address'}

invalid,bad_signature

After the transaction broadcast is created, the status is: invalid, bad_ Signature, what is this

Mnemonics checksum issue

const { Keypair, Address } = require ("@helium/crypto")
const { PaymentV1, Transaction } = require ("@helium/transactions")
const { Client } = require ("@helium/http")

make_transaction();
async function make_transaction(){

const client = new Client()

console.log("Checking the data: ", client)

// the transactions library needs to be configured
// with the latest chain vars in order to calcluate fees
const vars = await client.vars.get()
Transaction.config(vars)
// initialize an owned keypair from a 12 word mnemonic
const bob = await Keypair.fromWords(['abandon', 'ability', 'able', 'about', 'above', 'absent', 'absorb', 'abstract', 'absurd', 'abuse', 'access','accident'])

// initialize an address from a b58 string
const alice = Address.fromB58('148d8KTRcKA5JKPekBcKFd4KfvprvFRpjGtivhtmRmnZ8MFYnP3')
console.log("Checking the address: ", alice)
// get the speculative nonce for the keypair
const account = await client.accounts.get(bob.address.b58)
console.log("Checking the account: ", account);
// construct a payment txn
const paymentTxn = new PaymentV1({
payer: bob.address,
payee: alice,
amount: 1,
nonce: alice.speculativeNonce + 1,
})

console.log("nonce is: ", paymentTxn)
console.log('transaction fee is:', paymentTxn.fee)

const signedPaymentTxn = await paymentTxn.sign({ payer: bob })

console.log("Checking the serialized transaction: ", signedPaymentTxn.toString())
//client.transactions.submit(signedPaymentTxn.toString())
console.log("Checking the transaction hash: ", client.transactions.submit(signedPaymentTxn.toString()))

}

By executing above code it is giving me this error: "
(node:31994) UnhandledPromiseRejectionWarning: Error: invalid checksum
at Mnemonic.toEntropy (/home/alphabet-01/Desktop/anas/javascript/node_modules/@helium/crypto/build/Mnemonic.js:49:19)
at Function.fromMnemonic (/home/alphabet-01/Desktop/anas/javascript/node_modules/@helium/crypto/build/Keypair.js:34:34)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async Function.fromWords (/home/alphabet-01/Desktop/anas/javascript/node_modules/@helium/crypto/build/Keypair.js:29:25)
at async maketransaction (/home/alphabet-01/Desktop/anas/javascript/helium.js:19:13)
(node:31994) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:31994) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
root@alphabet01-HP-Pavilion-Notebook:/home/alphabet-01/Desktop/anas/javascript# node helium.js "

Erors

failed to get peer book. Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.39/containers/1dd755fd378876bf689711f9f06f09af06bcd34b55d9b4d33e0af537cb735e74/exec": context deadline exceeded

PaymentV1 Error : (invalid,bad_signature)

Hello, we’re trying to make a PaymentV1 transaction as described on readme.md. We’re using the latest versión of the repository, we generate the signed payment and submit it, but when looking at the helium api response for the transaction(https://api.helium.io/v1/pending_transactions/xrHd9AIx9Jd3l_TZzvGAc8wKYg9dUjtzrhYkChK8g9s)
this is what we get:
"status": "failed",
"failed_reason": "{invalid,bad_signature}",

This are the imports

   import * as crypto from '@helium/crypto';
   import * as transactions from '@helium/transactions';
   import * as http from '@helium/http';
   import Address from '@helium/address';

The req body is

{ keypair : ['one','two','three','four',...,'twelve']
  ,payeeAdress : a b58 string
  ,amount: a number, in this case 0.00001
   }

The client and vars are initialized and set correctly

    const client = new http.Client();
    const vars = await client.vars.get();
    transactions.Transaction.config(vars);

We also initialize the payer account and address and also the payee address

    const payer = await crypto.Keypair.fromWords(keypair);
    const payee = Address.fromB58(payeeAdress);
    const account = await client.accounts.get(payer.address.b58);

We build the payment txn

    const paymentTxn = new transactions.PaymentV1({
      payer: payer.address,
      payee: payee,
      amount: amount,
      nonce: account.speculativeNonce! + 1,
    });

We sign it and submit it to the Blockchain API

const signedPaymentTxn = await paymentTxn.sign({payer : payer})

[...] (then…)
client.transactions.submit(signedPaymentTxn.toString())

(and print the request before send…)
console.log(signedPaymentTxn);

PaymentV1 {

type: 'payment_v1',
payer: Address {
version: 0,
netType: 0,
keyType: 1,
publicKey: Uint8Array(32) [
221, 47, **, ***, ***, ***, **, ***,
***, ***, ***, ***, **, **, **, **,
***, **, **, **, ***, ***, **, ***,
*, ***, ***, **, ***, ***, **, **
]
},
payee: Address {
version: 0,
netType: 0,
keyType: 1,
publicKey: <Buffer ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **>
},
amount: 0.0001,
nonce: 5,
fee: 30000,
signature: Uint8Array(64) [
***, ***, ***, ***, **, ***, **, ***, **, ***, ***,
***, ***, ***, ***, ***, ***, ***, ***, ***, **, ***,
**, ***, ***, ***, ***, ***, ***, ***, ***, ***, ***,
***, **, ***, **, ***, ***, ***, ***, ***, ***, ***,
***, **, ***, ***, ***, ***, ***, ***, ***, *, ***,
**, ***, ***, ***, *, ***, ***, **, *
]
}
Also I will mentionate that we’re sending 0.0001 HNT, and in the response json object it shows
"amount": 0
Anyway, probably the amount is 0 because of the bad_signature error.

[http] add dc burns stats

data/datacredits.js:
  3  export const fetchDataCredits = async () => {
  4:   const response = await fetch('https://api.helium.io/v1/dc_burns/stats')
  5    const dcStats = await response.json()

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.