Skip to main content

integrate-onramp

Implement a provider's fiat→crypto createOnrampQuote in @sdp/payments, extend the closed quote contract, and wire API persistence plus dashboard rendering.

Aller à l'installation

Informations de source

Dépôt
solana-foundation/solana-developer-platform
Dernière activité de la source
3 septembre 2026 à 10:11
Langue détectée de SKILL.md
anglais
Étoiles
53
Forks
23

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
2 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
integrate-onramp
description
Implement a provider's fiat→crypto createOnrampQuote in @sdp/payments, extend the closed quote contract, and wire API persistence plus dashboard rendering.
disable-model-invocation
true
# Integrate on-ramp On-ramp = a counterparty buys crypto with fiat, delivered to an SDP-known wallet. Implement `createOnrampQuote` on the package client and add a branch to the API quote dispatch. There is no `executeOnramp` method in the current provider contract. `createOnrampQuote` is **optional** on `RampProvider` — implement it only if your provider has a lockable quote step. Choose the closest package client by delivery mode: manual instructions, hosted URL, or session widget — all three are represented under `packages/sdp-payments/src/ramps/providers/`. Provider-specific DB helpers live in `apps/sdp-api/src/routes/payments/handlers/ramps/<id>.ts`. ## Contract Read the current `RampOnrampQuoteInput` from `packages/sdp-payments/src/ramps/types.ts`. The handler resolves wallet, counterparty, identity/contact, and provider account ids before calling the package client; the client never reads the database. `PaymentRampQuote` is a closed union discriminated by both `provider` and `deliveryMode` in `packages/sdp-types/src/payments.ts`. Add the provider-specific quote arm, and add a `PaymentRampInstruction` arm for new manual instruction fields: - `deliveryMode: "manual_instructions"` — return `paymentInstructions` (bank/wire or on-chain funding details). - `deliveryMode: "hosted"` — return a `hostedUrl` the client renders (widget/redirect). - `deliveryMode: "session_widget"` — return the session fields required by an embedded SDK/frame. Prefer the upstream quote/session id. If the upstream does not mint one, use `rampId("ramp_quote")` from `@sdp/payments/ramps/shared` and pass that reference upstream. The webhook or reconciliation path must return the same reference. ## Handler wiring (the DB side) Add a branch to `apps/sdp-api/src/routes/payments/handlers/ramps.ts`. The handler owns all DB work: - resolves the counterparty + destination wallet, - ensures any provider-side customer/account exists (DB-touching `ensure*` helpers live in `apps/sdp-api/src/routes/payments/handlers/ramps/<id>.ts`), - calls your HTTP-only `createOnrampQuote` with pre-resolved inputs, - persists the transfer via `persistRampQuoteTransfer` (dedups by `(provider, providerReference)`; `rampQuoteTransferStatus` maps a `manual_instructions` + `pending` quote to `awaiting_payment`). A `reservedTransferId` is minted before the provider call so it can travel upstream as the reference; a provider whose failed calls must still be attributable to a row pre-creates the pending transfer instead and skips the post-quote persist. Runtime route: `POST /v1/payments/ramps/onramp/quote`, gated by provider availability, metered quota, permissions, and `policyGate`. This route is public OpenAPI today; update `apps/sdp-api/src/openapi/**` when the new provider changes its request/response shape and regenerate owned artifacts. For `hosted`, decide whether the upstream permits iframe embedding or requires a top-level redirect. Check the provider's CSP / `frame-ancestors` policy and return/render the URL accordingly; the dashboard's default hosted path assumes iframe embedding, so a redirect-only provider needs an explicit renderer instead of inheriting that path. ## Variety | deliveryMode | On-ramp quote shape | |---|---| | `manual_instructions` | bank pay-in or funding instructions built from the provisioned customer/resource | | `hosted` | signed provider widget `hostedUrl` | | `session_widget` | embedded provider session credentials | ## Gating — throw, don't fallback A provider that needs provisioning must fail loud when it's missing: a missing customer link, unverified customer, or unprovisioned funding resource throws `counterpartyNotProvisioned`. Getting the counterparty to a ready state is `counterparty-requirements` — never substitute a default. ## Rules + verify Shared rules live in `integrate-ramp-provider`. Hot here: - No fallbacks — missing customer/account/instructions throws; never default them. - HTTP in the provider; DB (counterparty, wallet, customer, transfer row) in the handler. - `deliveryMode` arms are a real discriminated union — return exactly one arm's fields; no `any`. - Update `apps/sdp-web/src/app/dashboard/payments/ramps/` when the provider's quote arm or instruction shape is not already rendered by the chosen delivery mode. - Verify `@sdp/payments`, focused API quote/persistence tests, OpenAPI generation when changed, and `sdp-web` typecheck/tests for the renderer.
Voir sur GitHub