feat: add onChainTransaction to transaction source/destination#681
Conversation
Adds an optional onChainTransaction (transactionHash + network) to BaseTransactionSource and BaseTransactionDestination for legs whose counterparty is an external crypto wallet. network references a new reusable CryptoNetwork enum (environment-qualified: mainnet vs devnet/testnet/regtest). Reconciliation instructions' transactionHash is now scoped purely to the inter-VASP settlement leg, with the external-wallet endpoint hash living only on the source/destination. Additive, no version bump.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
✱ Stainless preview builds for gridThis PR will update the cli go kotlin openapi php python ruby typescript ✅ grid-ruby studio · code
|
Greptile Summary⚔️🔥
Confidence Score: 5/5This looks safe to merge.
|
| Filename | Overview |
|---|---|
| openapi/components/schemas/common/ReconciliationInstructions.yaml | Clarifies that transactionHash is for the UMA settlement leg and directs external-wallet hashes to source or destination metadata. |
| openapi/components/schemas/transactions/OutgoingTransaction.yaml | Updates the outgoing transaction reconciliation description to point crypto payout hash consumers to destination.onChainTransaction. |
| openapi/components/schemas/transactions/BaseTransactionSource.yaml | Adds optional source-leg on-chain transaction metadata. |
| openapi/components/schemas/transactions/BaseTransactionDestination.yaml | Adds optional destination-leg on-chain transaction metadata. |
| openapi/components/schemas/transactions/OnChainTransaction.yaml | Defines the reusable on-chain transaction object. |
| openapi/components/schemas/crypto/CryptoNetwork.yaml | Defines supported blockchain networks with environment-qualified enum values. |
Reviews (2): Last reviewed commit: "docs: scope OutgoingTransaction reconcil..." | Re-trigger Greptile
…ent leg Greptile P1: the field description still promised a crypto transaction hash, which contradicts the sharpened ReconciliationInstructions schema (transactionHash = inter-VASP settlement leg only). Point readers to destination.onChainTransaction for the crypto payout.
|
@greptile review |
|
@faraday review this |
|
📌 Bolt Status 2026-07-13 04:40:15 UTC — ⚡ Agent |
The Stainless config strips the allOf ref to BaseTransactionSource/Destination from every concrete variant (the base is assumed empty after discriminator removal), so a base-declared onChainTransaction would be missing from generated SDK types — the same way base-declared currency is omitted today. Declare it inline on each variant instead, matching the per-variant discriminator pattern, and drop the base copies. Also add BITCOIN_MAINNET/BITCOIN_TESTNET to CryptoNetwork: grid supports BTC over L1 and a Bitcoin-sourced transaction needs a network value.
Revision 3 (review follow-ups)
|
…saction The receipts field-mapping table anticipated a dedicated hash field — point it at source/destination onChainTransaction with reconciliationInstructions.transactionHash scoped to the UMA settlement leg. Add a note to the reconciliation guide explaining when source/destination carry onChainTransaction.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
@bolt are there any other example transaction response objects in the docs which should contain these new objects? |
…action New OUTGOING_PAYMENT.COMPLETED and INCOMING_PAYMENT.COMPLETED example variants where the external-crypto-wallet leg carries onChainTransaction, so the API reference shows the field in a realistic payload. Existing fiat/UMA examples correctly omit it.
|
Good call — swept both the OpenAPI response examples and mintlify again. Findings:
|
…ings - Remove onChainTransaction from the UMA_ADDRESS source/destination variants: a UMA endpoint settles via the counterparty VASP, never a customer external wallet, so the field could not be truthfully populated there. - Hedge the reconciliation-guide note: the hash can land after the terminal status, so terminal webhook payloads may not include it — read it via GET /transactions. - Split the receipts mapping row: the wallet address comes from the external account's accountInfo, not onChainTransaction. - Use valid base58 strings for the Solana example signatures.
Reviewer feedback: the rest of the API (e.g. cryptoNetwork on the withdrawal-fee request) uses bare chain names and infers mainnet vs test network from the platform environment. Drop the environment suffix from CryptoNetwork (SOLANA_MAINNET/DEVNET → SOLANA, etc.) and document that the environment follows the platform, for consistency.

Summary
Adds an optional
onChainTransaction(transactionHash+network) toBaseTransactionSourceandBaseTransactionDestination, so every source/destination variant surfaces the on-chain transfer for a leg whose counterparty is an external crypto wallet.networkis environment-qualified (SOLANA_MAINNETvsSOLANA_DEVNET, etc.) so the hash can be looked up on the correct explorer.RealtimeFundingTransactionSourcealready carriestraceNumber/endToEndId(the bank-rail analog). A bridge flow (crypto in on one chain → crypto out on another) populates both legs, each with its own hash/network.ReconciliationInstructionsdocs to distinguish its settlement-layertransactionHash(for UMA sends, the inter-VASP leg) from the new per-leg field. No deprecation.Additive change — no
info.versionbump.Context
Grid should return on-chain transaction info for any transaction whose source or destination is an external crypto wallet, covering Fireblocks-settled and sandbox flows in both directions. This is the public-spec half; the sparkcore backend wiring + vendored SDK regen land in a separate webdev PR.
Slack thread: https://lightsparkgroup.slack.com/archives/D0AHLSKKV8R/p1783721701181659
Reply with a comment (e.g. LGTM) to approve — emoji reactions don't notify me here.
🤖 ionized-nexus(#1) | Feedback
Original PR: #680