Skip to content

modify /quotes and /quote/{quoteId}/execute for Embedded Wallet transfers#356

Open
DhruvPareek wants to merge 1 commit into04-17-feat_add_post__auth_credentials__id__challenge_to_resend_email_otpfrom
04-20-feat_sign_embedded_wallet_transfers_with_grid-wallet-signature_on__quotes_execute
Open

modify /quotes and /quote/{quoteId}/execute for Embedded Wallet transfers#356
DhruvPareek wants to merge 1 commit into04-17-feat_add_post__auth_credentials__id__challenge_to_resend_email_otpfrom
04-20-feat_sign_embedded_wallet_transfers_with_grid-wallet-signature_on__quotes_execute

Conversation

@DhruvPareek
Copy link
Copy Markdown

@DhruvPareek DhruvPareek commented Apr 20, 2026

Endpoint changes

  • POST /quotes/{quoteId}/execute — accepts optional Grid-Wallet-Signature header. Required when the quote's source is an Embedded Wallet; value is the signature over the quote's paymentInstructions[].accountOrWalletInfo.payloadToSign with the session private key of a verified credential on the source wallet.
  • POST /quotes (response only) — when source is an Embedded Wallet, paymentInstructions[].accountOrWalletInfo surfaces a new EMBEDDED_WALLET variant carrying payloadToSign.

Request / response

Quote response (Embedded Wallet source)

"paymentInstructions": [
  {
    "accountOrWalletInfo": {
      "accountType": "EMBEDDED_WALLET",
      "payloadToSign": ""
    },
    "instructionsNotes": ""
  }
]

Execute

POST /quotes/{quoteId}/execute
Headers: Grid-Wallet-Signature   (required for Embedded Wallet sources)
→ 200 Quote

Resources

  • PaymentEmbeddedWalletInfo — new payment-instruction variant: { accountType: EMBEDDED_WALLET, payloadToSign }
  • PaymentAccountType — enum extended with EMBEDDED_WALLET
  • PaymentInstructions.accountOrWalletInfooneOf gains the new variant and its discriminator mapping

Hierarchy

PaymentInstructions.accountOrWalletInfo   ← oneOf, discriminated by accountType
└── PaymentEmbeddedWalletInfo             ← allOf
    ├── BasePaymentAccountInfo            (shared base, carries accountType)
    └── { accountType: EMBEDDED_WALLET, payloadToSign }   (inline variant fields)

Guardrail

QuoteRequest.immediatelyExecute: true is documented as unsupported for Embedded Wallet sources — the payloadToSign isn't available at create-time, so the two-call flow (create quote → sign → execute) is mandatory.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 20, 2026

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

Project Deployment Actions Updated (UTC)
grid-flow-builder Ready Ready Preview, Comment Apr 21, 2026 7:16pm

Request Review

Copy link
Copy Markdown
Author

DhruvPareek commented Apr 20, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 20, 2026

✱ Stainless preview builds

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

kotlin

feat(api): add gridWalletSignature parameter and EmbeddedWallet type to quotes

openapi

feat(api): add Grid-Wallet-Signature to executeQuote, EMBEDDED_WALLET payment type

python

feat(api): add grid_wallet_signature param and embedded wallet type to quotes

typescript

feat(api): add Embedded Wallet payment type and signature parameter to quotes

Edit this comment to update them. They will appear in their respective SDK's changelogs.

grid-openapi studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ✅

New diagnostics (1 note)
💡 Schema/RequiredPropertyNotDefined: This schema marks `accountType` as `required`, but it isn't defined in `properties`, so it will be ignored.
grid-python studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ✅build ✅ (prev: build ❗) → lint ✅test ✅

pip install https://pkg.stainless.com/s/grid-python/b3fe2598060abdb9974df1b1c62697557e0252e0/grid-0.0.1-py3-none-any.whl
New diagnostics (1 note)
💡 Schema/RequiredPropertyNotDefined: This schema marks `accountType` as `required`, but it isn't defined in `properties`, so it will be ignored.
grid-typescript studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ✅build ✅lint ✅test ✅

npm install https://pkg.stainless.com/s/grid-typescript/d3d7cb3e59e044705cc03345052ad07a551ccfc4/dist.tar.gz
New diagnostics (1 note)
💡 Schema/RequiredPropertyNotDefined: This schema marks `accountType` as `required`, but it isn't defined in `properties`, so it will be ignored.
grid-kotlin studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ✅build ✅lint ✅test ✅

New diagnostics (2 note)
💡 Schema/RequiredPropertyNotDefined: This schema marks `accountType` as `required`, but it isn't defined in `properties`, so it will be ignored.
💡 Schema/EnumHasOneMember: Confirm intentional use of `enum` with single member.

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-04-21 19:20:27 UTC

@DhruvPareek DhruvPareek force-pushed the 04-17-feat_add_post__auth_credentials__id__challenge_to_resend_email_otp branch from 1889c01 to ace9654 Compare April 20, 2026 23:10
@DhruvPareek DhruvPareek force-pushed the 04-20-feat_sign_embedded_wallet_transfers_with_grid-wallet-signature_on__quotes_execute branch from 4159566 to 0634725 Compare April 20, 2026 23:10
@DhruvPareek DhruvPareek changed the title feat: sign Embedded Wallet transfers with Grid-Wallet-Signature on /quotes/execute modify Embedded Wallet transfers with Grid-Wallet-Signature on /quotes/execute Apr 21, 2026
@DhruvPareek DhruvPareek changed the title modify Embedded Wallet transfers with Grid-Wallet-Signature on /quotes/execute modify /quote and Embedded Wallet transfers with Grid-Wallet-Signature on /quotes/execute Apr 21, 2026
@DhruvPareek DhruvPareek changed the title modify /quote and Embedded Wallet transfers with Grid-Wallet-Signature on /quotes/execute modify /quotes and /quote/{quoteId}/execute for Embedded Wallet transfers Apr 21, 2026
@DhruvPareek DhruvPareek force-pushed the 04-17-feat_add_post__auth_credentials__id__challenge_to_resend_email_otp branch from ace9654 to fdaaf7d Compare April 21, 2026 02:18
@DhruvPareek DhruvPareek force-pushed the 04-20-feat_sign_embedded_wallet_transfers_with_grid-wallet-signature_on__quotes_execute branch from 0634725 to 83a5b13 Compare April 21, 2026 02:18
@DhruvPareek DhruvPareek force-pushed the 04-20-feat_sign_embedded_wallet_transfers_with_grid-wallet-signature_on__quotes_execute branch from 83a5b13 to 444f5fe Compare April 21, 2026 06:37
@DhruvPareek DhruvPareek force-pushed the 04-17-feat_add_post__auth_credentials__id__challenge_to_resend_email_otp branch from fdaaf7d to 3f57f28 Compare April 21, 2026 06:37
@DhruvPareek DhruvPareek marked this pull request as ready for review April 21, 2026 17:39
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 21, 2026

Greptile Summary

This PR extends POST /quotes and POST /quotes/{quoteId}/execute to support Embedded Wallet sources by surfacing a payloadToSign field in paymentInstructions[].accountOrWalletInfo and accepting an optional Grid-Wallet-Signature header on the execute endpoint. The new PaymentEmbeddedWalletInfo schema, discriminator mapping, and Stainless SDK transform are all applied consistently with the existing pattern for other account types.

  • P1: The execute endpoint description opens with "This endpoint can only be used for quotes with a source which is either an internal account, or has direct pull functionality" — a statement that now directly contradicts the Embedded Wallet paragraph added below it.

Confidence Score: 4/5

Safe to merge after fixing the contradictory restriction sentence in the execute endpoint description.

One P1 documentation contradiction exists: the execute endpoint description says 'can only be used for internal account or direct-pull sources' immediately before granting Embedded Wallet access, which will mislead integrators. All other changes (schema structure, discriminator, stainless transforms) are correct and consistent with existing patterns.

openapi/paths/quotes/quotes_{quoteId}_execute.yaml — contradictory restriction sentence at lines 7–8.

Important Files Changed

Filename Overview
openapi/paths/quotes/quotes_{quoteId}_execute.yaml Adds optional Grid-Wallet-Signature header and Embedded Wallet description; opening restriction paragraph now contradicts the Embedded Wallet paragraph (P1).
openapi/components/schemas/common/PaymentEmbeddedWalletInfo.yaml New schema for Embedded Wallet payment instructions; structure and discriminator are correct, but payloadToSign encoding format is undocumented (P2).
openapi/components/schemas/common/PaymentInstructions.yaml Adds PaymentEmbeddedWalletInfo to the oneOf list and discriminator mapping; both entries are consistent and correct.
openapi/components/schemas/quotes/QuoteRequest.yaml Adds guardrail documentation that immediatelyExecute: true is unsupported for Embedded Wallet sources; clear and accurate.
.stainless/stainless.yml Adds PaymentEmbeddedWalletInfo.allOf[0] to the remove transforms, consistent with all other PaymentXxx schema variants.

Sequence Diagram

sequenceDiagram
    participant Client
    participant GridAPI

    Client->>GridAPI: POST /quotes (source: EMBEDDED_WALLET)
    GridAPI-->>Client: 200 Quote with payloadToSign

    Note over Client: Sign payloadToSign with session private key

    Client->>GridAPI: POST /quotes/{quoteId}/execute + Grid-Wallet-Signature header
    alt Signature valid
        GridAPI-->>Client: 200 Quote executed
    else Signature missing or invalid
        GridAPI-->>Client: 401 Unauthorized
    end
Loading

Fix All in Claude Code

Prompt To Fix All With AI
This is a comment left during a code review.
Path: openapi/paths/quotes/quotes_{quoteId}_execute.yaml
Line: 7-8

Comment:
**Contradictory restriction in endpoint description**

The description opens with "This endpoint can only be used for quotes with a `source` which is either an internal account, or has direct pull functionality (e.g. ACH pull with an external account)." — but the very next paragraph grants Embedded Wallet sources access too. Any developer who reads only the first restrictive sentence will incorrectly conclude that Embedded Wallet–sourced quotes cannot use this endpoint.

The first limiting statement should be updated to include Embedded Wallet as a valid source type, or restructured so it doesn't contradict the paragraph that follows.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: openapi/components/schemas/common/PaymentEmbeddedWalletInfo.yaml
Line: 14-22

Comment:
**`payloadToSign` encoding format not documented**

The example value (`Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg==`) is clearly base64, but the field description only says "Payload that must be signed" without stating whether the value is already base64-encoded or is raw bytes. In contrast, the `Grid-Wallet-Signature` header explicitly says "base64-encoded." Without clarifying this, integrators may sign the base64 string directly instead of signing the decoded bytes (or vice versa), silently producing an invalid signature. Adding `format: byte` and a one-sentence note on encoding would remove the ambiguity.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat: sign Embedded Wallet transfers wit..." | Re-trigger Greptile

Comment on lines 7 to 8
This endpoint can only be used for quotes with a `source` which is either an internal account,
or has direct pull functionality (e.g. ACH pull with an external account).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Contradictory restriction in endpoint description

The description opens with "This endpoint can only be used for quotes with a source which is either an internal account, or has direct pull functionality (e.g. ACH pull with an external account)." — but the very next paragraph grants Embedded Wallet sources access too. Any developer who reads only the first restrictive sentence will incorrectly conclude that Embedded Wallet–sourced quotes cannot use this endpoint.

The first limiting statement should be updated to include Embedded Wallet as a valid source type, or restructured so it doesn't contradict the paragraph that follows.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/paths/quotes/quotes_{quoteId}_execute.yaml
Line: 7-8

Comment:
**Contradictory restriction in endpoint description**

The description opens with "This endpoint can only be used for quotes with a `source` which is either an internal account, or has direct pull functionality (e.g. ACH pull with an external account)." — but the very next paragraph grants Embedded Wallet sources access too. Any developer who reads only the first restrictive sentence will incorrectly conclude that Embedded Wallet–sourced quotes cannot use this endpoint.

The first limiting statement should be updated to include Embedded Wallet as a valid source type, or restructured so it doesn't contradict the paragraph that follows.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

embedded wallets are internal accounts

Comment on lines +14 to +22
payloadToSign:
type: string
description: >-
Payload that must be signed with the session private key of a
verified authentication credential on the source Embedded Wallet.
The resulting signature is passed as the `Grid-Wallet-Signature`
header on `POST /quotes/{quoteId}/execute` to authorize the
outbound transfer from the wallet.
example: Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg==
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 payloadToSign encoding format not documented

The example value (Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg==) is clearly base64, but the field description only says "Payload that must be signed" without stating whether the value is already base64-encoded or is raw bytes. In contrast, the Grid-Wallet-Signature header explicitly says "base64-encoded." Without clarifying this, integrators may sign the base64 string directly instead of signing the decoded bytes (or vice versa), silently producing an invalid signature. Adding format: byte and a one-sentence note on encoding would remove the ambiguity.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/common/PaymentEmbeddedWalletInfo.yaml
Line: 14-22

Comment:
**`payloadToSign` encoding format not documented**

The example value (`Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg==`) is clearly base64, but the field description only says "Payload that must be signed" without stating whether the value is already base64-encoded or is raw bytes. In contrast, the `Grid-Wallet-Signature` header explicitly says "base64-encoded." Without clarifying this, integrators may sign the base64 string directly instead of signing the decoded bytes (or vice versa), silently producing an invalid signature. Adding `format: byte` and a one-sentence note on encoding would remove the ambiguity.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

valid to add some additional description. Can you add a semi real example? Will it be a escaped json strong? Do they need to unescape it before signing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I can't determine the actual payload format from the spec alone — that depends on the backend implementation. But here's what needs to be answered and documented:

Key questions for the description:

  1. Is payloadToSign a base64-encoded opaque blob, or base64-encoded JSON?
  2. Do integrators sign the base64 string as-is, or decode it to raw bytes first, then sign?

The answer to (2) is the most critical thing to document. Based on common signing patterns, the typical expectation is: decode the base64 value to raw bytes, then sign those bytes. If that's correct, here's a suggested update:

Suggested change
payloadToSign:
type: string
description: >-
Payload that must be signed with the session private key of a
verified authentication credential on the source Embedded Wallet.
The resulting signature is passed as the `Grid-Wallet-Signature`
header on `POST /quotes/{quoteId}/execute` to authorize the
outbound transfer from the wallet.
example: Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg==
payloadToSign:
type: string
format: byte
description: >-
Base64-encoded payload to sign. Decode this value to raw bytes, then
sign the bytes with the session private key of a verified
authentication credential on the source Embedded Wallet. Base64-encode
the resulting signature and pass it as the `Grid-Wallet-Signature`
header on `POST /quotes/{quoteId}/execute`.
example: eyJxdW90ZUlkIjoiMDFKWlhZWi0xMjM0NTY3ODkwIiwidGltZXN0YW1wIjoiMjAyNS0wMS0xNVQxMDozMDowMFoifQ==

The example above decodes to {"quoteId":"01JZXYZ-1234567890","timestamp":"2025-01-15T10:30:00Z"} — a realistic-looking JSON blob. If the actual payload has a different structure (e.g., just a nonce, or includes an amount), replace this with whatever fields are actually present.

Once you confirm the signing contract (sign raw bytes vs. sign the base64 string), that one sentence is the most important thing to add.

Tip: You can customize Greptile's behavior for this repo with .greptile/rules and .greptile/config.

@DhruvPareek DhruvPareek force-pushed the 04-20-feat_sign_embedded_wallet_transfers_with_grid-wallet-signature_on__quotes_execute branch from 444f5fe to a8ee2e2 Compare April 21, 2026 19:07
@DhruvPareek DhruvPareek force-pushed the 04-20-feat_sign_embedded_wallet_transfers_with_grid-wallet-signature_on__quotes_execute branch from a8ee2e2 to abb4c24 Compare April 21, 2026 19:10
@DhruvPareek DhruvPareek force-pushed the 04-20-feat_sign_embedded_wallet_transfers_with_grid-wallet-signature_on__quotes_execute branch from abb4c24 to edbb528 Compare April 21, 2026 19:11
@DhruvPareek DhruvPareek force-pushed the 04-20-feat_sign_embedded_wallet_transfers_with_grid-wallet-signature_on__quotes_execute branch from edbb528 to 9eb8049 Compare April 21, 2026 19:15
@DhruvPareek DhruvPareek force-pushed the 04-17-feat_add_post__auth_credentials__id__challenge_to_resend_email_otp branch from 3f57f28 to 11d622e Compare April 21, 2026 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants