Skip to main content
A protected transfer locks USDC in a contract instead of sending it straight to an address. The recipient claims it with a secret; if the address was wrong or poisoned, the wrong party cannot claim and you reclaim. It replaces the “send $1 first and wait” ritual. The send form

Send

Give the recipient secret.secret, the grouped 16-character string. It carries all 80 bits and the salt is derived from it, so that one string is the whole credential. Anyone can submit the claim, but the funds always go to the recorded recipient, so a claim is front-run-safe. The money locked, waiting for the secret Every open transfer stays visible and cancellable while it waits. Active transfers

Claim

The recipient types the string; fromSecret turns it back into the pair the contract wants. Entering the secret
Claimed
A wrong code does not revert on chain; the contract returns false and counts an attempt, because the attempt counter has to survive for the five-guess lockout to bind. So a mined transaction is not proof of success. The SDK’s claim reads the receipt and throws WrongClaimCodeError (carrying attemptsRemaining) or TransferLockedError; on success it returns the transaction hash. Never treat a mined tx as a claim.

Cancel and refund

Unclaimed money belongs to the sender. There is no deadline on getting it back.

cancel(transferId)

Sender only, allowed any time before a claim lands, and on a locked transfer.

reclaimExpired(transferId)

Callable by anyone once the recall window lapses; funds only ever go back to the sender. No keeper required.

Approve-less sends

To skip a per-send approve, use Permit2: one-time approvePermit2(clients), then sendProtectedWithPermit signs an off-chain permit per send.