From 0e3805ac39a24d86813a1e5af75eee3035ebe6e1 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 7 Sep 2026 21:20:52 +0000 Subject: [PATCH] feat: add Arbitrum (ARBITRUM_WALLET) to Grid public API schema - Add ARBITRUM to CryptoNetwork.yaml enum (between PLASMA and SPARK) - Add ARBITRUM_WALLET to PaymentAccountType.yaml and ExternalAccountType.yaml - Add 3 new schema files: ArbitrumWalletInfo, PaymentArbitrumWalletInfo (USDC+USDT), ArbitrumWalletExternalAccountInfo - Wire discriminator mappings in PaymentInstructions, ExternalAccountCreateInfoOneOf, ExternalAccountInfoOneOf - Update .stainless/stainless.yml with Arbitrum model entries and allOf transform targets - Update docs: crypto-funding.mdx (supported blockchains table), external-accounts.mdx, internal-accounts.mdx - Update yaml examples: RealtimeFundingQuoteSource, EstimateCryptoWithdrawalFeeRequest, crypto_estimate-withdrawal-fee path, external-account-status webhook - Update skill files: SKILL.md and references/account-types.md - Update samples: frontend CreateUsdcExternalAccount + CreateQuote, Kotlin ExternalAccounts (incl. missing import fix), grid-visualizer crypto.ts + account-types.ts - Regenerate openapi.yaml and mintlify/openapi.yaml (npm run build:openapi) Plan ref: https://github.com/lightsparkdev/webdev/pull/34482 --- .claude/skills/grid-api/SKILL.md | 4 +- .../grid-api/references/account-types.md | 1 + .stainless/stainless.yml | 3 + .../grid-visualizer/src/data/account-types.ts | 7 ++ components/grid-visualizer/src/data/crypto.ts | 2 + mintlify/openapi.yaml | 70 ++++++++++++++++++- mintlify/snippets/external-accounts.mdx | 36 +++++++++- mintlify/snippets/internal-accounts.mdx | 14 ++++ mintlify/snippets/sending/crypto-funding.mdx | 2 + openapi.yaml | 70 ++++++++++++++++++- .../schemas/common/ArbitrumWalletInfo.yaml | 13 ++++ .../schemas/common/PaymentAccountType.yaml | 1 + .../common/PaymentArbitrumWalletInfo.yaml | 10 +++ .../schemas/common/PaymentInstructions.yaml | 2 + .../schemas/crypto/CryptoNetwork.yaml | 1 + .../EstimateCryptoWithdrawalFeeRequest.yaml | 2 +- .../ArbitrumWalletExternalAccountInfo.yaml | 6 ++ .../ExternalAccountCreateInfoOneOf.yaml | 2 + .../ExternalAccountInfoOneOf.yaml | 2 + .../ExternalAccountType.yaml | 1 + .../quotes/RealtimeFundingQuoteSource.yaml | 4 +- .../crypto_estimate-withdrawal-fee.yaml | 8 +++ openapi/webhooks/external-account-status.yaml | 15 ++++ samples/frontend/src/steps/CreateQuote.tsx | 2 +- .../src/steps/CreateUsdcExternalAccount.tsx | 6 ++ .../grid/sample/routes/ExternalAccounts.kt | 8 +++ 26 files changed, 280 insertions(+), 12 deletions(-) create mode 100644 openapi/components/schemas/common/ArbitrumWalletInfo.yaml create mode 100644 openapi/components/schemas/common/PaymentArbitrumWalletInfo.yaml create mode 100644 openapi/components/schemas/external_accounts/ArbitrumWalletExternalAccountInfo.yaml diff --git a/.claude/skills/grid-api/SKILL.md b/.claude/skills/grid-api/SKILL.md index 26d87d55e..416778c99 100644 --- a/.claude/skills/grid-api/SKILL.md +++ b/.claude/skills/grid-api/SKILL.md @@ -294,7 +294,7 @@ Returns: - `totalFee` — total cost in withdrawal currency (network fee converted + application fee) - `netAmount` — amount recipient receives after all fees -Supported networks: `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `SPARK`, `LIGHTNING`, `BITCOIN` +Supported networks: `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `ARBITRUM`, `SPARK`, `LIGHTNING`, `BITCOIN` ### Quotes (Cross-Currency Transfers) @@ -567,7 +567,7 @@ Use this flow when the user asks for a "realtime quote" or "just in time" funded **Compatible instant methods:** -- **Crypto:** BTC (Lightning, Spark), USDC (Solana, Base, Polygon, Ethereum), USDT (Tron, Ethereum, Plasma) +- **Crypto:** BTC (Lightning, Spark), USDC (Solana, Base, Polygon, Ethereum, Arbitrum), USDT (Tron, Ethereum, Plasma, Arbitrum) - **Fiat:** RTP, SEPA Instant, and other instant payment rails **Flow:** diff --git a/.claude/skills/grid-api/references/account-types.md b/.claude/skills/grid-api/references/account-types.md index c7b28f6f8..7344a1ca1 100644 --- a/.claude/skills/grid-api/references/account-types.md +++ b/.claude/skills/grid-api/references/account-types.md @@ -57,6 +57,7 @@ The **Available Rails** column lists the payment rails Grid may use for the crea | SOLANA_WALLET | USDC | Solana wallet address | | TRON_WALLET | USDT | TRON wallet address | | PLASMA_WALLET | USDT | Plasma wallet address (0x...) | +| ARBITRUM_WALLET | USDC, USDT | Arbitrum wallet address (0x...) | | POLYGON_WALLET | USDC | Polygon wallet address (0x...) | | BASE_WALLET | USDC | Base wallet address (0x...) | diff --git a/.stainless/stainless.yml b/.stainless/stainless.yml index affc639f3..30d9e11b3 100644 --- a/.stainless/stainless.yml +++ b/.stainless/stainless.yml @@ -203,6 +203,7 @@ resources: solana_wallet_info: '#/components/schemas/SolanaWalletExternalAccountInfo' tron_wallet_info: '#/components/schemas/TronWalletExternalAccountInfo' plasma_wallet_info: '#/components/schemas/PlasmaWalletExternalAccountInfo' + arbitrum_wallet_info: '#/components/schemas/ArbitrumWalletExternalAccountInfo' polygon_wallet_info: '#/components/schemas/PolygonWalletExternalAccountInfo' lightning_wallet_info: '#/components/schemas/LightningExternalAccountInfo' base_wallet_info: '#/components/schemas/BaseWalletExternalAccountInfo' @@ -893,6 +894,7 @@ openapi: - "$.components.schemas.PaymentSolanaWalletInfo.allOf[0]" - "$.components.schemas.PaymentTronWalletInfo.allOf[0]" - "$.components.schemas.PaymentPlasmaWalletInfo.allOf[0]" + - "$.components.schemas.PaymentArbitrumWalletInfo.allOf[0]" - "$.components.schemas.PaymentPolygonWalletInfo.allOf[0]" - "$.components.schemas.PaymentBaseWalletInfo.allOf[0]" - "$.components.schemas.PaymentEthereumWalletInfo.allOf[0]" @@ -947,6 +949,7 @@ openapi: - "$.components.schemas.SolanaWalletExternalAccountInfo.allOf[0]" - "$.components.schemas.TronWalletExternalAccountInfo.allOf[0]" - "$.components.schemas.PlasmaWalletExternalAccountInfo.allOf[0]" + - "$.components.schemas.ArbitrumWalletExternalAccountInfo.allOf[0]" - "$.components.schemas.PolygonWalletExternalAccountInfo.allOf[0]" - "$.components.schemas.BaseWalletExternalAccountInfo.allOf[0]" keys: [ "$ref" ] diff --git a/components/grid-visualizer/src/data/account-types.ts b/components/grid-visualizer/src/data/account-types.ts index 0592295f3..17f0132aa 100644 --- a/components/grid-visualizer/src/data/account-types.ts +++ b/components/grid-visualizer/src/data/account-types.ts @@ -271,6 +271,13 @@ export const accountTypeSpecs: Record = { ], beneficiaryRequired: false, }, + ARBITRUM_WALLET: { + accountType: 'ARBITRUM_WALLET', + fields: [ + { name: 'address', example: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' }, + ], + beneficiaryRequired: false, + }, AED_ACCOUNT: { accountType: 'AED_ACCOUNT', fields: [ diff --git a/components/grid-visualizer/src/data/crypto.ts b/components/grid-visualizer/src/data/crypto.ts index ddd492288..1d19f38d4 100644 --- a/components/grid-visualizer/src/data/crypto.ts +++ b/components/grid-visualizer/src/data/crypto.ts @@ -34,6 +34,7 @@ export const cryptoAssets: CryptoAsset[] = [ { type: 'POLYGON_WALLET', label: 'Wallet', network: 'Polygon' }, { type: 'BASE_WALLET', label: 'Wallet', network: 'Base' }, { type: 'ETHEREUM_WALLET', label: 'Wallet', network: 'Ethereum' }, + { type: 'ARBITRUM_WALLET', label: 'Wallet', network: 'Arbitrum' }, ], examplePerson: { fullName: 'Alex Rivera', nationality: 'US' }, }, @@ -44,6 +45,7 @@ export const cryptoAssets: CryptoAsset[] = [ { type: 'TRON_WALLET', label: 'Wallet', network: 'Tron' }, { type: 'ETHEREUM_WALLET', label: 'Wallet', network: 'Ethereum' }, { type: 'PLASMA_WALLET', label: 'Wallet', network: 'Plasma' }, + { type: 'ARBITRUM_WALLET', label: 'Wallet', network: 'Arbitrum' }, ], examplePerson: { fullName: 'Sam Chen', nationality: 'US' }, }, diff --git a/mintlify/openapi.yaml b/mintlify/openapi.yaml index d6b32d0f2..3de9a423b 100644 --- a/mintlify/openapi.yaml +++ b/mintlify/openapi.yaml @@ -5050,6 +5050,14 @@ paths: cryptoNetwork: SOLANA amount: 1000000 destinationAddress: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU + estimateArbitrumWithdrawal: + summary: Estimate fee for USDC withdrawal on Arbitrum + value: + internalAccountId: InternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123 + currency: USDC + cryptoNetwork: ARBITRUM + amount: 1000000 + destinationAddress: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' responses: '200': description: Fee estimation returned successfully @@ -11365,6 +11373,21 @@ webhooks: accountInfo: accountType: ETHEREUM_WALLET address: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' + arbitrumWalletActive: + summary: An Arbitrum wallet account became active + value: + id: Webhook:019542f5-b3e7-1d02-0000-000000000044 + type: EXTERNAL_ACCOUNT.STATUS_UPDATED + timestamp: '2025-08-15T14:32:00Z' + data: + id: ExternalAccount:f95dcbd6-dced-4ec4-b756-3c3a9ea3d966 + customerId: Customer:da459a29-1fb7-41ce-a4cb-eb3a3c9fd7a7 + status: ACTIVE + currency: USDC + ownershipType: FIRST_PARTY + accountInfo: + accountType: ARBITRUM_WALLET + address: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' verificationFailed: summary: A liveness check failed; a new challenge is needed to retry value: @@ -15091,6 +15114,7 @@ components: - SOLANA_WALLET - TRON_WALLET - PLASMA_WALLET + - ARBITRUM_WALLET - POLYGON_WALLET - BASE_WALLET - ETHEREUM_WALLET @@ -16179,6 +16203,33 @@ components: description: Type of asset enum: - USDT + ArbitrumWalletInfo: + type: object + required: + - address + - accountType + properties: + accountType: + type: string + enum: + - ARBITRUM_WALLET + address: + type: string + description: Arbitrum wallet address + example: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' + PaymentArbitrumWalletInfo: + title: Arbitrum Wallet + allOf: + - $ref: '#/components/schemas/BasePaymentAccountInfo' + - $ref: '#/components/schemas/ArbitrumWalletInfo' + - type: object + properties: + assetType: + type: string + description: Type of asset + enum: + - USDC + - USDT PolygonWalletInfo: type: object required: @@ -17725,6 +17776,7 @@ components: - $ref: '#/components/schemas/PaymentSolanaWalletInfo' - $ref: '#/components/schemas/PaymentTronWalletInfo' - $ref: '#/components/schemas/PaymentPlasmaWalletInfo' + - $ref: '#/components/schemas/PaymentArbitrumWalletInfo' - $ref: '#/components/schemas/PaymentPolygonWalletInfo' - $ref: '#/components/schemas/PaymentBaseWalletInfo' - $ref: '#/components/schemas/PaymentEthereumWalletInfo' @@ -17754,6 +17806,7 @@ components: SOLANA_WALLET: '#/components/schemas/PaymentSolanaWalletInfo' TRON_WALLET: '#/components/schemas/PaymentTronWalletInfo' PLASMA_WALLET: '#/components/schemas/PaymentPlasmaWalletInfo' + ARBITRUM_WALLET: '#/components/schemas/PaymentArbitrumWalletInfo' POLYGON_WALLET: '#/components/schemas/PaymentPolygonWalletInfo' BASE_WALLET: '#/components/schemas/PaymentBaseWalletInfo' ETHEREUM_WALLET: '#/components/schemas/PaymentEthereumWalletInfo' @@ -18074,6 +18127,7 @@ components: - ETHEREUM_WALLET - LIGHTNING - PLASMA_WALLET + - ARBITRUM_WALLET - POLYGON_WALLET - SOLANA_WALLET - SPARK_WALLET @@ -21070,6 +21124,13 @@ components: - $ref: '#/components/schemas/PlasmaWalletInfo' - $ref: '#/components/schemas/WalletBeneficiaryFields' - $ref: '#/components/schemas/WalletCustodyFields' + ArbitrumWalletExternalAccountInfo: + title: Arbitrum Wallet + allOf: + - $ref: '#/components/schemas/BaseExternalAccountInfo' + - $ref: '#/components/schemas/ArbitrumWalletInfo' + - $ref: '#/components/schemas/WalletBeneficiaryFields' + - $ref: '#/components/schemas/WalletCustodyFields' SolanaWalletExternalAccountInfo: title: Solana Wallet allOf: @@ -21301,6 +21362,7 @@ components: - $ref: '#/components/schemas/LightningExternalAccountInfo' - $ref: '#/components/schemas/PolygonWalletExternalAccountInfo' - $ref: '#/components/schemas/PlasmaWalletExternalAccountInfo' + - $ref: '#/components/schemas/ArbitrumWalletExternalAccountInfo' - $ref: '#/components/schemas/SolanaWalletExternalAccountInfo' - $ref: '#/components/schemas/SparkWalletExternalAccountInfo' - $ref: '#/components/schemas/TronWalletExternalAccountInfo' @@ -21352,6 +21414,7 @@ components: LIGHTNING_ACCOUNT: '#/components/schemas/LightningExternalAccountInfo' POLYGON_WALLET: '#/components/schemas/PolygonWalletExternalAccountInfo' PLASMA_WALLET: '#/components/schemas/PlasmaWalletExternalAccountInfo' + ARBITRUM_WALLET: '#/components/schemas/ArbitrumWalletExternalAccountInfo' SOLANA_WALLET: '#/components/schemas/SolanaWalletExternalAccountInfo' SPARK_WALLET: '#/components/schemas/SparkWalletExternalAccountInfo' TRON_WALLET: '#/components/schemas/TronWalletExternalAccountInfo' @@ -22245,6 +22308,7 @@ components: - $ref: '#/components/schemas/LightningExternalAccountInfo' - $ref: '#/components/schemas/PolygonWalletExternalAccountInfo' - $ref: '#/components/schemas/PlasmaWalletExternalAccountInfo' + - $ref: '#/components/schemas/ArbitrumWalletExternalAccountInfo' - $ref: '#/components/schemas/SolanaWalletExternalAccountInfo' - $ref: '#/components/schemas/SparkWalletExternalAccountInfo' - $ref: '#/components/schemas/TronWalletExternalAccountInfo' @@ -22295,6 +22359,7 @@ components: LIGHTNING: '#/components/schemas/LightningExternalAccountInfo' POLYGON_WALLET: '#/components/schemas/PolygonWalletExternalAccountInfo' PLASMA_WALLET: '#/components/schemas/PlasmaWalletExternalAccountInfo' + ARBITRUM_WALLET: '#/components/schemas/ArbitrumWalletExternalAccountInfo' SOLANA_WALLET: '#/components/schemas/SolanaWalletExternalAccountInfo' SPARK_WALLET: '#/components/schemas/SparkWalletExternalAccountInfo' TRON_WALLET: '#/components/schemas/TronWalletExternalAccountInfo' @@ -23004,6 +23069,7 @@ components: - POLYGON - TRON - PLASMA + - ARBITRUM - SPARK description: The blockchain network an on-chain transaction settled on. Whether this is the mainnet or a test network (e.g. Solana devnet) is determined by your platform's environment — sandbox platforms operate on test networks, production platforms on mainnet — mirroring how `cryptoNetwork` is interpreted elsewhere in the API. example: SOLANA @@ -23996,7 +24062,7 @@ components: example: USD cryptoNetwork: type: string - description: 'The crypto network to use for the funding source. Required when `currency` is a stablecoin (e.g. USDC, USDT). Specifies which network the customer will deposit on, so the correct deposit address can be generated. Example values: `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `TRON`, `PLASMA`, `SPARK`, `LIGHTNING`, `BITCOIN`.' + description: 'The crypto network to use for the funding source. Required when `currency` is a stablecoin (e.g. USDC, USDT). Specifies which network the customer will deposit on, so the correct deposit address can be generated. Example values: `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `TRON`, `PLASMA`, `ARBITRUM`, `SPARK`, `LIGHTNING`, `BITCOIN`.' example: SOLANA description: Fund the quote using a real-time funding source (RTP, SEPA Instant, Spark, Stables, etc.). This will require manual just-in-time funding using `paymentInstructions` in the response. Because quotes expire quickly, this option is only valid for instant payment methods. Do not try to fund a quote with a non-instant payment method (ACH, etc.). QuoteSourceOneOf: @@ -24358,7 +24424,7 @@ components: example: USDC cryptoNetwork: type: string - description: 'The blockchain network for the withdrawal. Example values: SOLANA, ETHEREUM, BASE, POLYGON, SPARK, LIGHTNING, BITCOIN.' + description: 'The blockchain network for the withdrawal. Example values: SOLANA, ETHEREUM, BASE, POLYGON, ARBITRUM, SPARK, LIGHTNING, BITCOIN.' example: SOLANA amount: type: integer diff --git a/mintlify/snippets/external-accounts.mdx b/mintlify/snippets/external-accounts.mdx index 107545b25..4c267b00b 100644 --- a/mintlify/snippets/external-accounts.mdx +++ b/mintlify/snippets/external-accounts.mdx @@ -1838,6 +1838,38 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco }' ``` +**Arbitrum** + +Supported assets: USDC, USDT. + +```bash cURL USDC +curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \ + -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \ + -H 'Content-Type: application/json' \ + -d '{ + "currency": "USDC", + "platformAccountId": "arbitrum_usdc_001", + "accountInfo": { + "accountType": "ARBITRUM_WALLET", + "address": "0xAbCDEF1234567890aBCdEf1234567890ABcDef12" + } + }' +``` + +```bash cURL USDT +curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \ + -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \ + -H 'Content-Type: application/json' \ + -d '{ + "currency": "USDT", + "platformAccountId": "arbitrum_usdt_001", + "accountInfo": { + "accountType": "ARBITRUM_WALLET", + "address": "0xAbCDEF1234567890aBCdEf1234567890ABcDef12" + } + }' +``` + **Lightning** Exactly one of `lightningAddress`, `invoice` (a single-use BOLT11 invoice) or `bolt12` @@ -1858,8 +1890,8 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco ``` Crypto wallets don't require beneficiary information. Send only assets on the - named network — EVM addresses look identical across Ethereum, Base, Polygon and - Plasma, and funds sent on the wrong network are unrecoverable. + named network — EVM addresses look identical across Ethereum, Base, Polygon, + Plasma, and Arbitrum, and funds sent on the wrong network are unrecoverable. diff --git a/mintlify/snippets/internal-accounts.mdx b/mintlify/snippets/internal-accounts.mdx index 45618890c..0b820431b 100644 --- a/mintlify/snippets/internal-accounts.mdx +++ b/mintlify/snippets/internal-accounts.mdx @@ -249,6 +249,20 @@ Each internal account includes `fundingPaymentInstructions` that tell your custo ``` + + For Arbitrum wallet accounts, using an Arbitrum wallet as the funding source (USDC or USDT): + + ```json + { + "accountOrWalletInfo": { + "accountType": "ARBITRUM_WALLET", + "assetType": "USDC", + "address": "0xAbCDEF1234567890aBCdEf1234567890ABcDef12" + } + } + ``` + + For Polygon wallet accounts, using a Polygon wallet as the funding source: diff --git a/mintlify/snippets/sending/crypto-funding.mdx b/mintlify/snippets/sending/crypto-funding.mdx index dbc9a01c8..1f9c22fd1 100644 --- a/mintlify/snippets/sending/crypto-funding.mdx +++ b/mintlify/snippets/sending/crypto-funding.mdx @@ -11,6 +11,8 @@ Transfers can be funded via USDC and BTC on popular blockchains including Solana | Tron | USDT | | Polygon | USDC | | Ethereum | USDC, USDT | +| Plasma | USDT | +| Arbitrum | USDC, USDT | | Lightning | BTC | | Spark | BTC | diff --git a/openapi.yaml b/openapi.yaml index d6b32d0f2..3de9a423b 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -5050,6 +5050,14 @@ paths: cryptoNetwork: SOLANA amount: 1000000 destinationAddress: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU + estimateArbitrumWithdrawal: + summary: Estimate fee for USDC withdrawal on Arbitrum + value: + internalAccountId: InternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123 + currency: USDC + cryptoNetwork: ARBITRUM + amount: 1000000 + destinationAddress: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' responses: '200': description: Fee estimation returned successfully @@ -11365,6 +11373,21 @@ webhooks: accountInfo: accountType: ETHEREUM_WALLET address: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' + arbitrumWalletActive: + summary: An Arbitrum wallet account became active + value: + id: Webhook:019542f5-b3e7-1d02-0000-000000000044 + type: EXTERNAL_ACCOUNT.STATUS_UPDATED + timestamp: '2025-08-15T14:32:00Z' + data: + id: ExternalAccount:f95dcbd6-dced-4ec4-b756-3c3a9ea3d966 + customerId: Customer:da459a29-1fb7-41ce-a4cb-eb3a3c9fd7a7 + status: ACTIVE + currency: USDC + ownershipType: FIRST_PARTY + accountInfo: + accountType: ARBITRUM_WALLET + address: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' verificationFailed: summary: A liveness check failed; a new challenge is needed to retry value: @@ -15091,6 +15114,7 @@ components: - SOLANA_WALLET - TRON_WALLET - PLASMA_WALLET + - ARBITRUM_WALLET - POLYGON_WALLET - BASE_WALLET - ETHEREUM_WALLET @@ -16179,6 +16203,33 @@ components: description: Type of asset enum: - USDT + ArbitrumWalletInfo: + type: object + required: + - address + - accountType + properties: + accountType: + type: string + enum: + - ARBITRUM_WALLET + address: + type: string + description: Arbitrum wallet address + example: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' + PaymentArbitrumWalletInfo: + title: Arbitrum Wallet + allOf: + - $ref: '#/components/schemas/BasePaymentAccountInfo' + - $ref: '#/components/schemas/ArbitrumWalletInfo' + - type: object + properties: + assetType: + type: string + description: Type of asset + enum: + - USDC + - USDT PolygonWalletInfo: type: object required: @@ -17725,6 +17776,7 @@ components: - $ref: '#/components/schemas/PaymentSolanaWalletInfo' - $ref: '#/components/schemas/PaymentTronWalletInfo' - $ref: '#/components/schemas/PaymentPlasmaWalletInfo' + - $ref: '#/components/schemas/PaymentArbitrumWalletInfo' - $ref: '#/components/schemas/PaymentPolygonWalletInfo' - $ref: '#/components/schemas/PaymentBaseWalletInfo' - $ref: '#/components/schemas/PaymentEthereumWalletInfo' @@ -17754,6 +17806,7 @@ components: SOLANA_WALLET: '#/components/schemas/PaymentSolanaWalletInfo' TRON_WALLET: '#/components/schemas/PaymentTronWalletInfo' PLASMA_WALLET: '#/components/schemas/PaymentPlasmaWalletInfo' + ARBITRUM_WALLET: '#/components/schemas/PaymentArbitrumWalletInfo' POLYGON_WALLET: '#/components/schemas/PaymentPolygonWalletInfo' BASE_WALLET: '#/components/schemas/PaymentBaseWalletInfo' ETHEREUM_WALLET: '#/components/schemas/PaymentEthereumWalletInfo' @@ -18074,6 +18127,7 @@ components: - ETHEREUM_WALLET - LIGHTNING - PLASMA_WALLET + - ARBITRUM_WALLET - POLYGON_WALLET - SOLANA_WALLET - SPARK_WALLET @@ -21070,6 +21124,13 @@ components: - $ref: '#/components/schemas/PlasmaWalletInfo' - $ref: '#/components/schemas/WalletBeneficiaryFields' - $ref: '#/components/schemas/WalletCustodyFields' + ArbitrumWalletExternalAccountInfo: + title: Arbitrum Wallet + allOf: + - $ref: '#/components/schemas/BaseExternalAccountInfo' + - $ref: '#/components/schemas/ArbitrumWalletInfo' + - $ref: '#/components/schemas/WalletBeneficiaryFields' + - $ref: '#/components/schemas/WalletCustodyFields' SolanaWalletExternalAccountInfo: title: Solana Wallet allOf: @@ -21301,6 +21362,7 @@ components: - $ref: '#/components/schemas/LightningExternalAccountInfo' - $ref: '#/components/schemas/PolygonWalletExternalAccountInfo' - $ref: '#/components/schemas/PlasmaWalletExternalAccountInfo' + - $ref: '#/components/schemas/ArbitrumWalletExternalAccountInfo' - $ref: '#/components/schemas/SolanaWalletExternalAccountInfo' - $ref: '#/components/schemas/SparkWalletExternalAccountInfo' - $ref: '#/components/schemas/TronWalletExternalAccountInfo' @@ -21352,6 +21414,7 @@ components: LIGHTNING_ACCOUNT: '#/components/schemas/LightningExternalAccountInfo' POLYGON_WALLET: '#/components/schemas/PolygonWalletExternalAccountInfo' PLASMA_WALLET: '#/components/schemas/PlasmaWalletExternalAccountInfo' + ARBITRUM_WALLET: '#/components/schemas/ArbitrumWalletExternalAccountInfo' SOLANA_WALLET: '#/components/schemas/SolanaWalletExternalAccountInfo' SPARK_WALLET: '#/components/schemas/SparkWalletExternalAccountInfo' TRON_WALLET: '#/components/schemas/TronWalletExternalAccountInfo' @@ -22245,6 +22308,7 @@ components: - $ref: '#/components/schemas/LightningExternalAccountInfo' - $ref: '#/components/schemas/PolygonWalletExternalAccountInfo' - $ref: '#/components/schemas/PlasmaWalletExternalAccountInfo' + - $ref: '#/components/schemas/ArbitrumWalletExternalAccountInfo' - $ref: '#/components/schemas/SolanaWalletExternalAccountInfo' - $ref: '#/components/schemas/SparkWalletExternalAccountInfo' - $ref: '#/components/schemas/TronWalletExternalAccountInfo' @@ -22295,6 +22359,7 @@ components: LIGHTNING: '#/components/schemas/LightningExternalAccountInfo' POLYGON_WALLET: '#/components/schemas/PolygonWalletExternalAccountInfo' PLASMA_WALLET: '#/components/schemas/PlasmaWalletExternalAccountInfo' + ARBITRUM_WALLET: '#/components/schemas/ArbitrumWalletExternalAccountInfo' SOLANA_WALLET: '#/components/schemas/SolanaWalletExternalAccountInfo' SPARK_WALLET: '#/components/schemas/SparkWalletExternalAccountInfo' TRON_WALLET: '#/components/schemas/TronWalletExternalAccountInfo' @@ -23004,6 +23069,7 @@ components: - POLYGON - TRON - PLASMA + - ARBITRUM - SPARK description: The blockchain network an on-chain transaction settled on. Whether this is the mainnet or a test network (e.g. Solana devnet) is determined by your platform's environment — sandbox platforms operate on test networks, production platforms on mainnet — mirroring how `cryptoNetwork` is interpreted elsewhere in the API. example: SOLANA @@ -23996,7 +24062,7 @@ components: example: USD cryptoNetwork: type: string - description: 'The crypto network to use for the funding source. Required when `currency` is a stablecoin (e.g. USDC, USDT). Specifies which network the customer will deposit on, so the correct deposit address can be generated. Example values: `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `TRON`, `PLASMA`, `SPARK`, `LIGHTNING`, `BITCOIN`.' + description: 'The crypto network to use for the funding source. Required when `currency` is a stablecoin (e.g. USDC, USDT). Specifies which network the customer will deposit on, so the correct deposit address can be generated. Example values: `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `TRON`, `PLASMA`, `ARBITRUM`, `SPARK`, `LIGHTNING`, `BITCOIN`.' example: SOLANA description: Fund the quote using a real-time funding source (RTP, SEPA Instant, Spark, Stables, etc.). This will require manual just-in-time funding using `paymentInstructions` in the response. Because quotes expire quickly, this option is only valid for instant payment methods. Do not try to fund a quote with a non-instant payment method (ACH, etc.). QuoteSourceOneOf: @@ -24358,7 +24424,7 @@ components: example: USDC cryptoNetwork: type: string - description: 'The blockchain network for the withdrawal. Example values: SOLANA, ETHEREUM, BASE, POLYGON, SPARK, LIGHTNING, BITCOIN.' + description: 'The blockchain network for the withdrawal. Example values: SOLANA, ETHEREUM, BASE, POLYGON, ARBITRUM, SPARK, LIGHTNING, BITCOIN.' example: SOLANA amount: type: integer diff --git a/openapi/components/schemas/common/ArbitrumWalletInfo.yaml b/openapi/components/schemas/common/ArbitrumWalletInfo.yaml new file mode 100644 index 000000000..5a9d48d83 --- /dev/null +++ b/openapi/components/schemas/common/ArbitrumWalletInfo.yaml @@ -0,0 +1,13 @@ +type: object +required: + - address + - accountType +properties: + accountType: + type: string + enum: + - ARBITRUM_WALLET + address: + type: string + description: Arbitrum wallet address + example: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' diff --git a/openapi/components/schemas/common/PaymentAccountType.yaml b/openapi/components/schemas/common/PaymentAccountType.yaml index d7ac415c1..94b4d49a6 100644 --- a/openapi/components/schemas/common/PaymentAccountType.yaml +++ b/openapi/components/schemas/common/PaymentAccountType.yaml @@ -24,6 +24,7 @@ enum: - SOLANA_WALLET - TRON_WALLET - PLASMA_WALLET + - ARBITRUM_WALLET - POLYGON_WALLET - BASE_WALLET - ETHEREUM_WALLET diff --git a/openapi/components/schemas/common/PaymentArbitrumWalletInfo.yaml b/openapi/components/schemas/common/PaymentArbitrumWalletInfo.yaml new file mode 100644 index 000000000..bc0482fd3 --- /dev/null +++ b/openapi/components/schemas/common/PaymentArbitrumWalletInfo.yaml @@ -0,0 +1,10 @@ +title: Arbitrum Wallet +allOf: + - $ref: ./BasePaymentAccountInfo.yaml + - $ref: ./ArbitrumWalletInfo.yaml + - type: object + properties: + assetType: + type: string + description: Type of asset + enum: [USDC, USDT] diff --git a/openapi/components/schemas/common/PaymentInstructions.yaml b/openapi/components/schemas/common/PaymentInstructions.yaml index e8043e5d7..ee8a28b36 100644 --- a/openapi/components/schemas/common/PaymentInstructions.yaml +++ b/openapi/components/schemas/common/PaymentInstructions.yaml @@ -59,6 +59,7 @@ properties: - $ref: ../common/PaymentSolanaWalletInfo.yaml - $ref: ../common/PaymentTronWalletInfo.yaml - $ref: ../common/PaymentPlasmaWalletInfo.yaml + - $ref: ../common/PaymentArbitrumWalletInfo.yaml - $ref: ../common/PaymentPolygonWalletInfo.yaml - $ref: ../common/PaymentBaseWalletInfo.yaml - $ref: ../common/PaymentEthereumWalletInfo.yaml @@ -88,6 +89,7 @@ properties: SOLANA_WALLET: ../common/PaymentSolanaWalletInfo.yaml TRON_WALLET: ../common/PaymentTronWalletInfo.yaml PLASMA_WALLET: ../common/PaymentPlasmaWalletInfo.yaml + ARBITRUM_WALLET: ../common/PaymentArbitrumWalletInfo.yaml POLYGON_WALLET: ../common/PaymentPolygonWalletInfo.yaml BASE_WALLET: ../common/PaymentBaseWalletInfo.yaml ETHEREUM_WALLET: ../common/PaymentEthereumWalletInfo.yaml diff --git a/openapi/components/schemas/crypto/CryptoNetwork.yaml b/openapi/components/schemas/crypto/CryptoNetwork.yaml index c03bf25ad..797330ec5 100644 --- a/openapi/components/schemas/crypto/CryptoNetwork.yaml +++ b/openapi/components/schemas/crypto/CryptoNetwork.yaml @@ -7,6 +7,7 @@ enum: - POLYGON - TRON - PLASMA + - ARBITRUM - SPARK description: >- The blockchain network an on-chain transaction settled on. Whether this is the diff --git a/openapi/components/schemas/crypto/EstimateCryptoWithdrawalFeeRequest.yaml b/openapi/components/schemas/crypto/EstimateCryptoWithdrawalFeeRequest.yaml index bb7377bc8..ae1033004 100644 --- a/openapi/components/schemas/crypto/EstimateCryptoWithdrawalFeeRequest.yaml +++ b/openapi/components/schemas/crypto/EstimateCryptoWithdrawalFeeRequest.yaml @@ -18,7 +18,7 @@ properties: type: string description: >- The blockchain network for the withdrawal. Example values: SOLANA, - ETHEREUM, BASE, POLYGON, SPARK, LIGHTNING, BITCOIN. + ETHEREUM, BASE, POLYGON, ARBITRUM, SPARK, LIGHTNING, BITCOIN. example: SOLANA amount: type: integer diff --git a/openapi/components/schemas/external_accounts/ArbitrumWalletExternalAccountInfo.yaml b/openapi/components/schemas/external_accounts/ArbitrumWalletExternalAccountInfo.yaml new file mode 100644 index 000000000..b3231968a --- /dev/null +++ b/openapi/components/schemas/external_accounts/ArbitrumWalletExternalAccountInfo.yaml @@ -0,0 +1,6 @@ +title: Arbitrum Wallet +allOf: + - $ref: ./BaseExternalAccountInfo.yaml + - $ref: ../common/ArbitrumWalletInfo.yaml + - $ref: ./WalletBeneficiaryFields.yaml + - $ref: ./WalletCustodyFields.yaml diff --git a/openapi/components/schemas/external_accounts/ExternalAccountCreateInfoOneOf.yaml b/openapi/components/schemas/external_accounts/ExternalAccountCreateInfoOneOf.yaml index b9d0a807e..b99266e38 100644 --- a/openapi/components/schemas/external_accounts/ExternalAccountCreateInfoOneOf.yaml +++ b/openapi/components/schemas/external_accounts/ExternalAccountCreateInfoOneOf.yaml @@ -42,6 +42,7 @@ oneOf: - $ref: ./LightningExternalAccountInfo.yaml - $ref: ./PolygonWalletExternalAccountInfo.yaml - $ref: ./PlasmaWalletExternalAccountInfo.yaml +- $ref: ./ArbitrumWalletExternalAccountInfo.yaml - $ref: ./SolanaWalletExternalAccountInfo.yaml - $ref: ./SparkWalletExternalAccountInfo.yaml - $ref: ./TronWalletExternalAccountInfo.yaml @@ -92,6 +93,7 @@ discriminator: LIGHTNING: ./LightningExternalAccountInfo.yaml POLYGON_WALLET: ./PolygonWalletExternalAccountInfo.yaml PLASMA_WALLET: ./PlasmaWalletExternalAccountInfo.yaml + ARBITRUM_WALLET: ./ArbitrumWalletExternalAccountInfo.yaml SOLANA_WALLET: ./SolanaWalletExternalAccountInfo.yaml SPARK_WALLET: ./SparkWalletExternalAccountInfo.yaml TRON_WALLET: ./TronWalletExternalAccountInfo.yaml diff --git a/openapi/components/schemas/external_accounts/ExternalAccountInfoOneOf.yaml b/openapi/components/schemas/external_accounts/ExternalAccountInfoOneOf.yaml index 67836c2ce..0ca1c1d75 100644 --- a/openapi/components/schemas/external_accounts/ExternalAccountInfoOneOf.yaml +++ b/openapi/components/schemas/external_accounts/ExternalAccountInfoOneOf.yaml @@ -41,6 +41,7 @@ oneOf: - $ref: ./LightningExternalAccountInfo.yaml - $ref: ./PolygonWalletExternalAccountInfo.yaml - $ref: ./PlasmaWalletExternalAccountInfo.yaml +- $ref: ./ArbitrumWalletExternalAccountInfo.yaml - $ref: ./SolanaWalletExternalAccountInfo.yaml - $ref: ./SparkWalletExternalAccountInfo.yaml - $ref: ./TronWalletExternalAccountInfo.yaml @@ -92,6 +93,7 @@ discriminator: LIGHTNING_ACCOUNT: ./LightningExternalAccountInfo.yaml POLYGON_WALLET: ./PolygonWalletExternalAccountInfo.yaml PLASMA_WALLET: ./PlasmaWalletExternalAccountInfo.yaml + ARBITRUM_WALLET: ./ArbitrumWalletExternalAccountInfo.yaml SOLANA_WALLET: ./SolanaWalletExternalAccountInfo.yaml SPARK_WALLET: ./SparkWalletExternalAccountInfo.yaml TRON_WALLET: ./TronWalletExternalAccountInfo.yaml diff --git a/openapi/components/schemas/external_accounts/ExternalAccountType.yaml b/openapi/components/schemas/external_accounts/ExternalAccountType.yaml index d06e9d850..00bd80946 100644 --- a/openapi/components/schemas/external_accounts/ExternalAccountType.yaml +++ b/openapi/components/schemas/external_accounts/ExternalAccountType.yaml @@ -41,6 +41,7 @@ enum: - ETHEREUM_WALLET - LIGHTNING - PLASMA_WALLET +- ARBITRUM_WALLET - POLYGON_WALLET - SOLANA_WALLET - SPARK_WALLET diff --git a/openapi/components/schemas/quotes/RealtimeFundingQuoteSource.yaml b/openapi/components/schemas/quotes/RealtimeFundingQuoteSource.yaml index ec7a38490..1cb838a9a 100644 --- a/openapi/components/schemas/quotes/RealtimeFundingQuoteSource.yaml +++ b/openapi/components/schemas/quotes/RealtimeFundingQuoteSource.yaml @@ -28,8 +28,8 @@ allOf: description: >- The crypto network to use for the funding source. Required when `currency` is a stablecoin (e.g. USDC, USDT). Specifies which network the customer will deposit - on, so the correct deposit address can be generated. Example values: - `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `TRON`, `PLASMA`, `SPARK`, + on, so the correct deposit address can be generated. Example values: + `SOLANA`, `ETHEREUM`, `BASE`, `POLYGON`, `TRON`, `PLASMA`, `ARBITRUM`, `SPARK`, `LIGHTNING`, `BITCOIN`. example: SOLANA description: >- diff --git a/openapi/paths/crypto/crypto_estimate-withdrawal-fee.yaml b/openapi/paths/crypto/crypto_estimate-withdrawal-fee.yaml index 2583e86e2..9dc97a6ce 100644 --- a/openapi/paths/crypto/crypto_estimate-withdrawal-fee.yaml +++ b/openapi/paths/crypto/crypto_estimate-withdrawal-fee.yaml @@ -24,6 +24,14 @@ post: cryptoNetwork: SOLANA amount: 1000000 destinationAddress: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU + estimateArbitrumWithdrawal: + summary: Estimate fee for USDC withdrawal on Arbitrum + value: + internalAccountId: InternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123 + currency: USDC + cryptoNetwork: ARBITRUM + amount: 1000000 + destinationAddress: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' responses: '200': description: Fee estimation returned successfully diff --git a/openapi/webhooks/external-account-status.yaml b/openapi/webhooks/external-account-status.yaml index d528ec031..60b76d703 100644 --- a/openapi/webhooks/external-account-status.yaml +++ b/openapi/webhooks/external-account-status.yaml @@ -66,6 +66,21 @@ post: accountInfo: accountType: ETHEREUM_WALLET address: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' + arbitrumWalletActive: + summary: An Arbitrum wallet account became active + value: + id: Webhook:019542f5-b3e7-1d02-0000-000000000044 + type: EXTERNAL_ACCOUNT.STATUS_UPDATED + timestamp: '2025-08-15T14:32:00Z' + data: + id: ExternalAccount:f95dcbd6-dced-4ec4-b756-3c3a9ea3d966 + customerId: Customer:da459a29-1fb7-41ce-a4cb-eb3a3c9fd7a7 + status: ACTIVE + currency: USDC + ownershipType: FIRST_PARTY + accountInfo: + accountType: ARBITRUM_WALLET + address: '0xAbCDEF1234567890aBCdEf1234567890ABcDef12' verificationFailed: summary: A liveness check failed; a new challenge is needed to retry value: diff --git a/samples/frontend/src/steps/CreateQuote.tsx b/samples/frontend/src/steps/CreateQuote.tsx index 7a27280fc..660382bc3 100644 --- a/samples/frontend/src/steps/CreateQuote.tsx +++ b/samples/frontend/src/steps/CreateQuote.tsx @@ -16,7 +16,7 @@ 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'] +const CRYPTO_NETWORKS = ['ARBITRUM', 'BASE', 'ETHEREUM', 'POLYGON', 'SOLANA'] // Decimals per source currency, used to scale the default sending amount into the // currency's smallest unit (lockedCurrencyAmount with lockedCurrencySide=SENDING). diff --git a/samples/frontend/src/steps/CreateUsdcExternalAccount.tsx b/samples/frontend/src/steps/CreateUsdcExternalAccount.tsx index db594e89b..50a9968d5 100644 --- a/samples/frontend/src/steps/CreateUsdcExternalAccount.tsx +++ b/samples/frontend/src/steps/CreateUsdcExternalAccount.tsx @@ -19,6 +19,12 @@ const NETWORK_CONFIGS: Record = { + ARBITRUM: { + label: "Arbitrum", + accountType: "ARBITRUM_WALLET", + address: "0xAbCDEF1234567890aBCdEf1234567890ABcDef12", + description: "USDC on Arbitrum", + }, BASE: { label: "Base", accountType: "BASE_WALLET", diff --git a/samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt b/samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt index a13a9d4fd..3fd483b71 100644 --- a/samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt +++ b/samples/kotlin/src/main/kotlin/com/grid/sample/routes/ExternalAccounts.kt @@ -19,6 +19,7 @@ import com.lightspark.grid.models.customers.externalaccounts.GbpBeneficiary import com.lightspark.grid.models.customers.externalaccounts.InrBeneficiary import com.lightspark.grid.models.customers.externalaccounts.MxnBeneficiary import com.lightspark.grid.models.customers.externalaccounts.PhpBeneficiary +import com.lightspark.grid.models.customers.externalaccounts.ArbitrumWalletInfo import com.lightspark.grid.models.customers.externalaccounts.PlasmaWalletInfo import com.lightspark.grid.models.customers.externalaccounts.PolygonWalletInfo import com.lightspark.grid.models.customers.externalaccounts.SolanaWalletInfo @@ -222,6 +223,13 @@ private fun buildAccountInfo(accountType: String, accountInfo: JsonNode): Extern .build() ExternalAccountCreate.AccountInfo.ofPlasmaWallet(info) } + "ARBITRUM_WALLET" -> { + val info = ArbitrumWalletInfo.builder() + .accountType(ArbitrumWalletInfo.AccountType.ARBITRUM_WALLET) + .address(accountInfo.requireText("address")) + .build() + ExternalAccountCreate.AccountInfo.ofArbitrumWallet(info) + } else -> throw IllegalArgumentException("Unsupported account type: $accountType") } }