description |
---|
The types used within the different library methods |
enum TxType {
Deposit,
Transfer,
Withdraw,
BridgeDeposit,
}
TxType.Deposit
: the deposit via token approval
{% hint style="warning" %}
The type TxType.Deposit
is supported but isn't in active use because it requires an extra approve transaction from the user. Use TxType.BridgeDeposit
instead.
{% endhint %}
TxType.Transfer
: move tokens inside a pool to the destination zk-addressesTxType.Withdraw
: withdrawal tokens from the pool to the destination 0x-addressTxType.BridgeDeposit
: deposit tokens to the privacy pool via permit scheme (the primary type for deposit tx)
interface RelayerFee {
fee: {
permittableDeposit: bigint;
transfer: bigint;
withdrawal: bigint;
deposit: bigint;
};
oneByteFee: bigint;
nativeConvertFee: bigint;
}
where
fee
- base cost of the transaction execution depending on the transaction type.
{% hint style="info" %}
In most cases of deposit fee.permittableDeposit
is used instead of fee.deposit
(because the 2nd one belongs to the deposits via approve which is not currently used on the deployed pools)
{% endhint %}
oneByteFee
- calldata byte cost (may be zero depended on relayer configuration).nativeConvertFee
- additional cost needed to swap withdrawn tokens to native coins (only for the withdrawal transactions).
interface FeeAmount {
total: bigint;
txCnt: number;
calldataTotalLength: number;
relayerFee: RelayerFee;
insufficientFunds: boolean;
}
where
total
- absolute fee value needed to process request (in pool dimension)txCnt
- number of transactions needed to process requestcalldataTotalLength
- number of calldata bytes occupied by all transactionsrelayerFee
- RelayerFee which was used for fee estimationinsufficientFunds
- true when the local balance is insufficient for requested tx amount
interface Limit {
total: bigint;
available: bigint;
}
interface PoolLimits {
deposit: {
total: bigint;
components: {
singleOperation: bigint;
dailyForAddress: Limit;
dailyForAll: Limit;
poolLimit: Limit;
};
}
withdraw: {
total: bigint;
components: {
dailyForAll: Limit;
};
}
dd: {
total: bigint;
components: {
singleOperation: bigint;
dailyForAddress: Limit;
};
}
tier: number;
}
where
Limit
- is an abstract limit withtotal
andavailable
tokens in the pool dimensionPoolLimits.deposit
- limits for deposit from the specified addresstotal
- total available to deposit from specified address right nowcomponents.singleOperation
- maximum deposit amount in the single txcomponents.dailyForAddress
- deposit limit for the specified address during that daycomponents.dailyForAll
- deposit limit for any address during that daycomponents.poolLimit
- TVL limit
PoolLimits.withdraw
- limits for withdrawal transactiontotal
- total available to withdraw right nowcomponents.dailyForAll
- withdraw limit for any address during that day
PoolLimits.dd
- limits for direct deposit transactiontotal
- total available to direct deposit right nowcomponents.singleOperation
- maximum direct deposit amount in the single txcomponents.dailyForAddress
- direct deposit limit for the specified address during that day
tier
- provided address tier (the higher tier - the higher limits), default 0
enum ProverMode {
Local,
Delegated,
DelegatedWithFallback
}
Local
- use local prover (most secure)Delegated
- use external proving machine (aka Delegated Prover)DelegatedWithFallback
- work primarily in Delegated mode; switch to Local is Delegated is unavailable
interface TreeState {
root: bigint;
index: bigint;
}
where
root
- Merkle root value (assuming all leaves placed at indices greater than or equal toindex
should be zeroed)index
- the index in Merkle tree where the next transaction will be placed
const exampleState: TreeState = {
root: 20259123668790783065614334268308370728058669663334716067122266810210516357394n,
index: 533760n
}
class GiftCardProperties {
sk: Uint8Array;
birthIndex: number;
balance: bigint;
poolAlias: string;
}
where
sk
- spending key (keep it in secret: everybody who know the key is able to use the gift-card's funds)birthIndex
- index in Merkle tree where gift-card was created. It's needed to speed-up card redeeming processbalance
- preassigned card balance in pool dimension (it's not an actual balance, just a label for smooth UI)poolAlias
- the card destination privacy pool name (it should be defined in client configuration)
It's a common interface to keep external service version information. Currently external service include relayer and delegated prover
interface ServiceVersion {
ref: string;
commitHash: string;
}
where
- ref - short version string (e.g.
3.1.0
) - commitHash - corresponded commit hash in version control system (e.g.
4535bc9592057706614d62889713be2ba9555838
)
A single history record always describes a single transaction to the pool.
enum HistoryTransactionType {
Deposit = 1,
TransferIn,
TransferOut,
Withdrawal,
AggregateNotes,
DirectDeposit,
}
enum HistoryRecordState {
Pending = 1,
Mined,
RejectedByRelayer,
RejectedByPool,
}
interface TokensMoving {
from: string,
to: string,
amount: bigint,
isLoopback: boolean,
ddFee?: bigint,
}
class HistoryRecord {
type: HistoryTransactionType,
timestamp: number,
actions: TokensMoving[],
fee: bigint,
txHash: string,
state: HistoryRecordState,
failureReason?: string,
extraInfo?: any,
}
where
HistoryTransactionType
describes all possible transaction typesHistoryRecordState
describes the transaction state.Pending
state means tx was sent to the relayer but not mined on the pool contract yet. The transaction inHistoryRecordState.Mined
state is a finalized one.HistoryRecordState.RejectedByRelayer
andHistoryRecordState.RejectedByPool
reflect transactions which wasn't completedTokensMoving
is an universal interface describing tokens amount and direction. A single history record may contain a fewTokensMoving
objectsTokensMoving.from
andTokensMoving.to
contain origin and destination addresses of the funds transferring. There are no strict restrictions for these fields. E.g.TokensMoving.to
field may contain0x
address for the withdrawal transaction as well as shielded address for the outgoing transfers inside a privacy pool. Due to privacy transactions nature one of these fields are always void stringTokensMoving.amount
is a token transferring value in the pool dimensionTokensMoving.isLoopback
is applicable for the outgoing transfers only. This field contain true in case of transferring funds to the own accountTokensMoving.ddFee
is an optional field which exists only for direct-deposit associated transactions and contains a direct deposit fee amount
HistoryRecord.type
is one of theHistoryTransactionType
enum membersHistoryRecord.timestamp
is an associated transaction time (in seconds since Jan 01 1970)HistoryRecord.actions
is a set of token moves (e.g. a multitransfer transaction may contain several destination addresses)HistoryRecord.fee
is a transaction cost (relayer's reward) in pool token dimension. The incoming transfers always have zero in this fieldHistoryRecord.txHash
is an associated transaction hash (to the pool smart contract)HistoryRecord.state
is a transaction state (anHistoryRecordState
member)HistoryRecord.failureReason
is an optionalstring
field which contain a problem description in case the history record is in a rejected stateHistoryRecord.extraInfo
is an optional field of any type which may contain transaction related info. For example, direct deposits made with the payment link may contain the following object in that field:
interface DDPaymentInfo {
note: string | null;
sender: string;
token: string;
}
The compliance history record provides additional details than the regular history record. It contains fields needed to provide evidence of historical ownership. Anyone can provide a regular history to the 3rd parties. But only the compliance-based history proves the records are unmodified and that all of them belong to the concrete account.
class ComplianceHistoryRecord extends HistoryRecord {
public index: number;
public nullifier?: Uint8Array;
public nextNullifier?: Uint8Array;
public encChunks: { data: Uint8Array, index: number }[];
public ecdhKeys: { key: Uint8Array, index: number }[];
public acc?: Account;
public notes: { note: Note, index: number }[];
public inputs?: {
account: {index: number, account: Account},
intermediateNullifier: string,
notes: {index: number, note: Note}[],
};
}
where
-
index
- the transaction index in the Merkle tree (the first leaf index) -
nullifier
- transaction nullifier needed to chain the transaction sequence (undefined
for incoming transfers) -
nextNullifier
- the nullifier based on the transaction output account (will be used in the next transaction) -
encChunks
- encrypted elements (a chunk corresponds to encrypted account or note) -
ecdhKeys
- keys to decrypting chunks at the corresponding indexes -
acc
- decrypted output account (undefined
for incoming transfers) -
notes
- a set of decrypted notes -
inputs
- transaction inputs (undefined for incoming txs)-
account
- decrypted input account (the first transaction has always zero account in that field) -
intermediateNullifier
- a nullifier pre-image, may be safely disclosed to 3rd parties without sharing intermediate key$$\eta$$ . Used to calculate nullifier in conjunction with input account. -
notes
- set of decrypted input notes which were aggregated to the account balance
-
The shielded address decomposition on the low-level components (see shielded address structure for details)
interface IAddressComponents {
format: string;
d: string;
p_d: string;
checksum: Uint8Array;
pool_id: string;
derived_from_our_sk: boolean;
is_pool_valid: boolean;
}
where
-
format
is one of the following values:-
'old'
- prefix-less address format, deprecated -
'pool'
- pool-specific address which should be used on the concrete privacy pool -
'generic'
- universal address which may be used on any pool
-
-
d
- address diversifier (a random number, decimal string) -
p_d
- diversifier public part (derived from the diversifier and account intermediate key$$\eta$$ , decimal string) -
checksum
- 4 bytes to verify address correctness -
pool_id
- the pool ID in string representation which the address belongs to ('any'
for generic addresses) -
derived_from_our_sk
- indicating is it own address -
is_pool_valid
- indicating is the address can be used on the current pool
The signature can be requested from the user during depositing funds into the shielded pool. The following interface describes request details. There are two signature types which can be requested depends on the deposit scheme (deposit scheme defined in the pool configuration)
enum SignatureType {
PersonalSign, // signature for deposit-via approve
TypedDataV4, // permit deposit scheme
}
interface SignatureRequest {
type: SignatureType,
data: any, // an string for personal sign, object for typed signatures
}
where
-
format
is one of the following values:-
'old'
- prefix-less address format, deprecated -
'pool'
- pool-specific address which should be used on the concrete privacy pool -
'generic'
- universal address which may be used on any pool
-
-
d
- address diversifier (a random number, decimal string) -
p_d
- diversifier public part (derived from the diversifier and account intermediate key$$\eta$$ , decimal string) -
checksum
- 4 bytes to verify address correctness
The following object is used to describe transfers inside a privacy pool or withdrawal directional in some cases
interface TransferRequest {
destination: string;
amountGwei: bigint;
}
where
destination
is an address of funds receiver (shielded or0x
)amountGwei
- token amount in pool dimension
The following object describes configuration of the single transfer/withdrawal transaction to the privacy pool
interface TransferConfig {
inNotesBalance: bigint;
outNotes: TransferRequest[];
calldataLength: number;
fee: bigint;
accountLimit: bigint;
}
where
inNotesBalance
is a sum of input note values which will be aggregated on the account when transaction processedoutNotes
- set of transfer requests processed with the transactioncalldataLength
- transaction's calldata bytes countfee
- absolute transaction fee (in pool dimension)accountLimit
- minimum account remainder after transaction (not in use currently, always0n
)
enum DirectDepositType {
Token,
Native
}
Token
- sending token to the poolNative
- sending native coins to the pool (available only for pools which are serve the native wrapped token like WETH)
{% hint style="info" %}
DirectDepositType.Native
is only available for pools which are serve the native wrapped token like WETH. Such pools must have isNative = true
in the theclient-configuration.md
{% endhint %}
The following object describes direct deposit transaction in the different states
enum DirectDepositState {
Queued, // was sent to the DD queue contract
Deposited, // was included in the privacy pool's state
Refunded, // was returned to the fallback address
}
interface DirectDeposit {
id: bigint;
state: DirectDepositState;
amount: bigint;
destination: string;
fallback: string;
timestamp: number;
queueTxHash: string;
}
where
id
unique DD identifierstate
- Queued/Deposited/Refudedamount
- DD value (in pool dimension, without fee)destination
- zk-address in the privacy pool to be depositedfallback
-0x
address to refund DD in case of it wasn't processed in timetimestamp
- when it got into the current statequeueTxHash
- initial transaction hash
Ephemeral addresses are used in the external deposit scheme. This is an EOA with the key management inside the library
interface EphemeralAddress {
index: number;
address: string;
tokenBalance: bigint;
nativeBalance: bigint;
permitNonce: number;
nativeNonce: number;
}
where
index
- index of address inside a pool (last HD path component)address
- 0x native addresstokenBalance
- token balance in pool dimension (meaning the token on which the pool operates)nativeBalance
- native address balance in weipermitNonce
- number of executed permit allowances (token transfers)nativeNonce
- number of outgoing native transactions
interface SyncStat {
txCount: number;
cdnTxCnt: number;
decryptedLeafs: number;
fullSync: boolean;
totalTime: number;
timePerTx: number;
}
where
txCount
- total transactions fetched (relayer + CDN)cdnTxCnt
- number of transactions fetched in binary format from CDN (cold storage)decryptedLeafs
- number of loaded leafs in the Merkle tree (deposit/withdrawal = 1 leaf, transfer = 1 + notes_cnt leafs)fullSync
-true
in case of bulding full Merkle tree on the clienttotalTime
- syncing time in millisecondstimePerTx
- average time per transaction in milliseconds
The callback is used to notify the application that the internal state has been updated. There are regular and continuous states. The second one has a progress
property (a number from 0 to 1).
type ClientStateCallback = (state: ClientState, progress?: number) => void;
enum ClientState {
Initializing,
AccountlessMode,
SwitchingPool,
AttachingAccount,
// the following routines belongs to the full mode only
FullMode,
StateUpdating, // fast sync
StateUpdatingContinuous, // sync which takes longer than threshold
HistoryUpdating,
}
The following client library states distinguished:
Initializing
- the state during the client instantiation. This state is short-term. After client initialization the state sets toAccountlessMode
AccountlessMode
- the client library is ready to operate but no account was attached. Limited functionality is available in that state (see account-less-mode-operations)SwitchingPool
- the client switches current privacy pool. Most routines are unavailable during this stateAttachingAccount
- the user account is initializing. This state also appears on pool switching when the client operates in full mode (if account was already attached to another pool it should be reattached to the new one)FullMode
- Regular state: client and account are ready to operate. All routines are availableStateUpdating
\StateUpdatingContinuous
- the client is syncing the user account state with the pool. The continuous state using in case of state sync take over threshold (1 sec currently)HistoryUpdating
- the history synchronization. Additional activities are needed to produce history records from the local state so it may take some time.
Forced exit is an optional pool contract feature for emergency withdraw of user funds if the relayer is unavailable.
enum ForcedExitState {
NotStarted,
CommittedWaitingSlot,
CommittedReady,
Completed,
Outdated,
}
where:
NotStarted
- the regular account state: forced exit was not initiatedCommittedWaitingSlot
- forced exit was committed (the first stage) but the exit window isn't opened yet (and you cannot send the execute transaction)CommittedReady
- the first stage (commit) was performed and exit window is available, so you are able to execute your committed forced exit nowCompleted
- the forced exit was executed and the account was destroyedOutdated
- forced exit was committed but the exit window has passed. You cannot execute a forced exit but you can cancel it and create a new one.
The committed forced exit retrieved from the pool contract
interface CommittedForcedExit {
nullifier: bigint;
to: string;
operator: string;
amount: bigint;
exitStart: number;
exitEnd: number;
txHash: string;
}
where:
nullifier
- the last account nullifier which was marked for forced exitto
- an address to withdraw fundsoperator
- address who allowed to execute forced exit (no execution limitations in case of operator equals zero address)amount
- value to withdraw (in pool dimension)exitStart
- timestamp when exit window opened (in seconds)exitEnd
- timestamp when exit window closed (in seconds)txHash
- commit transaction hash
The executed or cancelled forced exit retrieved from the pool contract
interface FinalizedForcedExit {
nullifier: bigint;
to: string;
amount: bigint;
cancelled: boolean;
txHash: string;
}
where:
nullifier
- the last account nullifier associated with the forced exitto
- an address to withdraw fundsamount
- value to withdraw (in pool dimension)cancelled
- false for successful forced exit, true for canceled onetxHash
- execute transaction hash
The following interface describes the transaction request which should be sent by the superior user or application. It can be approve or direct deposit transaction. For example:
interface PreparedTransaction {
to: string;
amount: bigint;
data: string;
selector?: string;
}
where:
to
- transaction destination addressamount
- amount of native coins to be sent with transactiondata
- prepared raw transaction data (depends on underlying blockchain)selector
- an optional field which can be used on some chains (e.g. Tron) where selector is separated from transaction data (for EVM networks selector is included indata
field so that field remainsundefined
)