Skip to content

feat: add onChainTransaction to transaction source/destination#681

Merged
jklein24 merged 7 commits into
mainfrom
07-10-grid-onchain-tx-source-dest
Jul 13, 2026
Merged

feat: add onChainTransaction to transaction source/destination#681
jklein24 merged 7 commits into
mainfrom
07-10-grid-onchain-tx-source-dest

Conversation

@jklein24

Copy link
Copy Markdown
Contributor

Summary

Adds an optional onChainTransaction (transactionHash + network) to BaseTransactionSource and BaseTransactionDestination, so every source/destination variant surfaces the on-chain transfer for a leg whose counterparty is an external crypto wallet.

  • network is environment-qualified (SOLANA_MAINNET vs SOLANA_DEVNET, etc.) so the hash can be looked up on the correct explorer.
  • Co-located with the leg it describes — the same place RealtimeFundingTransactionSource already carries traceNumber/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.
  • Sharpens ReconciliationInstructions docs to distinguish its settlement-layer transactionHash (for UMA sends, the inter-VASP leg) from the new per-leg field. No deprecation.

Additive change — no info.version bump.

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

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.
@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Preview Jul 13, 2026 7:56pm
grid-wallet-demo Ignored Ignored Preview Jul 13, 2026 7:56pm

Request Review

akanter commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions

github-actions Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

✱ Stainless preview builds for grid

This PR will update the grid SDKs with the following commit messages.

cli

chore(internal): regenerate SDK with no functional changes

go

docs(api): clarify ReconciliationInstructions documentation

kotlin

feat(api): add onChainTransaction field to BaseTransactionSource and BaseTransactionDestination

openapi

feat(api): add onChainTransaction field to transaction sources/destinations

php

feat(api): add onChainTransaction field to BaseTransactionSource/BaseTransactionDestination

python

docs(types): update ReconciliationInstructions documentation

ruby

feat(api): add on_chain_transaction field to transaction source/destination

typescript

feat(api): add onChainTransaction field to transaction source/destination types
⚠️ grid-openapi studio · code

Your SDK build had at least one "warning" diagnostic.
generate ⚠️

grid-ruby studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅build ✅lint ✅test ✅

⚠️ grid-go studio · code

Your SDK build had a failure in the lint CI job, which is a regression from the base state.
generate ✅build ✅lint ❗test ❗

go get github.com/stainless-sdks/grid-go@acc8108b19851acc909ec58e5900277a559b359f
⚠️ grid-kotlin studio · code

Your SDK build had a failure in the test CI job, which is a regression from the base state.
generate ⚠️build ✅lint ✅test ❗

grid-typescript studio · conflict

Your SDK build had at least one note diagnostic.

⚠️ grid-python studio · code

Your SDK build had a failure in the lint CI job, which is a regression from the base state.
generate ✅build ✅lint ❗test ❗

pip install https://pkg.stainless.com/s/grid-python/712e1d98da8f9708babb3d4e93b47a36dcb19ed6/grid-0.0.1-py3-none-any.whl
grid-php studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅lint ✅test ✅

⚠️ grid-cli studio · code

Your SDK build had a failure in the test CI job, which is a regression from the base state.
generate ⚠️build ⏭️lint ⏭️test ❗


This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-07-13 20:28:36 UTC

@jklein24
jklein24 marked this pull request as ready for review July 11, 2026 00:54
@greptile-apps

greptile-apps Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

⚔️🔥 \m/ ON-CHAIN THUNDER RIDES \m/ 🔥⚔️ This PR adds per-leg on-chain transaction metadata to the API schema.

  • Adds OnChainTransaction with transactionHash and environment-qualified network.
  • Adds CryptoNetwork values for supported chains and environments.
  • Surfaces optional onChainTransaction on transaction sources and destinations.
  • Clarifies reconciliation instructions as UMA settlement-layer metadata.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

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

Comment thread openapi/components/schemas/common/ReconciliationInstructions.yaml
…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.
@ls-bolt

ls-bolt Bot commented Jul 11, 2026

Copy link
Copy Markdown

@greptile review

@jklein24

Copy link
Copy Markdown
Contributor Author

@faraday review this

@ls-bolt

ls-bolt Bot commented Jul 13, 2026

Copy link
Copy Markdown

📌 Bolt Status

2026-07-13 04:40:15 UTC — ⚡ Agent ionized-nexus-3(#3) started


Feedback

Comment thread openapi/components/schemas/transactions/BaseTransactionDestination.yaml Outdated
Comment thread openapi/components/schemas/crypto/CryptoNetwork.yaml
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.
@lightspark-faraday

Copy link
Copy Markdown

Revision 3 (review follow-ups)

  • Stainless SDK gap (confirmed real): the config strips the allOf ref to BaseTransactionSource/BaseTransactionDestination from every concrete variant, so a base-declared onChainTransaction would never reach generated SDK types (same mechanism that already drops base-declared currency). Moved the field inline onto all 5 concrete variants (Account/UmaAddress/RealtimeFunding sources; Account/UmaAddress destinations) and removed the base copies — matches the per-variant discriminator pattern, no Stainless config change needed. The pre-existing currency omission is a separate follow-up candidate.
  • Bitcoin L1: added BITCOIN_MAINNET/BITCOIN_TESTNET to CryptoNetwork (grid supports BTC over L1). Lightning intentionally excluded — no explorer-visible chain tx.

make build + make lint-openapi clean (0 errors). Both threads resolved.


🤖 ionized-nexus(#1) | Feedback

…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.
@mintlify

mintlify Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
Grid 🟢 Ready View Preview Jul 13, 2026, 5:40 AM

@jklein24

Copy link
Copy Markdown
Contributor Author

@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.
@lightspark-faraday

Copy link
Copy Markdown

Good call — swept both the OpenAPI response examples and mintlify again. Findings:

  • Webhook examples (updated): the OUTGOING_PAYMENT.COMPLETED / INCOMING_PAYMENT.COMPLETED examples were the real gap — both carry full transaction objects but only had fiat/UMA variants. Added two new example variants: a completed USDC payout to an external wallet with destination.onChainTransaction, and a completed crypto-funded incoming payment with source.onChainTransaction (realtime-funding source). Existing fiat/UMA examples correctly omit the field.
  • Transaction endpoints (GET /transactions*): no inline response examples — the reference renders from schema property examples, so the new field appears there automatically via OnChainTransaction.yaml's examples.
  • Quote examples (POST /quotes): request payloads, pre-settlement — correctly no on-chain hash.
  • Mintlify guides: covered in the earlier commit (receipts field-mapping table + reconciliation guide note); the remaining guide examples are pre-settlement or elide source/destination entirely.

make build + make lint-openapi clean. Pushed as 0fba3a71.


🤖 ionized-nexus(#2) | Feedback

@lightspark-faraday lightspark-faraday Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Request changes

Comment thread mintlify/snippets/reconciliation/reconciliation.mdx
Comment thread mintlify/snippets/receipts.mdx Outdated
Comment thread openapi/webhooks/incoming-payment.yaml Outdated
Comment thread openapi/webhooks/outgoing-payment.yaml Outdated
Comment thread openapi/components/schemas/transactions/UmaAddressTransactionDestination.yaml Outdated
…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.
@jklein24
jklein24 merged commit a878b67 into main Jul 13, 2026
10 checks passed
@jklein24
jklein24 deleted the 07-10-grid-onchain-tx-source-dest branch July 13, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants