From 0f3faa3565e7934cc8f83e77ca7d271fbe6783a3 Mon Sep 17 00:00:00 2001 From: ezra ripps Date: Wed, 4 Feb 2026 13:43:33 -0500 Subject: [PATCH 1/3] Make provider public in fx and add refetch method to quotes/estimates --- src/services/fx/client.test.ts | 51 ++++++++++++++++++++++++++-------- src/services/fx/client.ts | 26 +++++++++++++++-- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/services/fx/client.test.ts b/src/services/fx/client.test.ts index 879dbdd6..c5c3e084 100644 --- a/src/services/fx/client.test.ts +++ b/src/services/fx/client.test.ts @@ -831,6 +831,15 @@ test('FX Server Estimate to Exchange Test', async function() { }); })); + const serverDoesNotRequireQuoteReturnValue = { + convertedAmount: 1002n, + convertedAmountBound: 850n, + cost: { + amount: 0n, + token: testCurrencyUSD + } + }; + await using serverDoesNotRequireQuote = new KeetaNetFXAnchorHTTPServer(await makeServerConfig({ quoteConfiguration: { requiresQuote: false, @@ -838,14 +847,7 @@ test('FX Server Estimate to Exchange Test', async function() { issueQuotes: true } }, async function() { - return({ - convertedAmount: 1002n, - convertedAmountBound: 850n, - cost: { - amount: 0n, - token: testCurrencyUSD - } - }); + return(serverDoesNotRequireQuoteReturnValue); })); await using serverDoesNotRequireDoesNotIssueQuote = new KeetaNetFXAnchorHTTPServer(await makeServerConfig({ @@ -979,9 +981,7 @@ test('FX Server Estimate to Exchange Test', async function() { } const sortedQuotes = quotes.sort(function(a, b) { - // @ts-ignore - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - return(String(a['provider'].providerID).localeCompare(String(b['provider'].providerID), ...localeCompareArgs)); + return(String(a.provider.providerID).localeCompare(String(b.provider.providerID), ...localeCompareArgs)); }); expect(sortedQuotes.map(function(entry) { @@ -1161,5 +1161,34 @@ test('FX Server Estimate to Exchange Test', async function() { } } } + + { + /** + * Check refetching quotes + */ + + const quotes = await fxClient.getEstimates({ from: testCurrencyUSD, to: testCurrencyEUR, amount: 1000n, affinity: 'from' }, undefined, { + providerIDs: [ 'TestDoesNotRequireQuote' ] + }); + + const singleEstimate = quotes?.[0]; + if (singleEstimate === undefined) { + throw(new Error('Could not get quote from TestDoesNotRequireQuote')); + } + + expect(singleEstimate.estimate.convertedAmount).toBe(1002n); + + serverDoesNotRequireQuoteReturnValue.convertedAmount = 999n; + + const refetchedEstimate = await singleEstimate.refetch(); + expect(refetchedEstimate.estimate.convertedAmount).toBe(999n); + + const singleQuote = await singleEstimate.getQuote(); + expect(singleQuote.quote.convertedAmount).toBe(999n); + + serverDoesNotRequireQuoteReturnValue.convertedAmount = 1002n; + const refetchedQuote = await singleQuote.refetch(); + expect(refetchedQuote.quote.convertedAmount).toBe(1002n); + } } }); diff --git a/src/services/fx/client.ts b/src/services/fx/client.ts index 39f35f7e..ebc82fdc 100644 --- a/src/services/fx/client.ts +++ b/src/services/fx/client.ts @@ -525,7 +525,7 @@ class KeetaFXAnchorProviderBase extends KeetaFXAnchorBase { * Estimate(optional) -> Quote(optional) -> Exchange -> ExchangeStatus */ class KeetaFXAnchorExchangeWithProvider { - private readonly provider: KeetaFXAnchorProviderBase; + readonly provider: KeetaFXAnchorProviderBase; readonly exchange: KeetaFXAnchorExchange constructor(provider: KeetaFXAnchorProviderBase, exchange: KeetaFXAnchorExchange) { @@ -548,7 +548,7 @@ interface CanCreateExchange { } class KeetaFXAnchorQuoteWithProvider implements CanCreateExchange { - private readonly provider: KeetaFXAnchorProviderBase; + readonly provider: KeetaFXAnchorProviderBase; readonly quote: KeetaFXAnchorQuote; readonly isQuote = true as const; @@ -565,10 +565,20 @@ class KeetaFXAnchorQuoteWithProvider implements CanCreateExchange { const exchange = await this.provider.createExchange({ quote: this.quote }, block); return(new KeetaFXAnchorExchangeWithProvider(this.provider, exchange)); } + + /** + * Re-fetch the quote from the provider. + * + * @returns a new KeetaFXAnchorQuoteWithProvider with the updated quote + */ + async refetch(): Promise { + const estimate = await this.provider.getQuote(); + return(new KeetaFXAnchorQuoteWithProvider(this.provider, estimate)); + } } class KeetaFXAnchorEstimateWithProvider implements CanCreateExchange { - private readonly provider: KeetaFXAnchorProviderBase; + readonly provider: KeetaFXAnchorProviderBase; readonly estimate: KeetaFXAnchorEstimate; readonly isQuote = false as const; @@ -590,6 +600,16 @@ class KeetaFXAnchorEstimateWithProvider implements CanCreateExchange { const exchange = await this.provider.createExchange({ estimate: this.estimate }, block); return(new KeetaFXAnchorExchangeWithProvider(this.provider, exchange)); } + + /** + * Re-fetch the estimate from the provider. + * + * @returns a new KeetaFXAnchorEstimateWithProvider with the updated estimate + */ + async refetch(): Promise { + const estimate = await this.provider.getEstimate(); + return(new KeetaFXAnchorEstimateWithProvider(this.provider, estimate)); + } } class KeetaFXAnchorClient extends KeetaFXAnchorBase { From 13f1002ff1c36590dc3caf8a6950eee422668ddd Mon Sep 17 00:00:00 2001 From: ezra ripps Date: Wed, 4 Feb 2026 13:45:47 -0500 Subject: [PATCH 2/3] add refetched to cspell --- .cspell.config.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.cspell.config.mjs b/.cspell.config.mjs index 949ca7d8..220349f2 100644 --- a/.cspell.config.mjs +++ b/.cspell.config.mjs @@ -115,7 +115,8 @@ export default { 'Valuizable', 'Valuize', 'VALUIZABLE', - 'wrongpath' + 'wrongpath', + 'refetched' ], flagWords: [ 'recieve' From 7caacd6a0eb27427505547376203341e2a5a1506 Mon Sep 17 00:00:00 2001 From: ezra ripps Date: Wed, 4 Feb 2026 14:00:29 -0500 Subject: [PATCH 3/3] rename estimate to quote --- src/services/fx/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/fx/client.ts b/src/services/fx/client.ts index ebc82fdc..b6518e08 100644 --- a/src/services/fx/client.ts +++ b/src/services/fx/client.ts @@ -572,8 +572,8 @@ class KeetaFXAnchorQuoteWithProvider implements CanCreateExchange { * @returns a new KeetaFXAnchorQuoteWithProvider with the updated quote */ async refetch(): Promise { - const estimate = await this.provider.getQuote(); - return(new KeetaFXAnchorQuoteWithProvider(this.provider, estimate)); + const quote = await this.provider.getQuote(); + return(new KeetaFXAnchorQuoteWithProvider(this.provider, quote)); } }