feat: close the surface gaps against rail0-go and rail0-ts - #19
Merged
Conversation
Three calls the other two SDKs have had and this one did not. Each is reachable only
through the SDK, so their absence was not an inconvenience — it was work a Ruby
integration could not do at all.
auth.logout — revokes the token THIS client carries, not every session for the address,
so signing out one process leaves the others signed in. It returns the body rather than
nil on purpose: the gateway's denylist fails open by design (a store outage must not
sign out the whole platform), so `revoked: false` means the token is still usable until
it expires, and the caller should treat its copy as compromised rather than assume the
session is gone. Ruby was the one SDK where a long-lived process could not hand a
session back.
payments.dispute_submit_by_hash / close_dispute_submit_by_hash — the payer's counterpart
to submit_by_hash. That generic method only covers the single-segment
/payments/{id}/{operation}/submitted shape, and `dispute/close` is two segments, which
is why these are separate methods rather than another operation argument. Without them a
Ruby caller signing with a wallet that broadcasts on its own could open and close
disputes with a raw signed transaction but never report one it had already sent.
Payer-only, and the payer authenticates account-less via SIWE: a bare hash carries no
signature, so the session is what proves who is reporting it.
Four specs, and the two that matter assert what would otherwise pass silently: that
`revoked: false` is surfaced rather than swallowed, and that close-dispute posts to the
two-segment path.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Three calls the other two SDKs have had and this one did not. Each is reachable only through the SDK, so their absence was not an inconvenience — it was work a Ruby integration could not do at all.
auth.logoutpayments.dispute_submit_by_hashpayments.close_dispute_submit_by_hashauth.logoutRevokes the token this client carries, not every session for the address — signing out one process leaves the others signed in.
It returns the body rather than
nilon purpose. The gateway's denylist fails open by design (a store outage must not sign out the whole platform), so{ revoked: false }means the token is still usable until it expires, and the caller should treat its own copy as compromised rather than assume the session is gone. Ruby was the one SDK where a long-lived process could not hand a session back at all.The two dispute report-by-hash calls
The payer's counterpart to
submit_by_hash. That generic method only covers the single-segment/payments/{id}/{operation}/submittedshape, anddispute/closeis two segments — which is why these are separate methods rather than anotheroperationargument. Without them, a Ruby caller signing with a wallet that broadcasts on its own (MetaMask) could open and close disputes with a raw signed transaction but could never report one it had already sent.Payer-only, and the payer authenticates account-less via SIWE: a bare hash carries no signature, so the session is what proves who is reporting it.
Security
Nothing widened, and one thing improved:
logoutis the first way this SDK can end a session it holds. All three are existing gateway endpoints called with the client's existing credential, and authorisation stays entirely server-side (payer-only on the dispute paths, session-scoped on logout). No new local state, nothing logged.The one judgement call worth a reviewer's eye is returning
revokedverbatim rather than raising when it isfalse— the failure is soft on the gateway's side, so it is the caller's decision to make, and the README says what it means.Performance
One request per call. No retries added (this SDK still retries network errors only — the 429 divergence across the three SDKs is a separate change), no extra round trips, no caching.
Tests
Four specs. The two that matter assert what would otherwise pass silently: that
revoked: falseis surfaced rather than swallowed, and that close-dispute posts to the two-segment path — the whole reason these are not one parameterised method.bundle exec rspec: 143 examples, 0 failures.Still open across the three SDKs
Not in this PR, for the record: the 429 policy diverges three ways (go retries honouring
Retry-After, ts surfaces it but never retries, ruby ignores it), no SDK has an auto-pager,ProveAddressexists only in go, and this README does not document therbsecp256k1native-build flags thatbundle installneeds before the signing extras will install.🤖 Generated with Claude Code