Docs / NEAR settlement
Authorize and recover NEAR settlement
Carry an allocation into payments with explicit approval, durable identity and independent receipt checks.
Prepare from the recorded round
const plan = await settlementPlanFromTranscript(transcript, customMechanism);
const result = await executeWithSpendingPolicies(plan, {
transport, journal, approvals, resolveBuyerKey,
});
console.log(result.summary); // confirmed, pending, failed, paidOmit customMechanism for a built-in rule. Every payment carries a canonical integer amount. Version 1 IDs bind round and buyer; version 2 binds round, buyer and seller. Split plans must be atomically bound before execution.
Buyer-signed spending policy
const policy = {
roundId: plan.roundId,
buyerId: "buyer.example.testnet",
asset: plan.asset,
transportScope: transport.scope,
sellers: ["seller.example.testnet"],
maxAmount: "1000000000000000000000",
expiresAt: Date.now() + 300_000,
};
const bytes = spendingPolicyMessage(policy);
// Sign bytes with the trusted buyer Ed25519 approval key.
// Pass { policy, signature: Uint8Array } in approvals.The signature binds round, buyer, asset, transport, seller allowlist, cumulative cap and expiry. The runner checks approval before preparation and again before broadcasting. Trust the resolver, not a public key supplied by an agent request. These are application-enforced policies, not NEAR restricted access keys or an on-chain spending contract.
Native testnet NEAR
nearTestnetTransport accepts your exact-payment signer. The signer constructs one native transfer from buyer to seller. The transport checks finalized sender, recipient, amount and action before confirming. Use the native testnet asset constant and named testnet accounts. The packaged SDK’s main runtime has zero dependencies; the separate live example uses near-api-js.
Run the reference testnet validation
From the swarmkit-market repository, install dependencies and run:
npm run testnet -- --faucet-testnet --gpu
npm run testnet -- --faucet-testnet --split
npm run testnet:audit -- .market/testnet/<printed-account>/evidence.jsonThe first run provisions 20 buyers and five sellers; the second allocates one buyer across two sellers. Both use disposable faucet accounts, incremental SDK stages and actual native testnet transfers. The runner interrupts after journaling the first signed transaction, resumes, and audits each finalized sender, recipient and amount. Evidence and signed journals remain under ignored .market/testnet; only public evidence should be shared. Keys are memory-only: this bounded validation tool is not a persistent wallet service. No mainnet tokens are needed.
The 14 November validation finalized all 20 GPU payments (0.036 testnet NEAR) and both split payments (0.0014 testnet NEAR). These validate coordination-to-native-payment integration, not resource delivery or Intents. The browser credit economy remains separate.
NEAR Intents
nearIntentsTransport operates on supported NEP-141 balances held in the mainnet Verifier. Buyers need funded Verifier balances and recognized signing keys. A buyer callback signs the exact NEP-413 message; a relayer callback signs the execute_intents transaction. The adapter simulates each transfer before requesting the relayer signature, then checks finalized execution against the approved payment.
const transport = nearIntentsTransport({
asset: "nep141:wrap.near",
relayerId: "your-relayer.near",
signIntent: buyerNep413Signer,
signTransaction: relayerTransactionSigner,
});The callbacks above are application implementations. The operator CLI provides an implementation using near-api-js. A recipient receives a Verifier balance; withdrawing it is a separate operation. This adapter does not offer cross-chain routing or solver optimization.
Recovery states
| Observation | Behavior |
|---|---|
| No journal entry | Check authorization before preparing. |
| Pending recorded hash | Inspect it; rebroadcast only the same stored bytes if still authorized. |
| Final confirmed payment | Reconcile it; do not sign again. |
| Final failed payment | Report failure. Replacement is a separate explicit workflow. |
| Expired / ambiguous transaction | Retain the journal and reconcile. The runner does not automatically replace it. |
Independent audit
const report = await auditSettlement(transcript, receipts, {
verifier: transport,
});
console.log(report.claimedSummary, report.verifiedSummary);
console.table(report.checks);Without a verifier, the report checks recorded claims only. With one, it compares observed status and rejects reused transaction hashes. Independent transfers can settle partially; SwarmKit does not reverse a confirmed payment or guarantee resource delivery.