From 5c2578239b3ca103e20944a293707f8315c97c08 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Thu, 6 Aug 2026 14:33:13 -0600 Subject: [PATCH 1/3] feat(relay): add api key and upgrade status endpoint to v3 --- .env | 1 + packages/public-api/.env.example | 1 + packages/public-api/src/config.ts | 1 + packages/public-api/src/env.ts | 1 + .../swapper/src/swappers/RelaySwapper/endpoints.ts | 9 ++++++--- .../swappers/RelaySwapper/utils/fetchRelayTrade.ts | 8 ++++++-- .../utils/getLatestRelayStatusMessage.ts | 4 +++- .../RelaySwapper/utils/notifyTransactionIndexing.ts | 3 ++- .../src/swappers/RelaySwapper/utils/relayService.ts | 8 ++++++++ .../swapper/src/swappers/RelaySwapper/utils/types.ts | 12 ++++++++++-- packages/swapper/src/types.ts | 1 + src/config.ts | 1 + src/vite-env.d.ts | 1 + 13 files changed, 42 insertions(+), 9 deletions(-) diff --git a/.env b/.env index 51becd51b92..496c12d667c 100644 --- a/.env +++ b/.env @@ -330,6 +330,7 @@ VITE_JITO_BLOCK_ENGINE_URL=https://mainnet.block-engine.jito.wtf # relay VITE_RELAY_API_URL=https://api.relay.link +VITE_RELAY_API_KEY=d62274fb-1edd-481a-b952-632896ebf830 # affiliate revenue VITE_AFFILIATE_REVENUE_URL=https://api.revenue.shapeshift.com diff --git a/packages/public-api/.env.example b/packages/public-api/.env.example index 2421379dabf..523a598dad7 100644 --- a/packages/public-api/.env.example +++ b/packages/public-api/.env.example @@ -76,6 +76,7 @@ ACROSS_API_KEY= BEBOP_API_KEY= CHAINFLIP_API_KEY= NEAR_INTENTS_API_KEY= +RELAY_API_KEY= # Affiliate DEFAULT_AFFILIATE_BPS=60 diff --git a/packages/public-api/src/config.ts b/packages/public-api/src/config.ts index 7bffb37a00c..fd4019f14f9 100644 --- a/packages/public-api/src/config.ts +++ b/packages/public-api/src/config.ts @@ -28,6 +28,7 @@ export const getServerConfig = (): SwapperConfig => ({ VITE_CHAINFLIP_API_URL: env.CHAINFLIP_API_URL, VITE_FEATURE_CHAINFLIP_SWAP_DCA: env.FEATURE_CHAINFLIP_SWAP_DCA, VITE_RELAY_API_URL: env.RELAY_API_URL, + VITE_RELAY_API_KEY: env.RELAY_API_KEY, VITE_BEBOP_API_KEY: env.BEBOP_API_KEY, VITE_NEAR_INTENTS_API_KEY: env.NEAR_INTENTS_API_KEY, VITE_TRON_GRID_API_KEY: env.TRON_GRID_API_KEY, diff --git a/packages/public-api/src/env.ts b/packages/public-api/src/env.ts index 74e7365e3db..d9851eb9445 100644 --- a/packages/public-api/src/env.ts +++ b/packages/public-api/src/env.ts @@ -83,6 +83,7 @@ const envSchema = z.object({ BOB_GATEWAY_API_KEY: z.string().default(''), CHAINFLIP_API_KEY: z.string().min(1), NEAR_INTENTS_API_KEY: z.string().min(1), + RELAY_API_KEY: z.string().default(''), TRON_GRID_API_KEY: z.string().default(''), // Feature flags diff --git a/packages/swapper/src/swappers/RelaySwapper/endpoints.ts b/packages/swapper/src/swappers/RelaySwapper/endpoints.ts index c4698027c52..db8e3c97543 100644 --- a/packages/swapper/src/swappers/RelaySwapper/endpoints.ts +++ b/packages/swapper/src/swappers/RelaySwapper/endpoints.ts @@ -12,7 +12,7 @@ import { getTradeQuote } from './getTradeQuote/getTradeQuote' import { getTradeRate } from './getTradeRate/getTradeRate' import { getLatestRelayStatusMessage } from './utils/getLatestRelayStatusMessage' import { notifyTransactionIndexing } from './utils/notifyTransactionIndexing' -import { relayService } from './utils/relayService' +import { getRelayRequestConfig, relayService } from './utils/relayService' import type { RelayStatus, RelayTradeQuoteInput, RelayTradeRateInput } from './utils/types' // Keep track of the trades we already notified the relay indexer about @@ -86,7 +86,8 @@ export const relayApi: SwapperApi = { const swapperTxLink = `https://relay.link/transaction/${txHash}` const maybeStatusResponse = await relayService.get( - `${config.VITE_RELAY_API_URL}/intents/status/v2?requestId=${relayMetadata.relayId}`, + `${config.VITE_RELAY_API_URL}/intents/status/v3?requestId=${relayMetadata.relayId}`, + getRelayRequestConfig(config), ) if (maybeStatusResponse.isErr()) { @@ -106,8 +107,10 @@ export const relayApi: SwapperApi = { case 'success': return TxStatus.Confirmed case 'pending': + case 'depositing': + case 'submitted': return TxStatus.Pending - case 'failed': + case 'failure': case 'refund': return TxStatus.Failed default: diff --git a/packages/swapper/src/swappers/RelaySwapper/utils/fetchRelayTrade.ts b/packages/swapper/src/swappers/RelaySwapper/utils/fetchRelayTrade.ts index 525584e5357..c94e6c2957c 100644 --- a/packages/swapper/src/swappers/RelaySwapper/utils/fetchRelayTrade.ts +++ b/packages/swapper/src/swappers/RelaySwapper/utils/fetchRelayTrade.ts @@ -2,12 +2,16 @@ import type { Result } from '@sniptt/monads' import type { AxiosResponse } from 'axios' import type { SwapErrorRight, SwapperConfig } from '../../../types' -import { relayService } from './relayService' +import { getRelayRequestConfig, relayService } from './relayService' import type { RelayFetchQuoteParams, RelayQuote } from './types' export const fetchRelayTrade = async ( params: RelayFetchQuoteParams, config: SwapperConfig, ): Promise, SwapErrorRight>> => { - return await relayService.post(`${config.VITE_RELAY_API_URL}/quote/v2`, params) + return await relayService.post( + `${config.VITE_RELAY_API_URL}/quote/v2`, + params, + getRelayRequestConfig(config), + ) } diff --git a/packages/swapper/src/swappers/RelaySwapper/utils/getLatestRelayStatusMessage.ts b/packages/swapper/src/swappers/RelaySwapper/utils/getLatestRelayStatusMessage.ts index c1adbd84034..3bb2fc3838e 100644 --- a/packages/swapper/src/swappers/RelaySwapper/utils/getLatestRelayStatusMessage.ts +++ b/packages/swapper/src/swappers/RelaySwapper/utils/getLatestRelayStatusMessage.ts @@ -10,10 +10,12 @@ export const getLatestRelayStatusMessage = (status: RelayStatus): string => { case statusValue === 'delayed': return RelayStatusMessage.Retrying case statusValue === 'pending': + case statusValue === 'depositing': + case statusValue === 'submitted': return RelayStatusMessage.DepositDetected case statusValue === 'success': return RelayStatusMessage.SwapComplete - case statusValue === 'failed': + case statusValue === 'failure': return RelayStatusMessage.SwapFailed default: return 'Unknown status' diff --git a/packages/swapper/src/swappers/RelaySwapper/utils/notifyTransactionIndexing.ts b/packages/swapper/src/swappers/RelaySwapper/utils/notifyTransactionIndexing.ts index 8d8ae730d94..3026ec29b38 100644 --- a/packages/swapper/src/swappers/RelaySwapper/utils/notifyTransactionIndexing.ts +++ b/packages/swapper/src/swappers/RelaySwapper/utils/notifyTransactionIndexing.ts @@ -2,7 +2,7 @@ import type { Result } from '@sniptt/monads' import type { AxiosResponse } from 'axios' import type { SwapErrorRight, SwapperConfig } from '../../../types' -import { relayService } from './relayService' +import { getRelayRequestConfig, relayService } from './relayService' import type { RelayQuote } from './types' type NotifyTransactionIndexingParams = { @@ -18,5 +18,6 @@ export const notifyTransactionIndexing = async ( return await relayService.post( `${config.VITE_RELAY_API_URL}/transactions/single`, params, + getRelayRequestConfig(config), ) } diff --git a/packages/swapper/src/swappers/RelaySwapper/utils/relayService.ts b/packages/swapper/src/swappers/RelaySwapper/utils/relayService.ts index 3a484a0ec2d..0313531cb65 100644 --- a/packages/swapper/src/swappers/RelaySwapper/utils/relayService.ts +++ b/packages/swapper/src/swappers/RelaySwapper/utils/relayService.ts @@ -1,3 +1,6 @@ +import type { AxiosRequestConfig } from 'axios' + +import type { SwapperConfig } from '../../../types' import { createCache, makeSwapperAxiosServiceMonadic } from '../../../utils' const maxAgeMillis = 15 * 1000 @@ -14,3 +17,8 @@ const axiosConfig = { const relayServiceBase = createCache(maxAgeMillis, cachedUrls, axiosConfig) export const relayService = makeSwapperAxiosServiceMonadic(relayServiceBase) + +export const getRelayRequestConfig = (config: SwapperConfig): AxiosRequestConfig | undefined => + config.VITE_RELAY_API_KEY + ? { headers: { 'x-api-key': config.VITE_RELAY_API_KEY } } + : undefined diff --git a/packages/swapper/src/swappers/RelaySwapper/utils/types.ts b/packages/swapper/src/swappers/RelaySwapper/utils/types.ts index d9f45f1be7d..0e673042e25 100644 --- a/packages/swapper/src/swappers/RelaySwapper/utils/types.ts +++ b/packages/swapper/src/swappers/RelaySwapper/utils/types.ts @@ -36,11 +36,19 @@ export type RelayMetadata = { } export type RelayStatus = { - status: 'success' | 'failed' | 'pending' | 'refund' | 'delayed' | 'waiting' + status: + | 'success' + | 'failure' + | 'pending' + | 'submitted' + | 'depositing' + | 'refund' + | 'delayed' + | 'waiting' details?: string inTxHashes: string[] txHashes: string[] - time: number + updatedAt: number originChainId: number destinationChainId: number } diff --git a/packages/swapper/src/types.ts b/packages/swapper/src/types.ts index 4c4c2f1a870..70acb039eeb 100644 --- a/packages/swapper/src/types.ts +++ b/packages/swapper/src/types.ts @@ -85,6 +85,7 @@ export type SwapperConfig = { VITE_CHAINFLIP_API_URL: string VITE_FEATURE_CHAINFLIP_SWAP_DCA: boolean VITE_RELAY_API_URL: string + VITE_RELAY_API_KEY: string VITE_BEBOP_API_KEY: string VITE_NEAR_INTENTS_API_KEY: string VITE_SUI_NODE_URL: string diff --git a/src/config.ts b/src/config.ts index 8df40260fed..e80e5c77b68 100644 --- a/src/config.ts +++ b/src/config.ts @@ -259,6 +259,7 @@ const validators = { VITE_FEATURE_THORCHAIN_TCY_WIDGET: bool({ default: false }), VITE_FEATURE_THORCHAIN_TCY_ACTIVITY: bool({ default: false }), VITE_RELAY_API_URL: url(), + VITE_RELAY_API_KEY: str({ default: '' }), VITE_COINCAP_API_KEY: str(), VITE_FEATURE_MAYA_SWAP: bool({ default: false }), VITE_FEATURE_BUTTERSWAP: bool({ default: false }), diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index ca2bd43281f..18b78fc88b5 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -119,6 +119,7 @@ interface ImportMetaEnv { readonly VITE_BERACHAIN_NODE_URL: string readonly VITE_FEATURE_BERACHAIN: string readonly VITE_RELAY_API_URL: string + readonly VITE_RELAY_API_KEY: string readonly VITE_TENDERLY_ACCOUNT_SLUG: string readonly VITE_TENDERLY_PROJECT_SLUG: string readonly VITE_TENDERLY_API_KEY: string From c9a7036f8ad523d709cbcbed448c4420af77cc89 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Thu, 6 Aug 2026 14:52:16 -0600 Subject: [PATCH 2/3] fix(relay): map in-flight relay statuses to pending Co-Authored-By: Claude Fable 5 --- packages/swapper/src/swappers/RelaySwapper/endpoints.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/swapper/src/swappers/RelaySwapper/endpoints.ts b/packages/swapper/src/swappers/RelaySwapper/endpoints.ts index db8e3c97543..2c28e4c3a38 100644 --- a/packages/swapper/src/swappers/RelaySwapper/endpoints.ts +++ b/packages/swapper/src/swappers/RelaySwapper/endpoints.ts @@ -106,6 +106,8 @@ export const relayApi: SwapperApi = { switch (statusResponse.status) { case 'success': return TxStatus.Confirmed + case 'waiting': + case 'delayed': case 'pending': case 'depositing': case 'submitted': From f7c26d994bd67fb6f779a846d91c4321f4a824e0 Mon Sep 17 00:00:00 2001 From: kaladinlight <35275952+kaladinlight@users.noreply.github.com> Date: Fri, 7 Aug 2026 09:57:50 -0600 Subject: [PATCH 3/3] lint fix --- .../swapper/src/swappers/RelaySwapper/utils/relayService.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/swapper/src/swappers/RelaySwapper/utils/relayService.ts b/packages/swapper/src/swappers/RelaySwapper/utils/relayService.ts index 0313531cb65..b845de39cc0 100644 --- a/packages/swapper/src/swappers/RelaySwapper/utils/relayService.ts +++ b/packages/swapper/src/swappers/RelaySwapper/utils/relayService.ts @@ -19,6 +19,4 @@ const relayServiceBase = createCache(maxAgeMillis, cachedUrls, axiosConfig) export const relayService = makeSwapperAxiosServiceMonadic(relayServiceBase) export const getRelayRequestConfig = (config: SwapperConfig): AxiosRequestConfig | undefined => - config.VITE_RELAY_API_KEY - ? { headers: { 'x-api-key': config.VITE_RELAY_API_KEY } } - : undefined + config.VITE_RELAY_API_KEY ? { headers: { 'x-api-key': config.VITE_RELAY_API_KEY } } : undefined