Skip to content

Add alfredpay support#1057

Open
gianfra-t wants to merge 64 commits intostagingfrom
add-alfredpay-support
Open

Add alfredpay support#1057
gianfra-t wants to merge 64 commits intostagingfrom
add-alfredpay-support

Conversation

@gianfra-t
Copy link
Contributor

@gianfra-t gianfra-t commented Feb 4, 2026

  • Integrates AlfredPay as a new fiat onramp provider for USD → EVM flows (via Polygon USDC + Squid Router)

    • Adds a full KYC lifecycle for AlfredPay: customer creation, redirect-based identity verification, status polling, and failure handling
    • Implements quoting pipeline (AlfredPay quote → fee calculation → Squid Router cross-chain route → finalize) and transaction
      preparation
      (approve + swap unsigned txs routed through Polygon)
    • Adds backend model, migration, controller, routes, and middleware for AlfredPay customer management
    • Adds frontend XState machine (alfredpayKycMachine), KYC flow UI component, ACH payment details display, and API service client
    • Extends shared package with AlfredPay types, API service singleton, and endpoint definitions
    • Includes minor non-AlfredPay cleanups: quote summary layout fix, email validation improvements, lint fixes, animation simplification

    Opinionated choices:

    • Leaves duplicated kyc/kyb endpoints, as our internal handling may be different for each in the near future and this allows for more flexibility at the cost of slightly repeated code.
    • We keep a state for the user in our database. This allows for easy checking of the user's state without consulting Alfredpay's API, and most importantly allows for tracking of sub-states (KYC linked opened, closed, etc) that are relevant only to us.
      This means we maintain a different KYC status for each user, that maps and extends Alfredpay's KYC status.

    New files

    Shared (packages/shared)

    • services/alfredpay/types.ts — Enums and request/response types for AlfredPay API
    • services/alfredpay/alfredpayApiService.ts — Singleton HTTP client for AlfredPay's penny API
    • endpoints/alfredpay.endpoints.ts — Frontend↔backend contract types

    Backend (apps/api)

    • migrations/023-create-alfredpay-customers-table.ts — DB table for AlfredPay customers
    • models/alfredPayCustomer.model.ts — Sequelize model
    • controllers/alfredpay.controller.ts — 6 endpoints (status, createCustomer, KYC link/opened/finished/status)
    • routes/v1/alfredpay.route.ts + middlewares/alfredpay.middleware.ts
    • services/quote/engines/ — Initialize, fee, and Squid Router engines for AlfredPay onramp
    • services/quote/routes/strategies/onramp-alfredpay-to-evm.strategy.ts
    • services/transactions/onramp/routes/alfredpay-to-evm.ts

    Frontend (apps/frontend)

    • machines/alfredpayKyc.machine.ts — XState machine for KYC flow
    • components/Alfredpay/AlfredpayKycFlow.tsx — KYC UI component
    • components/widget-steps/SummaryStep/USOnrampDetails.tsx — ACH payment details display
    • services/api/alfredpay.service.ts — API client

    Known TODOs

    • Hardcoded test email in createCustomer — needs to be restored to use SupabaseAuthService.getUserProfile()
    • UPDATE_REQUIRED KYC status is unhandled in mapKycStatus
    • Fee engine returns 0 fees — needs verification
    • alfredpayCustomer typed as any in RampContext
    • Leftover console.log statements in controller and USOnrampDetails.tsx
    • KYC failure retry not handled in its own state machine

    Test plan

    • Verify AlfredPay customer creation flow (create → get KYC link → complete KYC → poll until success)
    • Verify USD onramp quoting returns correct amounts from AlfredPay API
    • Verify transaction preparation builds correct Squid Router approve + swap txs
    • Verify ACH payment details are displayed correctly after ramp initiation
    • Verify KYC failure states are handled gracefully
    • Verify non-USD flows are unaffected by the changes
    • Run bun lint and bun typecheck to confirm no regressions

@netlify
Copy link

netlify bot commented Feb 4, 2026

Deploy Preview for vortexfi ready!

Name Link
🔨 Latest commit 8f81c53
🔍 Latest deploy log https://app.netlify.com/projects/vortexfi/deploys/69ab2993209d450008fdabcd
😎 Deploy Preview https://deploy-preview-1057--vortexfi.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Feb 4, 2026

Deploy Preview for vortex-sandbox ready!

Name Link
🔨 Latest commit 8f81c53
🔍 Latest deploy log https://app.netlify.com/projects/vortex-sandbox/deploys/69ab2993a218dc0008dd17f4
😎 Deploy Preview https://deploy-preview-1057--vortex-sandbox.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@ebma ebma changed the base branch from staging to 882-account-creation-on-vortex February 10, 2026 18:32
Base automatically changed from 882-account-creation-on-vortex to staging February 10, 2026 20:30
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Integrates AlfredPay as a new USD↔EVM fiat ramp provider (ACH-based onramp + offramp), including KYC lifecycle, quoting, transaction preparation/execution (SquidRouter + permit-based relayer execution), and supporting shared types/utilities across backend + frontend.

Changes:

  • Adds AlfredPay onramp/offramp quote strategies + engines, phase handlers, and transaction preparation on the API.
  • Adds frontend AlfredPay KYC XState flow and ACH payment details UI.
  • Extends shared package with AlfredPay endpoints/types, USD fiat token support, and typed-data signing/handling.

Reviewed changes

Copilot reviewed 162 out of 167 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
relayer-contract/typechain-types/index.ts Autogenerated TypeChain barrel exports for relayer contract + OZ deps
relayer-contract/typechain-types/factories/index.ts Autogenerated TypeChain factories barrel
relayer-contract/typechain-types/factories/contracts/index.ts Autogenerated factory export for TokenRelayer
relayer-contract/typechain-types/factories/@openzeppelin/index.ts Autogenerated OZ factory barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/utils/math/index.ts Autogenerated OZ SafeCast factory barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/utils/math/SafeCast__factory.ts Autogenerated OZ SafeCast factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/utils/index.ts Autogenerated OZ utils factories barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/utils/cryptography/index.ts Autogenerated OZ cryptography factories barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/utils/cryptography/EIP712__factory.ts Autogenerated OZ EIP712 factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/utils/cryptography/ECDSA__factory.ts Autogenerated OZ ECDSA factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/utils/Strings__factory.ts Autogenerated OZ Strings factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/utils/ShortStrings__factory.ts Autogenerated OZ ShortStrings factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/utils/Nonces__factory.ts Autogenerated OZ Nonces factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/token/index.ts Autogenerated OZ token factories barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/token/ERC20/index.ts Autogenerated OZ ERC20 factories barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/index.ts Autogenerated OZ ERC20 extensions factories barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit__factory.ts Autogenerated OZ IERC20Permit factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata__factory.ts Autogenerated OZ IERC20Metadata factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/token/ERC20/IERC20__factory.ts Autogenerated OZ IERC20 factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/interfaces/index.ts Autogenerated OZ interfaces factories barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts Autogenerated OZ draft-IERC6093 factories barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors__factory.ts Autogenerated OZ IERC721Errors factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors__factory.ts Autogenerated OZ IERC20Errors factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors__factory.ts Autogenerated OZ IERC1155Errors factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/interfaces/IERC5267__factory.ts Autogenerated OZ IERC5267 factory
relayer-contract/typechain-types/factories/@openzeppelin/contracts/index.ts Autogenerated OZ contracts factories barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/access/index.ts Autogenerated OZ access factories barrel
relayer-contract/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.ts Autogenerated OZ Ownable factory
relayer-contract/typechain-types/contracts/index.ts Autogenerated TokenRelayer type export barrel
relayer-contract/typechain-types/common.ts Autogenerated TypeChain common helpers/types
relayer-contract/typechain-types/@openzeppelin/index.ts Autogenerated OZ type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/utils/math/index.ts Autogenerated OZ math type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/utils/math/SafeCast.ts Autogenerated OZ SafeCast type
relayer-contract/typechain-types/@openzeppelin/contracts/utils/index.ts Autogenerated OZ utils type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/utils/cryptography/index.ts Autogenerated OZ cryptography type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/utils/cryptography/EIP712.ts Autogenerated OZ EIP712 type
relayer-contract/typechain-types/@openzeppelin/contracts/utils/cryptography/ECDSA.ts Autogenerated OZ ECDSA type
relayer-contract/typechain-types/@openzeppelin/contracts/utils/Strings.ts Autogenerated OZ Strings type
relayer-contract/typechain-types/@openzeppelin/contracts/utils/ShortStrings.ts Autogenerated OZ ShortStrings type
relayer-contract/typechain-types/@openzeppelin/contracts/utils/Nonces.ts Autogenerated OZ Nonces type
relayer-contract/typechain-types/@openzeppelin/contracts/token/index.ts Autogenerated OZ token type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/token/ERC20/index.ts Autogenerated OZ ERC20 type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/index.ts Autogenerated OZ ERC20 extensions type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.ts Autogenerated OZ IERC20Permit type
relayer-contract/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.ts Autogenerated OZ IERC20Metadata type
relayer-contract/typechain-types/@openzeppelin/contracts/token/ERC20/IERC20.ts Autogenerated OZ IERC20 type
relayer-contract/typechain-types/@openzeppelin/contracts/token/ERC20/ERC20.ts Autogenerated OZ ERC20 type
relayer-contract/typechain-types/@openzeppelin/contracts/interfaces/index.ts Autogenerated OZ interfaces type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts Autogenerated OZ draft-IERC6093 type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.ts Autogenerated OZ IERC721Errors type
relayer-contract/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.ts Autogenerated OZ IERC20Errors type
relayer-contract/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.ts Autogenerated OZ IERC1155Errors type
relayer-contract/typechain-types/@openzeppelin/contracts/interfaces/IERC5267.ts Autogenerated OZ IERC5267 type
relayer-contract/typechain-types/@openzeppelin/contracts/index.ts Autogenerated OZ contracts type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/access/index.ts Autogenerated OZ access type barrel
relayer-contract/typechain-types/@openzeppelin/contracts/access/Ownable.ts Autogenerated OZ Ownable type
relayer-contract/tsconfig.json Hardhat/TypeScript config for relayer-contract package
relayer-contract/package.json Hardhat/OpenZeppelin dependencies + scripts for relayer-contract
relayer-contract/ignition/modules/Relayer.ts Ignition deployment module for TokenRelayer
relayer-contract/ignition/deployments/chain-42161/deployed_addresses.json Deployment address record (Arbitrum)
relayer-contract/ignition/deployments/chain-42161/artifacts/TokenRelayer#TokenRelayer.dbg.json Ignition deployment debug metadata (Arbitrum)
relayer-contract/ignition/deployments/chain-137/deployed_addresses.json Deployment address record (Polygon)
relayer-contract/ignition/deployments/chain-137/artifacts/TokenRelayer#TokenRelayer.dbg.json Ignition deployment debug metadata (Polygon)
relayer-contract/hardhat.config.ts Hardhat network + solidity compiler settings
relayer-contract/contracts/TokenRelayer.sol New relayer contract for permit + signed payload execution
relayer-contract/.env.example Example env vars for deploying relayer contract
packages/shared/src/tokens/utils/typeGuards.ts Adds FreeTokenDetails support to token type guards
packages/shared/src/tokens/utils/helpers.ts Extends fiat token details resolver to include freeTokenConfig
packages/shared/src/tokens/types/base.ts Adds USD fiat token + FreeTokenDetails + TokenType.Fiat
packages/shared/src/tokens/index.ts Exports freeTokens config
packages/shared/src/tokens/freeTokens/config.ts Adds USD “free token” fiat config
packages/shared/src/tokens/constants/misc.ts Adds Polygon USDC address + decimals constants
packages/shared/src/services/squidrouter/onramp.ts Allows variable Polygon input token address (not hardcoded EURe)
packages/shared/src/services/index.ts Exports alfredpay services
packages/shared/src/services/alfredpay/index.ts New AlfredPay service exports
packages/shared/src/index.ts Exposes ramp endpoint types via shared index
packages/shared/src/helpers/signUnsigned.ts Adds typed-data handling + gas parameter tweaks in EVM signing
packages/shared/src/helpers/payment-method-mapper.ts Adds ACH as a payment method
packages/shared/src/helpers/parseNumbers.ts Adds guard for Big.js exponent NaN case
packages/shared/src/endpoints/ramp.endpoints.ts Adds typed-data tx shapes + new ramp phases + ACH payment data
packages/shared/src/endpoints/payment-methods.endpoints.ts Adds ACH enums
packages/shared/src/endpoints/monerium.ts Extracts generic Signature type
packages/shared/src/endpoints/index.ts Exports AlfredPay endpoints
packages/shared/src/endpoints/alfredpay.endpoints.ts Adds frontend↔backend contract types for AlfredPay
packages/shared/src/constants.ts Adds AlfredPay env vars
apps/frontend/src/translations/en.json Adds ACH onramp UI strings
apps/frontend/src/stores/quote/useQuoteStore.ts Maps USD to ACH destination
apps/frontend/src/services/transactions/userSigning.ts Adds typed-data signing support
apps/frontend/src/services/api/alfredpay.service.ts New frontend API client for AlfredPay endpoints
apps/frontend/src/pages/widget/index.tsx Renders AlfredPay KYC flow when applicable
apps/frontend/src/machines/types.ts Adds AlfredPay KYC machine actor/snapshot types (incl. TODO any)
apps/frontend/src/machines/ramp.machine.ts Registers AlfredPay KYC machine actor
apps/frontend/src/machines/kyc.states.ts Adds AlfredPay KYC state integration + USD decision
apps/frontend/src/machines/actors/validateKyc.actor.ts Requires KYC for USD flows
apps/frontend/src/machines/actors/sign.actor.ts Adds typed-data signing pipeline integration
apps/frontend/src/machines/actors/register.actor.ts Adds USD onramp registration payload
apps/frontend/src/contexts/rampState.tsx Adds AlfredPay actor/selector hooks
apps/frontend/src/components/widget-steps/SummaryStep/USOnrampDetails.tsx Adds ACH payment details UI
apps/frontend/src/components/widget-steps/SummaryStep/TransactionTokensDisplay.tsx Shows USOnrampDetails for USD buy flows
apps/frontend/src/components/TokenSelection/TokenSelectionList/helpers.tsx Includes freeTokenConfig in fiat token list
apps/frontend/src/components/Spinner/index.tsx Adds optional className to Spinner
apps/frontend/src/components/RampSubmitButton/RampSubmitButton.tsx Treats ACH details as deposit-ready for onramps
apps/frontend/src/components/Alfredpay/AlfredpayKycFlow.tsx New AlfredPay KYC UI flow component
apps/api/src/models/index.ts Registers AlfredPayCustomer model and associations
apps/api/src/models/alfredPayCustomer.model.ts New Sequelize model for AlfredPay customer lifecycle
apps/api/src/database/migrations/023-create-alfredpay-customers-table.ts Migration for alfredpay_customers table
apps/api/src/contracts/TokenRelayer.ts ABI for TokenRelayer contract execution
apps/api/src/api/services/transactions/validation.ts Skips EVM tx validation for typed-data txs
apps/api/src/api/services/transactions/onramp/routes/alfredpay-to-evm.ts Prepares AlfredPay USD onramp txs (Polygon→EVM)
apps/api/src/api/services/transactions/onramp/index.ts Routes USD onramps to AlfredPay transaction preparation
apps/api/src/api/services/transactions/onramp/common/types.ts Adds AlfredPay onramp params type
apps/api/src/api/services/transactions/onramp/common/transactions.ts Fixes maxPriorityFeePerGas assignment from estimateFeesPerGas
apps/api/src/api/services/transactions/offramp/index.ts Routes USD offramps to AlfredPay preparation
apps/api/src/api/services/transactions/offramp/common/types.ts Adds optional userId for offramps
apps/api/src/api/services/quote/routes/strategies/onramp-alfredpay-to-evm.strategy.ts New onramp route strategy for AlfredPay USD→EVM
apps/api/src/api/services/quote/routes/strategies/offramp-evm-to-alfredpay.strategy.ts New offramp route strategy for EVM→AlfredPay USD
apps/api/src/api/services/quote/routes/route-resolver.ts Resolves USD routes for onramp/offramp (ACH)
apps/api/src/api/services/quote/engines/squidrouter/onramp-polygon-to-evm-alfredpay.ts SquidRouter engine for AlfredPay onramp bridging
apps/api/src/api/services/quote/engines/squidrouter/onramp-evm-to-polygon.ts SquidRouter engine for bridging to Polygon for AlfredPay offramp
apps/api/src/api/services/quote/engines/initialize/onramp-alfredpay.ts AlfredPay onramp quote initialization engine
apps/api/src/api/services/quote/engines/initialize/offramp-from-evm-alfredpay.ts Offramp init engine bridging EVM→Polygon USDC
apps/api/src/api/services/quote/engines/initialize/offramp-alfredpay.ts AlfredPay offramp quote initialization engine
apps/api/src/api/services/quote/engines/finalize/onramp.ts Finalize engine handles USD onramps using alfredpayMint
apps/api/src/api/services/quote/engines/finalize/offramp.ts Finalize engine handles alfredpayOfframp in output computation
apps/api/src/api/services/quote/engines/fee/onramp-alfredpay-to-evm.ts Fee engine placeholder for AlfredPay onramp
apps/api/src/api/services/quote/engines/fee/offramp-evm-to-alfredpay.ts Fee engine placeholder for AlfredPay offramp
apps/api/src/api/services/quote/core/types.ts Extends QuoteContext with alfredpayMint/alfredpayOfframp
apps/api/src/api/services/quote/core/helpers.ts Adds ACH to supported chains
apps/api/src/api/services/phases/register-handlers.ts Registers AlfredPay phase handlers + permit execute handler
apps/api/src/api/services/phases/meta-state-types.ts Adds AlfredPay-related state metadata fields
apps/api/src/api/services/phases/handlers/squidrouter-permit-execution-handler.ts Executes TokenRelayer execute() using signed typed data
apps/api/src/api/services/phases/handlers/squid-router-phase-handler.ts Treats USD like EUR for choosing Polygon client
apps/api/src/api/services/phases/handlers/squid-router-pay-phase-handler.ts Treats USD like EUR for Polygon chain status polling
apps/api/src/api/services/phases/handlers/initial-phase-handler.ts Routes USD BUY/SELL initial phases to AlfredPay handlers
apps/api/src/api/services/phases/handlers/fund-ephemeral-handler.ts Adjusts ephemeral funding requirements + next-phase selection for USD
apps/api/src/api/services/phases/handlers/final-settlement-subsidy.ts Extends final settlement subsidy for AlfredPay offramps
apps/api/src/api/services/phases/handlers/destination-transfer-handler.ts Attempts to skip destination transfer for Polygon USD onramps
apps/api/src/api/services/phases/handlers/alfredpay-onramp-mint-handler.ts Polls AlfredPay onramp + checks Polygon USDC balance
apps/api/src/api/services/phases/handlers/alfredpay-offramp-transfer-handler.ts Sends Polygon transfer for offramp + polls AlfredPay completion
apps/api/src/api/routes/v1/index.ts Adds v1/alfredpay routes
apps/api/src/api/routes/v1/alfredpay.route.ts AlfredPay routes wiring + auth/middleware
apps/api/src/api/middlewares/alfredpay.middleware.ts Validates country param against AlfredPayCountry enum
.gitignore Ignores relayer-contract artifacts/cache
Comments suppressed due to low confidence (7)

apps/frontend/src/components/Alfredpay/AlfredpayKycFlow.tsx:3

  • cn is imported but never used, which will typically trip lint/noUnusedLocals. Remove the unused import or apply it to className composition if intended.
    apps/api/src/api/services/phases/handlers/squidrouter-permit-execution-handler.ts:4
  • This file imports isSignedTypedDataArray from @packages/shared while the rest of the imports come from @vortexfi/shared. Even if both resolve, mixing entrypoints can lead to duplicate module instances and type/instance mismatches. Prefer importing all shared helpers from the same package entrypoint (likely @vortexfi/shared).
import { isSignedTypedDataArray } from "@packages/shared";
import {
  EvmClientManager,
  getNetworkFromDestination,

apps/api/src/api/services/transactions/onramp/routes/alfredpay-to-evm.ts:4

  • This new route mixes imports from @packages/shared and @vortexfi/shared. Even if both resolve, mixing entrypoints can cause subtle type-guard mismatches and complicate module resolution. Consolidate shared imports under a single package entrypoint.
    apps/frontend/src/machines/actors/sign.actor.ts:1
  • This empty import (import {} ...) is a no-op and will typically trigger lint/TS unused-import checks. Please remove it.
    apps/frontend/src/components/widget-steps/SummaryStep/USOnrampDetails.tsx:15
  • This component includes unused imports (QRCodeSVG, CopyButton) and a console.log("loading"). These will fail stricter lint settings and leak debug output to end users. Remove unused imports and replace console.log with proper UI state (or structured logging behind a debug flag if needed).
    apps/frontend/src/machines/kyc.states.ts:100
  • There is a console.log inside the AlfredPay KYC invocation input mapping. This will spam logs in production and can leak user context. Remove it or guard it behind a debug flag.
    apps/api/src/api/services/transactions/validation.ts:7
  • This file introduces a new @packages/shared import while other shared types/utilities are imported from @vortexfi/shared. To avoid duplicate module instances and inconsistent type guards, prefer importing isSignedTypedData / isSignedTypedDataArray from the same shared package entrypoint used elsewhere in the file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +37 to +39
// For Alfredpay's onramps into Polygon, we skip his step, as we are on the destination network already!
if (state.type === RampDirection.BUY && state.to === Networks.Polygon && quote.inputCurrency === FiatToken.USD) {
throw new Error("DestinationTransferHandler: Only supports onramp operations");
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AlfredPay USD→Polygon onramp “skip destination transfer” branch currently throws an error, which will fail the ramp even though the intent is to bypass this phase. Instead of throwing, transition to the next phase (likely complete) or return the unchanged state so the workflow can proceed.

Suggested change
// For Alfredpay's onramps into Polygon, we skip his step, as we are on the destination network already!
if (state.type === RampDirection.BUY && state.to === Networks.Polygon && quote.inputCurrency === FiatToken.USD) {
throw new Error("DestinationTransferHandler: Only supports onramp operations");
// For Alfredpay's onramps into Polygon, we skip this step, as we are on the destination network already!
if (state.type === RampDirection.BUY && state.to === Networks.Polygon && quote.inputCurrency === FiatToken.USD) {
return this.transitionToNextPhase(state, "complete");

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +23
[FiatToken.USD]: {
assetSymbol: "USD",
decimals: 1,
fiat: {
assetIcon: "usd",
name: "US Dollar",
symbol: "USD"
}, // TODO find these values with Alfredpay
maxBuyAmountRaw: "10000000000",
maxSellAmountRaw: "100000000000000000000",
minBuyAmountRaw: "1",
minSellAmountRaw: "0.01",
pendulumRepresentative: PENDULUM_USDC_ASSETHUB,
type: TokenType.Fiat
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

freeTokenConfig entries should use consistent smallest-unit “raw” amounts and decimals like the existing Stellar/Moonbeam configs (which store integer strings). Here, decimals: 1 and values like minSellAmountRaw: "0.01" are inconsistent with the established pattern and will break limit validation and amount conversions. Define USD’s fiat decimals (typically 2) and express min/max amounts as integer raw strings in that unit.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Values used for testing purposes.

Comment on lines 56 to 59
const quote = await QuoteTicket.findByPk(state.quoteId);
if (!quote) {
throw new Error("Quote not found for the given state");
if (!quote || !quote.metadata.alfredpayOfframp) {
throw new Error("Quote not found or invalid for the given state");
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FinalSettlementSubsidyHandler is invoked for non-AlfredPay onramps (e.g. from squidRouterPay), but it now throws unless quote.metadata.alfredpayOfframp is present. This will break existing onramp flows. Gate AlfredPay-specific logic on state.type === SELL && quote.outputCurrency === USD, and allow other routes to execute without requiring alfredpayOfframp metadata.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was modified in a later commit. This is handled now.

Copy link
Member

@ebma ebma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we only using the relayer contract for offramps and not for onramps? Is there a reason, or just because of the initial effort?

}
finalOutputAmountDecimal = new Big(output);
} else if (request.inputCurrency === FiatToken.USD) {
const output = ctx.alfredpayMint?.outputAmountDecimal;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be ctx.evmToEvm?.outputAmountDecimal, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True... actually it makes me think, something we have not decided yet, and is how to cover for squidrouter costs (fee + slippage). If we cover it ourselves somehow in a fee, then it should be alfredpayMint?.outputAmountDecimal

@gianfra-t
Copy link
Contributor Author

@ebma We are not using the relayer contract for onramps because the ephemeral is the one sending the transaction in that flow, so we also control the execution. I don't see too much of a benefit in doing it for onramps, the relayer is mostly useful when interfacing with external users or systems.

Comment on lines +1 to +20
import {
AlfredPayCountry,
AlfredPayStatus,
AlfredpayApiService,
AlfredpayCreateCustomerRequest,
AlfredpayCreateCustomerResponse,
AlfredpayCustomerType,
AlfredpayGetKybRedirectLinkResponse,
AlfredpayGetKybStatusResponse,
AlfredpayGetKycRedirectLinkRequest,
AlfredpayGetKycRedirectLinkResponse,
AlfredpayGetKycStatusRequest,
AlfredpayGetKycStatusResponse,
AlfredpayKybStatus,
AlfredpayKycRedirectFinishedRequest,
AlfredpayKycRedirectOpenedRequest,
AlfredpayKycStatus,
AlfredpayStatusRequest,
AlfredpayStatusResponse
} from "@vortexfi/shared";
RampPhase
} from "@vortexfi/shared";
import logger from "../../../../config/logger";
import QuoteTicket from "../../../../models/quoteTicket.model";
Comment on lines +1 to +9
import {
EvmClientManager,
getNetworkFromDestination,
isNetworkEVM,
isSignedTypedDataArray,
Networks,
RampPhase,
SignedTypedData
} from "@vortexfi/shared";
RampPhase,
SignedTypedData
} from "@vortexfi/shared";
import { recoverTypedDataAddress } from "viem";
import { PhaseError } from "../../../errors/phase-error";
import { RELAYER_ADDRESS } from "../../transactions/offramp/routes/evm-to-alfredpay";
import { BasePhaseHandler } from "../base-phase-handler";
import { StateMetadata } from "../meta-state-types";
@@ -0,0 +1,28 @@
import { EvmToken, FiatToken, RampCurrency, RampDirection } from "@vortexfi/shared";
import Big from "big.js";
import { EvmBridgeQuoteRequest, getEvmBridgeQuote } from "../../core/squidrouter";
import { QuoteContext } from "../../core/types";
import { assignPreNablaContext, BaseInitializeEngine } from "./index";
Comment on lines +1 to +13
import {
AlfredpayApiService,
AlfredpayChain,
AlfredpayFiatCurrency,
AlfredpayOnChainCurrency,
AlfredpayPaymentMethodType,
CreateAlfredpayOnrampQuoteRequest,
CreateAlfredpayOnrampRequest,
ERC20_USDC_POLYGON_DECIMALS,
multiplyByPowerOfTen,
Networks,
RampDirection
} from "@vortexfi/shared";
import TaxId from "../../../models/taxId.model";
import { APIError } from "../../errors/api-error";
import { ActivePartner, handleQuoteConsumptionForDiscountState } from "../../services/quote/engines/discount/helpers";
import { SupabaseAuthService } from "../auth/supabase.service";
Comment on lines +1 to +19
import {
AlfredPayStatus,
createOfframpSquidrouterTransactionsToEvm,
ERC20_USDC_POLYGON,
EvmClientManager,
EvmNetworks,
EvmTokenDetails,
EvmTransactionData,
getNetworkFromDestination,
getNetworkId,
getOnChainTokenDetails,
isEvmToken,
isNetworkEVM,
Networks,
SignedTypedData,
SQUDROUTER_MAIN_CONTRACT_POLYGON,
TypedDataDomain,
UnsignedTx
} from "@vortexfi/shared";
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.

3 participants