Skip to content

feat: sdk example app#519

Open
valentinludu wants to merge 14 commits into
devfrom
feat/sdk-example-app
Open

feat: sdk example app#519
valentinludu wants to merge 14 commits into
devfrom
feat/sdk-example-app

Conversation

@valentinludu

@valentinludu valentinludu commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Webapp built with Next.js, wagmi, tailwind and nexusmutual/sdk as a proof of concept for developers who will integrate our sdk

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a complete Next.js + wagmi example application demonstrating SDK integration
    • Added cover metadata management capabilities for viewing and editing cover information
    • Integrated EIP-712 authentication for secure metadata operations
  • Updates

    • Refined quote flow to leverage cover metadata system
    • Streamlined IPFS validation by removing legacy content type handlers

@valentinludu valentinludu requested a review from mixplore June 17, 2026 13:30
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f21254f8-260e-459d-b4f4-cd08522775b4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a CoverData SDK class with getCover, viewCoverMetadata, and editCoverMetadata methods backed by new cover-metadata types and EIP-712 auth helpers. Refactors Quote to derive ipfsData from a backend /cover-metadata POST instead of IPFS content uploads, and removes all cover-related IPFS schemas. Adds a complete examples/nextjs-wagmi Next.js app demonstrating buy-cover, view-metadata, and edit-metadata flows.

Changes

SDK: Cover Metadata Module and Quote Refactor

Layer / File(s) Summary
Cover metadata types and EIP-712 auth module
src/types/cover-metadata.ts, src/types/index.ts, src/types/product.ts, src/auth.ts, src/auth.test.ts
New ProofOfLossEntry discriminated union, auth payload/signature types, and API response shapes; ProductType and Product replace ipfsContentType/ContentType with isProofOfLossRequired and proofOfLossInputTypes; buildAuthTypedData and buildCoverMetadataAuthMessage produce EIP-712 typed-data objects with tests.
Remove cover-related IPFS schemas and ContentType entries
src/ipfs/schemas.ts, src/types/ipfs.ts, src/ipfs/Ipfs.ts, src/ipfs/uploadIPFSContent.test.ts, src/ipfs/validateIPFSContent.test.ts
Deletes eight cover*/defiPassContent Zod schemas, removes corresponding ContentType enum members and inferred type exports, drops the matching switch branches from validateIPFSContent, and migrates affected tests to use stakingPoolDetails.
CoverData class and SDK entrypoint wiring
src/cover/Cover.ts, src/cover/index.ts, src/nexus-sdk.ts, src/index.ts, src/cover/Cover.test.ts
New CoverData class with getCover, viewCoverMetadata, editCoverMetadata, and buildAuthHeaders; NexusSDK gains a public cover property; src/index.ts re-exports cover and auth; full test suite for all three methods including auth header and BigInt serialization cases.
Quote refactor: IPFS content → cover-metadata endpoint
src/quote/Quote.ts, src/types/sdk.ts, src/quote/getQuoteAndBuyCoverInputs.test.ts
Quote constructor drops the Ipfs parameter; getQuoteAndBuyCoverInputs accepts coverMetadata, validates proof-of-loss type coverage, POSTs to /cover-metadata via new createCoverMetadata helper to obtain a CID, and removes the prior ipfsCidOrContent IPFS upload path; tests replaced to cover the new flow.

Next.js wagmi Example App

Layer / File(s) Summary
Project scaffolding and SDK/wagmi configuration
.npmignore, examples/nextjs-wagmi/package.json, examples/nextjs-wagmi/tsconfig.json, examples/nextjs-wagmi/next.config.ts, examples/nextjs-wagmi/postcss.config.mjs, examples/nextjs-wagmi/eslint.config.mjs, examples/nextjs-wagmi/pnpm-workspace.yaml, examples/nextjs-wagmi/.gitignore, examples/nextjs-wagmi/README.md, examples/nextjs-wagmi/config/wagmi.ts, examples/nextjs-wagmi/config/sdk.ts
Complete project configuration; wagmi mainnet config with injected() connector; pre-instantiated NexusSDK and ProductAPI clients; .npmignore excludes the examples directory from the published package.
App shell: providers, layout, home page, and debounce hook
examples/nextjs-wagmi/app/providers.tsx, examples/nextjs-wagmi/app/globals.css, examples/nextjs-wagmi/app/layout.tsx, examples/nextjs-wagmi/app/page.tsx, examples/nextjs-wagmi/hooks/useDebounce.ts
Providers composes WagmiProvider and QueryClientProvider; RootLayout applies Geist fonts and global Tailwind CSS; Home renders a ConnectButton and a wallet-gated grid of three feature cards; generic useDebounce hook.
Feature pages: buy-cover, view-metadata, edit-metadata
examples/nextjs-wagmi/app/buy-cover/page.tsx, examples/nextjs-wagmi/app/view-metadata/page.tsx, examples/nextjs-wagmi/app/edit-metadata/page.tsx
BuyCoverPage: product/amount/period/asset form, debounced product fetch, quote mutation, and buyCover contract call with ETH value and Etherscan receipt link. ViewMetadataPage: two-step getCoverviewCoverMetadata with optional EIP-712–signed private data. EditMetadataPage: ProofOfLossEntry builder, useSignTypedData, and editCoverMetadata mutation.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant BuyCoverPage
  participant NexusSDK
  participant NexusAPI
  participant CoverBrokerContract

  rect rgba(70, 130, 180, 0.5)
    note over User,NexusSDK: Quote flow
    User->>BuyCoverPage: Enter productId/amount/period/asset → Get Quote
    BuyCoverPage->>NexusSDK: getQuoteAndBuyCoverInputs({ coverMetadata? })
    NexusSDK->>NexusAPI: GET product + productType
    NexusSDK->>NexusAPI: POST /cover-metadata (if coverMetadata present)
    NexusAPI-->>NexusSDK: { cid }
    NexusSDK->>NexusAPI: GET /quote
    NexusAPI-->>NexusSDK: quote + buyCoverInput
    NexusSDK-->>BuyCoverPage: displayInfo + buyCoverParams
  end

  rect rgba(34, 139, 34, 0.5)
    note over User,CoverBrokerContract: Buy flow
    User->>BuyCoverPage: Confirm Buy Cover
    BuyCoverPage->>CoverBrokerContract: buyCover(params) [value=ETH if ETH asset]
    CoverBrokerContract-->>BuyCoverPage: transaction receipt
    BuyCoverPage-->>User: Etherscan link
  end
Loading
sequenceDiagram
  participant User
  participant EditMetadataPage
  participant wagmiSignTypedData
  participant CoverData

  User->>EditMetadataPage: Enter coverMetadataId + ProofOfLossEntry value → Submit
  EditMetadataPage->>wagmiSignTypedData: signTypedData(buildCoverMetadataAuthMessage())
  wagmiSignTypedData-->>EditMetadataPage: signature string
  EditMetadataPage->>CoverData: editCoverMetadata({ coverMetadataId, proofOfLoss, signature })
  CoverData->>CoverData: buildAuthHeaders(signature) → x-auth-* headers
  CoverData-->>EditMetadataPage: { result } or { error }
  EditMetadataPage-->>User: success panel or error message
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • NexusMutual/sdk#491: Modifies src/quote/Quote.ts to fetch products/product-types via ProductAPI, which is the same Quote class this PR refactors to replace IPFS content handling with a cover-metadata endpoint.

Suggested reviewers

  • MilGard91
  • rackstar
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: sdk example app' accurately and concisely describes the main change—adding a Next.js example application that demonstrates SDK integration.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 feat/sdk-example-app
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/sdk-example-app

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

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 17, 2026

Copy link
Copy Markdown

Deploying sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 47e8cfd
Status: ✅  Deploy successful!
Preview URL: https://e03106e2.sdk-9yp.pages.dev
Branch Preview URL: https://feat-sdk-example-app.sdk-9yp.pages.dev

View logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (7)
src/types/product.ts (2)

33-33: ⚡ Quick win

Consider documenting validation behavior.

The proofOfLossInputTypes field specifies which proof types are required when proof of loss data is provided. Consider adding a JSDoc comment to clarify that:

  • These types are validated only when coverMetadata.proofOfLoss is provided
  • All specified types must be present (at least one entry per type)
  • This is independent of ProductType.isProofOfLossRequired
📝 Suggested documentation
+  /**
+   * Required proof of loss input types for this product.
+   * When coverMetadata.proofOfLoss is provided, all types listed here must be present.
+   * Validated in conjunction with ProductType.isProofOfLossRequired.
+   */
   proofOfLossInputTypes?: ProofOfLossEntry['type'][];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/types/product.ts` at line 33, Add a JSDoc comment above the
proofOfLossInputTypes field to document its validation behavior. The comment
should clarify that these types are validated only when
coverMetadata.proofOfLoss is provided, that all specified types must be present
with at least one entry per type, and that this validation is independent of
ProductType.isProofOfLossRequired. This will help other developers understand
the field's purpose and behavior constraints.

15-15: ⚡ Quick win

Consider documenting the relationship with proofOfLossInputTypes.

The isProofOfLossRequired field works in conjunction with Product.proofOfLossInputTypes. Their relationship isn't immediately clear from the type definitions:

  • isProofOfLossRequired: Whether proof of loss data is mandatory for this product type
  • proofOfLossInputTypes: Which specific proof types must be present (validated only if proof is provided)

Consider adding a JSDoc comment explaining this relationship for future maintainers.

📝 Suggested documentation
+  /**
+   * Whether proof of loss is required for this product type.
+   * When true, coverMetadata.proofOfLoss must be provided and non-empty.
+   * Used in conjunction with Product.proofOfLossInputTypes to validate proof data.
+   */
   isProofOfLossRequired?: boolean;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/types/product.ts` at line 15, Add a JSDoc comment to the
`isProofOfLossRequired` field that documents its relationship with the
`proofOfLossInputTypes` field. The comment should clarify that
`isProofOfLossRequired` indicates whether proof of loss data is mandatory for
this product type, while `proofOfLossInputTypes` specifies which specific proof
types must be present (only validated when proof is actually provided). This
will help future maintainers understand how these two fields work together.
examples/nextjs-wagmi/app/page.tsx (1)

59-88: ⚡ Quick win

Add error handling for wallet connection failures.

The ConnectButton calls connect({ connector: injected() }) without handling potential errors. If the connection fails (e.g., user rejects, MetaMask not installed), the user receives no feedback.

♻️ Proposed fix to add error state
 function ConnectButton() {
   const { address, isConnected } = useAccount();
   const { mutate: connect } = useConnect();
   const { mutate: disconnect } = useDisconnect();
+  const [error, setError] = useState<string>();

   if (isConnected && address) {
     return (
       <div className="flex items-center gap-3">
         <span className="rounded-full bg-primary-light px-3 py-1.5 text-sm font-mono text-primary">
           {address.slice(0, 6)}...{address.slice(-4)}
         </span>
         <button
           onClick={() => disconnect()}
           className="rounded-lg border border-card-border px-4 py-2 text-sm font-medium text-muted transition-colors hover:border-primary hover:text-foreground"
         >
           Disconnect
         </button>
       </div>
     );
   }

   return (
-    <button
-      onClick={() => connect({ connector: injected() })}
-      className="rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-primary-hover"
-    >
-      Connect Wallet
-    </button>
+    <div>
+      <button
+        onClick={() => {
+          setError(undefined);
+          connect(
+            { connector: injected() },
+            {
+              onError: (err) => setError(err.message),
+            }
+          );
+        }}
+        className="rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-primary-hover"
+      >
+        Connect Wallet
+      </button>
+      {error && (
+        <p className="mt-2 text-sm text-red-600">{error}</p>
+      )}
+    </div>
   );
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/nextjs-wagmi/app/page.tsx` around lines 59 - 88, The ConnectButton
component needs error handling for the wallet connection process. Modify the
useConnect hook destructuring to also capture the error state that it returns,
then add a local state variable to track connection errors. When the user clicks
the connect button and the mutation fails, capture and display the error message
to the user in the UI. Consider adding error state management alongside the
connection logic in the onClick handler for the Connect Wallet button and
displaying the error message conditionally in the component's return statement.
examples/nextjs-wagmi/app/view-metadata/page.tsx (1)

17-21: ⚡ Quick win

Handle invalid cover ID input explicitly.

Line 20 converts coverId to a number without validation. If the user bypasses client-side checks or coverId contains non-numeric characters, Number(coverId) returns NaN, which would pass an invalid value to getCover().

While the UI's canFetch check (line 61) prevents the button from being enabled when coverId is invalid, adding explicit validation in the mutation function would make the error case clearer and provide better error messages.

♻️ Proposed fix to add explicit validation
   const viewMetadata = useMutation({
     mutationFn: async (): Promise<ViewCoverMetadataResponse> => {
+      const coverIdNum = Number(coverId);
+      if (!Number.isInteger(coverIdNum) || coverIdNum <= 0) {
+        throw new Error('Cover ID must be a positive integer');
+      }
+
       // Step 1: Get cover data (includes coverMetadataId)
-      const coverResponse = await sdk.cover.getCover(Number(coverId));
+      const coverResponse = await sdk.cover.getCover(coverIdNum);

       if (coverResponse.error) {
         throw new Error(coverResponse.error.message);
       }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/nextjs-wagmi/app/view-metadata/page.tsx` around lines 17 - 21, Add
explicit validation for the coverId parameter in the mutationFn function of the
viewMetadata useMutation hook before passing it to sdk.cover.getCover(). Instead
of directly calling Number(coverId), first validate that coverId is a non-empty
string and contains only numeric characters, then parse it. If validation fails,
throw an error with a clear message indicating what went wrong (e.g., "Invalid
cover ID provided"). This ensures that invalid inputs are caught early in the
mutation function with better error messaging rather than relying solely on the
UI-level canFetch check.
examples/nextjs-wagmi/app/edit-metadata/page.tsx (1)

28-41: ⚖️ Poor tradeoff

Consider validating entry values before building proof of loss.

The buildProofOfLoss function constructs entries without validating the format of entryValue. For example, when entryType is 'address', the function doesn't verify that entryValue is a valid Ethereum address. Adding validation would prevent submission of malformed data.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/nextjs-wagmi/app/edit-metadata/page.tsx` around lines 28 - 41, The
buildProofOfLoss function constructs proof of loss entries without validating
that entryValue conforms to the expected format for the given entryType. Add
validation logic at the beginning of the buildProofOfLoss function that checks
entryValue against each case type, such as validating that entryValue is a valid
Ethereum address when entryType is 'address', validating API key format when
entryType is 'api_key', and so on. This validation should occur before the
switch statement and should either throw an error or return an invalid state to
prevent malformed data from being submitted.
examples/nextjs-wagmi/app/buy-cover/page.tsx (1)

91-95: 💤 Low value

Review the exhaustive-deps disable.

The useEffect disables the react-hooks/exhaustive-deps rule because quoteMutation.reset is not included in the dependency array. This pattern can lead to stale closure bugs if the mutation object identity changes.

Consider whether quoteMutation.reset should be added to the deps array or wrap it in a useCallback to stabilize its identity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/nextjs-wagmi/app/buy-cover/page.tsx` around lines 91 - 95, The
useEffect hook disables the exhaustive-deps ESLint rule because
quoteMutation.reset is used within the effect but not included in the dependency
array, which can cause stale closure bugs. Fix this by either adding
quoteMutation.reset to the dependency array along with debouncedProductId, or by
wrapping quoteMutation.reset in a useCallback hook to stabilize its identity,
then remove the eslint-disable comment once the dependency issue is resolved.
examples/nextjs-wagmi/config/wagmi.ts (1)

1-11: 💤 Low value

Consider adding a comment about RPC fallback for public accessibility.

The config uses http() with no URL, which falls back to a public RPC, though an authenticated RPC URL is highly recommended to prevent rate-limiting. For an example app, this is acceptable, but a brief comment clarifying this trade-off would improve maintainability.

export const config = createConfig({
  chains: [mainnet],
  connectors: [injected()],
  transports: {
+   // Falls back to public RPC; use authenticated URL for production
    [mainnet.id]: http(),
  },
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/nextjs-wagmi/config/wagmi.ts` around lines 1 - 11, The http()
function in the transports configuration lacks documentation explaining its
behavior. Add a comment above the transports object that clarifies that http()
without a URL argument falls back to a public RPC endpoint, which may be
rate-limited, and note that while acceptable for example applications, an
authenticated RPC URL should be used in production environments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/nextjs-wagmi/app/buy-cover/page.tsx`:
- Line 75: The code on line 75 uses a non-null assertion on response.result
without first verifying that the result property exists. While the error check
on lines 71-73 guards against response.error, it does not guarantee that
response.result is present. Add an explicit check to verify that response.result
is defined and not null before returning it, and handle the case where result is
missing appropriately instead of relying on the non-null assertion operator.
- Line 350: The href attribute in the transaction link is hardcoded to the
mainnet Etherscan URL, which breaks for users on other networks. Instead of
using the hardcoded https://etherscan.io/tx/ string, dynamically construct the
explorer URL by accessing the current chain information from wagmi (typically
available through useNetwork or from the chain object in your wagmi config) and
use the appropriate blockExplorers property from the chain data to build the
correct explorer URL for the current network before appending the txHash.

In `@examples/nextjs-wagmi/app/edit-metadata/page.tsx`:
- Around line 53-69: Remove all debug console.log statements from the
editCoverMetadata function block in the page.tsx file. Specifically, delete the
four console.log calls: the one logging the signature ("enters sig"), the one
logging proofOfLoss, the one logging the response, and the one logging the
error. Keep all the actual business logic intact, including the buildProofOfLoss
call, the sdk.cover.editCoverMetadata API call, and the error handling
conditional check. Only remove the logging statements to prevent sensitive data
like signatures and proof of loss information from being exposed to browser
consoles.

In `@examples/nextjs-wagmi/package.json`:
- Line 26: The eslint-config-next package version set to 16.2.9 does not align
with the actual Next.js version being used in the project. Verify the Next.js
version specified in the dependencies of the package.json file and update the
eslint-config-next version to match the corresponding compatible version for
that Next.js release, ensuring consistency across both packages.

In `@src/cover/Cover.ts`:
- Around line 20-31: The validation check in the getCover method currently does
not prevent Infinity and -Infinity values from passing through since these are
not caught by the `!coverId || coverId <= 0` condition. Replace or enhance the
validation condition to also check that coverId is a finite number by using
Number.isFinite(coverId) or by adding explicit checks to reject Infinity and
-Infinity values alongside the existing checks for zero, negative numbers, and
NaN.

---

Nitpick comments:
In `@examples/nextjs-wagmi/app/buy-cover/page.tsx`:
- Around line 91-95: The useEffect hook disables the exhaustive-deps ESLint rule
because quoteMutation.reset is used within the effect but not included in the
dependency array, which can cause stale closure bugs. Fix this by either adding
quoteMutation.reset to the dependency array along with debouncedProductId, or by
wrapping quoteMutation.reset in a useCallback hook to stabilize its identity,
then remove the eslint-disable comment once the dependency issue is resolved.

In `@examples/nextjs-wagmi/app/edit-metadata/page.tsx`:
- Around line 28-41: The buildProofOfLoss function constructs proof of loss
entries without validating that entryValue conforms to the expected format for
the given entryType. Add validation logic at the beginning of the
buildProofOfLoss function that checks entryValue against each case type, such as
validating that entryValue is a valid Ethereum address when entryType is
'address', validating API key format when entryType is 'api_key', and so on.
This validation should occur before the switch statement and should either throw
an error or return an invalid state to prevent malformed data from being
submitted.

In `@examples/nextjs-wagmi/app/page.tsx`:
- Around line 59-88: The ConnectButton component needs error handling for the
wallet connection process. Modify the useConnect hook destructuring to also
capture the error state that it returns, then add a local state variable to
track connection errors. When the user clicks the connect button and the
mutation fails, capture and display the error message to the user in the UI.
Consider adding error state management alongside the connection logic in the
onClick handler for the Connect Wallet button and displaying the error message
conditionally in the component's return statement.

In `@examples/nextjs-wagmi/app/view-metadata/page.tsx`:
- Around line 17-21: Add explicit validation for the coverId parameter in the
mutationFn function of the viewMetadata useMutation hook before passing it to
sdk.cover.getCover(). Instead of directly calling Number(coverId), first
validate that coverId is a non-empty string and contains only numeric
characters, then parse it. If validation fails, throw an error with a clear
message indicating what went wrong (e.g., "Invalid cover ID provided"). This
ensures that invalid inputs are caught early in the mutation function with
better error messaging rather than relying solely on the UI-level canFetch
check.

In `@examples/nextjs-wagmi/config/wagmi.ts`:
- Around line 1-11: The http() function in the transports configuration lacks
documentation explaining its behavior. Add a comment above the transports object
that clarifies that http() without a URL argument falls back to a public RPC
endpoint, which may be rate-limited, and note that while acceptable for example
applications, an authenticated RPC URL should be used in production
environments.

In `@src/types/product.ts`:
- Line 33: Add a JSDoc comment above the proofOfLossInputTypes field to document
its validation behavior. The comment should clarify that these types are
validated only when coverMetadata.proofOfLoss is provided, that all specified
types must be present with at least one entry per type, and that this validation
is independent of ProductType.isProofOfLossRequired. This will help other
developers understand the field's purpose and behavior constraints.
- Line 15: Add a JSDoc comment to the `isProofOfLossRequired` field that
documents its relationship with the `proofOfLossInputTypes` field. The comment
should clarify that `isProofOfLossRequired` indicates whether proof of loss data
is mandatory for this product type, while `proofOfLossInputTypes` specifies
which specific proof types must be present (only validated when proof is
actually provided). This will help future maintainers understand how these two
fields work together.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 33f26520-26d1-4a93-9511-e2a9127874bb

📥 Commits

Reviewing files that changed from the base of the PR and between 0a65882 and 0ca5aac.

⛔ Files ignored due to path filters (4)
  • examples/nextjs-wagmi/app/favicon.ico is excluded by !**/*.ico
  • examples/nextjs-wagmi/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • examples/nextjs-wagmi/public/globe.svg is excluded by !**/*.svg
  • examples/nextjs-wagmi/public/vercel.svg is excluded by !**/*.svg
📒 Files selected for processing (37)
  • .npmignore
  • examples/nextjs-wagmi/.gitignore
  • examples/nextjs-wagmi/README.md
  • examples/nextjs-wagmi/app/buy-cover/page.tsx
  • examples/nextjs-wagmi/app/edit-metadata/page.tsx
  • examples/nextjs-wagmi/app/globals.css
  • examples/nextjs-wagmi/app/layout.tsx
  • examples/nextjs-wagmi/app/page.tsx
  • examples/nextjs-wagmi/app/providers.tsx
  • examples/nextjs-wagmi/app/view-metadata/page.tsx
  • examples/nextjs-wagmi/config/sdk.ts
  • examples/nextjs-wagmi/config/wagmi.ts
  • examples/nextjs-wagmi/eslint.config.mjs
  • examples/nextjs-wagmi/hooks/useDebounce.ts
  • examples/nextjs-wagmi/next.config.ts
  • examples/nextjs-wagmi/package.json
  • examples/nextjs-wagmi/pnpm-workspace.yaml
  • examples/nextjs-wagmi/postcss.config.mjs
  • examples/nextjs-wagmi/tsconfig.json
  • src/auth.test.ts
  • src/auth.ts
  • src/cover/Cover.test.ts
  • src/cover/Cover.ts
  • src/cover/index.ts
  • src/index.ts
  • src/ipfs/Ipfs.ts
  • src/ipfs/schemas.ts
  • src/ipfs/uploadIPFSContent.test.ts
  • src/ipfs/validateIPFSContent.test.ts
  • src/nexus-sdk.ts
  • src/quote/Quote.ts
  • src/quote/getQuoteAndBuyCoverInputs.test.ts
  • src/types/cover-metadata.ts
  • src/types/index.ts
  • src/types/ipfs.ts
  • src/types/product.ts
  • src/types/sdk.ts
💤 Files with no reviewable changes (4)
  • src/ipfs/validateIPFSContent.test.ts
  • src/ipfs/schemas.ts
  • src/ipfs/Ipfs.ts
  • src/types/ipfs.ts

throw new Error(response.error.message);
}

return response.result!;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Non-null assertion without verification.

The code uses the non-null assertion operator (response.result!) without first checking that response.result is defined. While Line 71-73 checks for response.error, the absence of an error doesn't guarantee result is present.

🛡️ Proposed fix to add explicit result check
     if (response.error) {
       throw new Error(response.error.message);
     }
+    if (!response.result) {
+      throw new Error('Quote failed: no result returned');
+    }

     return response.result!;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return response.result!;
if (response.error) {
throw new Error(response.error.message);
}
if (!response.result) {
throw new Error('Quote failed: no result returned');
}
return response.result!;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/nextjs-wagmi/app/buy-cover/page.tsx` at line 75, The code on line 75
uses a non-null assertion on response.result without first verifying that the
result property exists. While the error check on lines 71-73 guards against
response.error, it does not guarantee that response.result is present. Add an
explicit check to verify that response.result is defined and not null before
returning it, and handle the case where result is missing appropriately instead
of relying on the non-null assertion operator.

<div className="rounded-xl border border-green-200 bg-green-50 p-4 dark:border-green-900 dark:bg-green-950">
<p className="text-sm font-medium text-green-700 dark:text-green-300">Cover purchased!</p>
<a
href={`https://etherscan.io/tx/${txHash}`}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Hardcoded mainnet Etherscan URL.

The Etherscan link is hardcoded to https://etherscan.io, which only works on mainnet. If the wagmi config supports multiple networks, users will be directed to the wrong block explorer.

🔗 Suggested improvement to use chain-aware explorer

Use wagmi's chain information to construct the correct explorer URL:

+import { useAccount, useWriteContract, useWaitForTransactionReceipt, useChainId } from 'wagmi';
+import { mainnet } from 'wagmi/chains';

 export default function BuyCoverPage() {
-  const { address, isConnected } = useAccount();
+  const { address, isConnected, chain } = useAccount();
+  const explorerUrl = chain?.blockExplorers?.default?.url ?? 'https://etherscan.io';
   
   // ...
   
             {isConfirmed && txHash && (
               <div className="rounded-xl border border-green-200 bg-green-50 p-4 dark:border-green-900 dark:bg-green-950">
                 <p className="text-sm font-medium text-green-700 dark:text-green-300">Cover purchased!</p>
                 <a
-                  href={`https://etherscan.io/tx/${txHash}`}
+                  href={`${explorerUrl}/tx/${txHash}`}
                   target="_blank"
                   rel="noopener noreferrer"
                   className="mt-1 block text-sm text-green-600 underline dark:text-green-400"
                 >
                   View on Etherscan
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
href={`https://etherscan.io/tx/${txHash}`}
import { useAccount, useWriteContract, useWaitForTransactionReceipt, useChainId } from 'wagmi';
import { mainnet } from 'wagmi/chains';
export default function BuyCoverPage() {
const { address, isConnected, chain } = useAccount();
const explorerUrl = chain?.blockExplorers?.default?.url ?? 'https://etherscan.io';
// ... rest of component ...
{isConfirmed && txHash && (
<div className="rounded-xl border border-green-200 bg-green-50 p-4 dark:border-green-900 dark:bg-green-950">
<p className="text-sm font-medium text-green-700 dark:text-green-300">Cover purchased!</p>
<a
href={`${explorerUrl}/tx/${txHash}`}
target="_blank"
rel="noopener noreferrer"
className="mt-1 block text-sm text-green-600 underline dark:text-green-400"
>
View on Etherscan
</a>
</div>
)}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/nextjs-wagmi/app/buy-cover/page.tsx` at line 350, The href attribute
in the transaction link is hardcoded to the mainnet Etherscan URL, which breaks
for users on other networks. Instead of using the hardcoded
https://etherscan.io/tx/ string, dynamically construct the explorer URL by
accessing the current chain information from wagmi (typically available through
useNetwork or from the chain object in your wagmi config) and use the
appropriate blockExplorers property from the chain data to build the correct
explorer URL for the current network before appending the txHash.

Comment on lines +53 to +69
console.log('enters sig', { signature });
const proofOfLoss = [buildProofOfLoss()];
console.log('proof of loss', { proofOfLoss });

const response = await sdk.cover.editCoverMetadata({
coverMetadataId,
proofOfLoss,
signature: {
signature,
payload: typedData.value,
},
});

console.log('response', { response });

if (response.error) {
console.log('error', { error: response.error });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove debug console.log statements.

Multiple console.log statements are present in the production code (lines 53, 55, 66, 69). These should be removed before merging as they can leak sensitive information (signatures, proof of loss data) to browser consoles.

🧹 Proposed cleanup
       });
-      console.log('enters sig', { signature });
       const proofOfLoss = [buildProofOfLoss()];
-      console.log('proof of loss', { proofOfLoss });

       const response = await sdk.cover.editCoverMetadata({
         coverMetadataId,
         proofOfLoss,
         signature: {
           signature,
           payload: typedData.value,
         },
       });

-      console.log('response', { response });
-
       if (response.error) {
-        console.log('error', { error: response.error });
         throw new Error(response.error.message);
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log('enters sig', { signature });
const proofOfLoss = [buildProofOfLoss()];
console.log('proof of loss', { proofOfLoss });
const response = await sdk.cover.editCoverMetadata({
coverMetadataId,
proofOfLoss,
signature: {
signature,
payload: typedData.value,
},
});
console.log('response', { response });
if (response.error) {
console.log('error', { error: response.error });
const proofOfLoss = [buildProofOfLoss()];
const response = await sdk.cover.editCoverMetadata({
coverMetadataId,
proofOfLoss,
signature: {
signature,
payload: typedData.value,
},
});
if (response.error) {
throw new Error(response.error.message);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/nextjs-wagmi/app/edit-metadata/page.tsx` around lines 53 - 69,
Remove all debug console.log statements from the editCoverMetadata function
block in the page.tsx file. Specifically, delete the four console.log calls: the
one logging the signature ("enters sig"), the one logging proofOfLoss, the one
logging the response, and the one logging the error. Keep all the actual
business logic intact, including the buildProofOfLoss call, the
sdk.cover.editCoverMetadata API call, and the error handling conditional check.
Only remove the logging statements to prevent sensitive data like signatures and
proof of loss information from being exposed to browser consoles.

"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.2.9",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Verify eslint-config-next version compatibility.

The eslint-config-next version is set to 16.2.9, which matches the invalid Next.js version. This package version should align with the actual Next.js version being used.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/nextjs-wagmi/package.json` at line 26, The eslint-config-next
package version set to 16.2.9 does not align with the actual Next.js version
being used in the project. Verify the Next.js version specified in the
dependencies of the package.json file and update the eslint-config-next version
to match the corresponding compatible version for that Next.js release, ensuring
consistency across both packages.

Comment thread src/cover/Cover.ts
Comment on lines +20 to +31
public async getCover(coverId: number): Promise<GetCoverApiResponse | ErrorApiResponse> {
if (!coverId || coverId <= 0) {
return { result: undefined, error: { message: 'Invalid coverId: must be a positive number' } };
}

try {
const response = await this.sendRequest<GetCoverResponse>(`/cover/${coverId}`);
return { result: response, error: undefined };
} catch (error: unknown) {
return { result: undefined, error: { message: (error as Error).message || 'Failed to fetch cover' } };
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add validation for Infinity and -Infinity.

The current check !coverId || coverId <= 0 correctly rejects 0, NaN, and negative numbers, but allows Infinity to pass through. While the API would likely reject /cover/Infinity with a 404 or 400, catching this at the SDK layer provides a clearer error message to the caller.

🛡️ Suggested fix
-    if (!coverId || coverId <= 0) {
-      return { result: undefined, error: { message: 'Invalid coverId: must be a positive number' } };
+    if (!coverId || coverId <= 0 || !isFinite(coverId)) {
+      return { result: undefined, error: { message: 'Invalid coverId: must be a positive finite number' } };
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cover/Cover.ts` around lines 20 - 31, The validation check in the
getCover method currently does not prevent Infinity and -Infinity values from
passing through since these are not caught by the `!coverId || coverId <= 0`
condition. Replace or enhance the validation condition to also check that
coverId is a finite number by using Number.isFinite(coverId) or by adding
explicit checks to reject Infinity and -Infinity values alongside the existing
checks for zero, negative numbers, and NaN.

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.

1 participant