Mykobo Base EVM Integration#1159
Draft
ebma wants to merge 70 commits into
Draft
Conversation
Introduces the Mykobo anchor integration surface in the shared package: singleton MykoboApiService with bearer auth + 401 retry, request/response types, EURC EvmToken on Base, Mykobo env vars, and an email field on RegisterRampRequest.additionalData to bind a ramp to a Mykobo profile.
Adds an EVM-to-SEPA quote strategy that swaps USDC to EURC on Base via Nabla and reads the anchor fee dynamically from Mykobo's /fees endpoint, mirroring the AlfredPay model (no static anchor table row). RouteResolver sends sepa+EVM to the new strategy while sepa+AssetHub stays on the existing Stellar path. Adds Mykobo-specific RampState meta fields and the locked-in implementation plan doc.
Adds the execution slab for the Mykobo EUR offramp targeting Base (EVM): - New evm-to-mykobo route prepares squidRouter (skipped when source is Base USDC), fee distribution, Nabla USDC->EURC swap, Mykobo intent creation, presigned EURC transfer to receivables, plus USDC/EURC/AXLUSDC cleanup approvals. - New mykoboPayoutOnBase phase handler broadcasts the EURC transfer and polls Mykobo until the transaction reaches COMPLETED. - subsidizePostSwap branches to mykoboPayoutOnBase for EUR offramps and routes EUR EVM offramps through the EVM subsidy path. - fundEphemeral now provisions a Base ephemeral for EUR offramps and only verifies user-submitted squid hashes when a blueprint exists. - base-chain post-process sweeps the new baseCleanupEurc phase alongside existing Base cleanups. - ramp controller captures req.ip into additionalData so the Mykobo intent request carries the user IP required by the API.
- Add integration test hitting real Mykobo dev sandbox (fees, intent, quote creation, registerRamp) without on-chain submission. - Fix OffRampFinalizeEngine to honor nablaSwapEvm output for SEPA path (not just PIX); previously SEPA quotes failed finalization. - Strip /v1 from default MYKOBO_BASE_URL; client appends it itself, so env var is now the bare host (https://api-dev.mykobo.app). - Ignore lastRampStateMykoboEur.json test artifact.
Introduces the mykoboOnrampDeposit RampPhase for the upcoming EVM ephemeral flow, an IbanPaymentData.reference field for SCOR payment references, EURC Base ERC20 constants, a free-token config for Mykobo EUR, and wires the new phase into the frontend progress page maps. Reuses the unified subsidizePreSwap / subsidizePostSwap / distributeFees handlers for the EVM branch instead of introducing suffixed phase names.
The unified subsidizePreSwap, subsidizePostSwap, nablaApprove, nablaSwap, and distributeFees handlers previously branched into the EVM path when the input or output currency was BRL (and a partial EURC special-case for offramp post-swap). This hardcoded the BRL flow into every handler and required a new conditional for each future EVM-ephemeral route. Switch the dispatch to check quote.metadata.nablaSwapEvm, which is set by the quote engine whenever the EVM-ephemeral Nabla path is selected (BRL today, Mykobo EUR onramp + offramp next). Removes the FiatToken import where it is no longer used.
Adds OnRampInitializeMykoboEngine which estimates EURC delivered on the Base ephemeral after Mykobo's deposit fee, populating ctx.mykoboMint for downstream stages. Introduces a Mykobo onramp validation helper that checks for an EVM ephemeral and EURC on Base, a MykoboApiService.defaultDepositFee shortcut to lookup MykoboFeeKind.DEPOSIT fees, the MykoboOnrampTransactionParams type carrying the user email, and a parallel ctx.mykoboMint shape next to ctx.aveniaMint / ctx.aveniaTransfer in the quote context.
Adds OnRampSwapEngineMykoboEvm, an EVM Nabla swap variant that consumes ctx.mykoboMint and swaps EURC -> USDC on Base, OnRampMykoboToEvmFeeEngine which carries the Mykobo deposit fee as the anchor fee and computes the Squidrouter network fee for Base USDC -> destination, and the onrampMykoboToEvmStrategy route strategy that chains Initialize -> Fee -> NablaSwap -> Discount -> SquidRouter -> Finalize. Reuses OnRampSquidRouterBrlToEvmEngineBase since it operates on USDC on Base regardless of upstream fiat origin.
Replace Monerium with Mykobo as the EUR→EVM onramp path: - RouteResolver: EURC + EVM destination → onrampMykoboToEvmStrategy - InitialPhaseHandler: EURC BUY → mykoboOnrampDeposit phase Monerium AssetHub strategy is retained for the substrate path.
Add OnrampMykobo kind to ramp-transaction-preparation that routes EURC BUY on EVM destinations to a new prepareMykoboToEvmOnrampTransactions route. RampService.prepareMykoboOnrampTransactions creates the Mykobo deposit intent (EURC, DEPOSIT, evm ephemeral address) and surfaces IBAN + reference via ibanPaymentData. Monerium remains for EURC -> AssetHub.
Mykobo on Base replaces Monerium for EUR onramps. EUR onramps now route exclusively through the Mykobo EVM-ephemeral flow; EUR→AssetHub is no longer supported and returns HTTP 400. - Delete Monerium controller, route, service, handlers, quote engines, strategies, transaction routes, and shared endpoint module - Drop `moneriumAuthToken`, `moneriumMint`, `moneriumOnrampSelfTransfer`, `moneriumOnrampMint` from phase/quote/meta types and validation - Remove EURC→Monerium branch from fund-ephemeral nextPhaseSelector and ramp helpers explorer-link builder - Drop `onrampMoneriumToAssethubStrategy` import and SEPA→AssetHub branch from route-resolver; EURC+AssetHub BUY now hard 400 - Drop `createOnrampSquidrouterTransactionsFromPolygonToMoonbeam` from shared squidrouter; retain Polygon→EVM path for Alfredpay USDT - Inline `Signature` type into ramp.endpoints (was re-exported from deleted Monerium endpoint module) - Update validation.test fixtures to use generic squid/nabla phases
Sweep removal of Monerium frontend integration: KYC machine, redirect step, AssetHub form step, auth service, hook, stories, schema fields, URL params, translations, and progress flow entries. Mykobo replacement UI will be added in a dedicated slab. - Delete moneriumKyc.machine, moneriumAuth, monerium.service, useMoneriumFlow, MoneriumRedirectStep, MoneriumAssethubFormStep, related stories - Remove ERC2612 permit branch and SEPA SELL message-signature branch from sign.actor; drop `moneriumOfframpSignature` and `moneriumOnrampPermit` from additionalData - Drop `moneriumWalletAddress` from useRampSubmission, schema, register payload, types.phases; EUR onramps deposit directly to evmEphemeral - Remove `useMoneriumKycActor`/`Selector`, MoneriumKyc types from contexts and machines/types - Simplify `getRampFlow`: EURC BUY always uses `onramp_eur_evm` (Mykobo flow). Drop `onramp_eur_assethub` and `onramp_eur_assethub_via_hydration` - Replace `onramp_eur_evm` flow with Mykobo: initial → mykoboOnrampDeposit → subsidizePreSwap → nablaApprove → nablaSwap → subsidizePostSwap → squidRouter* → distributeFees → destinationTransfer → complete - Drop `MoneriumErrors.USER_MINT_ADDRESS_NOT_FOUND` branch from useGetRampRegistrationErrorMessage and SummaryStep banner - Drop `ERC20_EURE_POLYGON_*` constants from shared tokens; remove all Monerium translation keys from en.json and pt.json
Poll the Base ephemeral for EURC arrival from Mykobo's SEPA settlement, then transition to subsidizePreSwap so the Nabla EURC→USDC swap can run. - Mirror BRLA/Alfredpay mint-handler structure: `checkEvmBalancePeriodically` on Base for EURC against `evmEphemeralAddress`, expected raw amount taken from `quote.metadata.mykoboMint.outputAmountRaw` - Recovery shortcut: skip the wait if the ephemeral already holds \u226595% of the expected amount (handles fee variance between quote and settlement) - 24h payment timeout reflects SEPA business-day cutoffs; on timeout the phase transitions to `failed`. Inner balance-check timeout (5 min) bubbles up as a recoverable error so the outer process loop can retry - Register `mykoboOnrampDepositHandler` alongside Mykobo payout handler Flow: initial \u2192 mykoboOnrampDeposit \u2192 subsidizePreSwap \u2192 nablaApprove \u2192 nablaSwap \u2192 subsidizePostSwap \u2192 squidRouter* \u2192 destinationTransfer
…ture EUR offramp migrated to Mykobo on Base/EVM; ARS to be rebuilt with AlfredPay later. This removes all Stellar token configs, Spacewalk redeem paths, SEP-10 auth, Stellar/Spacewalk phase handlers, Stellar tx builders/validation, StellarTokenConfig/Details types, Stellar ephemeral helpers, and stellar_eurc /stellar_ars anchor fee branches. FiatToken.ARS preserved for the frontend selector. ARS via 'cbu' now throws explicit 'temporarily unavailable' error in route-resolver. PaymentData.anchorTargetAccount removed (only Stellar callsites). XCM event parser moved to xcmParsers.ts so substrate event listener compiles without redeem parsers.
Deletes stellar_eurc and stellar_ars rows from anchors table and removes XLM-token subsidies, completing the Stellar removal. New migration (028); prior migrations 005/008/022 are left untouched.
…ring Deletes stellarKyc XState machine + SEP-10/24 actors and services, the useSignChallenge hook, and stellar.service. Strips stellar ephemeral creation from useRampSubmission, register.actor, and ramp.machine; removes stellarKyc branch from kyc.states; removes spacewalkRedeem/stellarPayment/stellarCreate Account from phaseFlows and phaseMessages; cleans up rampState context, ramp page, RampSubmitButton, NetworkSelector, TokenSelection helpers, summary TransactionTokensDisplay, storage.service, services/api/index re-export, phases types, localStorage keys, and progress flow resolver. ARS coin icon and FiatToken.ARS preserved for the token selector.
Drops createStellarEphemeral usage from VortexSdk, the stellarEphemeral field from SDK input/internal types, and BrlHandler's stellar ephemeral plumbing. SDK no longer signs Stellar transactions since the backend has no Stellar offramp paths.
…m fallback Refactors the bridged-token-for-fallback ternary into an explicit if/else that throws if Ethereum USDC config is missing. Removes the only Mykobo-scoped biome lint error introduced in this branch.
…hemeral from mykobo offramp test Slab 7 removed stellarTokenConfig, which was the only place FiatToken.EURC had fiat metadata registered, causing getAnyFiatTokenDetails(EURC) to throw 'Token type is not Moonbeam' in the offramp quote validation path. - Register FiatToken.EURC in freeTokenConfig with decimals=6 (Circle's EVM EURC on Base) and matching min/max amount caps. - Remove the leftover Stellar ephemeral from the mykobo-eur-offramp integration test now that the Mykobo+Base flow only needs EVM+Substrate ephemerals (the normalize step now rejects Stellar entries). Mykobo offramp integration test: 5/5 passing against real sandbox.
Mirrors mykobo-eur-offramp.integration.test.ts for BUY direction. Covers Mykobo /fees DEPOSIT lookup, createTransactionIntent DEPOSIT returning IBAN instructions, EUR onramp quote on Base, and ramp registration which calls Mykobo at registration time and populates ibanPaymentData + state.mykoboTransactionId/Reference. Asserts Base-destination phase set: nablaApprove, nablaSwap, destinationTransfer, baseCleanupEurc, baseCleanupUsdc; no SquidRouter. Adds gitignore entries for the test scratch file. All 5/5 tests pass against the real Mykobo sandbox.
✅ Deploy Preview for vortexfi ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for vortex-sandbox ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…e flows Adds 05-integrations/mykobo.md covering the active EUR rail (SEPA <-> EURC on Base, mirroring BRLA-on-Base topology) with invariants, threat vectors, and audit checklist. Updates ramp-phase-flows.md corridor list, mermaids, handler-registry table, and audit checklist to reflect Mykobo on/offramp and the removal of the Stellar-EUR offramp and Monerium-EUR onramp.
…cated Adds deprecation banners pointing to mykobo.md. Stellar anchors remain active for ARS-only off-ramp; Monerium is fully removed from active corridors. Files retained for audit lineage of F-023 / F-024.
Updates module index, glossary, system architecture, ephemeral-account inventory, discount/validation notes, integration corridor lists, Spacewalk bridge intro, fund-routing F-029 (Mykobo Base ops added to MOONBEAM_FUNDING_PRIVATE_KEY blast radius), secret-management inventory (MYKOBO_* env vars added), and release-readiness env-var list (replace MONERIUM_* with MYKOBO_*). No code paths reference Monerium for new ramps; banners preserve audit lineage.
AUDIT-RESULTS.md: marks Section 5.2 Monerium DEPRECATED, adds Section 5.2b Mykobo with 21 checks (20 PASS, 1 PARTIAL log redaction, 1 FAIL on HTTP-client timeout per F-014), updates F-014 location list, marks F-023 SUPERSEDED and F-024 carried forward, retargets top-10 action item #9 to a per-user concurrent Mykobo-ramp limit. FINDINGS.md: F-014 service list now includes Mykobo+BRLA and notes the Monerium gap was inherited by the Mykobo client; F-023 status set to SUPERSEDED with resolution explaining the 24h Mykobo outer timeout; F-024 carried forward as DEFERRED — STILL APPLIES with the impact rewritten for the larger 24h exposure window per pending unpaid ramp.
The OffRampFromEvmInitializeEngine is shared by three strategies: - offrampToSepaEvm (Base → EUR via Mykobo) - offrampToPixEvm (Base → BRL via Avenia) - offrampEvmToAlfredpay (Polygon → BRL via Alfredpay) All Base-targeting strategies feed OffRampSwapEngineEvm, whose Nabla pool on Base only has USDC liquidity. The engine was unconditionally requesting USDT (ALFREDPAY_EVM_TOKEN) as the Squid bridge target, producing quote metadata (evmToEvm.toToken) that contradicts what the downstream Nabla swap actually expects. Derive the bridge target from the destination network: USDC for Base, USDT for Polygon (where the downstream path is a direct Alfredpay payout in USDT and Nabla is not involved).
Mykobo (EUR via SEPA) and Alfredpay/Avenia (BRL via PIX) offramps now have dedicated initializer files matching the project's anchor-named file convention. The Mykobo variant is fixed to Base+USDC since it has no other deployment target; the alfredpay variant keeps its network-aware USDC/USDT selection for Avenia (Base) and Alfredpay (Polygon).
OnRampSquidRouterBrlToEvmEngineBase is used by both the Avenia BRL and Mykobo EUR onramp strategies and does nothing currency-specific. Rename to OnRampSquidRouterToBaseEngine to remove the misleading prefix.
…edicated files Previously a single OffRampFromEvmInitializeEngine in offramp-from-evm-alfredpay.ts served two anchors with a network parameter: - Avenia (Base \u2192 BRL via PIX) needed USDC as the Squid target because the downstream Nabla pool only has USDC liquidity. - Alfredpay (Polygon \u2192 BRL) needed USDT because the partner pays out directly in USDT. The shared class with a runtime branch obscured the anchor-specific choices. Split into one file per anchor matching the existing file-naming convention: each class hardcodes its target network and token, removing the helper and the constructor parameter.
calculateSquidrouterNetworkFee was multiplying the route's native-token value by the GLMR/USD price for every route, including Base, Polygon, Ethereum, Avalanche and BSC routes. For Base->Polygon this under-reported the network fee by roughly four orders of magnitude (ETH ~$2500 vs GLMR ~$0.08). Map the source network to the correct CoinGecko native-token id and use a per-chain conservative fallback price so we never silently report a near-zero fee when the price feed is unavailable.
…x into mykobo-base-evm-api
…00 instead of 500 - register.actor.ts: replace duplicated inline additionalData dispatch with buildRegisterRampAdditionalData(); the previous version had no SELL+EURC branch, so Mykobo offramps fell through to the catch-all and never sent the user email, causing backend rejection. - registerAdditionalData.ts + test: add the helper and unit coverage that cover BUY/SELL EURC, BRL, and Alfredpay paths. - evm-to-mykobo.ts: throw APIError(400, isPublic) for missing email, ipAddress, and destinationAddress instead of plain Error so client gets a proper 4xx and a public error message.
…ransaction execution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1121.