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,
    },
  ],
});
ESC
Type to search