sdk-monorepo/docs/USAGE.md

6.6 KiB

Usage Examples

Make a deposit

import { Wallet, BigNumber } from "ethers"

import * as Tornado from "@tornado/sdk"
import * as dotenv from "dotenv"

dotenv.config()

async function main() {
    const torProvider = 
        new Tornado.Web.TorProvider(process.env.NETWORK_RPC!, { port: process.env. })

    const wallet = new Wallet(process.env.PRIVATE_KEY!, torProvider)

    console.log(
        "\n 🤑 Balance of the wallet on network => ", 
        (await wallet.getBalance()).div(BigNumber.from(10).pow(18)).toString(),
        '\n'
    )

    const core = new Tornado.Core()

    await core.connect(torProvider)

    console.log("\n 🌪️ Tornado Core connected\n")

    // You can set something lower here, in case you're a poor bastard, like me, obviously xD
    const instance = core.getInstance("eth", 1)

    const tx = core.createDepositTransaction(instance)

    console.log(`\n 💱 Deposit request created!\n\n${JSON.stringify(tx)}\n`)
    console.log(`\n Sending...\n`)

    const response = await wallet.sendTransaction(tx.request)

    console.log(`\n Response arrived!\n`)

    console.log(`\n Note: ${tx.note}, you need this, but it will be backed up!\n`)

    const receipt = await response.wait()

    console.log(`\n Receipt received!\n`)

    await core.backupNote(instance, tx)

    console.log("\n All backed up! Load with \"core.loadNotes\" next time!\n")
}

main()

Make a withdrawal

Goerli withdrawals for ETH showed to be working, but I still consider it experimental for ETH and definitely for tokens.

import { Wallet, BigNumber, utils } from "ethers"

import * as Tornado from "@tornado/sdk"
import * as dotenv from "dotenv"

dotenv.config()

async function main() {
    const torProvider =
        new Tornado.Web.TorProvider(process.env.NETWORK_RPC!, { port: 9150 })

    const depositorWallet = new Wallet(process.env.DEPOSITOR_PRIVATE_KEY!, torProvider)
    const receiverWallet = new Wallet(process.env.RECEIVER_PRIVATE_KEY!, torProvider)

    let initialBalanceOfReceiver = await receiverWallet.getBalance()
    const initialBalanceOfDepositor = await depositorWallet.getBalance()

    const zeroPointThree = utils.parseUnits("0.3")

    if (initialBalanceOfReceiver.lt(zeroPointThree)) {
        const response = await depositorWallet.sendTransaction({
            to: receiverWallet.address,
            value: zeroPointThree.sub(initialBalanceOfReceiver)
        })
        await response.wait()

        console.log("\n 🤑 Funded receiver wallet to exactly 0.3 ether \n")

        initialBalanceOfReceiver = await receiverWallet.getBalance()
    }

    console.log(
        "\n 🤑 Initial balance of depositor wallet on network => ",
        initialBalanceOfDepositor.toString(),
        '\n'
    )

    console.log(
        "\n 🤑 Initial balance of receiver wallet on network => ",
        initialBalanceOfReceiver.toString(),
        '\n'
    )

    const core = new Tornado.Core()

    await core.connect(torProvider)

    console.log("\n 🌪️ Tornado Core connected!\n")

    const instance = core.getInstance("eth", 1)

    const note = (await core.loadNotes())[0]

    const proof = await core.createDepositProof(
        instance,
        { address: receiverWallet.address },
        receiverWallet.address,
        note
    )

    console.log(`\n 📜 Proof built:\n\n${proof}\n`)

    const response = await instance.connect(receiverWallet).withdraw(proof[0], proof[1], proof[2], proof[3], proof[4], proof[5], proof[6])

    await response.wait()

    console.log("\n 🌪️🌪️🌪️💰🥷 Withdrawal successful! \n")

    console.log(
        "\n 🤑 Balance of the receiver wallet on network => ",
        (await receiverWallet.getBalance()).toString(),
        '\n'
    )
}

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 a zipped archive!
  await core.exportCacheZip('Deposits1ETH0.1')

  // Or a JSON file!
  await core.exportCacheJson('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 a zipped archive again!
  await core.exportCacheZip('Deposits1ETH0.1')

  // Or a JSON file!
  await core.exportCacheJson('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()