IPrivacy.withdrawWithAuthorization
withdrawWithAuthorization(
PrivacyWithdrawRequest request,
PrivacyActionAuthorization authorization
) external returns (bool) Withdraws funds from the shielded pool back to a transparent EVM recipient on behalf of an effectiveSender who signed an EIP-712 authorization. The executor (typically a relayer) submits the transaction; the precompile verifies the signature, enforces nonce / deadline replay protection, then performs the same nullifier-consuming withdraw state transition as the direct withdraw method. The amount field is a coin string parsed by the chain (e.g. "10000000000000000000aokrw" for 10 OKRW).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
request | PrivacyWithdrawRequest | ✓ | The shielded withdraw payload: proof, root, nullifier, amount (coin string, e.g. "10000000000000000000aokrw"), recipient (transparent EVM address), chainId, and expiresAtUnix. amount must fit the 64-bit shielded amount field — at most 2^64-1 aokrw = 18.446744073709551615 OKRW per operation; over that, request validation reverts with withdraw amount exceeds 64-bit shielded amount limit: invalid request before the proof is verified or the nullifier is consumed. The full failure list is on IPrivacy.withdraw; this method adds only the authorization checks. |
authorization | PrivacyActionAuthorization | ✓ | EIP-712 signed authorization from effectiveSender. executor must equal msg.sender; see privacy-authorization-eip712-domain for the canonical domain. |
Returns
Type:
bool Returns true on success. Failures revert.
Examples
Relayed withdraw of 10 OKRW
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const PRIVACY = "0x100000000000000000000000000000000000000b" as const;
const relayer = createWalletClient({
account: privateKeyToAccount(process.env.RELAYER_KEY as `0x${string}`),
transport: http("https://rpc-testnet.maroo.io"),
});
const withdrawRequest = {
proof: proofBytes,
root: merkleRoot,
nullifier: nullifierBytes,
amount: "10000000000000000000aokrw", // 10 OKRW
recipient: "0x1111111111111111111111111111111111111111", // TODO: replace before production
// The chain's Cosmos chain-id, EXACTLY. Fixed at genesis, exposed by no precompile, and
// a mismatch reverts with `withdraw chain id mismatch: expected <chain>, got <yours>`
// — which is how you find the right value. Never hardcode it.
chainId: process.env.COSMOS_CHAIN_ID as string,
expiresAtUnix: BigInt(Math.floor(Date.now() / 1000) + 300),
};
await relayer.writeContract({
address: PRIVACY,
abi: privacyAbi,
functionName: "withdrawWithAuthorization",
args: [
withdrawRequest,
{
effectiveSender,
executor: relayer.account.address,
nonce,
deadline: BigInt(Math.floor(Date.now() / 1000) + 300),
authorizationKind: 3, // withdraw
signature: eip712Signature,
},
],
});