Skip to content

feat!: complete receiver->customer rename (wave 2) + wire-contract CI check - #64

Open
ericviana wants to merge 1 commit into
mainfrom
eric/customers-wave-2
Open

feat!: complete receiver->customer rename (wave 2) + wire-contract CI check#64
ericviana wants to merge 1 commit into
mainfrom
eric/customers-wave-2

Conversation

@ericviana

Copy link
Copy Markdown
Member

Held PR — do not merge

This PR is breaking against the API deployed today. It only becomes correct once
blindpay-v2 #1799 reaches production. Labeled hold-until-1799-deploy; the orchestrator
merges after a production probe confirms the cutover.

What breaks

Wave 1 (already shipped, v4.1.0/v4.1.1) aligned the SDK with what production serves
today and added customer.* webhook events plus customer_id list filters, while
explicitly leaving the remaining receiver_* field renames for later because the
deployed API didn't accept them yet. This PR does that remaining work, matching the
target spec (post-#1799).

Migration table

Before After Where
receiver_id customer_id Payout, Payin, Transfer, Owner, ListPayinsInput/ListPayoutsInput, terms-of-service initiate(), Stellar/EVM/Solana payout+payin create responses
receiver_local_amount customer_local_amount quote responses, Payout
receiver_wallet_address customer_wallet_address Transfer, CreateTransferQuoteInput
receiver_network customer_network Transfer, CreateTransferQuoteInput
receiver_token customer_token Transfer, CreateTransferQuoteInput
receiver_invite_redirect_url customer_invite_redirect_url UpdateInstanceInput

Also:

  • Owner.receiver_id is removed. Wave 1 made it transitional (both receiver_id?
    and customer_id? optional); the target spec's CustomerOut.owners[] items have no
    required array at all, so Owner.customer_id stays optional and receiver_id is
    dropped.
  • receiver.new / receiver.update / receiver.delete removed from WebhookEvents.
    They were marked @deprecated in wave 1 (still firing); they stop firing at the same
    cutover, and the target spec's WebhookEndpointIn.events enum no longer lists them.
  • api-keys resource removed (blindpay.instances.apiKeys and its types) — API Keys is
    deliberately absent from the public API reference, so it doesn't belong in the SDK.
  • No receivers resource remained to remove (wave 1 already renamed it to customers).

Intentionally unchanged

  • receiver_amount (singular) — the receiving-side amount on quotes/payins/payouts/
    transfers — keeps its name everywhere. Verified: still present, unrenamed, in every
    file touched.
  • currency_type still accepts "sender" / "receiver".
  • re_-prefixed IDs are never rewritten (only the field names pointing at them
    change, never the ID values themselves).
  • The otc_only_supported_for_sender_without_cover_fees_and_receiver_with_cover_fees
    slug isn't modeled by this SDK (no error-code enum here), so there's nothing to
    preserve — noted for completeness.

Contract check (new CI gate)

Added scripts/contract-check.mjs (dependency-free, node scripts/contract-check.mjs /
bun run contract-check) and wired it into CI as its own job (contract-check.yaml,
parallel to lint). It checks the committed spec snapshot
(.api-sync/spec-snapshot.json, copied from the target spec) against every SDK type
declaration under src/resources/** and types/index.d.ts:

  • Hard fail — any field name the SDK declares that doesn't exist as a property (or
    parameter) name anywhere in the snapshot. This is exactly the bug class from wave 2:
    a renamed field left behind. Verified locally by reverting one rename
    (Payout.customer_id back to receiver_id) — the check fails with the exact
    file:line:field. Restored, and it's green again.
  • Hard fail — any webhook event enum member in the snapshot that the SDK's
    WebhookEvents union doesn't model (mapped explicitly against
    WebhookEndpointIn.events).
  • Warning only (non-blocking) — spec field names the SDK doesn't model anywhere
    (expected: lots of internal/ops-only and provider-specific fields this SDK
    intentionally doesn't surface).

.api-sync/contract-check-allowlist.json holds 22 entries for genuine pre-existing
divergences the check surfaced that are unrelated to this rename and out of scope here
(stale tracking_partner_fee, legacy billing_fee vs billing_fee_amount, partner-fee
evm_wallet_address/stellar_wallet_address that no longer exist on the spec, a couple
of bank-account field-name mismatches, and one camelCase path-only parameter). Each entry
has a reason and an owner; none of them touch a wave-2 field.

Versioning

Major bump: 5.0.0 (breaking field renames). Bumped package.json directly, matching
this repo's convention (the publish workflow reads package.json's version and skips
if already published — no separate changeset version step). Added
.changeset/customers-wave-2.md for the changelog.

Verification

Ran this repo's actual CI commands locally, in the order lint.yaml /
type-checking.yaml / tests.yaml run them, plus the new contract-check job:

bun install --frozen-lockfile
bun run lint:check      # 0 errors
bun run check-types     # 0 errors
bun run test            # 93 passed (19 files)
node scripts/contract-check.mjs   # OK, 1428 fields checked, 23 webhook events checked
bun run build           # builds clean (dist/ not committed, already gitignored)

https://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs

@ericviana ericviana added the hold-until-1799-deploy Do not merge until blindpay-v2 #1799 reaches production label Jul 27, 2026
@BernardoSM

BernardoSM commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

…re contract check

Wave-2 breaking release (5.0.0): the remaining receiver_* field renames, removal of
the receiver.* webhook events and legacy surface, and a mechanical contract-check in CI
that validates every SDK-declared wire key and the webhook enum against the committed
public spec snapshot (.api-sync/spec-snapshot.json).

Held until blindpay-v2 #1799 reaches production; the branch history was rebuilt as this
single commit so the snapshot only ever contains the public filtered spec.

Claude-Session: https://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs
@ericviana
ericviana force-pushed the eric/customers-wave-2 branch from 6a3376b to 8c69c1d Compare July 27, 2026 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hold-until-1799-deploy Do not merge until blindpay-v2 #1799 reaches production

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants