sdk-monorepo/docs/USAGE.md

5.3 KiB

Usage Examples

Build a deposit transaction

import * as Tornado from "@tornado/sdk"
import { providers } from "ethers"

async function main() {
    // Get the core Tornado Cash logic.
    const core = new Tornado.Core()

    // Connect a provider
    await core.connect(new providers.JsonRpcProvider("https://some.rpc.url"))

    // Build tx (synchronous)
    const tx = core.buildDepositTransaction(core.getInstance("usdc", "100"))

    // Print the tx to console
    console.log(tx)
}

main()

Build a withdrawal transaction

This is still considered experimental, I will flag it as not experimental after a certain number of production tests.

import * as Tornado from "@tornado/sdk"
import { providers, BigNumber } from "ethers"

async function main() {
  // The address to receive the funds...
  const receiverAddress = "0x0000000000000000000000000000000000000000"

  // Get the core Tornado Cash logic.
  const core = new Tornado.Core()

  // Get a regular ethers v5 provider.
  const provider = new providers.JsonRpcProvider("https://some.rpc.url")

  // This time we need to connect the provider
  await core.connect(provider)

  // We also need a relayer
  const relayer = new Tornado.Web.Relayer({
    url: "https://" + "some.relayer.org",
    // Web can also instead provide a TorHttpClient or an (ethers v5) TorProvider
    httpClient: new Tornado.Web.RegularHttpClient()
  })

  // We always have to fetch the current properties of a relayer
  await relayer.fetchProperties()

  // Once that is done let's get an instance we have a proof of
  const instance = core.getInstance("eth", "0.1")

  // We have to load the note, the arguments can be
  // indexes - indexes according to which you may choose the notes in cache
  // keys - the keys according to which you may choose the notes in cache
  // In our case we've set indexes to undefined and choosing our notes according to the instance
  // And then selecting the first one of those
  const note = (await core.loadNotes(undefined, {
    network: '' + core.chain.id,
    token: "eth",
    denomination: "0.1"
  }))[0]

  // Now build the proof
  const proof = await core.buildDepositProof(instance, relayer.properties, receiverAddress, note, {
    // Defaults after the function populates as a showcase
    // You can also leave all of this out and it will set it by itself
    checkNotesSpent: true,
    checkKnownRoot: true,
    merkleTreeHeight: 20,
    tokenDecimals: 18,
    ethPurchaseAmounts: [BigNumber.from(0)], // When doing multiple proofs, more elements in array
    gasPrice: undefined,
    gasPriceCushion: undefined,
  })

  console.log(proof)
}

main()

Synchronize Deposit Events Over Clearnet Without Sync Logs

import * as Tornado from "@tornado/sdk"
import { providers } from "ethers"

async function sync() {
  // Get a regular ethers v5 provider.
  const provider = new providers.JsonRpcProvider("https://some.rpc.url")

  // Get the core Tornado Cash logic.
  const core = new Tornado.Core()

  // Connect the provider (necessary)
  await core.connect(provider)

  // Get the instance to sync
  const instance = await core.getInstance("eth", 0.1)

  // Sync! Output will be in the project dir in the cache folder
  await core.syncDeposits(instance)

  // Now export it as an archive!
  await core.exportCacheZip('Deposits1ETH0.1')
}

sync()

Synchronize Deposit Events Over Tor Without Sync Logs

import * as Tornado from "@tornado/sdk"

async function sync() {
  // Get a torified ethers v5 provider.
  // You can set the port to 9150 if you use Tor Browser!
  const provider = new Tornado.Web.TorProvider("https://some.rpc.url", { port: 9050 })

  // Get the core Tornado Cash logic.
  const core = new Tornado.Core()

  // Connect the provider (necessary)
  await core.connect(provider)

  // Get the instance to sync
  const instance = core.getInstance("eth", 0.1)

  // Sync!
  await core.syncDeposits(instance,
    {
      // In this example, we're forcing to sync from the start block such that
      // if some RPC doesn't index all events, that we can rerun and insert other
      // elements not found in the former. PouchDB handles the insertions.
      startBlock: Tornado.Data.Onchain.getInstanceDeployBlockNumSync("1", "eth", "0.1")
    }
  )

  // Export as archive again!
  await core.exportCacheZip('Deposits1ETH0.1')
}

sync()

Synchronize Deposit Events With Custom Logs

import * as Tornado from "@tornado/sdk"

let logListener = function (...args: any[]) {
  if (args.length === 3) {
    console.debug(`\nSync will be started with SB: ${args[0]}, TB: ${args[1]}, BD: ${args[2]}\n`)
  } else if (args.length == 2) {
    console.debug(`Syncing from block ${args[0]} to ${args[1]}`)
  }
}

async function sync() {
  // Get a torified ethers v5 provider.
  const provider = new Tornado.Web.TorProvider("https://eth.llamarpc.com", { port: 9150 })

  // Get the core Tornado Cash logic.
  const core = new Tornado.Core()

  // Connect the provider (necessary)
  await core.connect(provider)

  // Get the instance to sync
  const instance = core.getInstance("eth", 0.1)

  // Log
  core.on('debug', logListener)

  // Sync!
  await core.syncDeposits(instance,
    {
      // Always sync from start if we want to do multiple RPCs
      startBlock: Tornado.Data.Onchain.getInstanceDeployBlockNumSync("1", "eth", "0.1")
    }
  )

  // Log
  core.off('debug', logListener)
}

sync()