npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

firovm-sdk

v0.0.25-alpha

Published

Simple sdk for interact with firovm

Readme

FIRO VM SDK

Simple sdk for interact with firovm.

Running Tests

# Unit tests
yarn test

Installation

npm i firovm-sdk

Usage

Create Client

import { Client } from "firovm-sdk";
const url = "http://user:[email protected]:8545";
const client = new Client(url);

Balance

const address = "TSy3YBFebUV79oZ1ijAzEEj8ULoV6GZnEQ";
const balance = await client.getBalance(address);
// 100000000 # 1 FVM

TokenBalance

const token = "3c76244790d45eef410f001d05ee5a5527f42b16";
const address = "TSy3YBFebUV79oZ1ijAzEEj8ULoV6GZnEQ";
const balance = await client.getTokenBalance(token, address);
// { balance: 1000000000000000000n, decimals: 18 } # 1 token of an 18 decimals frc20

Mnemonic Account

import { MnemonicAccount, Context, Network } from "firovm-sdk";
const context = new Context().withNetwork(Network.Regtest);

// Generate Mnemonic
const accountMain = new MnemonicAccount(context);
accountMain.mnemonic; // damp slice bar service agree top foot blast plunge exercise pattern canoe

// Recovery Mnemonic
const mnemonic =
  "damp slice bar service agree top foot blast plunge exercise pattern canoe";
const accountRecovery = new MnemonicAccount(context, mnemonic);
accountRecovery.mnemonic; // damp slice bar service agree top foot blast plunge exercise pattern canoe

// Recovery Index 2
const account2 = new MnemonicAccount(context, mnemonic, 2);
account2.export_privkey(); // b632c43685c957a9845799b75d8c4c2c7e2877c792660665c10c0ab12ec340aa
account2.export_privkey_as_WIF(); // cTgsVSTiF9Vy7ZniVLeMoxp7wEf8avwmidD4w3mZueGDAoPRT98c
account2.address(); // TSmgY9vCJNvEumvnPDyjYS3YRfnKWvgKx8
account2.hex_address(); // 0xb84C21fe5103D338500A58fB7A5C7bD534A3A615

Privatekey Account

import { PrivkeyAccount, Context, Network } from "firovm-sdk";
const context = new Context().withNetwork(Network.Regtest);
const account = new PrivkeyAccount(context);
account.export_privkey(); // b632c43685c957a9845799b75d8c4c2c7e2877c792660665c10c0ab12ec340aa
account.export_privkey_as_WIF(); // cTgsVSTiF9Vy7ZniVLeMoxp7wEf8avwmidD4w3mZueGDAoPRT98c
account.address(); // TSmgY9vCJNvEumvnPDyjYS3YRfnKWvgKx8
account.hex_address(); // 0xb84C21fe5103D338500A58fB7A5C7bD534A3A615

// Recovery from hex Privatekey
const hexPrivkey =
  "2b20f3e0b759aa353a20db5f29f081d946b77f3cb7f7fa80865c9fecc2846189";
const accountRecoveryHex = new PrivkeyAccount(context, hexPrivkey);

// Recovery from WIF
const wifKey = "cP2YAtVuis5cuQgtaZcePEyQ3MemRjT85U6UoMbMXkQzGK89feAi";
const accountRecoveryWIF = new PrivkeyAccount(context, wifKey);

Send native/token

// Send 1 Firo
const txId = await client.sendFrom(account, [
  {
    to: "TSy3YBFebUV79oZ1ijAzEEj8ULoV6GZnEQ",
    value: 1e8,
  },
]);

// Using unit converter
import { Unit } from "firovm-sdk";
const txId = await client.sendFrom(account, [
  {
    to: "TSy3YBFebUV79oZ1ijAzEEj8ULoV6GZnEQ",
    value: Unit.fromFVM(1).toSatoshis(),
  },
]);

// Send 15000 token of an 18 decimals token
const sendTokenTxId = await client.tokenTransfer(
  account,
  tokenContract,
  destinationAddress,
  BigInt("15000000000000000000000")
);

// Using unit converter
import { TokenUnit } from "firovm-sdk";
const sendTokenTxId = await client.tokenTransfer(
  account,
  tokenContract,
  destinationAddress,
  new TokenUnit(15000, 18).toBigNum()
);

Contract interaction

import ABI from "./abi.json"; // FRC20 ABI
const contractAddress = "0x8a62f1a163aa7fc9e1ba370eb27d52cdbbb60949"; // FRC20
const contract = new client.Contract(ABI, contractAddress);
const account1Hex = "0xcd99155ae57460ee1d7a37784bfd31ffa7dbb661";
const account2Hex = "0xba723d15e07f168e7797a9dce0bec0ee2f383865";
const account = new PrivkeyAccount(
  new Context().withNetwork(Network.Regtest),
  "cRhFsXE18dzNJwDM8Xg32vLAUtbFd9SK1DyCALxwmgFSRrCG98j1"
);

// query balance of token
const balance = await contract.methods.balanceOf(account1Hex).call();

// query decimal
const decimals = await contract.methods.decimals().call();

// create a transaction to send token
const txId = await contract.methods
  .transfer(account2Hex, 10)
  .send({ from: account });

// Approve to send token
const txId = await contract.methods
  .approve(account2Hex, 100)
  .send({ from: account });

// Deploy Contract
const txId = new client.Contract(ABI)
  .deploy(dataByteCode, ['args'])
  .send({ from: account };

Custom transactions

// initialize transaction
const tx = new Transaction();

// Add an output to send fund
tx.to(address, 1);

// Add an output to create OP_RETURN
tx.addData(data);

// Add an output to call contract
const callContractGas = await client.estimateFee(
  contractAddress,
  calldata,
  account.address()
);
tx.call(calldata, gasPrice, callContractGas, contractAddress);

// Add an output to create a contract
const createContractGas = await client.estimateFee("", code, account.address());
tx.call(code, gasPrice, createContractGas);

// Add custom utxos
const utxos = await client.getUtxos(...addresses);

// Complete the transaction(Calculate fee, fill inputs and sign)
tx.build([account], utxos);

client.sendTransaction(tx, true);
client.sendTransaction(tx, true, 0);

Get transactions by address

const allTxs = client.getaddresstxs(["TGwSEF8AeYUeMf5aDTavry8Xuvdn9zKM5T"]);

const someTxs = client.getaddresstxs(
  ["TGwSEF8AeYUeMf5aDTavry8Xuvdn9zKM5T"],
  182000,
  182001
);

Create Payment Message

import { toUnit, Units } from "firovm-sdk";

const contractAddress = "0x6c0ade60f61d37956ae9dd454a86a6bc7ea3b52c";

// Creating a URI payment for native
// bitcoin:TMZZPF9Rzow8pt2RAqumTWRXo2AkKaYgaE?amount=1.2&message=This%20is%20a%20message&label=This%20is%20a%20label
const uriStringNative = client.createURI(
  account.address(),
  1.2e8,
  "This is a message",
  "This is a label"
);

// Creating a URI payment for token
// bitcoin:TMZZPF9Rzow8pt2RAqumTWRXo2AkKaYgaE?contractAddress=0x6c0ade60f61d37956ae9dd454a86a6bc7ea3b52c&amountToken=15000000000000000000
const uriStringToken = client.createURI(
  account.address(),
  0,
  "",
  "",
  contractAddress,
  BigInt("15000000000000000000")
);

// Pay to address in URI
const txId = await client.payToURI(account, uriString);

NFT

import ABI from "./abiNFT.json"; // ERC721 ERC1155 ABI
const contractAddressNFT = "0x8a62f1a163aa7fc9e1ba370eb27d52cdbbb60949";
const contract = new client.Contract(ABI, contractAddressNFT);

const account = new PrivkeyAccount(
  new Context().withNetwork(Network.Regtest),
  "cRhFsXE18dzNJwDM8Xg32vLAUtbFd9SK1DyCALxwmgFSRrCG98j1"
);

// query balance of token
const balance = await contract.methods.balanceOf(account1Hex).call();

// transfer token
const tokenId = 1;
const from = "0xcd99155ae57460ee1d7a37784bfd31ffa7dbb661";
const to = "0xba723d15e07f168e7797a9dce0bec0ee2f383865";
const txId = await contract.methods
  .transferFrom(from, to, tokenId)
  .send({ from: account });

ERC721

reference: https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#IERC721

interface SendOptions {
  value?: number;
  gas?: number;
  gasPrice?: number;
  from: Account;
  input?: string;
  gasLimitMultiplier?: number;
}

const nftAddress = "0xd7134bce32fbea14b1fe987153c7b4646facc74a";
const nft = client.ERC721(nftAddress);

const account = "0xb118e03f6575AA270673c8D86D6Dcb07EB2D9221";
const balance = await nft.balanceOf(account);
// balance 1

const tokenId = 1;
const owner = await nft.ownerOf(tokenId);
// owner "address"

const address = await nft.getApproved(tokenId);
// address "to"

const approved = await nft.isApprovedForAll(
  address,
  "0xb118e03f6575AA270673c8D86D6Dcb07EB2D9223"
);
// approved true

const to = "0xb118e03f6575AA270673c8D86D6Dcb07EB2D9223";
const from = "0xb118e03f6575AA270673c8D86D6Dcb07EB2D9221";
const operator = "0xb118e03f6575AA270673c8D86D6Dcb07EB2D9222";
const tokenIds = 1;
const txid = await nft.approve(to, 1, SendOptions);
const txid = await nft.transferFrom(from, to, 1, SendOptions);
const txid = await nft.setApprovalForAll(operator, true, SendOptions);

ERC1155

reference: https://docs.openzeppelin.com/contracts/3.x/api/token/erc1155#IERC1155

const nftAddress = "0xd7134bce32fbea14b1fe987153c7b4646facc74a";
const nft = client.ERC1155(nftAddress);

const account = "0xb118e03f6575AA270673c8D86D6Dcb07EB2D9221";
const tokenId = 1;
const balance = await nft.balanceOf(account, tokenId);
// balance 1

const from = "0xb118e03f6575AA270673c8D86D6Dcb07EB2D9221";
const to = "0xb118e03f6575AA270673c8D86D6Dcb07EB2D9223";
const tokenId = 2;
const amount = 3;
const txid = await nft.safeTransferFrom(from, to, tokenId, 1, SendOptions);

Sign and Verify Message

import { Message } from "firovm-sdk";

const message = new Message("hello");
const account = new PrivkeyAccount(context);
const signature = await message.sign(account);
const verified = await message.verify(
  signature,
  account.get_pubkey().toString()
);

Sign and Verify Message in RSV format

import { Message } from "firovm-sdk";

const message = new Message("hello");
const account = new PrivkeyAccount(context);
const signature = await message.signWithRSVFormat(account);
const verified = await message.verifyRSVFormat(
  signature,
);

// or with public key
const verified = await message.verifyRSVFormat(
  signature,
  account.get_pubkey().toString()
);

Sign and Verify Message in compact VRS format

import { Message } from "firovm-sdk";

const message = new Message("hello");
const account = new PrivkeyAccount(context);
const signature = await message.signWithCompactVRSFormat(account);
const verified = await message.verifyCompactVRSFormat(
  signature,
);

// or with public key
const verified = await message.verifyCompactVRSFormat(
  signature,
  account.get_pubkey().toString()
);

Run Integration Test with FiroVM

yarn test:it
yarn test:down