The deposit flow is for the bridge is simple. The user sends native USDC to the bridge and it is credited to the account that sent it in less than 1 minute. The minimum deposit amount is $5. If you send an amount less than this it will not be credited and be lost forever.
Withdraw
The withdrawal flow requires a user wallet signature on the L1 only, and no Arbitrum transaction. The withdrawal from Arbitrum is handled entirely the validators, and the funds arrive in the user wallet in 3-4 minutes. This payload for signTypedData is
{
"action": {
"type": "withdraw3",
"signatureChainId": "0xa4b1",
"hyperliquidChain": "Mainnet" or "Testnet"
"destination": "0x000....0",
"amount": "12.3",
"time": 1698693262
},
"nonce": 1698693262 // IMPORTANT: this must match "time",
"signature": {"r": ..., "s": ..., "v": ... } // signedTypedData output based on Eip712 implementation above. See python sdk for equivalent python code
}
Deposit with permit
The bridge supports depositing on behalf of another user via the batchedDepositWithPermitfunction. Example code for how the user can sign the PermitPayload
const payload: PermitPayload = {
owner, // The address of the user with funds they want to deposit
spender, // The address of the bridge 0x2df1c51e09aecf9cacb7bc98cb1742757f163df7 on mainnet and 0x279c9462FDba349550b49a23DE27dd19d5891baA on testnet
value,
nonce,
deadline,
};
const isMainnet = true;
const domain = {
name: isMainnet ? "USD Coin" : "USDC2",
version: isMainnet ? "2" : "1",
chainId: isMainnet ? 42161 : 421614,
verifyingContract: isMainnet ? "0xaf88d065e77c8cC2239327C5EDb3A432268e5831" : "0x1870Dc7A474e045026F9ef053d5bB20a250Cc084",
};
const permitTypes = {
Permit: [
{ name: "owner", type: "address" },
{ name: "spender", type: "address" },
{ name: "value", type: "uint256" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" },
],
};
const dataToSign = {
domain,
types: permitTypes,
primaryType: "Permit",
message: payload,
} as const;
const data = await walletClient.signTypedData(dataToSign);
const signature = splitSig(data);