The core privacy infrastructure that is used under the hood is provided by the Hinkal protocol
- User signs with injected EOA wallet
- Hinkal session is initialized from mnemonic + signer
- Public USDC can be shielded/unshielded
- Private supply executes two Emporium ops:
- transfer USDC to adapter
- call adapter
onPrivateDeposit
- Adapter routes supply into vault/Aave position
- Private borrow calls adapter
borrowToRecipientand credits borrowed WETH back to private balance - Private repay transfers WETH to adapter and calls
repayFromPrivate - Private withdraw calls adapter
withdrawToRecipientand returns output to private balance
Three addresses can differ:
- EOA signer (wallet account)
- Private address (derived from mnemonic, used for owner hash)
- Hinkal sub-account (deterministic key used for action signing)
Do not treat these as interchangeable
- Validates chain + adapter config.
- Checks private spendable balance
- Pre-estimates Hinkal fee and enforces a reserve guard
- Stores
withdrawAuthSecretlocally in session after position creation - Prints backup secret in CLI output after position creation (sensitive)
- Uses private destination flow (not public recipient):
- adapter op recipient is Emporium
- Hinkal
recipientDatais included for private credit
- Resolves
maxto exact on-chain position amount - Includes fallback retry with
amount - 1for Aave rounding edge case - Rotates secret on partial withdraw; removes on full close
- Prints rotated secret in CLI output after partial withdraw (sensitive)
- Requires adapter borrow-token allowlist (
setBorrowTokenAllowed) - Uses same per-position auth secret model as withdraw
- Borrows with Aave variable rate mode (2)
- Routes borrowed WETH to Emporium and credits private balance
- Rotates secret after successful borrow
- Prints rotated secret in CLI output after borrow (sensitive)
- Builds two Emporium ops:
- transfer WETH to adapter
- call
repayFromPrivate
- Uses same per-position auth secret model
- Pays Hinkal fee in USDC (same reserve guard policy)
- Rotates secret after successful repay
- Prints rotated secret in CLI output after repay (sensitive)
Hinkal fee is runtime-estimated (flatFee) and not fixed
WebCLI reserve policy:
reserve = flatFee + max(flatFee * bufferBps, minBuffer)- defaults:
bufferBps = 2000(20%)minBuffer = 0.002 USDC
User-visible lines are printed before submit:
Fee estimate (supply): flatFee=... reserve=... required=...Fee estimate (withdraw): flatFee=... reserve=... requiredPrivateBalance=...Fee estimate (borrow): flatFee=... reserve=... requiredPrivateUSDC=...Fee estimate (repay): flatFee=... reserve=... requiredPrivateUSDC=...
Browser session is encrypted in local storage via:
src/privacy/privacySession.ts- CLI output also includes
WithdrawAuth backuplines by design today. - Anyone with the latest secret for a position can execute auth-protected private actions for that position.
- Treat these secrets like private keys and keep logs/screenshots private.
Most common root cause: private spendable is below action amount plus fee reserve
adapter.privacyExecutor() must match configured Emporium
Often allowance/token routing mismatch in adapter path; inspect preflight logs
Adapter must allowlist configured WETH via setBorrowTokenAllowed.