rail0-sdk 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -1
- data/lib/rail0/resources/accounts.rb +6 -2
- data/lib/rail0/resources/payments.rb +35 -14
- data/lib/rail0/resources/query.rb +47 -3
- data/lib/rail0/resources/wallets.rb +18 -10
- data/lib/rail0/resources/webhooks.rb +9 -9
- data/lib/rail0/types.rb +0 -10
- data/lib/rail0/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5432df0776e08a77c56678e4e977d87c81ddf2be6176fef59a95051e287a6ce9
|
|
4
|
+
data.tar.gz: 7747a265cc8d84f243a09a8b1ab66e3cba545a3817554bc321dc5aa9eaed34be
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 440edc898e25a83ad3c76615777b4074f7daf003904db75129df01c4fcb223aebad7e5a1e425212207842aa334cdab1bccfe79a0023fcf08578d5bc09da8462a
|
|
7
|
+
data.tar.gz: 7482c21a09309b6dabe1f26c4b19b29890d8b8dfc679d4fc1b15d8b1de76a39b2f5998414e2e28ab3ee840edc2e31e7531ebe3b215c0a308f92068d0754ac46a
|
data/README.md
CHANGED
|
@@ -378,6 +378,10 @@ client.payments.create(params, idempotency_key: nil) # or keyword fields
|
|
|
378
378
|
# Reusing a key for DIFFERENT terms raises Rail0::ApiError with code
|
|
379
379
|
# "idempotency_key_reused" (422) instead of returning the first payment.
|
|
380
380
|
client.payments.get(id)
|
|
381
|
+
client.payments.update(id, description: "Order #42") # → the payment, same shape as get
|
|
382
|
+
client.payments.update(id, description: nil) # nil (or "") clears it
|
|
383
|
+
# The description is the only editable field: off-chain, so any status, settled included.
|
|
384
|
+
# Payer or payee only (a non-participant gets 404); over 255 characters is a 422.
|
|
381
385
|
client.payments.list(status: "authorized", disputed: false, chain_id: 84532, sort: "-created_at")
|
|
382
386
|
client.payments.list(status: %w[authorized expired]) # any of several states → ?status=authorized,expired
|
|
383
387
|
client.payments.list(operation: "refund") # payments with at least one refund transaction
|
|
@@ -770,6 +774,17 @@ RAIL0 itself:
|
|
|
770
774
|
A failed transaction carries the same triple as `error_code`, `error_title` and
|
|
771
775
|
`error_detail`, whether it reverted on-chain or was refused before broadcast.
|
|
772
776
|
|
|
777
|
+
### Ids in request paths
|
|
778
|
+
|
|
779
|
+
Every id (and operation name) a method interpolates into a request path is
|
|
780
|
+
percent-encoded as ONE path segment, so a value carrying `/`, `?`, `#`, a space or
|
|
781
|
+
non-ASCII characters can never address a different route than the method names
|
|
782
|
+
(`payments.get("../webhooks/x")` requests `/payments/..%2Fwebhooks%2Fx`, not
|
|
783
|
+
`/webhooks/x`). The ids the gateway hands out — UUIDs, `0x` hex — are unchanged by it.
|
|
784
|
+
A value that is `nil`, empty, `"."` or `".."` is never a valid id, and would still
|
|
785
|
+
re-target the request once encoded, so the method raises `ArgumentError` before
|
|
786
|
+
sending anything.
|
|
787
|
+
|
|
773
788
|
## Configuration
|
|
774
789
|
|
|
775
790
|
```ruby
|
|
@@ -854,7 +869,7 @@ lib/rail0/
|
|
|
854
869
|
accounts.rb the caller's own account profile, read and update (JWT)
|
|
855
870
|
webhooks.rb webhook subscription management (JWT)
|
|
856
871
|
analytics.rb account-scoped payment analytics (JWT)
|
|
857
|
-
query.rb shared query-string
|
|
872
|
+
query.rb shared query-string and path-segment helpers
|
|
858
873
|
```
|
|
859
874
|
|
|
860
875
|
## Development
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "query"
|
|
4
|
+
|
|
3
5
|
module Rail0
|
|
4
6
|
module Resources
|
|
5
7
|
# The merchant account itself (requires JWT).
|
|
@@ -17,6 +19,8 @@ module Rail0
|
|
|
17
19
|
# {Resources::Wallets}; buyer-facing discovery of what a merchant accepts lives on
|
|
18
20
|
# {Resources::PaymentMethods}.
|
|
19
21
|
class Accounts
|
|
22
|
+
include Query
|
|
23
|
+
|
|
20
24
|
attr_reader :http
|
|
21
25
|
|
|
22
26
|
def initialize(http)
|
|
@@ -29,7 +33,7 @@ module Rail0
|
|
|
29
33
|
# @return [Hash] `id`, `name`, `email`, `created_at`, `updated_at`. `email` is part of
|
|
30
34
|
# the response because only the account's owner, or an operator, can read it.
|
|
31
35
|
def get(account_id)
|
|
32
|
-
http.get("/accounts/#{account_id}")
|
|
36
|
+
http.get("/accounts/#{segment(account_id)}")
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
# Update the account's own profile (PATCH /accounts/:account_id).
|
|
@@ -55,7 +59,7 @@ module Rail0
|
|
|
55
59
|
body[:email] = email unless email.nil?
|
|
56
60
|
raise ArgumentError, "at least one of name or email is required" if body.empty?
|
|
57
61
|
|
|
58
|
-
http.patch("/accounts/#{account_id}", body)
|
|
62
|
+
http.patch("/accounts/#{segment(account_id)}", body)
|
|
59
63
|
end
|
|
60
64
|
end
|
|
61
65
|
end
|
|
@@ -99,7 +99,25 @@ module Rail0
|
|
|
99
99
|
# (Integer or nil — divide `amount`, `capturable_amount` and `refundable_amount` by
|
|
100
100
|
# 10**decimals to render them) and `in_flight` (Boolean — see {list}).
|
|
101
101
|
def get(id)
|
|
102
|
-
http.get("/payments/#{id}")
|
|
102
|
+
http.get("/payments/#{segment(id)}")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Set or clear a payment's description (PATCH /payments/{id}).
|
|
106
|
+
#
|
|
107
|
+
# The description is the only field this route edits: it is off-chain metadata, so
|
|
108
|
+
# it can change at any status, settled payments included. Only a participant (the
|
|
109
|
+
# payer or the payee) may edit it — a non-participant gets the same 404 as an unknown
|
|
110
|
+
# id, and a deactivated caller wallet a 403 `wallet_deactivated`.
|
|
111
|
+
#
|
|
112
|
+
# +description:+ is required, and is always sent: passing +nil+ sends JSON +null+,
|
|
113
|
+
# which clears it (as does +""+). Over 255 characters is a 422.
|
|
114
|
+
# (rail0-gateway#373)
|
|
115
|
+
#
|
|
116
|
+
# @param id [String] Payment UUID or rail0_id.
|
|
117
|
+
# @param description [String, nil] The new description; +nil+ or +""+ clears it.
|
|
118
|
+
# @return [Hash] The updated payment, the same shape {get} returns.
|
|
119
|
+
def update(id, description:)
|
|
120
|
+
http.patch("/payments/#{segment(id)}", { description: description })
|
|
103
121
|
end
|
|
104
122
|
|
|
105
123
|
# List on-chain transactions for a payment.
|
|
@@ -114,7 +132,7 @@ module Rail0
|
|
|
114
132
|
# @return [Hash] { data: Array<Hash>, meta: { page:, per_page:, total: } }
|
|
115
133
|
def transactions(id, operation: nil, status: nil, sort: nil, page: nil, per_page: nil)
|
|
116
134
|
query = build_query(operation: operation, status: status, sort: sort, page: page, per_page: per_page)
|
|
117
|
-
http.get_list("/payments/#{id}/transactions#{query}")
|
|
135
|
+
http.get_list("/payments/#{segment(id)}/transactions#{query}")
|
|
118
136
|
end
|
|
119
137
|
|
|
120
138
|
# Fetch ONE of a payment's transactions
|
|
@@ -130,7 +148,7 @@ module Rail0
|
|
|
130
148
|
# @param transaction_id [String] Transaction UUID.
|
|
131
149
|
# @return [Hash]
|
|
132
150
|
def get_transaction(id, transaction_id)
|
|
133
|
-
http.get("/payments/#{id}/transactions/#{transaction_id}")
|
|
151
|
+
http.get("/payments/#{segment(id)}/transactions/#{segment(transaction_id)}")
|
|
134
152
|
end
|
|
135
153
|
|
|
136
154
|
# Re-enqueue a stuck broadcast
|
|
@@ -153,7 +171,7 @@ module Rail0
|
|
|
153
171
|
# @param transaction_id [String] The transaction row to redrive.
|
|
154
172
|
# @return [Hash] The transaction, re-enqueued.
|
|
155
173
|
def redrive(id, transaction_id)
|
|
156
|
-
http.post("/payments/#{id}/transactions/#{transaction_id}/redrive", {})
|
|
174
|
+
http.post("/payments/#{segment(id)}/transactions/#{segment(transaction_id)}/redrive", {})
|
|
157
175
|
end
|
|
158
176
|
|
|
159
177
|
# Submit the payer's EIP-712 signature (PUT /payments/{id}/sign).
|
|
@@ -161,7 +179,7 @@ module Rail0
|
|
|
161
179
|
# @param params [Hash] { signature: "0x…" } (65-byte 0x-prefixed hex).
|
|
162
180
|
# @return [Hash]
|
|
163
181
|
def sign(id, params)
|
|
164
|
-
http.put("/payments/#{id}/sign", params)
|
|
182
|
+
http.put("/payments/#{segment(id)}/sign", params)
|
|
165
183
|
end
|
|
166
184
|
|
|
167
185
|
# List a payment's dispute open/close history.
|
|
@@ -173,7 +191,7 @@ module Rail0
|
|
|
173
191
|
# @return [Hash] { data: Array<Hash>, meta: { page:, per_page:, total: } }
|
|
174
192
|
def disputes(id, status: nil, sort: nil, page: nil, per_page: nil)
|
|
175
193
|
query = build_query(status: status, sort: sort, page: page, per_page: per_page)
|
|
176
|
-
http.get_list("/payments/#{id}/disputes#{query}")
|
|
194
|
+
http.get_list("/payments/#{segment(id)}/disputes#{query}")
|
|
177
195
|
end
|
|
178
196
|
|
|
179
197
|
# Build the unsigned transaction for an operation
|
|
@@ -193,7 +211,7 @@ module Rail0
|
|
|
193
211
|
# with different terms is refused 422 +idempotency_key_reused+. Scoped to this
|
|
194
212
|
# payment. (rail0-gateway#331)
|
|
195
213
|
def prepare(id, operation, body = nil, idempotency_key: nil)
|
|
196
|
-
http.post("/payments/#{id}/#{operation}/prepare", body,
|
|
214
|
+
http.post("/payments/#{segment(id)}/#{segment(operation)}/prepare", body,
|
|
197
215
|
headers: idempotency_headers(idempotency_key))
|
|
198
216
|
end
|
|
199
217
|
|
|
@@ -203,7 +221,7 @@ module Rail0
|
|
|
203
221
|
# @param params [Hash] { signed_transaction: "0x…" }.
|
|
204
222
|
# @return [Hash]
|
|
205
223
|
def submit(id, operation, params)
|
|
206
|
-
http.post("/payments/#{id}/#{operation}", params)
|
|
224
|
+
http.post("/payments/#{segment(id)}/#{segment(operation)}", params)
|
|
207
225
|
end
|
|
208
226
|
|
|
209
227
|
# Record a transaction the caller broadcast themselves (MetaMask/wallet flow)
|
|
@@ -213,7 +231,7 @@ module Rail0
|
|
|
213
231
|
# @param params [Hash] { transaction_hash: "0x…" }.
|
|
214
232
|
# @return [Hash]
|
|
215
233
|
def submit_by_hash(id, operation, params)
|
|
216
|
-
http.post("/payments/#{id}/#{operation}/submitted", params)
|
|
234
|
+
http.post("/payments/#{segment(id)}/#{segment(operation)}/submitted", params)
|
|
217
235
|
end
|
|
218
236
|
|
|
219
237
|
# Phase 1 — build the unsigned authorize() transaction (escrow hold).
|
|
@@ -302,7 +320,7 @@ module Rail0
|
|
|
302
320
|
# @param params [Hash] { signed_transaction: "0x…" }.
|
|
303
321
|
# @return [Hash]
|
|
304
322
|
def dispute(id, params)
|
|
305
|
-
http.post("/payments/#{id}/dispute", params)
|
|
323
|
+
http.post("/payments/#{segment(id)}/dispute", params)
|
|
306
324
|
end
|
|
307
325
|
|
|
308
326
|
# Phase 1 — build the unsigned closeDispute() transaction (payer only).
|
|
@@ -318,7 +336,7 @@ module Rail0
|
|
|
318
336
|
# @param params [Hash] { signed_transaction: "0x…" }.
|
|
319
337
|
# @return [Hash]
|
|
320
338
|
def close_dispute(id, params)
|
|
321
|
-
http.post("/payments/#{id}/dispute/close", params)
|
|
339
|
+
http.post("/payments/#{segment(id)}/dispute/close", params)
|
|
322
340
|
end
|
|
323
341
|
|
|
324
342
|
# The payer's counterpart to {#submit_by_hash}, which covers only the operations
|
|
@@ -336,7 +354,7 @@ module Rail0
|
|
|
336
354
|
# @param params [Hash] { transaction_hash: "0x…" }.
|
|
337
355
|
# @return [Hash]
|
|
338
356
|
def dispute_submit_by_hash(id, params)
|
|
339
|
-
http.post("/payments/#{id}/dispute/submitted", params)
|
|
357
|
+
http.post("/payments/#{segment(id)}/dispute/submitted", params)
|
|
340
358
|
end
|
|
341
359
|
|
|
342
360
|
# Report an already-broadcast close-dispute transaction by hash (payer only); HTTP 202.
|
|
@@ -344,14 +362,17 @@ module Rail0
|
|
|
344
362
|
# @param params [Hash] { transaction_hash: "0x…" }.
|
|
345
363
|
# @return [Hash]
|
|
346
364
|
def close_dispute_submit_by_hash(id, params)
|
|
347
|
-
http.post("/payments/#{id}/dispute/close/submitted", params)
|
|
365
|
+
http.post("/payments/#{segment(id)}/dispute/close/submitted", params)
|
|
348
366
|
end
|
|
349
367
|
|
|
350
368
|
private
|
|
351
369
|
|
|
370
|
+
# +path+ is one of this class's own literals ("dispute/prepare",
|
|
371
|
+
# "dispute/close/prepare"), never caller input, so it is interpolated as-is:
|
|
372
|
+
# its `/` is meant to separate segments. Only +id+ goes through {#segment}.
|
|
352
373
|
def prepare_dispute(path, id, reason, idempotency_key: nil)
|
|
353
374
|
body = reason ? { reason: reason } : {}
|
|
354
|
-
http.post("/payments/#{id}/#{path}", body,
|
|
375
|
+
http.post("/payments/#{segment(id)}/#{path}", body,
|
|
355
376
|
headers: idempotency_headers(idempotency_key))
|
|
356
377
|
end
|
|
357
378
|
|
|
@@ -1,15 +1,59 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "cgi"
|
|
4
|
+
require "erb"
|
|
4
5
|
|
|
5
6
|
module Rail0
|
|
6
7
|
module Resources
|
|
7
|
-
# Shared
|
|
8
|
-
#
|
|
9
|
-
# are
|
|
8
|
+
# Shared URL builders for resource classes. Included so every resource turns
|
|
9
|
+
# keyword filters into a URL query the same way (nil values are dropped,
|
|
10
|
+
# booleans/integers are stringified) and escapes every caller-supplied path
|
|
11
|
+
# segment the same way ({#segment}).
|
|
10
12
|
module Query
|
|
13
|
+
# Segments that would not stay put once interpolated: "." and ".." are dot
|
|
14
|
+
# segments that a URL normaliser (a proxy, a CDN, the server's router) may
|
|
15
|
+
# resolve away, and an empty one collapses the path onto its parent.
|
|
16
|
+
UNSAFE_SEGMENTS = ["", ".", ".."].freeze
|
|
17
|
+
private_constant :UNSAFE_SEGMENTS
|
|
18
|
+
|
|
11
19
|
private
|
|
12
20
|
|
|
21
|
+
# Escapes ONE caller-supplied value for interpolation into a request path:
|
|
22
|
+
#
|
|
23
|
+
# http.get("/payments/#{segment(id)}/transactions/#{segment(transaction_id)}")
|
|
24
|
+
#
|
|
25
|
+
# Paths used to be plain interpolation, so an id was pasted in raw: one
|
|
26
|
+
# containing `/`, `?`, `#` or `..` addressed a different route than the method
|
|
27
|
+
# named — `payments.get("../webhooks/x")` was a GET on /webhooks/x with the
|
|
28
|
+
# caller's token. The ids this SDK is handed normally come from the gateway, but
|
|
29
|
+
# a caller that forwards one from a URL (a proxy route, a CLI argument) passes
|
|
30
|
+
# along whatever it was given.
|
|
31
|
+
#
|
|
32
|
+
# ERB::Util.url_encode percent-encodes everything outside the RFC 3986
|
|
33
|
+
# unreserved set (A-Z a-z 0-9 - . _ ~), UTF-8 byte by byte, with a space as
|
|
34
|
+
# %20 — the path-correct form (CGI.escape, used for queries, would turn a
|
|
35
|
+
# space into `+`, which in a path is a literal plus). For the values legitimately
|
|
36
|
+
# passed (UUIDs, 0x hex, operation names, integer ids) it changes nothing. This
|
|
37
|
+
# matches rail0-ts's `path` tag, which uses encodeURIComponent.
|
|
38
|
+
#
|
|
39
|
+
# A value that is exactly "", "." or ".." raises ArgumentError instead: encoding
|
|
40
|
+
# leaves the dots as they are (they are unreserved), so the segment would still
|
|
41
|
+
# be a dot segment, and an empty one silently re-targets the parent route
|
|
42
|
+
# (`payments.get("")` would list payments). None of them is a valid id, so
|
|
43
|
+
# failing before the request is the only honest answer.
|
|
44
|
+
#
|
|
45
|
+
# @param value [#to_s] The id (or other caller-supplied value) to interpolate.
|
|
46
|
+
# @return [String] The percent-encoded segment.
|
|
47
|
+
# @raise [ArgumentError] If the value is nil, empty, "." or "..".
|
|
48
|
+
def segment(value)
|
|
49
|
+
str = value.to_s
|
|
50
|
+
if value.nil? || UNSAFE_SEGMENTS.include?(str)
|
|
51
|
+
raise ArgumentError, "invalid path segment #{value.inspect}: an id must not be nil, empty, \".\" or \"..\""
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
ERB::Util.url_encode(str)
|
|
55
|
+
end
|
|
56
|
+
|
|
13
57
|
# Builds "?k=v&…" from keyword filters, or "" when every value is nil.
|
|
14
58
|
#
|
|
15
59
|
# An Array value becomes ONE comma-separated pair (`status: %w[a b]` →
|
|
@@ -38,7 +38,7 @@ module Rail0
|
|
|
38
38
|
query = build_query(chain_id: chain_id, token_symbol: token_symbol, active: active,
|
|
39
39
|
default: default, token_active: token_active,
|
|
40
40
|
sort: sort, page: page, per_page: per_page)
|
|
41
|
-
http.get_list("/accounts/#{account_id}/wallets#{query}")
|
|
41
|
+
http.get_list("/accounts/#{segment(account_id)}/wallets#{query}")
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Fetch a single wallet by its id or 0x address.
|
|
@@ -46,7 +46,7 @@ module Rail0
|
|
|
46
46
|
# @param id_or_address [String] Wallet UUID or 0x address.
|
|
47
47
|
# @return [Hash] id, address, label, active
|
|
48
48
|
def get(account_id, id_or_address)
|
|
49
|
-
http.get(
|
|
49
|
+
http.get(wallet_path(account_id, id_or_address))
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# Add a wallet to the account.
|
|
@@ -74,7 +74,7 @@ module Rail0
|
|
|
74
74
|
def create(account_id, address:, message:, signature:, label: nil)
|
|
75
75
|
body = { address: address, message: message, signature: signature }
|
|
76
76
|
body[:label] = label unless label.nil?
|
|
77
|
-
http.post("/accounts/#{account_id}/wallets", body)
|
|
77
|
+
http.post("/accounts/#{segment(account_id)}/wallets", body)
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
# Update a wallet's label and/or active status.
|
|
@@ -87,7 +87,7 @@ module Rail0
|
|
|
87
87
|
body = {}
|
|
88
88
|
body[:label] = label unless label.nil?
|
|
89
89
|
body[:active] = active unless active.nil?
|
|
90
|
-
http.patch(
|
|
90
|
+
http.patch(wallet_path(account_id, id_or_address), body)
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
# Soft-delete (deactivate) a wallet. Returns HTTP 204.
|
|
@@ -95,7 +95,7 @@ module Rail0
|
|
|
95
95
|
# @param id_or_address [String] Wallet UUID or 0x address.
|
|
96
96
|
# @return [nil]
|
|
97
97
|
def delete(account_id, id_or_address)
|
|
98
|
-
http.delete(
|
|
98
|
+
http.delete(wallet_path(account_id, id_or_address))
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
# Read a wallet's live on-chain balances across the configured chains. Each
|
|
@@ -109,7 +109,7 @@ module Rail0
|
|
|
109
109
|
# @return [Hash] wallet_id, address, balances
|
|
110
110
|
def balances(account_id, id_or_address, chain_id: nil, token_symbol: nil)
|
|
111
111
|
query = build_query(chain_id: chain_id, token_symbol: token_symbol)
|
|
112
|
-
http.get("
|
|
112
|
+
http.get("#{wallet_path(account_id, id_or_address)}/balances#{query}")
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
# ── Token holdings ────────────────────────────────────────────────────────
|
|
@@ -133,7 +133,7 @@ module Rail0
|
|
|
133
133
|
def add_token(account_id, id_or_address, chain_id:, token:, default: nil)
|
|
134
134
|
body = { chain_id: chain_id, token: token }
|
|
135
135
|
body[:default] = default unless default.nil?
|
|
136
|
-
http.post("
|
|
136
|
+
http.post("#{wallet_path(account_id, id_or_address)}/tokens", body)
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
# Stop accepting a token on this wallet (soft delete). Returns HTTP 204.
|
|
@@ -150,13 +150,13 @@ module Rail0
|
|
|
150
150
|
#
|
|
151
151
|
# @return [nil]
|
|
152
152
|
def remove_token(account_id, id_or_address, token_id)
|
|
153
|
-
http.delete("
|
|
153
|
+
http.delete("#{wallet_path(account_id, id_or_address)}/tokens/#{segment(token_id)}")
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
# Re-enable an existing token holding.
|
|
157
157
|
# @return [Hash] the token holding
|
|
158
158
|
def enable_token(account_id, id_or_address, token_id)
|
|
159
|
-
http.patch("
|
|
159
|
+
http.patch("#{wallet_path(account_id, id_or_address)}/tokens/#{segment(token_id)}/enable")
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
# Disable an existing token holding without forgetting it — the holding (and
|
|
@@ -166,7 +166,15 @@ module Rail0
|
|
|
166
166
|
# active default holding — promote another token to default first.
|
|
167
167
|
# @return [Hash] the token holding
|
|
168
168
|
def disable_token(account_id, id_or_address, token_id)
|
|
169
|
-
http.patch("
|
|
169
|
+
http.patch("#{wallet_path(account_id, id_or_address)}/tokens/#{segment(token_id)}/disable")
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
private
|
|
173
|
+
|
|
174
|
+
# "/accounts/{account_id}/wallets/{id_or_address}" with both ids escaped by
|
|
175
|
+
# {Query#segment} — the prefix every single-wallet route shares.
|
|
176
|
+
def wallet_path(account_id, id_or_address)
|
|
177
|
+
"/accounts/#{segment(account_id)}/wallets/#{segment(id_or_address)}"
|
|
170
178
|
end
|
|
171
179
|
end
|
|
172
180
|
end
|
|
@@ -71,7 +71,7 @@ module Rail0
|
|
|
71
71
|
# @param id [String] Webhook UUID.
|
|
72
72
|
# @return [Hash]
|
|
73
73
|
def get(id)
|
|
74
|
-
http.get("/webhooks/#{id}")
|
|
74
|
+
http.get("/webhooks/#{segment(id)}")
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
# Update a webhook's name, callback_url, and/or topics.
|
|
@@ -87,35 +87,35 @@ module Rail0
|
|
|
87
87
|
body[:name] = name unless name.nil?
|
|
88
88
|
body[:callback_url] = callback_url unless callback_url.nil?
|
|
89
89
|
body[:topics] = Array(topics) unless topics.nil?
|
|
90
|
-
http.patch("/webhooks/#{id}", body)
|
|
90
|
+
http.patch("/webhooks/#{segment(id)}", body)
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
# Re-enable a disabled webhook.
|
|
94
94
|
# @param id [String] Webhook UUID.
|
|
95
95
|
# @return [Hash]
|
|
96
96
|
def enable(id)
|
|
97
|
-
http.put("/webhooks/#{id}/enable")
|
|
97
|
+
http.put("/webhooks/#{segment(id)}/enable")
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
# Disable a webhook (stops deliveries without deleting it).
|
|
101
101
|
# @param id [String] Webhook UUID.
|
|
102
102
|
# @return [Hash]
|
|
103
103
|
def disable(id)
|
|
104
|
-
http.put("/webhooks/#{id}/disable")
|
|
104
|
+
http.put("/webhooks/#{segment(id)}/disable")
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
# Generate a new shared secret, returned once on the response.
|
|
108
108
|
# @param id [String] Webhook UUID.
|
|
109
109
|
# @return [Hash] webhook record including the new shared_secret
|
|
110
110
|
def rotate_secret(id)
|
|
111
|
-
http.put("/webhooks/#{id}/rotate_secret")
|
|
111
|
+
http.put("/webhooks/#{segment(id)}/rotate_secret")
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
# Reset the delivery circuit breaker and re-enable the webhook.
|
|
115
115
|
# @param id [String] Webhook UUID.
|
|
116
116
|
# @return [Hash]
|
|
117
117
|
def reset_circuit(id)
|
|
118
|
-
http.put("/webhooks/#{id}/reset_circuit")
|
|
118
|
+
http.put("/webhooks/#{segment(id)}/reset_circuit")
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
# List delivery attempts for a webhook.
|
|
@@ -138,7 +138,7 @@ module Rail0
|
|
|
138
138
|
query = build_query(status: status, topic: topic, payment_id: payment_id,
|
|
139
139
|
response_code: response_code, since: since, until: until_time,
|
|
140
140
|
sort: sort, page: page, per_page: per_page)
|
|
141
|
-
http.get_list("/webhooks/#{id}/event_callbacks#{query}")
|
|
141
|
+
http.get_list("/webhooks/#{segment(id)}/event_callbacks#{query}")
|
|
142
142
|
end
|
|
143
143
|
|
|
144
144
|
# Re-deliver one recorded delivery's exact payload
|
|
@@ -161,14 +161,14 @@ module Rail0
|
|
|
161
161
|
# @param callback_id [String] The event callback's UUID (from {event_callbacks}).
|
|
162
162
|
# @return [Hash] `{ status: "queued" }` (HTTP 202).
|
|
163
163
|
def redeliver(id, callback_id)
|
|
164
|
-
http.post("/webhooks/#{id}/event_callbacks/#{callback_id}/redeliver", {})
|
|
164
|
+
http.post("/webhooks/#{segment(id)}/event_callbacks/#{segment(callback_id)}/redeliver", {})
|
|
165
165
|
end
|
|
166
166
|
|
|
167
167
|
# Delete a webhook. Returns HTTP 204.
|
|
168
168
|
# @param id [String] Webhook UUID.
|
|
169
169
|
# @return [nil]
|
|
170
170
|
def delete(id)
|
|
171
|
-
http.delete("/webhooks/#{id}")
|
|
171
|
+
http.delete("/webhooks/#{segment(id)}")
|
|
172
172
|
end
|
|
173
173
|
end
|
|
174
174
|
end
|
data/lib/rail0/types.rb
CHANGED
|
@@ -173,16 +173,6 @@ module Rail0
|
|
|
173
173
|
keyword_init: true
|
|
174
174
|
)
|
|
175
175
|
|
|
176
|
-
# A wallet's token holding, with the wallet, token, and blockchain nested via their own schemas.
|
|
177
|
-
WalletToken = Struct.new(
|
|
178
|
-
:default, # Boolean
|
|
179
|
-
:active, # Boolean
|
|
180
|
-
:wallet, # Wallet
|
|
181
|
-
:token, # Token
|
|
182
|
-
:blockchain, # Blockchain
|
|
183
|
-
keyword_init: true
|
|
184
|
-
)
|
|
185
|
-
|
|
186
176
|
# A wallet's token holding as nested under its wallet (GET /accounts/:id/wallets): the token plus
|
|
187
177
|
# this wallet's per-token flags, without re-nesting the wallet.
|
|
188
178
|
WalletTokenHolding = Struct.new(
|
data/lib/rail0/version.rb
CHANGED
|
@@ -5,5 +5,5 @@ module Rail0
|
|
|
5
5
|
# consumed by path from a sibling checkout, where the number bought nothing: no registry
|
|
6
6
|
# ever served a 1.x, no tag was ever cut, and the one consumer resolves the working tree.
|
|
7
7
|
# Publishing from 1.2.0 would have implied two releases nobody can install.
|
|
8
|
-
VERSION = "1.
|
|
8
|
+
VERSION = "1.4.0"
|
|
9
9
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rail0-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Commerce Layer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: logger
|