fix(checkout): submit real batch purchase transaction - #972
Merged
nanaf6203-bit merged 1 commit intoAug 29, 2026
Merged
Conversation
Completes the batch checkout integration started in MettaChain#960 by wiring a real wagmi/viem executor. When a batch-purchase contract address is configured, executeBatchPurchase now resolves the connected wallet client, submits the batchPurchase call with per-item slippage-protected minimum amounts, and only reports success after the transaction receipt is observed on chain. The default path fails closed with a configuration error when no contract address is set, and disconnected wallets are rejected before any submission. The timeout/Math.random simulation is not reintroduced anywhere. Closes MettaChain#813
nanaf6203-bit
approved these changes
Aug 29, 2026
🔒 Preview Environment DestroyedThe preview environment for this PR has been torn down. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #813
The cart checkout path now submits a real batch purchase transaction instead of fabricating a result.
BatchTransactionService.executeBatchPurchaseresolves a wagmi/viem executor backed by the connected wallet: it validates the cart and wallet first, submits thebatchPurchasecontract call with the per-item slippage-protected minimum amounts, and only reportssuccess: trueafter the transaction receipt is observed on chain.Why
Previously (before #960) checkout waited on a timer, rolled
Math.random()to pick success/failure, and returned a generated0x...hash without touching a wallet or chain — users saw a "confirmed" purchase that never happened. #960 removed the simulation and added an executor seam, but deferred the actual submission. This PR completes the seam: when a deployed batch-purchase contract address is configured (NEXT_PUBLIC_BATCH_PURCHASE_ADDRESS), checkout really submits; when it is not configured, checkout fails closed with an explicit configuration error. There is no code path that returns a fabricated hash.What was built
src/lib/batchTransaction.tsexecuteBatchPurchasenow defaults to the configured real executor (injected executor still supported for tests), includes the property token address in the request, and keeps receipt-gated success, decoded revert/user-rejection handling, and fail-closed behavior.src/lib/batchPurchaseExecutor.tswriteContractwithbatchPurchase(propertyTokens[], quantities[], minAmounts[], deadline)and the quoted total asvalue, thenwaitForTransactionReceipt— success is only reported after the receipt.src/config/batchPurchase.tsBATCH_PURCHASE_ABIandgetBatchPurchaseContractAddress(), which readsNEXT_PUBLIC_BATCH_PURCHASE_ADDRESSand returnsnullwhen unset/malformed so checkout fails closed.src/lib/__tests__/batchTransaction.test.ts@wagmi/core/actions(wagmi/viem) and asserts: the real hash is returned only after a successful receipt; a reverted receipt is not reported as success; a disconnected wallet is rejected before any submission; a user rejection (4001) returnssuccess: falsewith the decoded reason..env.example,docs/smart-contract-integration.mdNEXT_PUBLIC_BATCH_PURCHASE_ADDRESS.Integration changes outside
src/lib/.env.example— documents the new optionalNEXT_PUBLIC_BATCH_PURCHASE_ADDRESS.docs/smart-contract-integration.md— documents the batch purchase contract address and checkout flow.Acceptance criteria coverage
executeBatchPurchasesubmits a real transaction for the connected account and resolvessuccess: trueonly after on-chain confirmation (receipt observed); no code path returns a fabricated hash. (batchPurchaseExecutor.ts—writeContract+waitForTransactionReceipt; success gated on receiptstatus === "success")Math.random()failure branch and thesetTimeoutsimulation are gone. (removed in fix(checkout): remove fabricated batch transaction results #960; no timer/random path exists in the current code)calculateMinimumAmountfeedsminAmounts(in wei) into thebatchPurchasecall; the contract is documented to reject purchases below those minimums. (batchTransaction.ts,batchPurchaseExecutor.ts,src/config/batchPurchase.ts)src/lib/__tests__/batchTransaction.test.tsrewritten to mock wagmi/viem and assert: success returns the real hash; user rejection returnssuccess: falsewith a decoded reason; disconnected wallet is rejected before any submission. (13/13 tests pass)npm run typecheck,npm test, andnpm run lintpass. — Repository-wide gates remain blocked by pre-existing issues unrelated to this change (syntax errors insrc/app/compare/page.tsx,src/components/PropertyCard.tsx,src/components/TransactionConfirmation.tsx,src/lib/toast.ts,src/stories/ResponsiveContainerExample.stories.ts,src/components/CartSidebar.tsx, plus the missingeslint-plugin-jsdocdependency). The issue-specific suite passes and the changed files are clean of type errors.Deliberately deferred
src/config/batchPurchase.tsnotes where a per-chain map belongs once deployments exist.Test plan
npx jest src/lib/__tests__/batchTransaction.test.ts— 13/13 passing.npx prettier --check src/lib/batchTransaction.ts src/lib/batchPurchaseExecutor.ts src/config/batchPurchase.ts src/lib/__tests__/batchTransaction.test.ts— all matched files pass.npm run typecheck— blocked by the pre-existing unrelated syntax errors listed above; none of the errors are in the changed files.npm run lint— blocked because the checked-out dependencies do not includeeslint-plugin-jsdoc(pre-existing tooling gap, same as fix(checkout): remove fabricated batch transaction results #960-fix(security): remove orphaned pages router file #963).npm test -- --runInBand— repository-wide run is blocked by pre-existing failures; the batchTransaction suite passes.Env vars / Notes
New optional variable:
NEXT_PUBLIC_BATCH_PURCHASE_ADDRESS. No other env vars, migrations, or API changes.