From 51a4aa7f0b8d25b76b1cfadbb36ede187bdf8770 Mon Sep 17 00:00:00 2001 From: peng Date: Thu, 18 Jun 2026 13:43:26 -0700 Subject: [PATCH] fix(samples/kotlin): select crypto network when funding a quote from USDC A RealtimeFundingQuoteSource with a crypto currency (e.g. USDC) requires a cryptoNetwork, otherwise the quote fails with INVALID_INPUT ("Crypto network is required ... for a crypto currency"). Pass cryptoNetwork through the quotes route and add a Funding Network selector to the quote step, shown only when the source currency is crypto. Fixes the Payout flow when funding from USDC. Co-Authored-By: Claude Opus 4.8 (1M context) --- samples/frontend/src/steps/CreateQuote.tsx | 40 ++++++++++++++++--- .../kotlin/com/grid/sample/routes/Quotes.kt | 3 ++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/samples/frontend/src/steps/CreateQuote.tsx b/samples/frontend/src/steps/CreateQuote.tsx index c51f5445e..929a650be 100644 --- a/samples/frontend/src/steps/CreateQuote.tsx +++ b/samples/frontend/src/steps/CreateQuote.tsx @@ -13,20 +13,31 @@ interface Props { const SOURCE_CURRENCIES = ['USD', 'USDC'] as const +// Currencies that fund over a crypto network and therefore require `cryptoNetwork`. +const CRYPTO_SOURCE_CURRENCIES = ['USDC'] +// Networks a stablecoin funding source can deposit on. +const CRYPTO_NETWORKS = ['BASE', 'ETHEREUM', 'POLYGON', 'SOLANA'] + export default function CreateQuote({ customerId, externalAccountId, destCurrency, onComplete, disabled }: Props) { const [body, setBody] = useState('') const [response, setResponse] = useState(null) const [error, setError] = useState(null) const [loading, setLoading] = useState(false) const [sourceCurrency, setSourceCurrency] = useState(SOURCE_CURRENCIES[0]) + const [cryptoNetwork, setCryptoNetwork] = useState(CRYPTO_NETWORKS[0]) + + const isCryptoSource = CRYPTO_SOURCE_CURRENCIES.includes(sourceCurrency) useEffect(() => { + const source: Record = { + sourceType: "REALTIME_FUNDING", + currency: sourceCurrency, + customerId: customerId ?? "" + } + // cryptoNetwork is required when funding from a crypto currency (e.g. USDC). + if (isCryptoSource) source.cryptoNetwork = cryptoNetwork setBody(JSON.stringify({ - source: { - sourceType: "REALTIME_FUNDING", - currency: sourceCurrency, - customerId: customerId ?? "" - }, + source, destination: { destinationType: "ACCOUNT", accountId: externalAccountId ?? "" @@ -35,7 +46,7 @@ export default function CreateQuote({ customerId, externalAccountId, destCurrenc lockedCurrencySide: "SENDING", purposeOfPayment: "GIFT" }, null, 2)) - }, [customerId, externalAccountId, sourceCurrency, destCurrency]) + }, [customerId, externalAccountId, sourceCurrency, destCurrency, isCryptoSource, cryptoNetwork]) const submit = async () => { setLoading(true) @@ -72,6 +83,23 @@ export default function CreateQuote({ customerId, externalAccountId, destCurrenc ))} + {isCryptoSource && ( +
+ + +

Required when funding from a crypto currency — the network the customer deposits {sourceCurrency} on.

+
+ )}