0.0.13-alpha

Signed-off-by: AlienTornadosaurusHex <>
This commit is contained in:
AlienTornadosaurusHex 2023-06-10 20:27:32 +00:00
parent c5478b159d
commit 19c687c9d2
211 changed files with 10991 additions and 216 deletions

View file

@ -13,7 +13,7 @@
"crypto",
"zk"
],
"version": "0.0.12-alpha",
"version": "0.0.13-alpha",
"engines": {
"node": "^18"
},

View file

@ -0,0 +1,508 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BigNumber,
BigNumberish,
BytesLike,
CallOverrides,
ContractTransaction,
Overrides,
PayableOverrides,
PopulatedTransaction,
Signer,
utils
} from 'ethers'
import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi'
import type { Listener, Provider } from '@ethersproject/providers'
import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent, PromiseOrValue } from './common'
export interface TornadoRouterInterface extends utils.Interface {
functions: {
'approveTokenForInstance(address,address,uint256)': FunctionFragment
'backupNotes(bytes[])': FunctionFragment
'deposit(address,bytes32,bytes)': FunctionFragment
'governanceProxyAddress()': FunctionFragment
'initialize(address,address)': FunctionFragment
'instanceRegistry()': FunctionFragment
'relayerRegistry()': FunctionFragment
'rescueTokens(address,address,uint256)': FunctionFragment
'setInstanceRegistry(address)': FunctionFragment
'setRelayerRegistry(address)': FunctionFragment
'version()': FunctionFragment
'withdraw(address,bytes,bytes32,bytes32,address,address,uint256,uint256)': FunctionFragment
}
getFunction(
nameOrSignatureOrTopic:
| 'approveTokenForInstance'
| 'backupNotes'
| 'deposit'
| 'governanceProxyAddress'
| 'initialize'
| 'instanceRegistry'
| 'relayerRegistry'
| 'rescueTokens'
| 'setInstanceRegistry'
| 'setRelayerRegistry'
| 'version'
| 'withdraw'
): FunctionFragment
encodeFunctionData(
functionFragment: 'approveTokenForInstance',
values: [PromiseOrValue<string>, PromiseOrValue<string>, PromiseOrValue<BigNumberish>]
): string
encodeFunctionData(functionFragment: 'backupNotes', values: [PromiseOrValue<BytesLike>[]]): string
encodeFunctionData(
functionFragment: 'deposit',
values: [PromiseOrValue<string>, PromiseOrValue<BytesLike>, PromiseOrValue<BytesLike>]
): string
encodeFunctionData(functionFragment: 'governanceProxyAddress', values?: undefined): string
encodeFunctionData(
functionFragment: 'initialize',
values: [PromiseOrValue<string>, PromiseOrValue<string>]
): string
encodeFunctionData(functionFragment: 'instanceRegistry', values?: undefined): string
encodeFunctionData(functionFragment: 'relayerRegistry', values?: undefined): string
encodeFunctionData(
functionFragment: 'rescueTokens',
values: [PromiseOrValue<string>, PromiseOrValue<string>, PromiseOrValue<BigNumberish>]
): string
encodeFunctionData(functionFragment: 'setInstanceRegistry', values: [PromiseOrValue<string>]): string
encodeFunctionData(functionFragment: 'setRelayerRegistry', values: [PromiseOrValue<string>]): string
encodeFunctionData(functionFragment: 'version', values?: undefined): string
encodeFunctionData(
functionFragment: 'withdraw',
values: [
PromiseOrValue<string>,
PromiseOrValue<BytesLike>,
PromiseOrValue<BytesLike>,
PromiseOrValue<BytesLike>,
PromiseOrValue<string>,
PromiseOrValue<string>,
PromiseOrValue<BigNumberish>,
PromiseOrValue<BigNumberish>
]
): string
decodeFunctionResult(functionFragment: 'approveTokenForInstance', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'backupNotes', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'deposit', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'governanceProxyAddress', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'initialize', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'instanceRegistry', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'relayerRegistry', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'rescueTokens', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'setInstanceRegistry', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'setRelayerRegistry', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'version', data: BytesLike): Result
decodeFunctionResult(functionFragment: 'withdraw', data: BytesLike): Result
events: {
'EncryptedNote(address,bytes)': EventFragment
'InstanceRegistryUpdated(address)': EventFragment
'RelayerRegistryUpdated(address)': EventFragment
'TokenApproved(address,uint256)': EventFragment
}
getEvent(nameOrSignatureOrTopic: 'EncryptedNote'): EventFragment
getEvent(nameOrSignatureOrTopic: 'InstanceRegistryUpdated'): EventFragment
getEvent(nameOrSignatureOrTopic: 'RelayerRegistryUpdated'): EventFragment
getEvent(nameOrSignatureOrTopic: 'TokenApproved'): EventFragment
}
export interface EncryptedNoteEventObject {
sender: string
encryptedNote: string
}
export type EncryptedNoteEvent = TypedEvent<[string, string], EncryptedNoteEventObject>
export type EncryptedNoteEventFilter = TypedEventFilter<EncryptedNoteEvent>
export interface InstanceRegistryUpdatedEventObject {
newInstanceRegistryProxyAddress: string
}
export type InstanceRegistryUpdatedEvent = TypedEvent<[string], InstanceRegistryUpdatedEventObject>
export type InstanceRegistryUpdatedEventFilter = TypedEventFilter<InstanceRegistryUpdatedEvent>
export interface RelayerRegistryUpdatedEventObject {
newRelayerRegistryProxyAddress: string
}
export type RelayerRegistryUpdatedEvent = TypedEvent<[string], RelayerRegistryUpdatedEventObject>
export type RelayerRegistryUpdatedEventFilter = TypedEventFilter<RelayerRegistryUpdatedEvent>
export interface TokenApprovedEventObject {
spender: string
amount: BigNumber
}
export type TokenApprovedEvent = TypedEvent<[string, BigNumber], TokenApprovedEventObject>
export type TokenApprovedEventFilter = TypedEventFilter<TokenApprovedEvent>
export interface TornadoRouter extends BaseContract {
contractName: 'TornadoRouter'
connect(signerOrProvider: Signer | Provider | string): this
attach(addressOrName: string): this
deployed(): Promise<this>
interface: TornadoRouterInterface
queryFilter<TEvent extends TypedEvent>(
event: TypedEventFilter<TEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined
): Promise<Array<TEvent>>
listeners<TEvent extends TypedEvent>(eventFilter?: TypedEventFilter<TEvent>): Array<TypedListener<TEvent>>
listeners(eventName?: string): Array<Listener>
removeAllListeners<TEvent extends TypedEvent>(eventFilter: TypedEventFilter<TEvent>): this
removeAllListeners(eventName?: string): this
off: OnEvent<this>
on: OnEvent<this>
once: OnEvent<this>
removeListener: OnEvent<this>
functions: {
approveTokenForInstance(
_token: PromiseOrValue<string>,
_spender: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
backupNotes(
_encryptedNotes: PromiseOrValue<BytesLike>[],
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
deposit(
_tornado: PromiseOrValue<string>,
_commitment: PromiseOrValue<BytesLike>,
_encryptedNote: PromiseOrValue<BytesLike>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
governanceProxyAddress(overrides?: CallOverrides): Promise<[string]>
initialize(
_instanceRegistryAddress: PromiseOrValue<string>,
_relayerRegistryAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
instanceRegistry(overrides?: CallOverrides): Promise<[string]>
relayerRegistry(overrides?: CallOverrides): Promise<[string]>
rescueTokens(
_token: PromiseOrValue<string>,
_to: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
setInstanceRegistry(
_newInstanceRegistryProxyAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
setRelayerRegistry(
_newRelayerRegistryProxyAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
version(overrides?: CallOverrides): Promise<[string]>
withdraw(
_tornado: PromiseOrValue<string>,
_proof: PromiseOrValue<BytesLike>,
_root: PromiseOrValue<BytesLike>,
_nullifierHash: PromiseOrValue<BytesLike>,
_recipient: PromiseOrValue<string>,
_relayer: PromiseOrValue<string>,
_fee: PromiseOrValue<BigNumberish>,
_refund: PromiseOrValue<BigNumberish>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
}
approveTokenForInstance(
_token: PromiseOrValue<string>,
_spender: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
backupNotes(
_encryptedNotes: PromiseOrValue<BytesLike>[],
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
deposit(
_tornado: PromiseOrValue<string>,
_commitment: PromiseOrValue<BytesLike>,
_encryptedNote: PromiseOrValue<BytesLike>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
governanceProxyAddress(overrides?: CallOverrides): Promise<string>
initialize(
_instanceRegistryAddress: PromiseOrValue<string>,
_relayerRegistryAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
instanceRegistry(overrides?: CallOverrides): Promise<string>
relayerRegistry(overrides?: CallOverrides): Promise<string>
rescueTokens(
_token: PromiseOrValue<string>,
_to: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
setInstanceRegistry(
_newInstanceRegistryProxyAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
setRelayerRegistry(
_newRelayerRegistryProxyAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
version(overrides?: CallOverrides): Promise<string>
withdraw(
_tornado: PromiseOrValue<string>,
_proof: PromiseOrValue<BytesLike>,
_root: PromiseOrValue<BytesLike>,
_nullifierHash: PromiseOrValue<BytesLike>,
_recipient: PromiseOrValue<string>,
_relayer: PromiseOrValue<string>,
_fee: PromiseOrValue<BigNumberish>,
_refund: PromiseOrValue<BigNumberish>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>
callStatic: {
approveTokenForInstance(
_token: PromiseOrValue<string>,
_spender: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: CallOverrides
): Promise<void>
backupNotes(_encryptedNotes: PromiseOrValue<BytesLike>[], overrides?: CallOverrides): Promise<void>
deposit(
_tornado: PromiseOrValue<string>,
_commitment: PromiseOrValue<BytesLike>,
_encryptedNote: PromiseOrValue<BytesLike>,
overrides?: CallOverrides
): Promise<void>
governanceProxyAddress(overrides?: CallOverrides): Promise<string>
initialize(
_instanceRegistryAddress: PromiseOrValue<string>,
_relayerRegistryAddress: PromiseOrValue<string>,
overrides?: CallOverrides
): Promise<void>
instanceRegistry(overrides?: CallOverrides): Promise<string>
relayerRegistry(overrides?: CallOverrides): Promise<string>
rescueTokens(
_token: PromiseOrValue<string>,
_to: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: CallOverrides
): Promise<void>
setInstanceRegistry(
_newInstanceRegistryProxyAddress: PromiseOrValue<string>,
overrides?: CallOverrides
): Promise<void>
setRelayerRegistry(
_newRelayerRegistryProxyAddress: PromiseOrValue<string>,
overrides?: CallOverrides
): Promise<void>
version(overrides?: CallOverrides): Promise<string>
withdraw(
_tornado: PromiseOrValue<string>,
_proof: PromiseOrValue<BytesLike>,
_root: PromiseOrValue<BytesLike>,
_nullifierHash: PromiseOrValue<BytesLike>,
_recipient: PromiseOrValue<string>,
_relayer: PromiseOrValue<string>,
_fee: PromiseOrValue<BigNumberish>,
_refund: PromiseOrValue<BigNumberish>,
overrides?: CallOverrides
): Promise<void>
}
filters: {
'EncryptedNote(address,bytes)'(
sender?: PromiseOrValue<string> | null,
encryptedNote?: null
): EncryptedNoteEventFilter
EncryptedNote(sender?: PromiseOrValue<string> | null, encryptedNote?: null): EncryptedNoteEventFilter
'InstanceRegistryUpdated(address)'(
newInstanceRegistryProxyAddress?: null
): InstanceRegistryUpdatedEventFilter
InstanceRegistryUpdated(newInstanceRegistryProxyAddress?: null): InstanceRegistryUpdatedEventFilter
'RelayerRegistryUpdated(address)'(
newRelayerRegistryProxyAddress?: null
): RelayerRegistryUpdatedEventFilter
RelayerRegistryUpdated(newRelayerRegistryProxyAddress?: null): RelayerRegistryUpdatedEventFilter
'TokenApproved(address,uint256)'(
spender?: PromiseOrValue<string> | null,
amount?: null
): TokenApprovedEventFilter
TokenApproved(spender?: PromiseOrValue<string> | null, amount?: null): TokenApprovedEventFilter
}
estimateGas: {
approveTokenForInstance(
_token: PromiseOrValue<string>,
_spender: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>
backupNotes(
_encryptedNotes: PromiseOrValue<BytesLike>[],
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>
deposit(
_tornado: PromiseOrValue<string>,
_commitment: PromiseOrValue<BytesLike>,
_encryptedNote: PromiseOrValue<BytesLike>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>
governanceProxyAddress(overrides?: CallOverrides): Promise<BigNumber>
initialize(
_instanceRegistryAddress: PromiseOrValue<string>,
_relayerRegistryAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>
instanceRegistry(overrides?: CallOverrides): Promise<BigNumber>
relayerRegistry(overrides?: CallOverrides): Promise<BigNumber>
rescueTokens(
_token: PromiseOrValue<string>,
_to: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>
setInstanceRegistry(
_newInstanceRegistryProxyAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>
setRelayerRegistry(
_newRelayerRegistryProxyAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>
version(overrides?: CallOverrides): Promise<BigNumber>
withdraw(
_tornado: PromiseOrValue<string>,
_proof: PromiseOrValue<BytesLike>,
_root: PromiseOrValue<BytesLike>,
_nullifierHash: PromiseOrValue<BytesLike>,
_recipient: PromiseOrValue<string>,
_relayer: PromiseOrValue<string>,
_fee: PromiseOrValue<BigNumberish>,
_refund: PromiseOrValue<BigNumberish>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>
}
populateTransaction: {
approveTokenForInstance(
_token: PromiseOrValue<string>,
_spender: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>
backupNotes(
_encryptedNotes: PromiseOrValue<BytesLike>[],
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>
deposit(
_tornado: PromiseOrValue<string>,
_commitment: PromiseOrValue<BytesLike>,
_encryptedNote: PromiseOrValue<BytesLike>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>
governanceProxyAddress(overrides?: CallOverrides): Promise<PopulatedTransaction>
initialize(
_instanceRegistryAddress: PromiseOrValue<string>,
_relayerRegistryAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>
instanceRegistry(overrides?: CallOverrides): Promise<PopulatedTransaction>
relayerRegistry(overrides?: CallOverrides): Promise<PopulatedTransaction>
rescueTokens(
_token: PromiseOrValue<string>,
_to: PromiseOrValue<string>,
_amount: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>
setInstanceRegistry(
_newInstanceRegistryProxyAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>
setRelayerRegistry(
_newRelayerRegistryProxyAddress: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>
version(overrides?: CallOverrides): Promise<PopulatedTransaction>
withdraw(
_tornado: PromiseOrValue<string>,
_proof: PromiseOrValue<BytesLike>,
_root: PromiseOrValue<BytesLike>,
_nullifierHash: PromiseOrValue<BytesLike>,
_recipient: PromiseOrValue<string>,
_relayer: PromiseOrValue<string>,
_fee: PromiseOrValue<BigNumberish>,
_refund: PromiseOrValue<BigNumberish>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>
}
}

File diff suppressed because one or more lines are too long

View file

@ -10,3 +10,4 @@ export { MulticallContract__factory } from './MulticallContract__factory'
export { RelayerRegistry__factory } from './RelayerRegistry__factory'
export { TornadoInstance__factory } from './TornadoInstance__factory'
export { TornadoProxy__factory } from './TornadoProxy__factory'
export { TornadoRouter__factory } from './TornadoRouter__factory'

View file

@ -10,6 +10,7 @@ export type { MulticallContract } from './MulticallContract'
export type { RelayerRegistry } from './RelayerRegistry'
export type { TornadoInstance } from './TornadoInstance'
export type { TornadoProxy } from './TornadoProxy'
export type { TornadoRouter } from './TornadoRouter'
export * as factories from './factories'
export { ERC20__factory } from './factories/ERC20__factory'
export { ERC20Mock__factory } from './factories/ERC20Mock__factory'
@ -20,3 +21,4 @@ export { MulticallContract__factory } from './factories/MulticallContract__facto
export { RelayerRegistry__factory } from './factories/RelayerRegistry__factory'
export { TornadoInstance__factory } from './factories/TornadoInstance__factory'
export { TornadoProxy__factory } from './factories/TornadoProxy__factory'
export { TornadoRouter__factory } from './factories/TornadoRouter__factory'

View file

@ -2,7 +2,7 @@
import { DeepRequired, MarkOptional, Merge } from 'ts-essentials'
// Local types
import { TornadoInstance, TornadoProxy } from './deth'
import { TornadoInstance, TornadoRouter } from './deth'
// Monorepo
import { RelayerProperties as RelayerDataProperties } from '@tornado/sdk-data'
@ -29,6 +29,7 @@ export namespace Options {
export namespace Core {
export interface Deposit {
depositsPerInstance?: Array<number>
callInstanceDirectly?: boolean
doNotPopulate?: boolean
}
@ -145,9 +146,9 @@ export class Core extends Synchronizer {
return this.loadInstance(this.chain.id, token, denomination)
}
getProxy(): TornadoProxy {
this._checkProvider('getProxy')
return Contracts.getProxy(String(this.chain.id), this.chain.provider)
getRouter(): TornadoRouter {
this._checkProvider('getRouter')
return Contracts.getRouter(String(this.chain.id), this.chain.provider)
}
async createDepositProof(
@ -162,7 +163,6 @@ export class Core extends Synchronizer {
)[0]
}
// TODO: Abstract out verification parts of this and provide it as a standalone service in crypto or somewhere else
/**
* @param instance This is the Tornado Instance which will be withdrawn from.
* @param relayerProperties The properties of the relayer that is going to be used for the withdrawals. If the service fee is 0, it is assumed that there is no relayer, but that a manual wallet withdraw is being made. These properties are included in the ZK proof.
@ -180,12 +180,17 @@ export class Core extends Synchronizer {
): Promise<Array<Array<string>>> {
this._checkProvider('createDepositProofs')
// Extract commitments and nullifier hashes
/* ~~~~~~~~~~~~~~~~~~~~~~ EXTRACT NOTES, COMMITMENTS & BASIC CHECKS ~~~~~~~~~~~~~~~~~~~~~~ */
const hexCommitments: string[] = []
const hexNullifierHashes: string[] = []
const purchaseAmounts =
options?.ethPurchaseAmounts ?? new Array(depositInfo.length).fill(BigNumber.from(0))
// Inputs must equal in length
if (depositInfo.length !== recipientAddresses.length)
throw ErrorUtils.getError(
'Core.createDepositProofs: the number of recipients must equal the length of depositInfo.'
@ -196,27 +201,17 @@ export class Core extends Synchronizer {
'Core.createDepositProofs: if purchase amounts is specified, it must equal the length of depositInfo.'
)
// Extract all notes and commitments from the deposit info
depositInfo.forEach((deposit) => {
hexCommitments.push(deposit.hexCommitment)
hexNullifierHashes.push(deposit.hexNullifierHash)
})
// Determine cache name
const { network, token, denomination } = await Onchain.getInstanceLookupKeys(instance.address)
const name = 'Deposits' + (network + token + denomination).toUpperCase()
// Find all leaves & indices by reading from cache
const [leaves, leafIndices] = await this._findLeavesAndIndices(name, hexCommitments)
const invalidCommitments: string[] = []
this.emit(
'debug',
`\nFound leaves and indices, num leaves: ${leaves.length}, indices: [${leafIndices.join(', ')}]`
)
/* ~~~~~~~~~~~~~~~~~~~~~~ FETCH WHETHER SOME OR ALL NOTES HAVE BEEN SPENT ~~~~~~~~~~~~~~~~~~~~~~ */
// Determine whether we will be checking whether notes are spent
const checkSpent = options?.checkNotesSpent !== false
const spentNotes: string[] = []
this.emit('debug', `\nCheck spent notes? => ${checkSpent}`)
@ -225,10 +220,29 @@ export class Core extends Synchronizer {
if (checkSpent) this.emit('debug', `\nSpent array: [${checkSpentArray?.join(', ')}]`)
/* ~~~~~~~~~~~~~~~~~~~~~~ COLLECT LEAVES, ALL COMMITMENTS MUST HAVE A LEAF ~~~~~~~~~~~~~~~~~~~~~~ */
// Determine cache name
const { network, token, denomination } = await Onchain.getInstanceLookupKeys(instance.address)
const name = 'Deposits' + (network + token + denomination).toUpperCase()
// Find all leaves & indices by reading from cache
const [leaves, leafIndices] = await this._findLeavesAndIndices(name, hexCommitments)
this.emit(
'debug',
`\nFound leaves and indices, num leaves: ${leaves.length}, indices: [${leafIndices.join(', ')}]`
)
/* ~~~~~~~~~~~~~~~~~~~~~~ VALIDATE NOTES AND COMMITMENT ~~~~~~~~~~~~~~~~~~~~~~ */
// Check whether a commitment has not been found in all deposits, meaning that it is invalid
// Also add the invalid commitments. We can do leafIndices[i] because the matched one are concatenated
// at the start
const spentNotes: string[] = []
const invalidCommitments: string[] = []
for (let i = 0, len = depositInfo.length; i < len; i++) {
if (!leafIndices[i]) invalidCommitments.push(hexCommitments[i])
if (checkSpent && checkSpentArray![i]) spentNotes.push(hexNullifierHashes[i])
@ -251,6 +265,8 @@ export class Core extends Synchronizer {
: '')
)
/* ~~~~~~~~~~~~~~~~~~~~~~ BUILD MERKLE TREE & TEST VALIDITY ~~~~~~~~~~~~~~~~~~~~~~ */
// Otherwise, build the merkle tree from the leaves
const merkleTree = Primitives.buildMerkleTree({
height: options?.merkleTreeHeight ?? Constants.MERKLE_TREE_HEIGHT,
@ -268,6 +284,8 @@ export class Core extends Synchronizer {
'Core.createDepositProofs: the merkle tree created is not valid, something went wrong with syncing.'
)
/* ~~~~~~~~~~~~~~~~~~~~~~ PREPARE DATA FOR PROOF & BUILD PROOF ~~~~~~~~~~~~~~~~~~~~~~ */
// Rest of note invariant arguments
const inputsForProofs: InputFor.DepositProof[] = []
const gasPrice = options?.gasPrice ?? (await this.chain.getGasPrice())
@ -305,7 +323,7 @@ export class Core extends Synchronizer {
].join(', ')}]\n`
)
// Compute proofs
// Collect all data for proofs
for (let i = 0, len = depositInfo.length; i < len; i++) {
inputsForProofs.push({
public: {
@ -335,6 +353,7 @@ export class Core extends Synchronizer {
})
}
// Compute proofs and return
return await Primitives.calcDepositProofs(inputsForProofs)
}
@ -556,7 +575,7 @@ export class Core extends Synchronizer {
/**
* This is the main function which is used to build Tornado Cash Classic deposit transactions. An address need not be supplied because the returned note proves a deposit.
* @param instances The TornadoInstance instances for which to build transactions.
* @param options The number of deposits per instance, whether or not to populate the transactions (only in the sense of encoding transaction data), and whether to backup notes and invoices. Defaults: `depositsPerInstance = [1]*instance_num, doNotPopulate = false, backup { notes = true, invoices = false }`
* @param options The number of deposits per instance, whether or not to populate the transactions (only in the sense of encoding transaction data), whether to backup notes and invoices, and whether to call the instance directly instead of the router. Defaults: `depositsPerInstance = [1]*instance_num, doNotPopulate = false, callInstanceDirectly = false, backup { notes = true, invoices = false }`
* @returns A promise which resolves to the created transactions.
* @todo TODO: Maybe this should be sync and deposit backups should be async somewhere else
*/
@ -568,6 +587,8 @@ export class Core extends Synchronizer {
const depositsPerInstance = options?.depositsPerInstance ?? new Array<number>(instances.length).fill(1)
const callInstanceDirectly = options?.callInstanceDirectly ?? false
const doNotPopulate = options?.doNotPopulate ?? false
if (depositsPerInstance.length != instances.length)
@ -575,9 +596,7 @@ export class Core extends Synchronizer {
'Core.createDepositTx: number of deposit amount elements must equal the number of instances!'
)
const chainId = this.chain.id
const proxy: TornadoProxy = Contracts.getProxy(String(chainId), this.chain.provider)
const router: TornadoRouter = this.getRouter()
const txs: Array<Transactions.Deposit> = []
@ -591,15 +610,21 @@ export class Core extends Synchronizer {
if (!doNotPopulate) {
txs.push({
request: {
to: proxy.address,
data: proxy.interface.encodeFunctionData('deposit', [
instances[i].address,
deposit.hexCommitment,
[]
]),
value: token == 'eth' ? parseUnits(denomination) : BigNumber.from(0)
},
request: !callInstanceDirectly
? {
to: router.address,
data: router.interface.encodeFunctionData('deposit', [
instances[i].address,
deposit.hexCommitment,
[]
]),
value: token == 'eth' ? parseUnits(denomination) : BigNumber.from(0)
}
: {
to: instances[i].address,
data: instances[i].interface.encodeFunctionData('deposit', [deposit.hexCommitment]),
value: token == 'eth' ? parseUnits(denomination) : BigNumber.from(0)
},
note: pathstring + '_' + note,
invoice: pathstring + '_' + deposit.hexCommitment
})