0.0.25-alpha • Published 8 months ago

firovm-sdk v0.0.25-alpha

Weekly downloads
-
License
ISC
Repository
github
Last release
8 months ago

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:pass@127.0.0.1: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