Skip to content

siriuscore/siriusjs-wallet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

siriusJS Wallet

This is a client-side wallet library that can generate private keys from a mnemonic, or import private keys from other sirius wallets.

It can sign transactions locally, and submit the raw transaction data to a remote sirius node. The blockchain data is provided by the Insight API, rather than the raw siriusd RPC calls.

This library makes it possible to run a DApp without the users having to run a full siriusd node.

Install

A bit manual at the moment. Copy the generated JavaScript libraries in the lib folder to your project.

API

Examples

Create Mnemonic+Password Wallet

import { networks, generateMnemonic } from "siriusjs-wallet"

async function main() {
  const network = networks.testnet
  const mnemonic = generateMnemonic()
  const password = "covfefe"

  const wallet = network.fromMnemonic(mnemonic, password)

  console.log("mnemonic:", mnemonic)
  console.log("public address:", wallet.address)
  console.log("private key (WIF):", wallet.toWIF())
}

main().catch((err) => console.log(err))

Example Output:

mnemonic: hold struggle ready lonely august napkin enforce retire pipe where avoid drip
public address: qLUHmrFGexxpyHwQphLpE1czZNFE5m1xmV
private key (WIF): cNQKccYYQyGX9G9Qxq2DJev9jHygbZpb2UG7EvUapbtDx5XhkhYE

Send Fund

This example restores a wallet from a private key (in WIF format), then sending value to another address.

The transaction is signed locally, and the transaction submitted to a remote API.

The currency unit used is satoshi. To convert sirius to satoshi you should multiply the amount you want with 1e8.

import { networks } from "siriusjs-wallet"

async function main() {
  // Use the test network. Or `networks.mainnet`
  const network = networks.testnet

  const wif = "L3royRxpg1F4UVNieDfwaVuVGxoAd3Vp6eN7w3puap3vXU9JNa6P"
  const wallet = network.fromWIF(wif)

  console.log(wallet.address)

  const toAddr = "SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ"
  // Sending 0.1 sirius
  const sendtx = await wallet.send(toAddr, 1, 0.1 * 1e8)
  console.log("sendtx", sendtx)
}

main().catch((err) => console.log(err))

Send To Contract

Let's burn some money using the Burn contract:

pragma solidity ^0.4.18;

contract Burn {
  uint256 public totalburned;
  event DidBurn(address burnerAddress, uint256 burnedAmount);

  function burnbabyburn() public payable {
    totalburned = msg.value;
    DidBurn(msg.sender, msg.value);
  }
}

The ABI encoding for the burnbabyburn() invokation is e179b912. We'll burn 0.05 sirius, expressed in unit of satoshi.

import { networks } from "siriusjs-wallet"

async function main() {
  const network = networks.testnet

  const privateKey = "L3royRxpg1F4UVNieDfwaVuVGxoAd3Vp6eN7w3puap3vXU9JNa6P"

  const wallet = network.fromWIF(privateKey)


  const contractAddress = "b10071ee33512ce8a0c06ecbc14a5f585a27a3e2"
  const encodedData = "e179b912" // burnbabyburn()

  const tx = await wallet.contractSend(contractAddress, encodedData, {
    amount: 0.05 * 1e8, // 0.05 sirius in satoshi
  })

  console.log(tx)
}

main().catch((err) => console.log(err))

Networks

Two networks are predefined:

import { networks } from "siriusjs-wallet"

// Main Network
networks.mainnet

// Test Network
networks.testnet

fromPrivateKey

Alias for fromWIF.

fromWIF

fromWIF constructs a wallet from private key (in WIF format).

Suppose you want to import the public address SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ. Use sirius-cli to dump the private key from wallet:

./sirius-cli dumpprivkey "SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ"

L3royRxpg1F4UVNieDfwaVuVGxoAd3Vp6eN7w3puap3vXU9JNa6P
const network = networks.testnet

const privateKey = "L3royRxpg1F4UVNieDfwaVuVGxoAd3Vp6eN7w3puap3vXU9JNa6P"

const wallet = network.fromWIF(privateKey)
console.log("public address:", wallet.address)

Output:

public address: SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ

fromMnemonic

fromMnemonic constructs a wallet from mnemonic. User can optionally specify a password to add to the mnemonic entropy.

const network = networks.testnet
const mnemonic = "hold struggle ready lonely august napkin enforce retire pipe where avoid drip"
const password = "covfefe"

const wallet = network.fromMnemonic(mnemonic, password)

console.log("public address:", wallet.address)
console.log("private key (WIF):", wallet.toWIF())

Example Output:

public address: SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ
private key (WIF): L3royRxpg1F4UVNieDfwaVuVGxoAd3Vp6eN7w3puap3vXU9JNa6P

Wallet

Wallet manages blockchain access for an address. It is able to create and sign transactions locally for sending a payment or interacting with a smart contract.

You would typically construct a Wallet instance using the factory methods provided by Network.

async wallet.getInfo

Get basic information about the wallet address.

Example:

const info = await wallet.getInfo()
console.log(info)

Output:

{ addrStr: 'SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ',
  balance: 128.47960699,
  balanceSat: 12847960699,
  totalReceived: 599.92142295,
  totalReceivedSat: 59992142295,
  totalSent: 471.44181596,
  totalSentSat: 47144181596,
  unconfirmedBalance: 0,
  unconfirmedBalanceSat: 0,
  unconfirmedTxApperances: 0,
  txApperances: 21,
  transactions:
   [ 'd12ff9cfd76836d8eb5a39bc40f1dc5e6e2032bfa132f66cca638a7e76f2b6e7',
     '44fa64f34361cf5460ca116ea396098eb0d20dd43839375c07d69a282d4e29b6',
     'ca86c477bc595f08f158eed0d4307ee6e1e674a2c14f808b013b38cb1e929aa0',
     'fbf41aaca56dd013934471b4630f8ca52a6216cf791701a07f3e5c0ba16902d5',
     'af8fff4a74ff9217d629c17aa84412e8810888983cbc4f6b764740e68b51e5d0',
     'e9172194ef9493a2dd8dddd02aa58a1c13dbfb09a7e04cb97558d951e4b93a88',
     '3e167a2534d5d18b71ba56bbba8bfdb317711b3f2ef30f10d34941ddc9aa4861',
     'bd15b9d9cf4e94915e246a7d78de14cb0a6acec12624902b45717997ef71854e',
     '0c99d68c261dd713819c068bd0213bc048bd4928b3d86d71503bb3348d7f42f5',
     'd5b823bb524862855181d231e716ff86fa301f701fd4c23b68168debe334da2e',
     '7660e89eb45b536b9c7527edafc0884fc2941c0f050625780d3e100c8aeb28f4',
     'eddbbac9bb7dae1cf4093d893133eb52c483b13ea66f6354c63302f9127ec1bd',
     '6f99149d78ad720591b4cca643fe2599a0a07076f8f3e80b5962cba326772e83',
     '0ef2548cceaaa41b7c0127f6e943d103f2fcc236d05e59593e05381f7a8474a0',
     '851753842d80e8dea92de643e0f3784cf7cbdbb02ae879593cbeac2c78560bac',
     '729c839d63f7426a1f4ada7eb5a35b556556665a4b42e102694674551752bb03',
     'ee50d8422dce064d40eb021f4829f5b871e8d2927d93ea136dc0df01b1a72e08',
     'caf8b48b9d38c3a27de3d24c5a738f63ec37619d419cfcd061bc991d8369bda3',
     '3b59444033d61457fe229a866dc9cb4a60a4b070ea3a73cacba27516fd30cee8',
     '5e9ca1c946deaf5458d2b6236145b225eee61ec6991b7df8ee96573b53d82584',
     'cfbadf76884ca661816f25487f6493826579afe257517ebd7d1fc2b0020eb289' ] }

async wallet.send

Send payment to a receiving address. The transaction is signed locally using the wallet's private key, and the raw transaction submitted to a remote API (without revealing the wallet's secret).

Method signature:

/**
 * @param to The receiving address
 * @param amount The amount to transfer (in satoshi)
 * @return The raw transaction as hexadecimal string
 *
 */
public async send(
  to: string,
  amount: number,
  opts: ISendTxOptions = {},
): Promise<Insight.ISendRawTxResult>

Example:

const toAddress = "SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ"
const amount = 0.15 * 1e8 // 0.15 sirius

const tx = await wallet.send(toAddress, amount)
console.log(tx)

Output:

{ txid: '40fec162e0d4e1377b5e6744eeba562408e22f60399be41e7ba24e1af37f773c' }

async wallet.send options

export interface ISendTxOptions {
  /**
   * Fee rate to pay for the raw transaction data (satoshi per byte). The
   * default value is the query result of current network's fee rate.
   */
  feeRate?: number
}

Setting tx fee rate manually:

const tx = await wallet.send(toAddress, amount, {
  // rate is 400 satoshi per byte, or  ~0.004 sirius/KB, as is typical.
  feeRate: 400,
})

async wallet.generateTx

Generate and sign a payment transaction.

Method signature:

/**
 * @param to The receiving address
 * @param amount The amount to transfer (in satoshi)
 * @param opts
 *
 * @returns The raw transaction as hexadecimal string
 */
public async generateTx(
  to: string,
  amount: number,
  opts: ISendTxOptions = {},
): Promise<string>

Example:

const toAddress = "SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ"
const amount = 0.15 * 1e8

const rawtx = await wallet.generateTx(toAddress, amount)
console.log(rawtx)

Example output, the raw transaction as hexadecimal string:

0100000001a09a921ecb383b018b804fc1a274e6e1e67e30d4d0ee58f1085f59bc77c486ca010000006a47304402202fa6106aca6c682ab89b02ad62614462d1ec5e95cb8b4810ce793ad52a4002590220531cf380368cb8f92c7dd03ee375423073a14e5b7da6f48127c63cab17fbf2d7012103c12c73abaccf35b40454e7eb0c4b5760ce7a720d0cd2c9fb7f5423168aaeea03ffffffff02c0e1e400000000001976a914afb616c886f0efd9a9a486ccc07a09ab8d7a4bb288ac49b6ffe0010000001976a914c78300c58ab7c73e1767e3d550464d591ab0a12888ac00000000

You can decode the raw transaction using sirius-cli:

./sirius-cli decoderawtransaction 0100000001a09a921ecb38...

{
  // ...
  "vout": [
    {
      "value": 0.15000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 afb616c886f0efd9a9a486ccc07a09ab8d7a4bb2 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914afb616c886f0efd9a9a486ccc07a09ab8d7a4bb288ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ"
        ]
      }
    },
    {
      "value": 80.69822025,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 c78300c58ab7c73e1767e3d550464d591ab0a128 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914c78300c58ab7c73e1767e3d550464d591ab0a12888ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "SRoinb4dd2M63T8qHdPd9iN9e2TkcitgTQ"
        ]
      }
    }
  ]
}

There are two vouts:

  1. 0.15. This is the amount we want to send.
  2. 80.69822025. This is the amount we going back to the original owner as change.

async wallet.contractSend

Create a send-to-contract transaction that invokes a contract's method.

/**
  * @param contractAddress Address of the contract in hexadecimal
  * @param encodedData The ABI encoded method call, and parameter values.
  * @param opts
  */
public async contractSend(
  contractAddress: string,
  encodedData: string,
  opts: IContractSendTXOptions = {},
): Promise<Insight.ISendRawTxResult>

Example:

Invoke the burn() method, and transfer 5000000 satoshi to the contract.

  1. The burn() method call ABI encodes to e179b912
  2. The 5000000 is msg.value in contract code.
const contractAddress = "1620cd3c24b29d424932ec30c5925f8c0a00941c"
// ABI encoded data for the send-to-method transaction
const encodedData = "e179b912"

// Invoke a contract's method, and transferring 0.05 to it.
const tx = await wallet.contractSend(contractAddress, encodedData, {
  amount: 0.05 * 1e8,
})

console.log(tx)

Output:

{ txid: 'd12ff9cfd76836d8eb5a39bc40f1dc5e6e2032bfa132f66cca638a7e76f2b6e7' }

async wallet.generateContractSendTx

Generate a raw a send-to-contract transaction that invokes a contract's method.

Method signature:

/**
  * @param contractAddress
  * @param encodedData
  * @param opts
  */
public async generateContractSendTx(
  contractAddress: string,
  encodedData: string,
  opts: IContractSendTXOptions = {},
): Promise<string>

Example:

const contractAddress = "1620cd3c24b29d424932ec30c5925f8c0a00941c"
const encodedData = "e179b912"

const rawtx = await wallet.generateContractSendTx(contractAddress, encodedData, {
  amount: 0.01 * 1e8,
})

console.log(rawtx)

Example output:

0100000001e7b6f2767e8a63ca6cf632a1bf32206e5edcf140bc395aebd83668d7cff92fd1010000006b483045022100b86c4cbb2aecab44c951f99c0cbbf6115cf80881b39f33b4efd4d296892c1c15022062db1f681e684616e55303556577c9242102ff7a6815894dfb3090a7928fa13a012103c12c73abaccf35b40454e7eb0c4b5760ce7a720d0cd2c9fb7f5423168aaeea03ffffffff0240420f000000000022540390d003012804e179b912141620cd3c24b29d424932ec30c5925f8c0a00941cc2880256e0010000001976a914c78300c58ab7c73e1767e3d550464d591ab0a12888ac00000000

Decode the raw transaction:

./sirius-cli decoderawtransaction 0100000001e7b6f2767e8a6...

Decoded Raw TX:

{
  // ...
  "vout": [
    {
      "value": 0.01000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "4 250000 40 314145249 1620cd3c24b29d424932ec30c5925f8c0a00941c OP_CALL",
        "hex": "540390d003012804e179b912141620cd3c24b29d424932ec30c5925f8c0a00941cc2",
        "type": "call"
      }
    },
    {
      "value": 80.58700424,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 c78300c58ab7c73e1767e3d550464d591ab0a128 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914c78300c58ab7c73e1767e3d550464d591ab0a12888ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "qbkJZTKQfcout2joWVmnvUrJUDTg93bhdv"
        ]
      }
    }
  ]
}

There are two vouts:

  1. call 0.11. This is the amount we want to send to the contract.
  2. pubkeyhash 80.58700424. This is the amount we going back to the original owner as change.

async wallet.contractCall

Query a contract's method. It returns the result and logs of a simulated execution of the contract's code.

Method signature:

/**
 * @param contractAddress Address of the contract in hexadecimal
 * @param encodedData The ABI encoded method call, and parameter values.
 * @param opts
 */
public async contractCall(
  contractAddress: string,
  encodedData: string,
  opts: IContractSendTXOptions = {},
): Promise<Insight.IContractCall>

Example:

const contractAddress = "b10071ee33512ce8a0c06ecbc14a5f585a27a3e2"
const encodedData = "e179b912"

const result = await wallet.contractCall(contractAddress, encodedData, {
  amount: 0.01 * 1e8,
})

console.log(JSON.stringify(result, null, 2))

Output:

{
  "address": "b10071ee33512ce8a0c06ecbc14a5f585a27a3e2",
  "executionResult": {
    "gasUsed": 27754,
    "excepted": "None",
    "newAddress": "b10071ee33512ce8a0c06ecbc14a5f585a27a3e2",
    "output": "",
    "codeDeposit": 0,
    "gasRefunded": 0,
    "depositSize": 0,
    "gasForDeposit": 0
  },
  "transactionReceipt": {
    "stateRoot": "c04b98dbd1a38be8ecfb71e40072c90a1ee9f5961bb80fa6262f8a32979427bb",
    "gasUsed": 27754,
    "bloom": "0000000000000000000020004000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "log": [
      {
        "address": "b10071ee33512ce8a0c06ecbc14a5f585a27a3e2",
        "topics": [
          "9c31339612219a954bda4c790e4b182b6499bdf1464c392cb50e61d8afa1f9f2"
        ],
        "data": "000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000"
      }
    ]
  }
}

About

A TypeScript toolkit for building Sirius light wallets

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published