Skip to content

Conversation

@premiumjibles
Copy link

@premiumjibles premiumjibles commented Dec 17, 2025

Summary

This finishes the implemention for near intents in our revenue tracking tool

Testing

  • Make sure unchained ain't dead

If you want to properly test this locally:

  1. Install dependencies (from repo root)
    cd /home/sean/Repos/shapeshift-unchained
    yarn install

  2. Copy and configure env
    cp node/proxy/sample.env node/proxy/.env
    // Edit node/proxy/.env with real API keys (BEBOP_API_KEY, ZRX_API_KEY, etc.)

  3. Start reverse proxy (from repo root)
    docker-compose up -d reverse-proxy

  4. Start proxy API
    cd node/proxy
    docker-compose up

  5. Test endpoint (in another terminal)

curl "http://api.proxy.localhost/api/v1/affiliate/revenue?startTimestamp=$(( $(date +%s) - 604800 ))&endTimestamp=$(date +%s)"

This will fail right now for nearintents until we get an explorer API key

Screenshots

image

Near intents errors right now until we get an explorer API key. But it doesn't crash and gives a proper error

@premiumjibles premiumjibles requested a review from a team as a code owner December 17, 2025 00:40
@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

📝 Walkthrough

Walkthrough

The changes introduce nearIntents as a new provider for affiliate revenue collection, replace Promise.all with Promise.allSettled to enable resilient partial failure handling, track and report failed providers in responses, and extend the Fees and AffiliateRevenueResponse data structures with additional asset metadata fields (assetId, chainId, service, timestamp, txHash).

Changes

Cohort / File(s) Summary
Affiliate Revenue Provider Integration
node/proxy/api/src/affiliateRevenue/index.ts
Introduces nearIntents as a new provider; replaces Promise.all with Promise.allSettled for resilient error handling; adds failed provider tracking via failedProviders array; implements Axios-based error formatting; extends Fees with assetId, chainId, service, timestamp, txHash; extends AffiliateRevenueResponse to include failedProviders field
Near Intents Asset Parsing
node/proxy/api/src/affiliateRevenue/nearIntents.ts
Adds asset parsing mappings (NEAR_INTENTS_TO_CHAIN_ID, SLIP44_BY_NETWORK); implements parseNearIntentsAsset function to derive chainId and assetId from originAsset formats; enhances getFees workflow with parsing and error handling; extracts txHash from originChainTxHashes and includes timestamp in fee entries
Type Definitions
node/proxy/api/src/models.ts
Adds failedProviders: Service[] property to AffiliateRevenueResponse interface
OpenAPI Schema
node/proxy/api/src/swagger.json
Introduces Service enum schema; extends AffiliateRevenueResponse schema with failedProviders array property; updates required fields

Sequence Diagram

sequenceDiagram
    participant Client
    participant AffiliateRevenue as Affiliate Revenue<br/>Aggregator
    participant Providers as Provider<br/>(bebop, chainflip, etc.)
    participant ErrorHandler as Error<br/>Handler

    Note over Client,ErrorHandler: New Flow: Promise.allSettled + Partial Success

    Client->>AffiliateRevenue: GET /affiliate-revenue
    
    AffiliateRevenue->>AffiliateRevenue: Add nearIntents to providers

    par Collect All Providers
        AffiliateRevenue->>Providers: getFees (Promise.allSettled)
        Note right of Providers: Now includes nearIntents
        alt Provider Success
            Providers-->>AffiliateRevenue: fees data
        else Provider Failure
            Providers-->>ErrorHandler: error
            ErrorHandler->>AffiliateRevenue: formatError()
            AffiliateRevenue->>AffiliateRevenue: Track in failedProviders
        end
    end

    Note over AffiliateRevenue: Resolve all promises<br/>(not stopping on first error)
    
    AffiliateRevenue->>AffiliateRevenue: Aggregate successful fees<br/>Track failures
    AffiliateRevenue->>AffiliateRevenue: Extend Fees with:<br/>assetId, chainId, service,<br/>timestamp, txHash
    
    AffiliateRevenue-->>Client: AffiliateRevenueResponse<br/>(totalUsd, byService,<br/>failedProviders)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • nearIntents asset parsing logic (nearIntents.ts): Review the chain ID and slip44 mappings, validate that the originAsset parsing correctly handles both nep141.*.near and nep141:-0x formats, and ensure error handling gracefully skips malformed entries.
  • Promise.allSettled control flow change (affiliateRevenue/index.ts): Verify that the transition from fail-fast (Promise.all) to resilient partial collection works correctly; confirm failed providers are accurately tracked and reported.
  • Extended data structures: Ensure Fees extensions (assetId, chainId, service, timestamp, txHash) are consistently populated across all provider integrations and that schema updates in swagger.json and models.ts remain synchronized.

Possibly related PRs

Poem

🐰 Through many providers we hop with care,
No single failure brings us despair,
NearIntents joins the trusty pack,
Each asset tracked, none fall through the crack,
Resilient revenue, fluffy and fine! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: finish implementation for near intents revenue tracking' directly and accurately summarizes the main change—completing Near intents revenue tracking implementation with new asset parsing, fee extraction, and error handling integration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 11436_near_intents

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.

Copy link

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

🧹 Nitpick comments (4)
node/proxy/api/src/affiliateRevenue/nearIntents.ts (3)

51-51: Fallback to slip44:0 (Bitcoin) may produce incorrect asset IDs.

When SLIP44_BY_NETWORK[network] is undefined, defaulting to 0 (Bitcoin's slip44) could silently produce incorrect asset identifiers for networks not in the mapping. Consider either:

  1. Returning null to skip unknown networks (consistent with line 46/56)
  2. Throwing/logging when an unmapped network has a token address
-    return { chainId, assetId: `${chainId}/slip44:${SLIP44_BY_NETWORK[network] ?? 0}` }
+    const slip44 = SLIP44_BY_NETWORK[network]
+    if (slip44 === undefined) return null
+    return { chainId, assetId: `${chainId}/slip44:${slip44}` }

62-63: Same fallback issue for native assets.

This has the same concern as line 51 - falling back to slip44:0 for unknown networks could produce incorrect asset IDs.

-  const slip44 = SLIP44_BY_NETWORK[network] ?? 0
-  return { chainId, assetId: `${chainId}/slip44:${slip44}` }
+  const slip44 = SLIP44_BY_NETWORK[network]
+  if (slip44 === undefined) return null
+  return { chainId, assetId: `${chainId}/slip44:${slip44}` }

106-119: Consider adding a timeout to the axios request.

The axios call has no timeout configured. If the Near Intents API becomes slow or unresponsive, this could cause the request to hang indefinitely, potentially blocking the entire revenue aggregation.

     const { data } = (await axios.get<TransactionsResponse>(
       'https://explorer.near-intents.org/api/v0/transactions-pages',
       {
         params: {
           referral: 'shapeshift',
           page,
           perPage: 100,
           statuses: 'SUCCESS',
           startTimestampUnix: startTimestamp,
           endTimestampUnix: endTimestamp,
         },
         headers: { Authorization: `Bearer ${NEAR_INTENTS_API_KEY}` },
+        timeout: 30000,
       }
     )) as { data: TransactionsResponse }
node/proxy/api/src/affiliateRevenue/index.ts (1)

11-11: Index-based provider mapping is fragile.

The providerNames array must stay in sync with the order of getFees calls in Promise.allSettled. If someone adds or reorders providers, the mapping will silently break, attributing errors to wrong providers.

Consider using a more robust approach:

-const providerNames: Service[] = ['zrx', 'bebop', 'thorchain', 'mayachain', 'chainflip', 'portals', 'nearintents']
+const providers: { name: Service; getFees: (start: number, end: number) => Promise<Fees[]> }[] = [
+  { name: 'zrx', getFees: zrx.getFees },
+  { name: 'bebop', getFees: bebop.getFees },
+  { name: 'thorchain', getFees: thorchain.getFees },
+  { name: 'mayachain', getFees: mayachain.getFees },
+  { name: 'chainflip', getFees: chainflip.getFees },
+  { name: 'portals', getFees: portals.getFees },
+  { name: 'nearintents', getFees: nearintents.getFees },
+]

Then iterate:

const results = await Promise.allSettled(
  providers.map(p => p.getFees(startTimestamp, endTimestamp))
)

results.forEach((result, index) => {
  const provider = providers[index].name
  // ...
})

Also applies to: 41-59

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 026c8f1 and 66f1b99.

📒 Files selected for processing (4)
  • node/proxy/api/src/affiliateRevenue/index.ts (3 hunks)
  • node/proxy/api/src/affiliateRevenue/nearIntents.ts (2 hunks)
  • node/proxy/api/src/models.ts (1 hunks)
  • node/proxy/api/src/swagger.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
node/proxy/api/src/affiliateRevenue/index.ts (1)
node/proxy/api/src/models.ts (1)
  • Service (6-6)
🪛 Checkov (3.2.334)
node/proxy/api/src/swagger.json

[medium] 131-135: Ensure that arrays have a maximum number of items

(CKV_OPENAPI_21)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: check
🔇 Additional comments (5)
node/proxy/api/src/models.ts (1)

10-10: LGTM!

The failedProviders field is properly typed using Service[], maintaining type safety and consistency with the rest of the response structure.

node/proxy/api/src/swagger.json (1)

114-136: Schema additions are consistent with TypeScript types.

The Service enum and failedProviders array are correctly defined and align with models.ts. The array is naturally bounded by the number of providers (currently 7), so while adding maxItems: 7 could satisfy the static analysis hint (CKV_OPENAPI_21), it's a minor consideration.

node/proxy/api/src/affiliateRevenue/nearIntents.ts (1)

129-129: Empty string fallback for txHash may cause data quality issues.

When originChainTxHashes is empty, txHash becomes an empty string. Verify this is acceptable for downstream consumers of the Fees data structure, or consider logging a warning similar to the asset parsing failure.

node/proxy/api/src/affiliateRevenue/index.ts (2)

13-24: Good error formatting implementation.

The formatError helper properly handles axios-specific errors, generic Error instances, and unknown error types. This provides consistent and useful error messages in logs.


51-59: Good use of Promise.allSettled for graceful degradation.

This approach ensures that failures in individual providers don't break the entire revenue aggregation. Failed providers are tracked and reported, while successful results are still processed and returned.

@premiumjibles premiumjibles marked this pull request as draft December 17, 2025 00:43
@premiumjibles premiumjibles marked this pull request as ready for review December 17, 2025 03:12
@premiumjibles premiumjibles changed the base branch from develop to 11435_graceful_errors December 17, 2025 03:12
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.

2 participants