Problem
The @suimpp/mpp server verify() callback checks the transaction on-chain (succeeded, right recipient, right amount) but does not track used digests. The same TX digest could be presented against multiple challenges — paying once but consuming multiple API calls.
Context
mppx already solves this for the tempo method with assertHashUnused / markHashUsed + a store interface. The same pattern should be added to the sui method.
Proposed Solution
Add digest tracking to @suimpp/mpp/server:
-
Add an optional store interface to SuiServerOptions:
interface DigestStore {
has(digest: string): Promise<boolean>;
set(digest: string): Promise<void>;
}
-
In verify(), before returning the receipt:
- Call
store.has(digest) — if true, throw "Digest already used"
- Call
store.set(digest) — mark as consumed
-
Provide a default in-memory store (Map with TTL) for single-instance deployments
-
Allow custom stores (Redis, DB) for multi-instance / serverless deployments
References
- mppx tempo implementation:
assertHashUnused / markHashUsed pattern
- Current verify:
packages/mpp/src/server.ts lines 39-119
Problem
The
@suimpp/mppserververify()callback checks the transaction on-chain (succeeded, right recipient, right amount) but does not track used digests. The same TX digest could be presented against multiple challenges — paying once but consuming multiple API calls.Context
mppx already solves this for the
tempomethod withassertHashUnused/markHashUsed+ a store interface. The same pattern should be added to thesuimethod.Proposed Solution
Add digest tracking to
@suimpp/mpp/server:Add an optional
storeinterface toSuiServerOptions:In
verify(), before returning the receipt:store.has(digest)— if true, throw "Digest already used"store.set(digest)— mark as consumedProvide a default in-memory store (Map with TTL) for single-instance deployments
Allow custom stores (Redis, DB) for multi-instance / serverless deployments
References
assertHashUnused/markHashUsedpatternpackages/mpp/src/server.tslines 39-119