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.

Ir para a instalação

Informações da origem

Repositório
solana-foundation/solana-developer-platform
Última atividade na origem
3 de setembro de 2026 às 10:11
Idioma detectado do SKILL.md
inglês
Estrelas
53
Forks
23

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
2 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
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.
Ver no GitHub