Skip to content

Minting page standalone#2140

Merged
prxt6529 merged 59 commits intomainfrom
minting-page-standalone
Mar 24, 2026
Merged

Minting page standalone#2140
prxt6529 merged 59 commits intomainfrom
minting-page-standalone

Conversation

@prxt6529
Copy link
Copy Markdown
Collaborator

@prxt6529 prxt6529 commented Mar 19, 2026

Summary by CodeRabbit

  • New Features

    • Added standalone mint page export functionality with deployment scripts
    • Added wallet balance display component
    • Added support for local timezone in mint countdowns
    • Added Manifold.xyz marketplace link support
    • Added configurable provider feature toggles for wallet authentication, cookies, version checks, and settings mode
  • Bug Fixes

    • Fixed drop status determination to use isDropComplete instead of isFinalized
    • Improved media loading with Arweave and IPFS fallback support
    • Enhanced security headers with IPFS gateway endpoint configuration
  • UI/UX Updates

    • Modernized Manifold Minting UI with Tailwind CSS styling
    • Added artist information strips to mint pages
    • Improved media display with automatic gateway fallback switching
  • Tests

    • Added comprehensive test coverage for Manifold Minting phases, hooks, and standalone mint pages

prxt6529 added 20 commits March 18, 2026 17:24
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request introduces a standalone minting application for The Memes, refactors authentication to support optional wallet integration, adds comprehensive test coverage for minting phases, enhances media handling with IPFS/Arweave gateway fallbacks, and enables runtime provider configuration via feature flags.

Changes

Cohort / File(s) Summary
Standalone Application Architecture
standalone/standalone-memes-mint/...
New Next.js application structure with custom layout, pages, configuration (next.config.ts, tailwind, postcss, tsconfig), export script, and README documenting build/deploy workflow for static S3 deployment with optional CloudFront invalidation.
Manifold Minting Component Refactoring
components/manifold-minting/ManifoldMinting.tsx, components/manifold-minting/ManifoldMintingConnect.tsx, components/manifold-minting/ManifoldMintingWidget.tsx
Major refactoring: added standalone prop for external 6529.io linking, replaced Bootstrap/SCSS with Tailwind layouts, refactored meme phase card logic and description clamping, updated distribution fetching with async effects, changed onMintFor and recipient handling from empty string to null, added hideConnect conditional rendering, normalized mint count validation.
Manifold Claim Hook & Time Logic
hooks/useManifoldClaim.ts, hooks/useMintCountdownState.ts, helpers/manifold-display-helpers.ts
Refactored claim state management: added async meme roots fetching, introduced nextMemePhase and isDropComplete fields, split claim building into dedicated helper, updated phase resolution to match onchain merkle roots, reworked countdown state to track now timestamp with 1s updates and handle finalized/upcoming phase transitions.
Authentication & Provider Configuration
components/auth/Auth.tsx, components/providers/Providers.tsx, components/cookies/CookieConsentContext.tsx, contexts/SeizeSettingsContext.tsx
Added optional enableWalletAuthentication, enableCookieConsent, enableVersionCheck, enableMyStream, and settingsMode flags to runtime provider composition; refactored Auth with conditional wallet signing and JWT handling; added cookie consent disable capability; introduced SeizeSettingsMode.LOCAL for offline settings.
Media & Gateway Handling
components/nft-image/utils/gateway-fallback.ts, components/nft-image/renderers/*, components/drop-forge/craft/DropForgeCraftClaimPageClient.tsx, components/drops/view/item/content/media/MediaDisplay.tsx, config/securityHeaders.ts
Added IPFS gateway detection and fallback resolution alongside Arweave; implemented automatic URL fallback switching with timeout/error handling for HTML media; refactored iframe source resolution; updated CSP headers to include configured IPFS gateway endpoint; added media source link cards with copy/open actions.
Testing Infrastructure
__tests__/components/manifold-minting/*, __tests__/hooks/useManifoldClaim.test.tsx, __tests__/hooks/useMintCountdownState.test.tsx, __tests__/providers/AppKitAdapterManager.test.ts, __tests__/contexts/SeizeSettingsContext.test.tsx, __tests__/standalone/StandaloneTheMemesMintPageClient.test.tsx, __tests__/the-memes/MemePageArt.test.tsx
Comprehensive new test coverage: added ManifoldMintingPhases test suite with phase/status badge assertions, extended useManifoldClaim tests for meme phase selection, created useMintCountdownState tests for phase transitions, added standalone page client tests for loading/error/empty states, updated existing tests with new mock paths and constants.
Configuration & Build Tools
.github/workflows/build-upload-deploy-prod.yml, .gitignore, eslint.config.*.mjs, knip.jsonc, tailwind.config.ts, package.json
Updated workflow display name; adjusted .gitignore for standalone build outputs; extended ESLint ignore patterns for standalone config files; added Knip entry points; expanded Tailwind content scanning to include ./standalone/**/*; added npm scripts for export-mint-page and jiti dependency.
Marketplace & Component Linking
components/nft-marketplace-links/NFTMarketplaceLinks.tsx, components/drop-forge/launch/DropForgeLaunchClaimPageClient*.tsx, components/the-memes/MemePageArt.tsx, components/drop-forge/DropForgeTestnetIndicator.tsx
Added Manifold.xyz marketplace entry gated by memes contract; introduced include6529CollectionLink and craftHref props for navigation; refactored attribute filtering with predicate-based exclusion; added layout props (alignEnd, padBottom) to testnet indicator.
Utility Enhancements & Random Generation
helpers/AllowlistToolHelpers.ts, helpers/Helpers.ts, helpers/time.ts, utils/appkit-initialization.utils.ts, components/wallet-connect-balance/WalletConnectBalance.tsx, components/common/SandboxedExternalIframe.tsx
Replaced Math.random() with cryptographic globalThis.crypto.getRandomValues in random color/ObjectId generation; added Time.toLocaleHMString() method; updated AppKit config types and feature ordering; added new WalletConnectBalance component for wallet state display; enhanced SandboxedExternalIframe with load/error callbacks.
Miscellaneous Updates
components/home/now-minting/NowMintingStatsGrid.tsx, components/nft-image/NFTImage.module.scss, components/nft-image/renderers/NFTImageRenderer.tsx, components/leaderboard/*, components/the-memes/TheMemesMint.tsx, app/the-memes/mint/page.tsx, config/env.schema.ts, scripts/eslint-rule-summary.cjs, components/distribution-plan-tool/create-snapshots/form/CreateSnapshotForm.tsx
Changed status tone calculation to use isDropComplete; updated NFT image height constraints; refactored src selection logic; improved leaderboard styling and level display; added standalone prop to TheMemesMint; updated API fetch configuration; added STANDALONE_MAIN_SITE_BASE to env schema; refactored ESLint script with git helper functions; enhanced security for window.open calls.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • #2112 — Modifies Manifold minting phase logic and NFT marketplace links configuration.
  • #1984 — Extensive overlapping changes to manifold minting hooks, components, constants, and related test infrastructure.
  • #1925 — Modifies manifold "mint for me" flow recipient handling and related ManifoldMintingConnect/Widget components.

Poem

🐰 A standalone mint has come to be,
With auth that bows when told to flee,
Gateway fallbacks hop and stitch,
Tests ensure no logic glitch,
Providers dance to flags divine,
The Memes now in standalone shine! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.31% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Minting page standalone' directly relates to the main objective of this changeset: creating a standalone deployment of the minting page. Multiple file summaries reference 'standalone' mode/configuration, and the PR introduces a complete standalone mint page infrastructure including new Next.js configurations, export scripts, and provider flags.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch minting-page-standalone

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
components/auth/Auth.tsx (1)

741-750: ⚠️ Potential issue | 🟠 Major

Don't clear the stored JWT when auth is bypassed.

removeAuthJwt() still runs before the enableWalletAuthentication early return, so switching the active proxy in that mode logs the current user out even though no re-auth happens.

Proposed fix
-    removeAuthJwt();
     if (!address) {
+      removeAuthJwt();
       setActiveProfileProxy(null);
       return;
     }
 
     if (!enableWalletAuthentication) {
       setActiveProfileProxy(profileProxy);
       return;
     }
+
+    removeAuthJwt();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/auth/Auth.tsx` around lines 741 - 750, The call to removeAuthJwt()
is executed unconditionally and clears the stored JWT even when
enableWalletAuthentication is false; change the logic so removeAuthJwt() is only
called when wallet-based auth is enabled (i.e., when enableWalletAuthentication
is true and you are about to switch auth state), leaving the JWT intact when
bypassing auth; adjust the block around removeAuthJwt(),
setActiveProfileProxy(profileProxy), address and profileProxy so the early
return for !enableWalletAuthentication runs before any removeAuthJwt()
invocation.
components/manifold-minting/ManifoldMintingWidget.tsx (2)

442-447: ⚠️ Potential issue | 🟠 Major

Sanitize free-form mint counts before onMint can run.

Line 446 accepts negatives and blank input, and the disabled check on Lines 479-483 only tests !mintCount, so -1 still leaves the button enabled. Downstream, getValue() clamps the payment to zero while getMintArgsList() still sees the raw count, so the contract call can be malformed.

Suggested fix
       <input
         className="tw-h-11 tw-w-[100px] tw-rounded-xl tw-border tw-border-white/10 tw-bg-iron-950 tw-px-3 tw-text-sm tw-text-white focus:tw-border-primary-500 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-primary-500/30"
         type="number"
+        min={1}
+        step={1}
         value={mintCount}
-        onChange={(e) => setMintCount(Number.parseInt(e.target.value))}
+        onChange={(e) => {
+          const nextCount = Number.parseInt(e.target.value, 10);
+          setMintCount(Number.isFinite(nextCount) ? Math.max(0, nextCount) : 0);
+        }}
       />
             disabled={
               mintWrite.isPending ||
               props.claim.status !== ManifoldClaimStatus.ACTIVE ||
-              !mintCount
+              mintCount < 1
             }

Also applies to: 451-456, 479-483

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/manifold-minting/ManifoldMintingWidget.tsx` around lines 442 -
447, The mint count input allows negative and empty values which bypass the
disabled check and can produce malformed contract args; sanitize and normalize
the value in the input onChange and before invoking onMint by ensuring
setMintCount always stores a non-negative integer (e.g., coerce blank -> 0 and
clamp negatives -> 0) and also defensively validate in the mint flow (before
calling getMintArgsList/onMint) to re-check and coerce mintCount to a safe
non-negative integer; update usages around mintCount, setMintCount, onMint,
getValue, and getMintArgsList to rely on the sanitized value so the button
disabled logic (which checks mintCount) and the contract arg generation never
see negatives or NaN.

420-447: ⚠️ Potential issue | 🟠 Major

Give the mint-count control an explicit label.

Lines 463-465 render display text, but it is not associated with the native select/input on Lines 420-447. Screen readers will announce an unlabeled combo box/spinbutton in the mint flow.

Suggested fix
-          <span className="tw-text-base tw-font-medium tw-text-white">
+          <label
+            htmlFor="mint-count"
+            className="tw-text-base tw-font-medium tw-text-white"
+          >
             Select Mint Count:
-          </span>
+          </label>
-      <select
+      <select
+        id="mint-count"
         className="tw-h-11 tw-rounded-xl tw-border tw-border-white/10 tw-bg-iron-950 tw-px-3 tw-text-sm tw-text-white focus:tw-border-primary-500 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-primary-500/30"
         value={mintCount}
         onChange={(e) => setMintCount(Number.parseInt(e.target.value))}
       >
-      <input
+      <input
+        id="mint-count"
         className="tw-h-11 tw-w-[100px] tw-rounded-xl tw-border tw-border-white/10 tw-bg-iron-950 tw-px-3 tw-text-sm tw-text-white focus:tw-border-primary-500 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-primary-500/30"
         type="number"
         value={mintCount}
         onChange={(e) => setMintCount(Number.parseInt(e.target.value))}
       />

Also applies to: 462-469

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/manifold-minting/ManifoldMintingWidget.tsx` around lines 420 -
447, The mint-count controls (the select rendered in the unnamed
select-returning function and the input in printMintCountInput) are missing an
accessible label; add an explicit label element tied to each control using a
unique id (e.g., id="mint-count-select" and id="mint-count-input") and match it
with a <label htmlFor="...">Mint count</label>, or alternatively add a clear
aria-label/aria-labelledby on the select and input so screen readers announce
them; ensure you update the JSX around the select and the printMintCountInput
function and keep the existing value/mutation (mintCount, setMintCount) intact.
components/manifold-minting/ManifoldMinting.tsx (1)

748-760: ⚠️ Potential issue | 🟠 Major

Missing dependencies in useEffect will cause stale data.

The fetch URL uses props.token_id and props.contract, but these are not included in the dependency array. If either changes while props.address remains the same, the distribution data will be stale.

Additionally, there's no error handling for fetch failures, which could leave the component in an inconsistent state.

🐛 Proposed fix to add missing dependencies and error handling
   useEffect(() => {
     if (props.address) {
       fetch(
         `https://api.6529.io/api/distributions?card_id=${props.token_id}&contract=${props.contract}&page=1&search=${props.address}`
       )
         .then((response) => response.json())
         .then((data) => {
           setDistribution(data.data[0]);
-        });
+        })
+        .catch(() => {
+          setDistribution(undefined);
+        });
     } else {
       setDistribution(undefined);
     }
-  }, [props.address]);
+  }, [props.address, props.token_id, props.contract]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/manifold-minting/ManifoldMinting.tsx` around lines 748 - 760, The
useEffect that fetches distribution data (uses props.token_id, props.contract,
props.address and calls setDistribution) is missing props.token_id and
props.contract from its dependency array and lacks error handling; update the
dependency array to include props.token_id and props.contract so the effect
reruns when they change, and wrap the fetch in try/catch (or handle promise
rejections) to setDistribution(undefined) or an error state on failure and log
the error to avoid leaving stale or inconsistent state.
🧹 Nitpick comments (6)
utils/appkit-initialization.utils.ts (2)

103-103: Redundant call to setWalletFeaturesOrder.

This call sets ["onramp", "send"], but the same value is already passed via walletFeaturesOrder in the config object at line 161. Consider removing this redundant call since the config already handles it.

♻️ Proposed fix
   const appKitConfig = buildAppKitConfig(newAdapter, config.chains);
   const appKit = createAppKit(appKitConfig);
-  appKit.setWalletFeaturesOrder(["onramp", "send"]);
   const ready = appKit.ready();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@utils/appkit-initialization.utils.ts` at line 103, Remove the redundant
explicit call to appKit.setWalletFeaturesOrder(["onramp", "send"]) because the
same order is already provided via the walletFeaturesOrder property in the
initialization config; delete the appKit.setWalletFeaturesOrder invocation
(referencing the appKit.setWalletFeaturesOrder call) and keep the
walletFeaturesOrder setting in the config object so the order is applied once.

154-162: Clarify the intent of walletFeaturesOrder with disabled features.

walletFeaturesOrder is set to ["onramp", "send"], but onramp is disabled (onramp: false). If onramp is disabled, ordering it in the features list may be ineffective. If this is intentional (e.g., for future enablement), consider adding a comment. Otherwise, verify whether the ordering has any effect when the feature is disabled.

Verify the features config structure against the @reown/appkit library:

`@reown/appkit` features config walletFeaturesOrder onramp swaps
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@utils/appkit-initialization.utils.ts` around lines 154 - 162, The features
config includes walletFeaturesOrder (value ["onramp","send"]) while onramp is
set to false, which is ambiguous; either remove "onramp" from
walletFeaturesOrder, enable onramp, or add a clarifying comment explaining why a
disabled feature appears in the order (e.g., reserved for future enablement).
Locate the features object in utils/appkit-initialization.utils.ts and update
the walletFeaturesOrder or add the inline comment; also verify the final
structure against the `@reown/appkit` features config expectations (specifically
walletFeaturesOrder handling of onramp/swaps) to ensure the ordering has effect
when features are disabled.
components/nft-marketplace-links/NFTMarketplaceLinks.tsx (1)

69-73: Guard the 6529 link by contract or lift it to the caller.

include6529CollectionLink injects a hardcoded /the-memes/${id} URL regardless of contract, so this otherwise-generic component will render a bad 6529 target if another collection enables the flag.

Also applies to: 82-90

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/nft-marketplace-links/NFTMarketplaceLinks.tsx` around lines 69 -
73, The include6529CollectionLink boolean currently injects a hardcoded
`/the-memes/${id}` URL regardless of the contract, which causes incorrect links;
update the NFTMarketplaceLinks component to either (A) guard the 6529 link by
checking the contract value (e.g., only render the `/the-memes/${id}` link when
contract matches the canonical 6529 contract/address you expect) before using
id, or (B) lift responsibility to the caller by replacing
include6529CollectionLink with an explicit optional prop like custom6529Url (or
customCollectionLink) and render that URL only if provided; modify the rendering
logic where include6529CollectionLink is used (the block referencing
include6529CollectionLink and id) to implement one of these approaches and
ensure no hardcoded `/the-memes/${id}` is emitted for other contracts.
components/manifold-minting/ManifoldMintingConnect.tsx (1)

20-24: Rename or invert showConnect.

This prop hides the inline connect UI when it is true, so the API currently reads opposite to the behavior and is easy to wire backwards from the parent.

Also applies to: 204-207

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/manifold-minting/ManifoldMintingConnect.tsx` around lines 20 - 24,
The prop showConnect is semantically inverted (true hides the inline connect UI)
— rename it to hideConnect (or invert its boolean usage) across the
ManifoldMintingConnect component and its consumers: update the prop type
definition, the destructuring in ManifoldMintingConnect (replace showConnect
with hideConnect or flip the condition where showConnect is used), and change
any conditional render branches that control the inline connect UI (including
the other occurrence noted around the second conditional block) so the prop
reads naturally (hideConnect === true hides the UI). Ensure all parent usages
and prop tests are updated to the new name/logic.
standalone/standalone-memes-mint/src/app/page.tsx (1)

10-12: Consider adding error handling for build-time data fetching.

If fetchLatestTheMemesMintNft() fails during the static build (e.g., API unavailable), the build will fail without a clear error message. Consider wrapping this in a try-catch with a descriptive error, or documenting that a working API endpoint is required at build time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@standalone/standalone-memes-mint/src/app/page.tsx` around lines 10 - 12, Wrap
the call to fetchLatestTheMemesMintNft() inside StandaloneTheMemesMintPage in a
try-catch so build-time failures are handled; on catch, either throw a new Error
with a clear descriptive message that includes the original error information
(e.g., "Failed to fetch latest TheMemesMint NFT: <err>") or return a safe
fallback render for TheMemesMintPageShell, ensuring you reference the functions
StandaloneTheMemesMintPage, fetchLatestTheMemesMintNft, and
TheMemesMintPageShell so the error path is obvious and debuggable.
components/providers/Providers.tsx (1)

67-93: Extract the shared provider subtree once.

Lines 67-93 duplicate TitleProvider through NavigationHistoryProvider in both branches. Any future change to that stack now has two places to drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/providers/Providers.tsx` around lines 67 - 93, The TitleProvider →
NavigationHistoryProvider subtree is duplicated; extract that shared stack
(TitleProvider, HeaderProvider, ScrollPositionProvider, ViewProvider,
NavigationHistoryProvider wrapping {children}) into a single variable or small
component (e.g., SharedProviders or renderSharedProviders) and then
conditionally wrap it with MyStreamProvider when enableMyStream is true (i.e.,
return enableMyStream ? <MyStreamProvider>{shared}</MyStreamProvider> : shared)
so future changes live in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.gitignore:
- Line 25: Remove the gitignore rule that blocks the Next.js source public
directory by deleting the line "/standalone/standalone-memes-mint/src/public/"
from .gitignore (or replace it with a more specific build output ignore if
needed); this ensures the project's src/public/ static assets (favicons,
robots.txt, sitemaps) are tracked by git instead of being inadvertently
excluded.

In `@components/manifold-minting/ManifoldMintingConnect.tsx`:
- Around line 185-197: The Link component is wrapping a <button>, creating
nested interactive elements (Link and button) which breaks focus/click behavior
on iOS for the mint CTA; fix by removing the inner <button> and make the Link
itself the interactive element (or replace Link with a button that
programmatically navigates to mintOn6529Href), keeping the same
classes/appearance: update the Link usage around mintOn6529Href so the Link
receives the tw-w-full tw-rounded-xl ... tw-font-semibold classes and the text
"Mint on 6529.io", or alternatively make the button call
window.open(mintOn6529Href, '_blank', 'noopener,noreferrer') and remove the Link
wrapper.

In `@components/providers/AppKitAdapterManager.ts`:
- Around line 42-49: The console.warn in AppKitAdapterManager currently logs
sensitive chain.rpcUrls; remove rpcUrls from the warning payload and only emit
non-sensitive identifiers (e.g., chain.id and chain.name) or a redacted
placeholder; update the warning emitted by the method containing the
console.warn to stop including chain.rpcUrls (replace with "rpcUrls: redacted"
or omit entirely) so provider URLs / key-bearing endpoints are not leaked.

In `@components/wallet-connect-balance/WalletConnectBalance.tsx`:
- Around line 4-6: The click handler currently calls seizeDisconnect directly
which can produce an unhandled rejection; update the handler that invokes
seizeDisconnect (the onClick disconnect callback in WalletConnectBalance) to
await the async call inside a try/catch (or attach .catch) and handle/log errors
(e.g., using processLogger or console.error) so any rejection from
seizeDisconnect is caught and does not bubble as an unhandled promise; apply the
same pattern to the other disconnect invocation around the seizeDisconnect call
observed elsewhere in the component.

In `@hooks/useManifoldClaim.ts`:
- Around line 303-325: When memesRootsState.status === "success" but roots are
empty or no root matches, the code currently returns undefined and loses the
time-based fallback; change the branches so that after building memePhases (via
buildMemesPhases(Time.seconds(start))) you fall back to
getScheduledMemePhase(phase, start, end) whenever memesRootsState.roots.length
=== 0 or when matchedRoot is undefined /
getMemePhaseIdForRootPhase(matchedRoot?.phase) is falsy; keep using memePhases
to resolve PUBLIC, but otherwise return the scheduled phase so downstream values
like nextMemePhase and isDropComplete remain correct.

In `@standalone/standalone-memes-mint/scripts/export-mint-page.cjs`:
- Around line 95-134: The function resolveCloudFrontDistributionIdByAlias
currently uses a substring JMESPath query (contains) and returns the first
match, which can pick the wrong distribution; change the query to match aliases
exactly (e.g. use Aliases.Items[?@ == 'hostname'] in the JMESPath string passed
to spawnSync) and update post-processing: after splitting proc.stdout into ids
(in resolveCloudFrontDistributionIdByAlias) treat non-unique results as failures
— log a warning and return null if ids.length !== 1 instead of using ids[0];
keep existing error/status checks on the spawnSync proc.

In `@utils/appkit-initialization.utils.ts`:
- Around line 105-109: Remove the call to the non-existent method
appKit.updateRemoteFeatures invoked inside the ready.then(...) callback; this
API does not exist in `@reown/appkit` and will break TypeScript/ runtime. Rely on
the existing initial config where swaps is set to false (the initial config that
contains swaps: false) or, if you intended to programmatically change feature
flags, replace the call with the library-supported API after checking
`@reown/appkit` docs; otherwise simply delete the ready.then block that calls
appKit.updateRemoteFeatures.

---

Outside diff comments:
In `@components/auth/Auth.tsx`:
- Around line 741-750: The call to removeAuthJwt() is executed unconditionally
and clears the stored JWT even when enableWalletAuthentication is false; change
the logic so removeAuthJwt() is only called when wallet-based auth is enabled
(i.e., when enableWalletAuthentication is true and you are about to switch auth
state), leaving the JWT intact when bypassing auth; adjust the block around
removeAuthJwt(), setActiveProfileProxy(profileProxy), address and profileProxy
so the early return for !enableWalletAuthentication runs before any
removeAuthJwt() invocation.

In `@components/manifold-minting/ManifoldMinting.tsx`:
- Around line 748-760: The useEffect that fetches distribution data (uses
props.token_id, props.contract, props.address and calls setDistribution) is
missing props.token_id and props.contract from its dependency array and lacks
error handling; update the dependency array to include props.token_id and
props.contract so the effect reruns when they change, and wrap the fetch in
try/catch (or handle promise rejections) to setDistribution(undefined) or an
error state on failure and log the error to avoid leaving stale or inconsistent
state.

In `@components/manifold-minting/ManifoldMintingWidget.tsx`:
- Around line 442-447: The mint count input allows negative and empty values
which bypass the disabled check and can produce malformed contract args;
sanitize and normalize the value in the input onChange and before invoking
onMint by ensuring setMintCount always stores a non-negative integer (e.g.,
coerce blank -> 0 and clamp negatives -> 0) and also defensively validate in the
mint flow (before calling getMintArgsList/onMint) to re-check and coerce
mintCount to a safe non-negative integer; update usages around mintCount,
setMintCount, onMint, getValue, and getMintArgsList to rely on the sanitized
value so the button disabled logic (which checks mintCount) and the contract arg
generation never see negatives or NaN.
- Around line 420-447: The mint-count controls (the select rendered in the
unnamed select-returning function and the input in printMintCountInput) are
missing an accessible label; add an explicit label element tied to each control
using a unique id (e.g., id="mint-count-select" and id="mint-count-input") and
match it with a <label htmlFor="...">Mint count</label>, or alternatively add a
clear aria-label/aria-labelledby on the select and input so screen readers
announce them; ensure you update the JSX around the select and the
printMintCountInput function and keep the existing value/mutation (mintCount,
setMintCount) intact.

---

Nitpick comments:
In `@components/manifold-minting/ManifoldMintingConnect.tsx`:
- Around line 20-24: The prop showConnect is semantically inverted (true hides
the inline connect UI) — rename it to hideConnect (or invert its boolean usage)
across the ManifoldMintingConnect component and its consumers: update the prop
type definition, the destructuring in ManifoldMintingConnect (replace
showConnect with hideConnect or flip the condition where showConnect is used),
and change any conditional render branches that control the inline connect UI
(including the other occurrence noted around the second conditional block) so
the prop reads naturally (hideConnect === true hides the UI). Ensure all parent
usages and prop tests are updated to the new name/logic.

In `@components/nft-marketplace-links/NFTMarketplaceLinks.tsx`:
- Around line 69-73: The include6529CollectionLink boolean currently injects a
hardcoded `/the-memes/${id}` URL regardless of the contract, which causes
incorrect links; update the NFTMarketplaceLinks component to either (A) guard
the 6529 link by checking the contract value (e.g., only render the
`/the-memes/${id}` link when contract matches the canonical 6529
contract/address you expect) before using id, or (B) lift responsibility to the
caller by replacing include6529CollectionLink with an explicit optional prop
like custom6529Url (or customCollectionLink) and render that URL only if
provided; modify the rendering logic where include6529CollectionLink is used
(the block referencing include6529CollectionLink and id) to implement one of
these approaches and ensure no hardcoded `/the-memes/${id}` is emitted for other
contracts.

In `@components/providers/Providers.tsx`:
- Around line 67-93: The TitleProvider → NavigationHistoryProvider subtree is
duplicated; extract that shared stack (TitleProvider, HeaderProvider,
ScrollPositionProvider, ViewProvider, NavigationHistoryProvider wrapping
{children}) into a single variable or small component (e.g., SharedProviders or
renderSharedProviders) and then conditionally wrap it with MyStreamProvider when
enableMyStream is true (i.e., return enableMyStream ?
<MyStreamProvider>{shared}</MyStreamProvider> : shared) so future changes live
in one place.

In `@standalone/standalone-memes-mint/src/app/page.tsx`:
- Around line 10-12: Wrap the call to fetchLatestTheMemesMintNft() inside
StandaloneTheMemesMintPage in a try-catch so build-time failures are handled; on
catch, either throw a new Error with a clear descriptive message that includes
the original error information (e.g., "Failed to fetch latest TheMemesMint NFT:
<err>") or return a safe fallback render for TheMemesMintPageShell, ensuring you
reference the functions StandaloneTheMemesMintPage, fetchLatestTheMemesMintNft,
and TheMemesMintPageShell so the error path is obvious and debuggable.

In `@utils/appkit-initialization.utils.ts`:
- Line 103: Remove the redundant explicit call to
appKit.setWalletFeaturesOrder(["onramp", "send"]) because the same order is
already provided via the walletFeaturesOrder property in the initialization
config; delete the appKit.setWalletFeaturesOrder invocation (referencing the
appKit.setWalletFeaturesOrder call) and keep the walletFeaturesOrder setting in
the config object so the order is applied once.
- Around line 154-162: The features config includes walletFeaturesOrder (value
["onramp","send"]) while onramp is set to false, which is ambiguous; either
remove "onramp" from walletFeaturesOrder, enable onramp, or add a clarifying
comment explaining why a disabled feature appears in the order (e.g., reserved
for future enablement). Locate the features object in
utils/appkit-initialization.utils.ts and update the walletFeaturesOrder or add
the inline comment; also verify the final structure against the `@reown/appkit`
features config expectations (specifically walletFeaturesOrder handling of
onramp/swaps) to ensure the ordering has effect when features are disabled.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b8e4ffbd-21a4-46f6-9e83-a5933016c83b

📥 Commits

Reviewing files that changed from the base of the PR and between bfaae1f and 91ed875.

⛔ Files ignored due to path filters (3)
  • package-lock.json is excluded by !**/package-lock.json
  • public/6529bgwhite.svg is excluded by !**/*.svg
  • public/manifold.svg is excluded by !**/*.svg
📒 Files selected for processing (47)
  • .github/workflows/build-upload-deploy-prod.yml
  • .gitignore
  • __tests__/components/manifold-minting/ManifoldMinting.test.tsx
  • __tests__/components/manifold-minting/ManifoldMintingConnect.test.tsx
  • __tests__/components/manifold-minting/ManifoldMintingPhases.test.tsx
  • __tests__/components/providers/AppKitAdapterManager.test.ts
  • __tests__/hooks/useManifoldClaim.test.tsx
  • __tests__/hooks/useMintCountdownState.test.tsx
  • app/the-memes/mint/page.tsx
  • components/auth/Auth.tsx
  • components/cookies/CookieConsentContext.tsx
  • components/drop-forge/DropForgeTestnetIndicator.tsx
  • components/home/now-minting/NowMintingStatsGrid.tsx
  • components/manifold-minting/ManifoldMinting.module.scss
  • components/manifold-minting/ManifoldMinting.tsx
  • components/manifold-minting/ManifoldMintingConnect.tsx
  • components/manifold-minting/ManifoldMintingWidget.tsx
  • components/nft-image/NFTImage.module.scss
  • components/nft-image/renderers/NFTImageRenderer.tsx
  • components/nft-marketplace-links/NFTMarketplaceLinks.tsx
  • components/providers/AppKitAdapterManager.ts
  • components/providers/Providers.tsx
  • components/providers/WagmiSetup.tsx
  • components/the-memes/TheMemesMint.tsx
  • components/the-memes/TheMemesMintPageShell.tsx
  • components/user/utils/profile/UserProfileTooltip.tsx
  • components/utils/tooltip/UserProfileTooltipWrapper.tsx
  • components/wallet-connect-balance/WalletConnectBalance.tsx
  • eslint.config.mjs
  • eslint.config.single.mjs
  • eslint.config.tight.mjs
  • helpers/manifold-display-helpers.ts
  • helpers/time.ts
  • hooks/useManifoldClaim.ts
  • hooks/useMintCountdownState.ts
  • knip.jsonc
  • package.json
  • standalone/standalone-memes-mint/README.md
  • standalone/standalone-memes-mint/scripts/export-mint-page.cjs
  • standalone/standalone-memes-mint/src/app/layout.tsx
  • standalone/standalone-memes-mint/src/app/page.tsx
  • standalone/standalone-memes-mint/src/next.config.ts
  • standalone/standalone-memes-mint/src/postcss.config.js
  • standalone/standalone-memes-mint/src/tailwind.config.cjs
  • standalone/standalone-memes-mint/src/tsconfig.json
  • tailwind.config.ts
  • utils/appkit-initialization.utils.ts
💤 Files with no reviewable changes (1)
  • components/manifold-minting/ManifoldMinting.module.scss

Comment thread .gitignore
Comment thread components/manifold-minting/ManifoldMintingConnect.tsx
Comment thread components/providers/AppKitAdapterManager.ts Outdated
Comment thread components/wallet-connect-balance/WalletConnectBalance.tsx
Comment thread hooks/useManifoldClaim.ts Outdated
Comment thread standalone/standalone-memes-mint/scripts/export-mint-page.cjs Outdated
Comment thread utils/appkit-initialization.utils.ts Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
components/wallet-connect-balance/WalletConnectBalance.tsx (1)

63-63: ⚠️ Potential issue | 🟡 Minor

Catch disconnect failures in the click handler.

Line 63 passes seizeDisconnect directly; since it returns a promise and can throw, failures can surface as unhandled rejections in the UI event path.

Proposed fix
 import { useSeizeConnectContext } from "../auth/SeizeConnectContext";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { faPlugCircleXmark } from "@fortawesome/free-solid-svg-icons";
+import { logErrorSecurely } from "@/utils/error-sanitizer";
@@
-        onClick={seizeDisconnect}
+        onClick={() => {
+          void seizeDisconnect().catch((error) => {
+            logErrorSecurely("wallet_connect_balance_disconnect", error);
+          });
+        }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/wallet-connect-balance/WalletConnectBalance.tsx` at line 63, The
onClick currently passes seizeDisconnect directly which returns a promise and
can throw, causing unhandled rejections; wrap the call in a safe click handler
(e.g., an async wrapper or promise .catch) inside WalletConnectBalance.tsx so
any rejection from seizeDisconnect is caught and handled (log the error and/or
show user feedback) rather than bubbling as an unhandled rejection; update the
JSX onClick to call that wrapper handler instead of seizeDisconnect directly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@components/wallet-connect-balance/WalletConnectBalance.tsx`:
- Line 63: The onClick currently passes seizeDisconnect directly which returns a
promise and can throw, causing unhandled rejections; wrap the call in a safe
click handler (e.g., an async wrapper or promise .catch) inside
WalletConnectBalance.tsx so any rejection from seizeDisconnect is caught and
handled (log the error and/or show user feedback) rather than bubbling as an
unhandled rejection; update the JSX onClick to call that wrapper handler instead
of seizeDisconnect directly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 98ad1af4-9598-4f26-8068-6d0ebc9e04d3

📥 Commits

Reviewing files that changed from the base of the PR and between 91ed875 and 29cd8ab.

📒 Files selected for processing (6)
  • __tests__/components/providers/AppKitAdapterManager.test.ts
  • components/providers/AppKitAdapterManager.ts
  • components/providers/Providers.tsx
  • components/wallet-connect-balance/WalletConnectBalance.tsx
  • standalone/standalone-memes-mint/README.md
  • standalone/standalone-memes-mint/src/app/layout.tsx
✅ Files skipped from review due to trivial changes (3)
  • components/providers/AppKitAdapterManager.ts
  • standalone/standalone-memes-mint/README.md
  • tests/components/providers/AppKitAdapterManager.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • standalone/standalone-memes-mint/src/app/layout.tsx
  • components/providers/Providers.tsx

Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/manifold-minting/ManifoldMintingConnect.tsx (1)

79-81: ⚠️ Potential issue | 🟠 Major

Don't persist an empty-string recipient.

Both branches now call onMintFor("") to mean “no destination”, but components/manifold-minting/ManifoldMintingWidget.tsx:219-237 still pushes mintForAddress straight into the contract args. That makes "" an invalid wallet value in shared mint state, not just a UI sentinel. Please switch this flow to a nullable recipient and gate minting on address validity before args are built.

Also applies to: 88-94

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/manifold-minting/ManifoldMintingConnect.tsx` around lines 79 - 81,
Change the empty-string sentinel to a nullable recipient: when no wallet is
selected call onMintFor(null) instead of onMintFor(""), update both places where
selectedFrenWallet is handled (the block around selectedFrenWallet checks at
79-81 and the similar branch at 88-94) and make sure ManifoldMintingWidget uses
a nullable mintForAddress (type: string | null). Before building contract args
or pushing mintForAddress into args, validate that mintForAddress is a
non-empty, well-formed address (e.g., using existing isValidAddress utility) and
only include it in the contract args when valid; otherwise omit the recipient
arg and prevent/disable minting until a valid address is present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/manifold-minting/ManifoldMinting.tsx`:
- Around line 256-299: ArtistInfoStrip always renders a Link to `/${handle}`
even when used inside the standalone export; update it to accept a boolean prop
(e.g., standalone) and, when standalone is true, either render a non-navigation
element (span/div) or point the href to the local standalone route instead of
`/${handle}`; update every call site (notably the printActions() render path) to
pass standalone={true} for export usage and keep default behavior for embedded
uses so internal profile routing is preserved where appropriate.
- Around line 839-875: When props.address changes the previous distribution
remains visible until the fetch completes; inside the useEffect that depends on
props.address/props.contract/props.token_id (the effect that defines
loadDistribution), reset the displayed distribution immediately by calling
setDistribution(undefined) before starting the fetch (i.e., at the top of the
effect or right before invoking loadDistribution) so the UI doesn't briefly show
the old recipient's data; keep the isCancelled guard and existing error handling
around the async loadDistribution function and only
setDistribution(data.data[0]) when not cancelled.

In `@hooks/useManifoldClaim.ts`:
- Around line 296-300: The phase determination incorrectly requires
claimData.total > 0 to set ManifoldPhase.PUBLIC, causing a fresh public drop
with zero mints to be labeled ALLOWLIST; update the logic around publicMerkle
(computed via areEqualAddresses(NULL_MERKLE, merkleRoot)) so that if
publicMerkle is true the phase is set to ManifoldPhase.PUBLIC regardless of
claimData.total, otherwise set to ManifoldPhase.ALLOWLIST; modify the code that
assigns phase (the variable named phase using publicMerkle, areEqualAddresses,
NULL_MERKLE, merkleRoot, and ManifoldPhase enums) to remove the claimData.total
check.

In `@scripts/eslint-rule-summary.cjs`:
- Around line 41-48: Replace the hard-coded diff base "main...HEAD" used when
computing changedFiles via runGitCommand with dynamic base-ref discovery: first
check GITHUB_BASE_REF env, then try a remote ref like origin/main, and if those
are unavailable compute a merge base with git merge-base (or fail if none).
Update the logic around the changedFiles computation (the runGitCommand call
that builds the diff args) to use the discovered base string instead of
"main...HEAD", and ensure failures to discover a valid base throw or log an
error (propagate instead of catching and returning []) so the script exits
nonzero rather than silently reporting "No changed files to lint."

In
`@standalone/standalone-memes-mint/src/components/StandaloneAnchorInterceptor.tsx`:
- Around line 30-32: The click handler in the StandaloneAnchorInterceptor
component currently only intercepts plain left-clicks and uses window.open,
leaving modifier/middle-clicks and context-menu actions pointing to the original
standalone URL; instead, compute the rewritten main-site URL inside the
component (reuse the existing rewrite logic used before window.open), set the
actual anchor element's href to that rewritten URL (e.g., event.currentTarget or
the <a> ref) so all default browser behaviors (Cmd/Ctrl-click, middle-click,
“open in new tab”, copy link) use the corrected destination, and avoid
preventing default navigation for those cases—also consider applying the same
href rewrite when rendering anchors upstream if possible; update the code paths
that currently call window.open (the handler referenced in
StandaloneAnchorInterceptor) to assign the rewritten URL to the anchor before
returning.

In `@standalone/standalone-memes-mint/src/next.config.ts`:
- Around line 7-21: Replace the hardcoded main-site URL in standalonePublicEnv
with a value read from the environment: use
process.env["STANDALONE_MAIN_SITE_BASE"]?.trim() with a clear fallback (e.g.,
standaloneBaseEndpoint) instead of the literal "https://6529.io"; update the
standalonePublicEnv object (symbol standalonePublicEnv and key
STANDALONE_MAIN_SITE_BASE) so exports and runtime rewrites (see
export-mint-page.cjs and StandaloneAnchorInterceptor.tsx) will use the
configured value rather than always pointing to production.

---

Outside diff comments:
In `@components/manifold-minting/ManifoldMintingConnect.tsx`:
- Around line 79-81: Change the empty-string sentinel to a nullable recipient:
when no wallet is selected call onMintFor(null) instead of onMintFor(""), update
both places where selectedFrenWallet is handled (the block around
selectedFrenWallet checks at 79-81 and the similar branch at 88-94) and make
sure ManifoldMintingWidget uses a nullable mintForAddress (type: string | null).
Before building contract args or pushing mintForAddress into args, validate that
mintForAddress is a non-empty, well-formed address (e.g., using existing
isValidAddress utility) and only include it in the contract args when valid;
otherwise omit the recipient arg and prevent/disable minting until a valid
address is present.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 747835cc-cbc9-42ac-8fca-9e6b3f858c43

📥 Commits

Reviewing files that changed from the base of the PR and between 29cd8ab and d6dbf5c.

⛔ Files ignored due to path filters (6)
  • standalone/standalone-memes-mint/src/public/6529.svg is excluded by !**/*.svg
  • standalone/standalone-memes-mint/src/public/6529bgwhite.svg is excluded by !**/*.svg
  • standalone/standalone-memes-mint/src/public/favicon.ico is excluded by !**/*.ico
  • standalone/standalone-memes-mint/src/public/manifold.svg is excluded by !**/*.svg
  • standalone/standalone-memes-mint/src/public/opensea.png is excluded by !**/*.png
  • standalone/standalone-memes-mint/src/public/rarible.svg is excluded by !**/*.svg
📒 Files selected for processing (25)
  • .gitignore
  • components/auth/Auth.tsx
  • components/distribution-plan-tool/create-snapshots/form/CreateSnapshotForm.tsx
  • components/manifold-minting/ManifoldMinting.tsx
  • components/manifold-minting/ManifoldMintingConnect.tsx
  • components/manifold-minting/ManifoldMintingWidget.tsx
  • components/nft-image/renderers/NFTImageRenderer.tsx
  • components/nft-marketplace-links/NFTMarketplaceLinks.tsx
  • components/providers/AppKitAdapterManager.ts
  • components/providers/Providers.tsx
  • components/wallet-connect-balance/WalletConnectBalance.tsx
  • config/env.schema.ts
  • helpers/AllowlistToolHelpers.ts
  • helpers/Helpers.ts
  • hooks/useManifoldClaim.ts
  • hooks/useMintCountdownState.ts
  • scripts/eslint-rule-summary.cjs
  • standalone/standalone-memes-mint/README.md
  • standalone/standalone-memes-mint/scripts/export-mint-page.cjs
  • standalone/standalone-memes-mint/src/app/layout.tsx
  • standalone/standalone-memes-mint/src/app/page.tsx
  • standalone/standalone-memes-mint/src/components/StandaloneAnchorInterceptor.tsx
  • standalone/standalone-memes-mint/src/next.config.ts
  • standalone/standalone-memes-mint/src/tsconfig.json
  • utils/appkit-initialization.utils.ts
✅ Files skipped from review due to trivial changes (6)
  • .gitignore
  • components/providers/AppKitAdapterManager.ts
  • config/env.schema.ts
  • components/distribution-plan-tool/create-snapshots/form/CreateSnapshotForm.tsx
  • standalone/standalone-memes-mint/src/tsconfig.json
  • standalone/standalone-memes-mint/README.md
🚧 Files skipped from review as they are similar to previous changes (9)
  • components/nft-image/renderers/NFTImageRenderer.tsx
  • utils/appkit-initialization.utils.ts
  • hooks/useMintCountdownState.ts
  • components/auth/Auth.tsx
  • components/wallet-connect-balance/WalletConnectBalance.tsx
  • standalone/standalone-memes-mint/scripts/export-mint-page.cjs
  • standalone/standalone-memes-mint/src/app/page.tsx
  • standalone/standalone-memes-mint/src/app/layout.tsx
  • components/manifold-minting/ManifoldMintingWidget.tsx

Comment thread components/manifold-minting/ManifoldMinting.tsx
Comment thread components/manifold-minting/ManifoldMinting.tsx
Comment thread hooks/useManifoldClaim.ts Outdated
Comment thread scripts/eslint-rule-summary.cjs Outdated
Comment thread standalone/standalone-memes-mint/src/components/StandaloneAnchorInterceptor.tsx Outdated
Comment thread standalone/standalone-memes-mint/src/next.config.ts Outdated
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Comment thread components/drop-forge/craft/DropForgeCraftClaimPageClient.tsx Fixed
Comment thread components/drop-forge/craft/DropForgeCraftClaimPageClient.tsx Fixed
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
@prxt6529
Copy link
Copy Markdown
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 24, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (7)
components/leaderboard/LeaderboardCollector.tsx (1)

43-55: Consider using an explicit check for level presence.

The truthy check props.level ? will treat 0 as falsy, meaning users with level 0 won't see the level badge. Since level is typed as a required number prop (not optional), and the LEVEL_COLORS config in UserCICAndLevel.tsx includes a minLevel: 0 entry, level 0 appears to be a valid displayable value.

If level 0 should display the badge, consider:

Suggested change
-        {props.level ? (
+        {props.level !== undefined ? (

Or, if the intent is that level 0 means "no level assigned", consider making the prop optional (level?: number) to clarify the API contract.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/leaderboard/LeaderboardCollector.tsx` around lines 43 - 55, The
current conditional uses a truthy check on props.level which treats 0 as falsy
and hides the level badge; update the check to explicitly test for
undefined/null (e.g., props.level !== undefined && props.level !== null) so a
valid level 0 will render the UserCICAndLevel badge, or alternatively change the
prop signature to make level optional (level?: number) if 0 should mean "no
level"—adjust the rendering around UserCICAndLevel and any callers accordingly
to match the chosen contract.
__tests__/components/the-memes/MemePageArt.test.tsx (1)

129-132: Optional cleanup: redundant mock reset.

jest.clearAllMocks() already clears mockNFTAttributes, so mockNFTAttributes.mockClear() can be removed to keep setup minimal.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@__tests__/components/the-memes/MemePageArt.test.tsx` around lines 129 - 132,
The beforeEach setup is calling mockNFTAttributes.mockClear() redundantly after
jest.clearAllMocks(); remove the explicit mockNFTAttributes.mockClear() call so
the block only calls jest.clearAllMocks() and then sets
mockNftHelpers.getAnimationFileTypeFromMetadata.mockReturnValue("gif") (locate
this in the beforeEach block that references mockNFTAttributes.mockClear and
jest.clearAllMocks).
standalone/standalone-memes-mint/scripts/export-mint-page.cjs (1)

143-219: Consider adding a request timeout.

The HTTP request has no timeout configured. If the remote server is unresponsive, fetchJson will hang indefinitely, potentially blocking deployments.

♻️ Proposed fix to add timeout
     const req = client.request(
       parsedUrl,
       {
         method: "GET",
         headers: {
           Accept: "application/json",
         },
+        timeout: 30000,
       },
       (res) => {

Then handle the timeout event:

     req.on("error", reject);
+    req.on("timeout", () => {
+      req.destroy();
+      reject(new Error(`Request timed out while fetching ${url}`));
+    });
     req.end();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@standalone/standalone-memes-mint/scripts/export-mint-page.cjs` around lines
143 - 219, The fetchJson function lacks a request timeout and can hang; update
fetchJson to accept an optional timeout parameter (default e.g. 10000 ms) and
apply it to the outgoing request (use req.setTimeout or an AbortController-style
abort) so that when the timer fires you abort the request and reject with a
clear timeout Error; ensure you handle the aborted request cleanly by
listening/removing the 'error' and 'timeout' handlers and avoiding
double-resolve/reject (refer to fetchJson, req, and the client.request response
handler) and include a helpful message like `Timeout after ${timeout}ms while
fetching ${url}`.
components/drops/view/item/content/media/MediaDisplay.tsx (1)

55-64: Simplify redundant conditional in useEffect.

The early return on urls.length === 0 performs the same reset logic as the non-empty case, making the condition unnecessary.

♻️ Proposed simplification
   useEffect(() => {
-    if (urls.length === 0) {
-      setActiveIndex(0);
-      setDidLoadCurrentUrl(false);
-      return;
-    }
-
     setActiveIndex(0);
     setDidLoadCurrentUrl(false);
   }, [urls]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/drops/view/item/content/media/MediaDisplay.tsx` around lines 55 -
64, The useEffect in MediaDisplay.tsx contains a redundant conditional: both the
urls.length === 0 branch and the else branch call setActiveIndex(0) and
setDidLoadCurrentUrl(false). Simplify by removing the conditional and early
return so the effect simply runs on urls change and always calls
setActiveIndex(0) and setDidLoadCurrentUrl(false); locate the effect that
references urls and the setters setActiveIndex and setDidLoadCurrentUrl to
update it.
components/common/SandboxedExternalIframe.tsx (1)

137-137: Remove unused dependency iframeTitle from useMemo.

iframeTitle is included in the dependency array but is never used inside the memoized computation. The title is applied directly to the <iframe> element on line 186, not via iframeProps. This unnecessary dependency causes extra re-computation when the title changes.

♻️ Proposed fix
-  }, [canonicalSrc, frameClassName, iframeTitle]);
+  }, [canonicalSrc, frameClassName]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/common/SandboxedExternalIframe.tsx` at line 137, The useMemo hook
computing iframeProps unnecessarily includes iframeTitle in its dependency array
even though iframeTitle is not referenced inside the memoized computation;
update the dependency array for the memo that builds iframeProps (the useMemo
that currently lists canonicalSrc, frameClassName, iframeTitle) to remove
iframeTitle so it only depends on canonicalSrc and frameClassName, leaving the
iframeTitle prop applied directly to the <iframe> element as before.
components/nft-image/utils/gateway-fallback.ts (1)

46-58: Consider extracting shared IPFS gateway host helper.

This function duplicates the logic in components/waves/memes/submission/constants/security.ts (getConfiguredIpfsGatewayHost). Both parse publicEnv.IPFS_GATEWAY_ENDPOINT and normalize the hostname.

Consider extracting this to a shared utility (e.g., in @/config/env or a dedicated IPFS helpers module) to avoid divergence if the validation logic needs to change.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/nft-image/utils/gateway-fallback.ts` around lines 46 - 58,
Duplicate IPFS gateway parsing/normalization exists: extract a shared helper
(e.g., export getConfiguredIpfsGatewayHost from a new module in the config/env
or ipfs helpers file) that reads publicEnv.IPFS_GATEWAY_ENDPOINT, constructs a
URL, and returns canonicalizeArweaveGatewayHostname(parsedUrl.hostname) or null
on error; replace the local implementation in
components/nft-image/utils/gateway-fallback.ts and the duplicate in
components/waves/memes/submission/constants/security.ts with imports of the new
getConfiguredIpfsGatewayHost to ensure a single source of truth and keep
canonicalizeArweaveGatewayHostname usage unchanged.
config/securityHeaders.ts (1)

37-37: Consider filtering empty sources to avoid extra whitespace in CSP.

When configuredIpfsGatewaySource is empty, the resulting CSP contains double spaces (e.g., ...${arweaveGatewaySources} https://cf-ipfs.com...). While harmless for parsing, this could be cleaner.

♻️ Optional: filter empty values before interpolation
+ const mediaSources = [
+   "'self'",
+   "blob:",
+   "https://*.cloudfront.net",
+   "https://videos.files.wordpress.com",
+   arweaveGatewaySources,
+   configuredIpfsGatewaySource,
+   "https://cf-ipfs.com/ipfs/*",
+   "https://*.twimg.com",
+   "https://artblocks.io",
+   "https://*.artblocks.io",
+ ].filter(Boolean).join(" ");

This pattern could be applied to build each directive from an array, filtering out empty strings before joining. This also improves maintainability of the long CSP string.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/securityHeaders.ts` at line 37, The CSP string currently interpolates
variables like configuredIpfsGatewaySource and arweaveGatewaySources directly,
which yields extra spaces when values are empty; update the code that builds the
value (the long template string assigned to value in config/securityHeaders.ts)
to construct each directive from an array of source strings (e.g., for
frame-src, media-src, img-src, connect-src), filter out falsy/empty entries
(Array.prototype.filter(Boolean)), then join(' ') so empty variables (like
configuredIpfsGatewaySource) are removed and no double spaces remain; ensure you
reference and use the existing symbols (configuredIpfsGatewaySource,
arweaveGatewaySources, apiEndpoint) when building those arrays so behavior is
unchanged when values are present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@contexts/SeizeSettingsContext.tsx`:
- Around line 103-119: The effect must restore the mount flag on every run so
subsequent runs can update state: at the start of the useEffect body set
isMountedRef.current = true before checking mode; keep the existing early-return
branch for SeizeSettingsMode.LOCAL (which calls setIsLoaded(true)) and keep the
existing cleanup that sets isMountedRef.current = false; this ensures
loadSeizeSettings() sees a true isMountedRef and can update state when mode
changes. Reference: useEffect, isMountedRef, loadSeizeSettings, setIsLoaded,
SeizeSettingsMode.

---

Nitpick comments:
In `@__tests__/components/the-memes/MemePageArt.test.tsx`:
- Around line 129-132: The beforeEach setup is calling
mockNFTAttributes.mockClear() redundantly after jest.clearAllMocks(); remove the
explicit mockNFTAttributes.mockClear() call so the block only calls
jest.clearAllMocks() and then sets
mockNftHelpers.getAnimationFileTypeFromMetadata.mockReturnValue("gif") (locate
this in the beforeEach block that references mockNFTAttributes.mockClear and
jest.clearAllMocks).

In `@components/common/SandboxedExternalIframe.tsx`:
- Line 137: The useMemo hook computing iframeProps unnecessarily includes
iframeTitle in its dependency array even though iframeTitle is not referenced
inside the memoized computation; update the dependency array for the memo that
builds iframeProps (the useMemo that currently lists canonicalSrc,
frameClassName, iframeTitle) to remove iframeTitle so it only depends on
canonicalSrc and frameClassName, leaving the iframeTitle prop applied directly
to the <iframe> element as before.

In `@components/drops/view/item/content/media/MediaDisplay.tsx`:
- Around line 55-64: The useEffect in MediaDisplay.tsx contains a redundant
conditional: both the urls.length === 0 branch and the else branch call
setActiveIndex(0) and setDidLoadCurrentUrl(false). Simplify by removing the
conditional and early return so the effect simply runs on urls change and always
calls setActiveIndex(0) and setDidLoadCurrentUrl(false); locate the effect that
references urls and the setters setActiveIndex and setDidLoadCurrentUrl to
update it.

In `@components/leaderboard/LeaderboardCollector.tsx`:
- Around line 43-55: The current conditional uses a truthy check on props.level
which treats 0 as falsy and hides the level badge; update the check to
explicitly test for undefined/null (e.g., props.level !== undefined &&
props.level !== null) so a valid level 0 will render the UserCICAndLevel badge,
or alternatively change the prop signature to make level optional (level?:
number) if 0 should mean "no level"—adjust the rendering around UserCICAndLevel
and any callers accordingly to match the chosen contract.

In `@components/nft-image/utils/gateway-fallback.ts`:
- Around line 46-58: Duplicate IPFS gateway parsing/normalization exists:
extract a shared helper (e.g., export getConfiguredIpfsGatewayHost from a new
module in the config/env or ipfs helpers file) that reads
publicEnv.IPFS_GATEWAY_ENDPOINT, constructs a URL, and returns
canonicalizeArweaveGatewayHostname(parsedUrl.hostname) or null on error; replace
the local implementation in components/nft-image/utils/gateway-fallback.ts and
the duplicate in components/waves/memes/submission/constants/security.ts with
imports of the new getConfiguredIpfsGatewayHost to ensure a single source of
truth and keep canonicalizeArweaveGatewayHostname usage unchanged.

In `@config/securityHeaders.ts`:
- Line 37: The CSP string currently interpolates variables like
configuredIpfsGatewaySource and arweaveGatewaySources directly, which yields
extra spaces when values are empty; update the code that builds the value (the
long template string assigned to value in config/securityHeaders.ts) to
construct each directive from an array of source strings (e.g., for frame-src,
media-src, img-src, connect-src), filter out falsy/empty entries
(Array.prototype.filter(Boolean)), then join(' ') so empty variables (like
configuredIpfsGatewaySource) are removed and no double spaces remain; ensure you
reference and use the existing symbols (configuredIpfsGatewaySource,
arweaveGatewaySources, apiEndpoint) when building those arrays so behavior is
unchanged when values are present.

In `@standalone/standalone-memes-mint/scripts/export-mint-page.cjs`:
- Around line 143-219: The fetchJson function lacks a request timeout and can
hang; update fetchJson to accept an optional timeout parameter (default e.g.
10000 ms) and apply it to the outgoing request (use req.setTimeout or an
AbortController-style abort) so that when the timer fires you abort the request
and reject with a clear timeout Error; ensure you handle the aborted request
cleanly by listening/removing the 'error' and 'timeout' handlers and avoiding
double-resolve/reject (refer to fetchJson, req, and the client.request response
handler) and include a helpful message like `Timeout after ${timeout}ms while
fetching ${url}`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6cb5edb1-ae12-40e7-b885-aec0c830231a

📥 Commits

Reviewing files that changed from the base of the PR and between 926685b and 5eb7b4b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (33)
  • __tests__/components/the-memes/MemePageArt.test.tsx
  • __tests__/contexts/SeizeSettingsContext.test.tsx
  • __tests__/standalone/StandaloneTheMemesMintPageClient.test.tsx
  • app/the-memes/mint/page.tsx
  • components/common/SandboxedExternalIframe.tsx
  • components/drop-forge/craft/DropForgeCraftClaimPageClient.tsx
  • components/drop-forge/launch/DropForgeLaunchClaimPageClient.tsx
  • components/drop-forge/launch/DropForgeLaunchClaimPageClient.view.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/leaderboard/Leaderboard.module.scss
  • components/leaderboard/LeaderboardCollector.tsx
  • components/manifold-minting/ManifoldMinting.tsx
  • components/nft-attributes/NFTAttributes.tsx
  • components/nft-image/NFTModel.tsx
  • components/nft-image/renderers/NFTHTMLRenderer.tsx
  • components/nft-image/renderers/NFTImageRenderer.tsx
  • components/nft-image/renderers/NFTVideoRenderer.tsx
  • components/nft-image/utils/gateway-fallback.ts
  • components/providers/Providers.tsx
  • components/the-memes/MemePageArt.tsx
  • components/wallet-connect-balance/WalletConnectBalance.tsx
  • components/waves/memes/submission/constants/security.ts
  • config/nextConfig.ts
  • config/securityHeaders.ts
  • contexts/SeizeSettingsContext.tsx
  • package.json
  • standalone/standalone-memes-mint/README.md
  • standalone/standalone-memes-mint/scripts/export-mint-page.cjs
  • standalone/standalone-memes-mint/src/app/StandaloneTheMemesMintPageClient.tsx
  • standalone/standalone-memes-mint/src/app/layout.tsx
  • standalone/standalone-memes-mint/src/app/page.tsx
  • tailwind.config.ts
  • types/enums.ts
✅ Files skipped from review due to trivial changes (4)
  • types/enums.ts
  • standalone/standalone-memes-mint/src/app/page.tsx
  • components/wallet-connect-balance/WalletConnectBalance.tsx
  • standalone/standalone-memes-mint/README.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • app/the-memes/mint/page.tsx
  • components/nft-image/renderers/NFTImageRenderer.tsx
  • tests/standalone/StandaloneTheMemesMintPageClient.test.tsx
  • tailwind.config.ts
  • standalone/standalone-memes-mint/src/app/StandaloneTheMemesMintPageClient.tsx
  • components/providers/Providers.tsx

Comment thread contexts/SeizeSettingsContext.tsx
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Comment thread standalone/standalone-memes-mint/scripts/export-mint-page.cjs Fixed
Signed-off-by: prxt6529 <prxt@6529.io>
Comment thread standalone/standalone-memes-mint/scripts/export-mint-page.cjs Dismissed
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
Signed-off-by: prxt6529 <prxt@6529.io>
@sonarqubecloud
Copy link
Copy Markdown

@prxt6529 prxt6529 merged commit 6516a24 into main Mar 24, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants