WHAT IT IS
A payer-side Gate, not a facilitator or payment rail
The Gateway consumes verified authority, obtains one signed provider-bound permit and atomically redeems it through a live PROCESSOR credential. Only a fresh redemption unlocks the adapter. It then checks a fresh x402 v2 PAYMENT-REQUIRED challenge, asks the customer's compatible x402 v2 client to create one exact EIP-3009 payload and attempts one paid HTTP request. It does not replace an x402 resource server, facilitator, wallet, RPC provider or token contract.
DOWNLOAD
Pin and verify both execution modules
curl --proto '=https' --tlsv1.2 -fsSLO https://mandateshield.com/sdk/v1.10.0/mandateshield-gateway.mjs
curl --proto '=https' --tlsv1.2 -fsSLO https://mandateshield.com/sdk/v1.10.0/mandateshield-x402-v2-exact.mjs
curl --proto '=https' --tlsv1.2 -fsSLO https://mandateshield.com/sdk/v1.10.0/mandateshield-gateway.d.ts
curl --proto '=https' --tlsv1.2 -fsSLO https://mandateshield.com/sdk/v1.10.0/mandateshield-x402-v2-exact.d.ts
curl --proto '=https' --tlsv1.2 -fsSLO https://mandateshield.com/sdk/v1.10.0/SHA256SUMS
if command -v sha256sum >/dev/null 2>&1; then
grep -E ' mandateshield-(gateway|x402-v2-exact)\.(mjs|d\.ts)$' SHA256SUMS | sha256sum -c -
else
grep -E ' mandateshield-(gateway|x402-v2-exact)\.(mjs|d\.ts)$' SHA256SUMS | shasum -a 256 -c -
fiThe versioned files are listed with byte-verifiable SHA-256 digests in SHA256SUMS. The rolling SDK path may change and should not be used for a pinned production deployment.
INTEGRATE
Keep every payment credential inside the trusted Gate
import { createMandateShieldGateway } from "./mandateshield-gateway.mjs"
import {
createX402HttpRequestBinding,
createX402V2ExactEip3009Adapter,
X402_EXECUTION_PROFILE
} from "./mandateshield-x402-v2-exact.mjs"
const requestBinding = await createX402HttpRequestBinding({
url: "https://reports.example/quarterly",
method: "GET",
headers: { accept: "application/pdf" }
})
const finalEnvelope = {
...finalPurchaseFacts,
http_request: requestBinding.http_request
}
// Sign and strictly verify finalEnvelope before Gate execution.
const x402 = createX402V2ExactEip3009Adapter({
providerEnvironment: "live",
providerAccount: "agent-payer-production",
x402Client: compatibleX402V2Client,
artifactJournal: encryptedGlobalLinearizableArtifactJournal,
verifyAuthorization: configuredEip3009SignatureVerifier,
captureSubmissionAnchor:
configuredLatestBlockHashPinnedUnusedNonceVerifier,
verifySettlement: configuredChainVerifier,
trustedAssets: [{
network: "eip155:8453",
asset: process.env.USDC_TOKEN_ADDRESS,
name: "USD Coin",
version: "2",
asset_decimals: 6
}],
trustedPayees: [{
merchant_id: "merchant_reports",
network: "eip155:8453",
pay_to: process.env.REPORTS_PAYEE_ADDRESS,
resource_origin: "https://reports.example"
}],
trustedPayers: [{
network: "eip155:8453",
asset: process.env.USDC_TOKEN_ADDRESS,
payer: process.env.AGENT_PAYER_ADDRESS
}],
minimumConfirmations: 2
})
const gateway = createMandateShieldGateway({
journal: globalLinearizableGatewayJournal,
// Must use a live PROCESSOR key whose audience is the value below.
// The client must implement transitionExecutionAuthorization() and
// redeemExecutionPermit().
mandateShield: processorClient,
provider: x402
})
const result = await gateway.execute({
receipt_id: reservation.signed_receipt.receipt_id,
compact: reservation.signed_receipt.compact,
expected_envelope: finalEnvelope,
expected_audience: "https://gate.example/x402",
provider_input: {
profile: X402_EXECUTION_PROFILE,
payment_required: originalPaymentRequired,
selected_accept_index: 0,
request: requestBinding.request
}
})The signed x402 payload is stored before transmission in the customer-controlled artifact journal. Treat that payload as a payment credential: encrypt it at rest, restrict access and never send it to MandateShield or public logs.
The named clients, globally shared linearizable journals and verification callbacks in the example are customer-supplied trusted components. Both journals must declare GLOBAL_SHARED_LINEARIZABLE, and all regions and workers must actually share the same namespace; the declaration is not an independent storage attestation. The EIP-3009 verifier must recover the signer locally; the chain verifier must query the configured network and enforce the public verifier contract. Its pre-submission callback must read the latest canonical head and query nonce state at that exact block hash with a require-canonical guard; it must never submit a transaction.
providerEnvironment and providerAccount are non-secret, stable identifiers bound into the signed permit. The account identifier names the customer-controlled x402 processing configuration; it must not contain a wallet private key, API token or other credential.
EXACT BINDINGS
The payment cannot silently move to another action
- x402 version 2, HTTP transport and
exactscheme. - EIP-155 network and EIP-3009 token domain.
- Signed atomic amount, token address and
payTo. - Exactly one Gate-configured payer per network and asset, followed by local EIP-3009 signer recovery and durable payload binding.
- Merchant identity plus trusted resource origin.
- Canonical URL, HTTP method, body-byte digest and canonical allowed-header projection digest.
- Redirects disabled for both challenge and paid requests.
- Generic Gate journal identity also binds the complete
provider_input. - The adapter emits an
X402_V2_EXACTprovider binding containing the environment, processing-account identifier, one-request identifier, signedpayTodestination, method, canonical HTTPS resource and exact body digest. - Provider submission remains locked until MandateShield returns a fresh atomic redemption with a credential-bound claim ID. A replayed, expired, mismatched or unavailable redemption reaches neither the x402 challenge nor the paid request.
- The fresh
CONSUMEresult's exactsettlement_deadline_atis bound into the Gate context, journal identity and signed-payload artifact. - The artifact binds both
payload_digestandauthorization_digest, plus the exact nonce,valid_afterandvalid_before. - One journal shared by every Gate for the same payer must atomically implement
claimUniqueAuthorization. The network, token, payer and nonce ownership key may belong to only one receipt-bound artifact. - Before
TRANSMITTING, the journal stores the latest canonical, block-hash-pinnedNONCE_UNUSED_ANCHORand its request and acceptance timestamps. - Signing requires at least 180 seconds of settlement-release headroom. The EIP-3009
valid_beforeboundary must leave that same headroom before the settlement deadline.
FAILURE SEMANTICS
An uncertain signature is never silently retried or released
A missing or uncertain execution-permit redemption locks the execution before any x402 network request. After a fresh redemption but before the paid request starts, a failed challenge, signing, signature verification or payload validation is definitively NOT_SUBMITTED. Once the paid request may have left the Gate, timeouts, malformed responses, repeated 402 responses and incomplete chain evidence remain UNKNOWN or PENDING. The adapter does not resend that paid request.
COMMIT requires the customer's configured chain verifier to decode transferWithAuthorization from the canonical transaction and bind the canonical transaction, block, network, token, payer, payee, amount, nonce, authorization digest, payload digest, validity window and minimum confirmation count. The settlement block must be strictly later than the stored anchor, and the verifier must establish that the exact anchor hash remains its canonical ancestor. Caller-supplied settlement fields are not independent proof.
The hosted path begins by reporting the transaction hash as payment_reference with the exact provider_submission_id, permit_id, claim_id and a bounded caller outcome to POST /api/v2/provider-submissions. That report is onlyCALLER_ASSERTED input. MandateShield independently queries the configured EVM RPC, checks the canonical block and minimum confirmations, and binds the exact token, payer, payee, amount and Transfer log.
An exact finalized transfer, or a confirmed reverted transaction, can produce CHAIN_FINALIZED evidence with independent_verification=true and autonomously COMMIT or RELEASE. Insufficient confirmations, RPC unavailability, canonical-chain changes and binding conflicts remain pending or conflicting. They stay fail-closed for reconciliation and never authorize a retry.
Release after transmission is possible only when a sufficiently confirmed canonical block after valid_before proves the exact nonce remained unused and that UNUSED_EXPIRED evidence is accepted before the bound settlement deadline. That proof must also revalidate the stored anchor as a canonical ancestor. After that deadline, absence evidence remains UNKNOWN and the reservation stays conservatively charged. A later canonical CONFIRMED transfer may still close SETTLEMENT_UNKNOWN as committed; it can never justify a late release.
PINNED COMPATIBILITY
Tested packages with pinned specification references
The compatibility test uses @x402/core 2.19.0 and @x402/evm 2.19.0 from the release lockfile. It exercises those installed package interfaces and the exact/EIP-3009 payload shape. The specification links below are pinned separately to a reviewable source commit; the test does not build that commit or prove package-to-source correspondence. This is not an x402 Foundation certification, partnership or live-chain audit.
PUBLIC CONTRACTS
Review the state and storage boundary before integration
HONEST BOUNDARY
What this release does not claim
This profile does not claim support for every x402 scheme, extension, chain or token. A server-reported PAYMENT-RESPONSE is not treated as independent proof. This is not an x402 Foundation partnership or certification, a live settlement service, an exactly-once HTTP guarantee, an RPC uptime promise or an independent security audit.
Signed provider permits require canonical HTTPS resources and the permit profile supports GET, POST, PUT and PATCH. The standalone HTTP binding helper can model loopback requests when explicitly enabled, but the signed Gateway deliberately rejects plain HTTP, HEAD and DELETE before CONSUME.