Skip to content

feat: replace direct IPFS upload with POST /cover-metadata endpoint#518

Open
valentinludu wants to merge 8 commits into
devfrom
feat/cover-metadata-api
Open

feat: replace direct IPFS upload with POST /cover-metadata endpoint#518
valentinludu wants to merge 8 commits into
devfrom
feat/cover-metadata-api

Conversation

@valentinludu

@valentinludu valentinludu commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace direct IPFS upload in Quote.getQuoteAndBuyCoverInputs with a call to POST /cover-metadata on the backend
  • The backend now handles IPFS upload (stores only a UUID reference) and keeps private proof-of-loss data in Postgres
  • Remove ipfsCidOrContent param, replace with coverMetadata accepting { proofOfLoss?, publicData? }
  • Use isProofOfLossRequired (from product type API) to enforce metadata requirement

What was removed

  • Ipfs dependency from Quote class (still available on NexusSDK.ipfs for claims/governance)
  • 8 cover-specific IPFS content types and schemas: coverValidators, coverQuotaShare, coverAumCoverAmountPercentage, coverWalletAddress, coverWalletAddresses, coverFreeText, coverDesignatedWallets, defiPassContent
  • ipfsContentType field from ProductType

What was added

  • CoverMetadataInput, ProofOfLossEntry, ProofOfLossValue, CoverPublicData types
  • isProofOfLossRequired on ProductType, proofOfLossInputTypes on Product
  • Private createCoverMetadata() method that POSTs to /cover-metadata and returns the CID

Why

Previously the SDK uploaded proof-of-loss data directly to IPFS, making sensitive information (wallet addresses, validator keys, API keys) publicly accessible on-chain. The new flow stores private data server-side in Postgres and only puts a UUID reference on IPFS, improving privacy for cover holders.

Breaking changes

  • GetQuoteAndBuyCoverInputsParams.ipfsCidOrContent removed → use coverMetadata
  • Quote constructor no longer accepts an Ipfs instance
  • Cover-specific ContentType enum values removed from exports

@coderabbitai

coderabbitai Bot commented Jun 3, 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: 5f923df9-ace2-4f90-b752-49933a538d42

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

This PR refactors cover input handling from client-side schema validation to server-side metadata generation. It removes all legacy cover input IPFS schemas, redefines the IPFS content type system, introduces cover metadata type contracts, and refactors the Quote service to POST metadata to a dedicated endpoint instead of accepting pre-validated IPFS content.

Changes

Cover Metadata Generation Refactoring

Layer / File(s) Summary
Cover metadata type contracts
src/types/cover-metadata.ts, src/types/index.ts
New file defines ProofOfLossType ('address' | 'api_key' | 'validator' | 'csv'), ProofOfLossValue interface with optional amount/currency, ProofOfLossEntry combining type and content array, CoverPublicData with optional quota/percentage fields, and CoverMetadataInput and CoverMetadataResponse contracts. Barrel export added to src/types/index.ts.
IPFS content type system redesign
src/ipfs/schemas.ts, src/types/ipfs.ts, src/ipfs/validateIPFSContent.test.ts
Removes coverValidators, coverQuotaShare, coverAumCoverAmountPercentage, coverWalletAddress(s), coverFreeText, coverDesignatedWallets, and defiPassContentSchema from schemas. Replaces ContentType enum members and type aliases: removes cover/DeFi family types, adds stakingPoolDetails, claimProof, assessmentCriteriaAnswers, assessmentReason, governanceProposal, governanceCategory, file, productAnnex, coverMetadataRef. Updates IPFSContentTypes union and IPFSTypeContentTuple. Removes legacy cover type validation tests and adjusts test setup.
Product and SDK type contracts
src/types/product.ts, src/types/sdk.ts
ProductType gains optional isProofOfLossRequired flag (replaces ipfsContentType). Product adds optional proofOfLossInputTypes array. GetQuoteAndBuyCoverInputsParams adds optional coverMetadata field typed as CoverMetadataInput.
Quote service refactoring and SDK wiring
src/nexus-sdk.ts, src/quote/Quote.ts
Constructor removes optional ipfs parameter; NexusSDK instantiates Quote with only config. getQuoteAndBuyCoverInputs destructures coverMetadata instead of ipfsCidOrContent. Removes prior CID/content validation logic. Adds proof-of-loss requirement gating: returns error if required but missing. When metadata is provided, calls new createCoverMetadata helper to POST to /cover-metadata and obtain CID. Failures return Failed to create cover metadata error.
Test updates and validation
src/ipfs/uploadIPFSContent.test.ts, src/quote/getQuoteAndBuyCoverInputs.test.ts
uploadIPFSContent tests replace CoverFreeText fixture with StakingPoolDetails. getQuoteAndBuyCoverInputs tests remove IPFS imports, add CoverMetadataInput import, replace IPFS test section with metadata flow coverage: validates missing required metadata error, verifies POST /cover-metadata invocation when metadata provided, confirms request skipped when absent, asserts failure handling. Updates ipfsData assertion to empty string in final quote test.

Sequence Diagram

sequenceDiagram
  participant Caller
  participant Quote
  participant ProductAPI
  participant CoverMetadataAPI as POST /cover-metadata
  Caller->>Quote: getQuoteAndBuyCoverInputs(params with coverMetadata)
  Quote->>ProductAPI: fetch product config
  ProductAPI-->>Quote: product with isProofOfLossRequired flag
  alt proofOfLossRequired && !coverMetadata
    Quote-->>Caller: error: missing cover metadata
  else coverMetadata provided
    Quote->>CoverMetadataAPI: POST CoverMetadataInput
    CoverMetadataAPI-->>Quote: CoverMetadataResponse {cid}
    Quote->>Quote: compute quote with ipfsData=cid
    Quote-->>Caller: buyCoverInput with ipfsData=cid
  else no metadata provided
    Quote->>Quote: compute quote with ipfsData=''
    Quote-->>Caller: buyCoverInput with ipfsData=''
  end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

  • NexusMutual/sdk#513: Adds and wires ContentType.coverMetadataRef end-to-end across schemas, types, and validation logic, overlapping with this PR's IPFS type system changes.
  • NexusMutual/sdk#491: Modifies the same Quote.ts / getQuoteAndBuyCoverInputs code path to use runtime product API data; this PR further refactors that path to generate ipfsData from coverMetadata via server-side POST.

Suggested Reviewers

  • mixplore
  • shark0der
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the primary change: replacing direct IPFS uploads with a POST /cover-metadata endpoint call for cover metadata handling.

✏️ 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/cover-metadata-api
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/cover-metadata-api

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

@valentinludu valentinludu changed the title feat: replace direct IPFS upload with POST /cover-metadata endpoint [DO NOT MERGE] feat: replace direct IPFS upload with POST /cover-metadata endpoint Jun 3, 2026
@valentinludu valentinludu linked an issue Jun 3, 2026 that may be closed by this pull request

@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: 1

Caution

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

⚠️ Outside diff range comments (1)
src/quote/Quote.ts (1)

46-48: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update README to match the new coverMetadata + POST /cover-metadata flow

README.md still documents the removed ipfsCidOrContent / IPFSContentTypes param and describes local IPFS upload behavior, but Quote.getQuoteAndBuyCoverInputs now uses coverMetadata and creates the CID via POST /cover-metadata (then passes it as ipfsData). Update the README examples and the ipfsCidOrContent section (≈ lines 180-196, 210-224, 229-232).

Want me to draft the README update for the new coverMetadata flow?

🤖 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/quote/Quote.ts` around lines 46 - 48, README still documents the removed
ipfsCidOrContent / IPFSContentTypes and local IPFS upload behavior; update all
examples and sections (~lines noted) to reflect that
Quote.getQuoteAndBuyCoverInputs now accepts coverMetadata, posts it to POST
/cover-metadata to obtain a CID which is passed as ipfsData to the API, remove
references to ipfsCidOrContent/IPFSContentTypes and replace with a short example
showing construction of coverMetadata, the POST /cover-metadata call returning
the CID, and how that CID is used as ipfsData in the getQuoteAndBuyCoverInputs
call.
🧹 Nitpick comments (1)
src/quote/Quote.ts (1)

236-243: 💤 Low value

Guard against a missing response before reading cid.

The sibling helpers getQuote and getProductCapacity both check if (!response) throw ... before dereferencing. createCoverMetadata reads response.cid directly; if sendRequest resolves to undefined, this throws an opaque TypeError instead of a clear error. Adding a guard keeps behavior consistent and produces a clearer message.

♻️ Proposed guard
     const response = await this.sendRequest<CoverMetadataResponse>('/cover-metadata', options);
+    if (!response?.cid) {
+      throw new Error('Failed to create cover metadata');
+    }
     return response.cid;
🤖 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/quote/Quote.ts` around lines 236 - 243, createCoverMetadata currently
dereferences response.cid without ensuring sendRequest returned a value; add the
same guard used in getQuote/getProductCapacity: after calling
this.sendRequest<CoverMetadataResponse>('/cover-metadata', options) check if
response is falsy and throw a descriptive error (e.g., "Failed to create cover
metadata: empty response") before returning response.cid so we avoid opaque
TypeErrors.
🤖 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 `@src/quote/Quote.ts`:
- Around line 141-162: Tighten the proof-of-loss gating: when
productType.isProofOfLossRequired is true, verify coverMetadata.proofOfLoss
exists and has content (e.g., check coverMetadata?.proofOfLoss?.length) and
return the same error if it’s missing or empty instead of only checking for
coverMetadata truthiness; update the hasCoverMetadata logic to reflect this.
Also harden createCoverMetadata usage by validating its response includes a
non-empty cid before assigning ipfsData (or return a clear error if cid is
missing), so you don’t silently proceed with ipfsData = '' when the backend
reply is unexpected.

---

Outside diff comments:
In `@src/quote/Quote.ts`:
- Around line 46-48: README still documents the removed ipfsCidOrContent /
IPFSContentTypes and local IPFS upload behavior; update all examples and
sections (~lines noted) to reflect that Quote.getQuoteAndBuyCoverInputs now
accepts coverMetadata, posts it to POST /cover-metadata to obtain a CID which is
passed as ipfsData to the API, remove references to
ipfsCidOrContent/IPFSContentTypes and replace with a short example showing
construction of coverMetadata, the POST /cover-metadata call returning the CID,
and how that CID is used as ipfsData in the getQuoteAndBuyCoverInputs call.

---

Nitpick comments:
In `@src/quote/Quote.ts`:
- Around line 236-243: createCoverMetadata currently dereferences response.cid
without ensuring sendRequest returned a value; add the same guard used in
getQuote/getProductCapacity: after calling
this.sendRequest<CoverMetadataResponse>('/cover-metadata', options) check if
response is falsy and throw a descriptive error (e.g., "Failed to create cover
metadata: empty response") before returning response.cid so we avoid opaque
TypeErrors.
🪄 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: fe3d4bd1-d04e-46ba-ac68-3b6b2134fab0

📥 Commits

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

📒 Files selected for processing (12)
  • 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/Ipfs.ts
  • src/ipfs/validateIPFSContent.test.ts
  • src/ipfs/schemas.ts
  • src/types/ipfs.ts

Comment thread src/quote/Quote.ts Outdated
@cloudflare-workers-and-pages

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

Copy link
Copy Markdown

Deploying sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 270bc6d
Status: ✅  Deploy successful!
Preview URL: https://d0b0876f.sdk-9yp.pages.dev
Branch Preview URL: https://feat-cover-metadata-api.sdk-9yp.pages.dev

View logs

@valentinludu valentinludu changed the title [DO NOT MERGE] feat: replace direct IPFS upload with POST /cover-metadata endpoint feat: replace direct IPFS upload with POST /cover-metadata endpoint Jun 10, 2026
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.

Upload cover metadata to DB

1 participant