Code Monkey home page Code Monkey logo

send-crypto's Introduction

send crypto


A minimal JavaScript library for sending crypto assets.

Currently doesn't support hierarchical or single-use addresses.

Supported assets

  • BTC

  • LTC

  • ZEC (transparent txs only)

  • BCH

  • FIL

  • ETH

  • ERC20 tokens



Usage

npm install --save send-crypto
# or
yarn add send-crypto

Replace "BTC" with any supported asset:

const CryptoAccount = require("send-crypto");

/* Load account from private key */
const privateKey = process.env.PRIVATE_KEY || CryptoAccount.newPrivateKey();
const account = new CryptoAccount(privateKey);

/* Print address */
console.log(await account.address("BTC"));
// > "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"

/* Print balance */
console.log(await account.getBalance("BTC"));
// > 0.01

/* Send 0.01 BTC */
const txHash = await account
    .send("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", 0.01, "BTC")
    .on("transactionHash", console.log)
    // > "3387418aaddb4927209c5032f515aa442a6587d6e54677f08a03b8fa7789e688"
    .on("confirmation", console.log);
// > 1
// > 2 ...

UNITS: getBalance and send can be replaced with getBalanceInSats and sendSats respectively to use the blockchain's smallest units (satoshis for BTC, wei for ETH, etc.).

CONFIG: Each of the functions address, getBalance and send accept an optional options parameter. See the available options in the sections "All balance and transaction options" for each asset below.



Examples

Setup


Load private key from a .env file

.env:

PRIVATE_KEY="1234512341"

Use the dotenv library (installed with npm i -D dotenv) or run source .env before running:

require("dotenv").config();
const CryptoAccount = require("send-crypto");
const account = new CryptoAccount(process.env.PRIVATE_KEY);


Create new account
const privateKey = CryptoAccount.newPrivateKey();
console.log(`Save your key somewhere: ${privateKey}`);
const account = new CryptoAccount(privateKey);

BTC, ZEC, BCH


Send BTC (Bitcoin)
const CryptoAccount = require("send-crypto");
const account = new CryptoAccount(process.env.PRIVATE_KEY);

// Send BTC
await account.send("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", 0.01, "BTC");


Send ZEC (Zcash)
const CryptoAccount = require("send-crypto");
const account = new CryptoAccount(process.env.PRIVATE_KEY);

// Send ZEC
await account.send("t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd", 0.01, "ZEC");


Send BCH (Bitcoin Cash)

CashAddr, BitPay and legacy addresses are supported.

const CryptoAccount = require("send-crypto");
const account = new CryptoAccount(process.env.PRIVATE_KEY);

// Send BCH
await account.send(
    "bitcoincash:qp3wjpa3tjlj042z2wv7hahsldgwhwy0rq9sywjpyy",
    0.01,
    "BCH"
);

You can replace "BTC" with "ZEC" or "BCH" in the following examples:


Send entire balance
const balance = await account.getBalance("BTC");
await account.send("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", balance, "BTC", {
    subtractFee: true,
});

// Or using sats as the unit
const balanceInSats = await account.getBalanceInSats("BTC");
await account.sendSats(
    "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
    balanceInSats,
    "BTC",
    { subtractFee: true }
);


Wait for 6 confirmations
await new Promise((resolve, reject) =>
    account.send("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", 0.01, "BTC")
        .on("confirmation", confirmations => { if (confirmations >= 6) { resolve(); } })
        .catch(reject);
);


Send testnet funds
const testnetAccount = new CryptoAccount(process.env.PRIVATE_KEY, {
    network: "testnet",
});
await testnetAccount.send("12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX", 0.01, "BTC");


All balance and transaction options

The getBalance and getBalanceInSats options are:

{
    // Get the balance of an address other than the current account's
    address?: string;

    // The number of confirmations UTXOs must have to be included in the balance
    confirmations?: number; // defaults to 0
}

The send and sendSats options are:

{
    // The number of confirmations UTXOs must have to be included in the inputs
    confirmations?: number; // defaults to 0

    // The fee in satoshis/zatoshis to use
    fee?: number;           // defaults to 10000

    // Whether the fee should be included or excluded from `value`
    subtractFee?: boolean;  // defaults to false
}

ETH, ERC20


Send ETH (Ether, Ethereum)
const CryptoAccount = require("send-crypto");
const account = new CryptoAccount(process.env.PRIVATE_KEY);

// Send ETH
await account.send("0x05a56e2d52c817161883f50c441c3228cfe54d9f", 0.01, "ETH");


Send ERC20 tokens

You can transfer arbitrary ERC20 tokens by providing the token's address:

const CryptoAccount = require("send-crypto");
const account = new CryptoAccount(process.env.PRIVATE_KEY);

await account.send("0x05a56e2d52c817161883f50c441c3228cfe54d9f", 1.234, {
    type: "ERC20",
    address: "0x408e41876cccdc0f92210600ef50372656052a38",
});

A few well known ERC20 tokens can be referenced by name:

await account.send("0x05a56e2d52c817161883f50c441c3228cfe54d9f", 1.234, {
    type: "ERC20",
    name: "DAI",
});

See the ERC20s.ts to see the tokens than can be referenced by name.



Send testnet funds (ropsten, kovan, etc.)

The supported testnets are mainnet, ropsten, kovan, rinkeby and goerli.

// Use "testnet" BTC, BCH & ZEC; use "ropsten" ETH.
const testnetAccount = new CryptoAccount(process.env.PRIVATE_KEY, {
    network: "testnet",
});
const testnetAccount = new CryptoAccount(process.env.PRIVATE_KEY, {
    network: "ropsten",
});
// Use "testnet" BTC, BCH & ZEC; use "kovan" ETH.
const testnetAccount = new CryptoAccount(process.env.PRIVATE_KEY, {
    network: "kovan",
});


All balance and transaction options

The getBalance and getBalanceInSats options are:

{
    // Get the balance of an address other than the current account's
    address?: string;
}

The send and sendSats options are:

{
    // Gas limit
    gas?: number | string;

    // Gas price in WEI
    gasPrice?: number | string | BN;

    // Include data with the transfer
    data?: string;

    // Override the transaction nonce
    nonce?: number;

    // [ETH] Whether the fee should be included or excluded from `value`
    subtractFee?: boolean;  // defaults to false

    // [ERC20] Approve instead of transferring
    approve?: boolean; // defaults to false
}







Custom assets

If you want to send a cryptocurrency or token that isn't supported by the library, or enhance support for one of the assets above (e.g. add support for a new address format), you can write your own handler using the instructions below.


Adding custom assets

Handlers must implement the (TypeScript) interface below.

The handlesAsset function is called to ask if the handler can handle an asset.

All other functions are optional. If a function isn't provided, the next handler is called instead.

export abstract class Handler<
    ConstructorOptions = {},
    AddressOptions = {},
    BalanceOptions extends { address?: string } = { address?: string },
    TxOptions = {}
> {
    // sharedState allows multiple handlers access common state.
    constructor(
        privateKey: string,
        network: string,
        constructorOptions?: ConstructorOptions,
        sharedState?: any
    ) {
        /* */
    }

    // Returns whether or not this can handle the asset
    public handlesAsset!: (asset: Asset) => boolean;

    // Returns the address of the account
    public address?: (
        asset: Asset,
        options?: AddressOptions,
        deferHandler?: DeferHandler
    ) => Promise<string>;

    // Returns the balance of the account
    public getBalance?: (
        asset: Asset,
        options?: BalanceOptions,
        deferHandler?: DeferHandler
    ) => Promise<BigNumber>;
    public getBalanceInSats?: (
        asset: Asset,
        options?: BalanceOptions,
        deferHandler?: DeferHandler
    ) => Promise<BigNumber>;

    // Transfers the asset to the provided address
    public send?: (
        to: string,
        value: BigNumber,
        asset: Asset,
        options?: TxOptions,
        deferHandler?: DeferHandler
    ) => PromiEvent<string>;
    public sendSats?: (
        to: string,
        value: BigNumber,
        asset: Asset,
        options?: TxOptions,
        deferHandler?: DeferHandler
    ) => PromiEvent<string>;
}

And then register the handler:

const CryptoAccount = require("send-crypto");
const account = new CryptoAccount(process.env.PRIVATE_KEY);
account.registerHandler(MyCystomHandler);

registerHandler accepts an optional priority parameter for setting the order of handlers (see index.ts to see the default ordering).

You can wrap around other handlers by using the defer parameter passed in to each function. For example, to add support for ENS names for Ethereum, you can resolve the to address and then call defer:

class ENSResolver {
    /* ... */

    handlesAsset = (asset: Asset) => asset === "ETH";

    resolveENSName = (to: string): Promise<string> => {
        /* ... */
    };

    send = async (
        to: string,
        value: BigNumber,
        asset: Asset,
        deferHandler: Handler
    ): PromiEvent<string> => {
        return deferHandler.send(await resolveENSName(to), value, asset);
    };
}

See the following handlers as references:


send-crypto's People

Contributors

0x31 avatar filippofinke 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

send-crypto's Issues

BTC account using bip84 private key

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
    [x] question about how to use this project

  • Summary

How do I use a bip84 private key generated from a seed phrase generated here. I get invalid private key buffer error.

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

Returned error: The execution failed due to an exception.

Code:

const CryptoAccount = require("send-crypto");
const keys = require("../../config/keys");

const account = new CryptoAccount(keys.privateKey, {
  network: "kovan"
});

account
  .send("0x868c75dFB5460797EB4cc12e60B1ab468439c337", 10, {
    type: "ERC20",
    address: keys.contractAddress
  })
  .catch(console.error);

Response:

Error: Returned error: The execution failed due to an exception.
    at Object.ErrorResponse (/Users/me/Desktop/myproject/node_modules/web3-core-helpers/src/errors.js:29:16)
    at /Users/me/Desktop/myproject/node_modules/web3-core-requestmanager/src/index.js:140:36
    at XMLHttpRequest.request.onreadystatechange (/Users/me/Desktop/myproject/node_modules/web3-providers-http/src/index.js:110:13)
    at XMLHttpRequestEventTarget.dispatchEvent (/Users/me/Desktop/myproject/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
    at XMLHttpRequest._setReadyState (/Users/me/Desktop/myproject/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
    at XMLHttpRequest._onHttpResponseEnd (/Users/me/Desktop/myproject/node_modules/xhr2-cookies/dist/xml-http-request.js:318:14)
    at IncomingMessage.<anonymous> (/Users/me/Desktop/myproject/node_modules/xhr2-cookies/dist/xml-http-request.js:289:61)
    at IncomingMessage.emit (events.js:323:22)
    at endReadableNT (_stream_readable.js:1204:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)

Error object from /node_modules/web3-core-helpers/src/errors.js:29:16

{
  jsonrpc: '2.0',
  id: 2,
  error: {
    code: -32016,
    data: 'Reverted',
    message: 'The execution failed due to an exception.'
  }
}

How to handle an ERC20 asset running on other chains? For example, BSC, Polygon.

  • I'm submitting a ...
    [ ] bug report
    [] feature request
    [ ] question about the decisions made in the repository
    [x ] question about how to use this project

  • Summary
    There are many ERC20 tokens running on BSC or other chains, but not on ETH mainnet, maybe an extra contruct option named chainRPC or something else could help?

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

Rpc Use

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
    [X] question about how to use this project

  • Summary

this library is just what I need but I have a doubt, these RPCs like bitcoin who maintains them and who pays for them, I see that there is no restriction on their use so I have a doubt based on this problem

Fees problem

How can I fix the problem with fees/taxes on ETH
When I'm trying to send a transaction I get that I don't have enough balance to pay the fees

Is it possible to use a private key longer than 32 bytes?

  • I'm submitting a ...
    [ ] bug report
    [x] feature request
    [ ] question about the decisions made in the repository
    [ ] question about how to use this project

Hey, this package is super convenient and easy to use, however I'm a little bit concerned about the length of the private key being used. Is there any way to use something longer? I've tried generating my own:

const Crypto = require('crypto')
const privateKey = Crypto.randomBytes(128).toString("hex")

console.log(privateKey)

but I'm getting Error: invalid private key buffer.

Expected property "1" of type BigInteger, got n

  • I'm submitting a ...
    [ x] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
    [ ] question about how to use this project

  • Summary
    Hi sir. Hope you are doing well. As a blockchain developer, I found new critical issues when I transfer BTC using send-crypto

         const txHash = await account
          .send(walletAddress, walletBalance, "BTC", {
            subtractFee: true,
          })
          .on("transactionHash", console.log)
          .on("confirmation", console.log);
    

It works well on local side.
But it doesn't work on online.
image

As you can see, all values are gotten.
If you know the reason, please let me know soon.
Looking forward to hearing from you soon.
Thanks
Apollo0102

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

Will sending BTC in satoshi lower dust error chance?

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
    [x] question about how to use this project

  • Summary

Hello, I've been having issues sending amounts of 0.0001 - 0.0003 BTC. I have been sometimes getting dust errors. I thought that this amount is too large for a dust error? I send with 1000 satoshi fee.

I was wondering if sending in satoshi instead of BTC would lower the dust fee? Because I did send my full balance in satoshi and it worked. But that balance was something like 0.0003123, so perhaps the minimum dust fee is >= 0.0003?

Thanks!

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

TypeError: inst._eth.resolveAddress is not a function

  • I'm submitting a ...
    [*] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
    [ ] question about how to use this project

  • Summary
    In v2.1.1.
    After confirming "yes", the following error occurs:

Proceed? [y/N]: y
TypeError: inst._eth.resolveAddress is not a function

Testnet Bitcoin balance is zero after successful txs

Do I have a misunderstanding of bitcoin testnet - can you help me clarify things?

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

View specific ERC20 token balance.

Is It possible to view the balance of a specific ERC20 token? For example, if I send USDC to an ETH address, is It possible to see the USDC balance ?

Sochain outdated

The API Litecoin uses is no longer available, making send crypto with litecoin no longer work. Is it possible to fix this?

How to get private key?

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
    [ x] question about how to use this project

  • Summary

Hi, how can I get private key for my BTC address and import via «send-crypto»?

Getting the testnet balance is not working anymore

Getting the balance with an ETH Testnet Wallet is not working anymore.
But the ETH Mainnet is still woking.

//My Code

const GetWalletInfo = async () => {

const account = new CryptoAccount(PrivKey, {
network: "goerli",
});

/* Print Balance */
console.log(await account.getBalance("ETH"));

}

GetWalletInfo()

// Console Error

    var error = new Error(message);
                ^

Error: could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.7.0)
at Logger.makeError (/Users/elisabethbangoura/Desktop/testingBTCAddress/node_modules/@ethersproject/logger/lib/index.js:238:21)
at Logger.throwError (/Users/elisabethbangoura/Desktop/testingBTCAddress/node_modules/@ethersproject/logger/lib/index.js:247:20)
at JsonRpcProvider. (/Users/elisabethbangoura/Desktop/testingBTCAddress/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:609:54)
at step (/Users/elisabethbangoura/Desktop/testingBTCAddress/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:48:23)
at Object.throw (/Users/elisabethbangoura/Desktop/testingBTCAddress/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:29:53)
at rejected (/Users/elisabethbangoura/Desktop/testingBTCAddress/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:21:65)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
reason: 'could not detect network',
code: 'NETWORK_ERROR',
event: 'noNetwork'
}

Node.js v18.16.0
....

BCH certificate has expired

I'm currently working on an application which works very well, but discovered this issue today.

when I try to get the balance of Bitcoin cash address it gives this error below. I believe it has to do with the SSL.

"message": "certificate has expired",
"name": "Error",
"stack": "Error: certificate has expired\n at TLSSocket.onConnectSecure (_tls_wrap.js:1502:34)\n at TLSSocket.emit (events.js:314:20)\n at TLSSocket._finishInit (_tls_wrap.js:937:8)\n at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:711:12)",
"config": {
"url": "https://explorer-tbch.api.bitcoin.com/tbch/v1/addr/bchtest:qr8tm9fu626levty7euhs3q5az37gy3m3szwnd9586/utxo",
"method": "get",
"headers": {
"Accept": "application/json, text/plain, /",
"User-Agent": "axios/0.21.1"
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 30000,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1
},
"code": "CERT_HAS_EXPIRED"
}

Can't make an ERC20 Transaction Error: call revert exception!!!

  • I'm submitting a ...
    [ X] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
    [ ] question about how to use this project

I get this error when I want to make an ERC20 Transaction with the coins in the list. I use the Ropsten network: ->
Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="decimals()", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.6.3)

Can someone help me with that?

How to get segwit address from this library?

  • I'm submitting a ...
    [ ] bug report
    [ tick] feature request
    [ ] question about the decisions made in the repository
    [ ] question about how to use this project

  • Summary

I was using this code for sending btc transactions and it was working really good. I like the simplicity. However, when I imported my private key (mainnet BTC) and tried to see the wallet address, it was showing a legacy address. While, the wallet that I created was segwit. So, I am a bit confused here. Can some help me get the segwit address?

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

Steps to reproduce:

  • First, I imported the private key and converted to buffer using ECPair

    const keyPair = ECPair.fromWIF(private_key);
    const account = new CryptoAccount(keyPair.privateKey);

  • Then I checked the account using the folllowing:

    var addr = await account.address("BTC");
    console.log("Wallet address:", addr);

  • The address was shown as following

"1QAFzHidiMNVED9AfP*****************" Starting with "1"

Whereas, it should output something like this,

"bc1qlc9jt4kx5x***************" Starting with bc1

Can somebody please help out here?

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.