SwiftRemit validates payout confirmation using a deterministic commitment proof.
When a remittance is created, the contract stores a PayoutCommitment (BytesN<32>) for that remittance ID. On confirm_payout(remittance_id, proof), the submitted proof is accepted only if it exactly matches the stored commitment.
If proof is required for the remittance (settlement_config.require_proof = true):
proof = None->MissingProofproof != stored_commitment->InvalidProofproof == stored_commitment-> payout can proceed
The commitment uses the same canonical hash as settlement IDs (SHA-256):
remittance_id(u64, big-endian)sender(Address, XDR bytes)agent(Address, XDR bytes)amount(i128, big-endian)fee(i128, big-endian)expiry(u64, big-endian,0ifNone)
Hash function: sha256(serialized_bytes).
Agents can generate the expected proof off-chain using remittance data:
proof = sha256(
remittance_id_be
|| sender_xdr
|| agent_xdr
|| amount_be
|| fee_be
|| expiry_be_or_zero
)
Submit that 32-byte hash as proof to confirm_payout.
- Proofs are remittance-specific because
remittance_idis part of the hash. - Duplicate payout is still blocked by settlement deduplication checks.
- Remittances without
require_proofremain backward compatible and do not require a proof.