import { withdraw, RENT_FEE, FEE_RATE } from 'privacycash-evm'
const BRIDGE_URL = 'https://evm.privacycash.org/bridge'
const MINIMUM_BRIDGE_AMOUNT = 0.005 // ETH
/**
* Calculate how much ETH the relayer will actually receive after
* Privacy Cash withdrawal fees are deducted from the user's balance.
*/
function calculateWithdrawableAmount(totalAmount: number): number {
const flatFee = RENT_FEE // 0.00025 ETH
const rateFee = (totalAmount * FEE_RATE) / 10000 // 0.35%
return totalAmount - flatFee - rateFee
}
async function runBridge(address: string, signature: string) {
const totalWithdrawAmount = 0.1 // ETH you will deduct from your private balance
const recipientAddress = '0xRECIPIENT_ADDRESS' // destination address on output chain
if (totalWithdrawAmount < MINIMUM_BRIDGE_AMOUNT) {
throw new Error(`Minimum bridge amount is ${MINIMUM_BRIDGE_AMOUNT} ETH`)
}
// Net amount the relayer receives (after Privacy Cash fees)
const withdrawableAmount = calculateWithdrawableAmount(totalWithdrawAmount)
const params = {
inputChain: 'base',
outputChain: 'ethereum', // see supported chains above
inputTokenName: 'eth', // always 'eth' for Base
outputTokenName: 'eth', // token on the destination chain
inputTokenAmount: withdrawableAmount.toFixed(8),
refundAddress: address, // your Base address for refunds
recipientAddress, // destination address
quoteWaitingTimeMs: 3000, // recommended delay for best routing
}
// STEP 1: Get quote and relayer deposit address
const quoteResponse = await fetch(BRIDGE_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...params, step: 'quote' }),
})
const quoteData = await quoteResponse.json()
if (!quoteData.success) throw new Error(quoteData.error || 'Failed to get quote')
const depositAddress: string = quoteData.quote.depositAddress
console.log('Relayer deposit address:', depositAddress)
console.log('Estimated output:', quoteData.quote.amountOutFormatted)
// STEP 2: Withdraw to the relayer's deposit address on Base
const txHash = await withdraw({
withdrawAmountInput: totalWithdrawAmount,
recipient: depositAddress, // relayer's one-time Base address
keyBasePath: '/circuit',
signature,
address,
})
console.log('Withdrawal tx:', txHash)
// STEP 3: Notify the relayer of the transaction hash
const notifyResponse = await fetch(BRIDGE_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
txHash,
depositAddress,
step: 'send_tx',
}),
})
const notifyData = await notifyResponse.json()
if (notifyData.success) {
console.log('Bridge successfully initiated!')
} else {
console.error('Relayer notification failed:', notifyData.error)
}
}