tronzap-sdk 1.0.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 +7 -0
- data/CHANGELOG.md +23 -0
- data/LICENSE +21 -0
- data/README.es.md +396 -0
- data/README.md +392 -0
- data/README.pt-br.md +392 -0
- data/README.ru.md +392 -0
- data/lib/tronzap/client.rb +239 -0
- data/lib/tronzap/coerce.rb +127 -0
- data/lib/tronzap/configuration.rb +140 -0
- data/lib/tronzap/errors.rb +150 -0
- data/lib/tronzap/http_adapter.rb +168 -0
- data/lib/tronzap/models/activate_address_rate.rb +11 -0
- data/lib/tronzap/models/address_resources.rb +13 -0
- data/lib/tronzap/models/aml_risk_factor.rb +28 -0
- data/lib/tronzap/models/bandwidth_rate.rb +28 -0
- data/lib/tronzap/models/direct_recharge_rate.rb +38 -0
- data/lib/tronzap/models/energy_rate.rb +44 -0
- data/lib/tronzap/models/enums.rb +26 -0
- data/lib/tronzap/models/resource_amounts.rb +13 -0
- data/lib/tronzap/models/timestamp.rb +58 -0
- data/lib/tronzap/models/transaction_params.rb +46 -0
- data/lib/tronzap/requests/address_activation.rb +28 -0
- data/lib/tronzap/requests/aml_check.rb +68 -0
- data/lib/tronzap/requests/aml_history.rb +34 -0
- data/lib/tronzap/requests/bandwidth_transaction.rb +33 -0
- data/lib/tronzap/requests/calculate.rb +32 -0
- data/lib/tronzap/requests/check_transaction.rb +48 -0
- data/lib/tronzap/requests/energy_transaction.rb +42 -0
- data/lib/tronzap/requests/estimate_energy.rb +38 -0
- data/lib/tronzap/requests/resource_bundle_transaction.rb +51 -0
- data/lib/tronzap/requests/validation.rb +56 -0
- data/lib/tronzap/response_decoder.rb +115 -0
- data/lib/tronzap/responses/account_balance.rb +20 -0
- data/lib/tronzap/responses/address_info.rb +26 -0
- data/lib/tronzap/responses/aml_check.rb +56 -0
- data/lib/tronzap/responses/aml_history.rb +28 -0
- data/lib/tronzap/responses/aml_service.rb +30 -0
- data/lib/tronzap/responses/calculation.rb +40 -0
- data/lib/tronzap/responses/direct_recharge_info.rb +22 -0
- data/lib/tronzap/responses/energy_estimate.rb +44 -0
- data/lib/tronzap/responses/service_rates.rb +36 -0
- data/lib/tronzap/responses/transaction.rb +44 -0
- data/lib/tronzap/version.rb +6 -0
- data/lib/tronzap-sdk.rb +4 -0
- data/lib/tronzap.rb +47 -0
- metadata +107 -0
data/README.md
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# Tron Energy Rental via API
|
|
2
|
+
## Ruby SDK by TronZap.com
|
|
3
|
+
|
|
4
|
+
**[English](README.md)** | [Español](README.es.md) | [Português](README.pt-br.md) | [Русский](README.ru.md)
|
|
5
|
+
|
|
6
|
+
[](https://rubygems.org/gems/tronzap-sdk)
|
|
7
|
+
[](https://github.com/tron-energy-market/tronzap-sdk-ruby/actions/workflows/ci.yml)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
10
|
+
Official Ruby SDK for the TronZap API.
|
|
11
|
+
This SDK allows you to easily integrate with TronZap services for TRON energy rental.
|
|
12
|
+
|
|
13
|
+
TronZap.com allows you to [buy TRON energy](https://tronzap.com/), making USDT (TRC20) transfers cheaper by significantly reducing transaction fees.
|
|
14
|
+
|
|
15
|
+
👉 [Register for an API key](https://tronzap.com) to start using TronZap API and integrate it via the SDK.
|
|
16
|
+
|
|
17
|
+
- Website: https://tronzap.com/
|
|
18
|
+
- API reference: https://docs.tronzap.com/
|
|
19
|
+
- RubyGems: https://rubygems.org/gems/tronzap-sdk
|
|
20
|
+
- Source: https://github.com/tron-energy-market/tronzap-sdk-ruby
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
Add the gem to your Gemfile:
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
gem "tronzap-sdk"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
or install it directly:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
gem install tronzap-sdk
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
- Ruby 3.3 or newer
|
|
39
|
+
- One runtime dependency, `bigdecimal`. The SDK does not depend on Rails.
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
require "tronzap"
|
|
45
|
+
|
|
46
|
+
client = Tronzap::Client.new(
|
|
47
|
+
api_token: "your_api_token",
|
|
48
|
+
api_secret: "your_api_secret"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
begin
|
|
52
|
+
balance = client.get_balance
|
|
53
|
+
puts "balance: #{balance.balance.to_s("F")} (deposit to #{balance.address})"
|
|
54
|
+
|
|
55
|
+
# Estimate how much energy a USDT transfer needs, then buy exactly that much.
|
|
56
|
+
estimate = client.estimate_energy(from_address: "TSenderAddress", to_address: "TRecipientAddress")
|
|
57
|
+
|
|
58
|
+
transaction = client.create_energy_transaction(
|
|
59
|
+
address: "TRecipientAddress",
|
|
60
|
+
energy: estimate.energy,
|
|
61
|
+
duration: 1,
|
|
62
|
+
external_id: "order-42",
|
|
63
|
+
activate_address: true
|
|
64
|
+
)
|
|
65
|
+
puts "transaction #{transaction.id} costs #{transaction.amount.to_s("F")} and is #{transaction.status}"
|
|
66
|
+
rescue Tronzap::Error => e
|
|
67
|
+
warn "TronZap call failed: #{e.message}"
|
|
68
|
+
end
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`require "tronzap"` loads the SDK. With Bundler, `gem "tronzap-sdk"` in the Gemfile loads it as well.
|
|
72
|
+
|
|
73
|
+
A runnable walkthrough of every operation lives in
|
|
74
|
+
[`examples/basic_usage.rb`](examples/basic_usage.rb):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
export TRONZAP_API_TOKEN=your_api_token
|
|
78
|
+
export TRONZAP_API_SECRET=your_api_secret
|
|
79
|
+
export TRONZAP_BASE_URL=api.tronzap.com # optional
|
|
80
|
+
ruby -Ilib examples/basic_usage.rb
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
By default it only reads and spends nothing. Setting `TRONZAP_ALLOW_PURCHASES=1`
|
|
84
|
+
also exercises the endpoints that create transactions and AML checks, which debit
|
|
85
|
+
the account balance. See the comment at the top of the file for the other optional
|
|
86
|
+
variables.
|
|
87
|
+
|
|
88
|
+
## Configuration
|
|
89
|
+
|
|
90
|
+
The client takes the two credentials from your dashboard: the API token is sent as
|
|
91
|
+
a bearer token, and the API secret signs every request body and is never sent.
|
|
92
|
+
Everything else is optional. Pass the settings as keyword arguments, in a block,
|
|
93
|
+
or both; the block runs last:
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
client = Tronzap::Client.new(
|
|
97
|
+
api_token: api_token,
|
|
98
|
+
api_secret: api_secret,
|
|
99
|
+
base_url: "api.tronzap.com", # defaults to Tronzap::Configuration::DEFAULT_BASE_URL
|
|
100
|
+
timeout: 10, # seconds; defaults to 30
|
|
101
|
+
user_agent: "my-app/1.0"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
client = Tronzap::Client.new do |config|
|
|
105
|
+
config.api_token = ENV.fetch("TRONZAP_API_TOKEN")
|
|
106
|
+
config.api_secret = ENV.fetch("TRONZAP_API_SECRET")
|
|
107
|
+
config.timeout = 10
|
|
108
|
+
end
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`base_url` takes either a bare domain or a full URL: a missing scheme becomes
|
|
112
|
+
`https` and a trailing slash is trimmed, so `"api.tronzap.com"`,
|
|
113
|
+
`"api.tronzap.com/"` and `"https://api.tronzap.com"` are equivalent. Pass an
|
|
114
|
+
explicit scheme to opt out, for example `"http://localhost:8080"` against a local
|
|
115
|
+
mock.
|
|
116
|
+
|
|
117
|
+
`timeout` applies to opening the connection and to each read and write, not to
|
|
118
|
+
the request as a whole.
|
|
119
|
+
|
|
120
|
+
The SDK keeps no global state. Each client validates its settings when it is
|
|
121
|
+
created and freezes them, so a client is immutable and safe to share between
|
|
122
|
+
threads. Create one per set of credentials. `inspect` never shows the
|
|
123
|
+
credentials.
|
|
124
|
+
|
|
125
|
+
### Your own HTTP adapter
|
|
126
|
+
|
|
127
|
+
The default adapter uses `Net::HTTP` from the standard library, opens a new
|
|
128
|
+
connection for every request, always verifies TLS certificates, and honours the
|
|
129
|
+
`https_proxy` environment variable. To trust a private certificate authority, pass
|
|
130
|
+
its PEM file:
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
adapter = Tronzap::HttpAdapter::NetHttp.new(ca_file: "/etc/ssl/corporate-ca.pem")
|
|
134
|
+
client = Tronzap::Client.new(api_token: api_token, api_secret: api_secret, adapter: adapter)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Any object with a `call` method can replace it. It receives a
|
|
138
|
+
`Tronzap::HttpAdapter::Request` (`http_method`, `url`, `headers`, `body`,
|
|
139
|
+
`timeout`) and returns a `Tronzap::HttpAdapter::Response` (`status`, `headers`,
|
|
140
|
+
`body`). Send the body unchanged: it is signed byte for byte.
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
class FaradayAdapter
|
|
144
|
+
def initialize(connection)
|
|
145
|
+
@connection = connection
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def call(request)
|
|
149
|
+
response = @connection.post(request.url, request.body, request.headers) do |req|
|
|
150
|
+
req.options.timeout = request.timeout
|
|
151
|
+
end
|
|
152
|
+
Tronzap::HttpAdapter::Response.new(status: response.status, headers: response.headers.to_h,
|
|
153
|
+
body: response.body.to_s)
|
|
154
|
+
rescue Faraday::TimeoutError => e
|
|
155
|
+
raise Tronzap::TimeoutError, e.message
|
|
156
|
+
rescue Faraday::SSLError => e
|
|
157
|
+
raise Tronzap::SslError, e.message
|
|
158
|
+
rescue Faraday::ConnectionFailed => e
|
|
159
|
+
raise Tronzap::ConnectionError, e.message
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Standard Ruby network errors raised by an adapter (`Timeout::Error`,
|
|
165
|
+
`OpenSSL::SSL::SSLError`, `SocketError`, `SystemCallError`, `IOError`) are
|
|
166
|
+
reported as `Tronzap::NetworkError` subclasses automatically. Errors of other HTTP
|
|
167
|
+
libraries need to be translated by the adapter, as above.
|
|
168
|
+
|
|
169
|
+
## Available methods
|
|
170
|
+
|
|
171
|
+
| Method | Endpoint | Description |
|
|
172
|
+
|---|---|---|
|
|
173
|
+
| `get_services` | `/v1/services` | Available services and prices |
|
|
174
|
+
| `get_balance` | `/v1/balance` | Current account balance |
|
|
175
|
+
| `get_address_info(address)` | `/v1/address-info` | Address resources (energy, bandwidth) and balances (TRX, USDT) |
|
|
176
|
+
| `estimate_energy(from_address:, to_address:, contract_address: nil)` | `/v1/estimate-energy` | Energy a transfer needs, and its cost |
|
|
177
|
+
| `calculate(address:, energy:, duration: 1)` | `/v1/calculate` | Price a purchase without creating a transaction |
|
|
178
|
+
| `create_energy_transaction(address:, energy:, duration: 1, external_id: nil, activate_address: false)` | `/v1/transaction/new` | Buy energy |
|
|
179
|
+
| `create_bandwidth_transaction(address:, bandwidth:, external_id: nil)` | `/v1/transaction/new` | Buy bandwidth |
|
|
180
|
+
| `create_resource_bundle_transaction(address:, energy:, bandwidth:, duration: 1, external_id: nil, activate_address: false)` | `/v1/transaction/new` | Buy energy and bandwidth in one transaction |
|
|
181
|
+
| `create_address_activation_transaction(address:, external_id: nil)` | `/v1/transaction/new` | Activate a TRON address |
|
|
182
|
+
| `check_transaction(id: nil, external_id: nil)` | `/v1/transaction/check` | Status of a transaction, by id or external id |
|
|
183
|
+
| `get_direct_recharge_info` | `/v1/direct-recharge-info` | Direct recharge address and rates |
|
|
184
|
+
| `get_aml_services` | `/v1/aml-checks` | AML services and pricing |
|
|
185
|
+
| `create_aml_check(type:, network:, address:, transaction_hash: nil, direction: nil)` | `/v1/aml-checks/new` | Start an AML screening |
|
|
186
|
+
| `check_aml_status(id)` | `/v1/aml-checks/check` | Status and result of an AML check |
|
|
187
|
+
| `get_aml_history(page: 1, per_page: 10, status: nil)` | `/v1/aml-checks/history` | Paginated AML check history |
|
|
188
|
+
|
|
189
|
+
Methods with parameters take either keyword arguments or a request object from
|
|
190
|
+
`Tronzap::Requests`, so a request can be built, validated and passed around before
|
|
191
|
+
it is sent:
|
|
192
|
+
|
|
193
|
+
```ruby
|
|
194
|
+
request = Tronzap::Requests::EnergyTransaction.new(address: "TRecipientAddress", energy: 65000)
|
|
195
|
+
client.create_energy_transaction(request)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
A request is validated when it is created, so an invalid one raises
|
|
199
|
+
`ArgumentError` and never reaches the API. Amounts must be positive `Integer`s.
|
|
200
|
+
Defaults match the API: `duration` is 1 hour, and AML history starts at page 1
|
|
201
|
+
with 10 items.
|
|
202
|
+
|
|
203
|
+
Results are immutable `Data` objects in `Tronzap::Responses` and
|
|
204
|
+
`Tronzap::Models`, not hashes: `transaction.status`, `estimate.energy`. Collections
|
|
205
|
+
are frozen and never `nil`, and values the API may omit are `nil`.
|
|
206
|
+
|
|
207
|
+
### Buying resources
|
|
208
|
+
|
|
209
|
+
```ruby
|
|
210
|
+
# Energy, optionally activating the address in the same call.
|
|
211
|
+
client.create_energy_transaction(
|
|
212
|
+
address: "TRecipientAddress",
|
|
213
|
+
energy: 65000,
|
|
214
|
+
duration: 1, # hours; see get_services for the durations on sale
|
|
215
|
+
external_id: "order-42",
|
|
216
|
+
activate_address: true
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Bandwidth.
|
|
220
|
+
client.create_bandwidth_transaction(address: "TRecipientAddress", bandwidth: 345, external_id: "bandwidth-1")
|
|
221
|
+
|
|
222
|
+
# Energy and bandwidth together in one transaction.
|
|
223
|
+
client.create_resource_bundle_transaction(
|
|
224
|
+
address: "TRecipientAddress",
|
|
225
|
+
energy: 65000,
|
|
226
|
+
bandwidth: 345,
|
|
227
|
+
external_id: "bundle-1"
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
# Activation on its own.
|
|
231
|
+
client.create_address_activation_transaction(address: "TRecipientAddress", external_id: "activation-1")
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Energy prices are per unit, bandwidth prices are per 1000 units: in
|
|
235
|
+
`get_services`, `EnergyRate#price` × 65000 is the cost of 65000 energy, while 345
|
|
236
|
+
bandwidth at a `BandwidthRate#price` of 1 costs 0.345.
|
|
237
|
+
|
|
238
|
+
The API currently reports a resource bundle with `service` equal to `:energy`, not
|
|
239
|
+
`:resource_bundle`. Read `params.amounts` to see which resources a transaction
|
|
240
|
+
contains.
|
|
241
|
+
|
|
242
|
+
### Following a transaction
|
|
243
|
+
|
|
244
|
+
A transaction moves through `:new` → `:pending` → `:success` or `:failed`:
|
|
245
|
+
|
|
246
|
+
```ruby
|
|
247
|
+
transaction = nil
|
|
248
|
+
loop do
|
|
249
|
+
sleep 2
|
|
250
|
+
transaction = client.check_transaction(external_id: "order-42")
|
|
251
|
+
break unless %i[new pending].include?(transaction.status)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
puts "finished as #{transaction.status}, hash #{transaction.transaction_hash || "none"}"
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### AML screening
|
|
258
|
+
|
|
259
|
+
```ruby
|
|
260
|
+
check = client.create_aml_check(Tronzap::Requests::AmlCheck.for_address("TRX", "TAddressToScreen"))
|
|
261
|
+
# or Tronzap::Requests::AmlCheck.for_hash("BTC", "bc1RecipientAddress", "TX_HASH", direction: :withdrawal)
|
|
262
|
+
|
|
263
|
+
result = client.check_aml_status(check.id)
|
|
264
|
+
if result.status == :completed
|
|
265
|
+
puts "#{result.risk_level} #{result.risk_score.to_s("F")} #{result.risk_factors.size} factor(s)"
|
|
266
|
+
end
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
`risk_score` is `nil` until screening finishes. A completed check can have a score
|
|
270
|
+
of 0, which is not the same as having no score yet.
|
|
271
|
+
|
|
272
|
+
## Error handling
|
|
273
|
+
|
|
274
|
+
Every failure of an API call is a `Tronzap::Error`. Rescue a subclass to handle
|
|
275
|
+
one kind of failure:
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
Tronzap::Error
|
|
279
|
+
├── Tronzap::ApiError — the API answered with a non-zero code
|
|
280
|
+
├── Tronzap::HttpError — non-2xx response without an API payload
|
|
281
|
+
│ ├── Tronzap::RateLimitError — HTTP 429
|
|
282
|
+
│ ├── Tronzap::UnauthorizedError — HTTP 401 or 403
|
|
283
|
+
│ └── Tronzap::ServerError — HTTP 5xx
|
|
284
|
+
├── Tronzap::InvalidResponseError — 2xx response the SDK could not read
|
|
285
|
+
└── Tronzap::NetworkError — no response arrived
|
|
286
|
+
├── Tronzap::ConnectionError — DNS failure, connection refused
|
|
287
|
+
├── Tronzap::TimeoutError — the request exceeded its timeout
|
|
288
|
+
└── Tronzap::SslError — TLS handshake or certificate failure
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
`ApiError`, `HttpError` and `InvalidResponseError` carry the HTTP status
|
|
292
|
+
(`status`) and the raw response body (`response_body`). `ApiError` also carries
|
|
293
|
+
the API error code (`code`), the error key (`error_key`) and the request ID
|
|
294
|
+
(`request_id`). `RateLimitError#retry_after` holds the `Retry-After` delay in
|
|
295
|
+
seconds when the API sends one.
|
|
296
|
+
|
|
297
|
+
Invalid arguments are not API failures: they raise `ArgumentError` before anything
|
|
298
|
+
is sent.
|
|
299
|
+
|
|
300
|
+
```ruby
|
|
301
|
+
begin
|
|
302
|
+
client.create_energy_transaction(address: "TRecipientAddress", energy: 65000)
|
|
303
|
+
rescue Tronzap::ApiError => e
|
|
304
|
+
# Application-level failure: the code says exactly what went wrong.
|
|
305
|
+
case e.code
|
|
306
|
+
when Tronzap::ErrorCode::INVALID_TRON_ADDRESS
|
|
307
|
+
# The key may narrow it down, e.g. "invalid_tron_address.from_address"
|
|
308
|
+
warn "bad address: #{e.error_key}"
|
|
309
|
+
when Tronzap::ErrorCode::INSUFFICIENT_FUNDS
|
|
310
|
+
warn "top up the account"
|
|
311
|
+
when Tronzap::ErrorCode::ADDRESS_NOT_ACTIVATED
|
|
312
|
+
warn "activate the address first"
|
|
313
|
+
else
|
|
314
|
+
warn "api error #{e.code}: #{e.message} (request #{e.request_id || "-"})"
|
|
315
|
+
end
|
|
316
|
+
rescue Tronzap::RateLimitError => e
|
|
317
|
+
# Back off and retry, after e.retry_after seconds if the API sent it.
|
|
318
|
+
rescue Tronzap::UnauthorizedError
|
|
319
|
+
# Bad token or signature.
|
|
320
|
+
rescue Tronzap::TimeoutError, Tronzap::ServerError
|
|
321
|
+
# Transient; safe to retry.
|
|
322
|
+
rescue Tronzap::NetworkError
|
|
323
|
+
# Unreachable.
|
|
324
|
+
end
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
`request_id` is the identifier the API assigns to each request. Quote it when
|
|
328
|
+
contacting support.
|
|
329
|
+
|
|
330
|
+
An API error takes precedence over the HTTP status: the API reports some failures
|
|
331
|
+
with a 2xx status and others with a 4xx or 5xx status, so a readable payload with
|
|
332
|
+
a non-zero code is always reported as `Tronzap::ApiError`, never as
|
|
333
|
+
`Tronzap::HttpError`.
|
|
334
|
+
|
|
335
|
+
### API error codes
|
|
336
|
+
|
|
337
|
+
| Code | Constant | Description |
|
|
338
|
+
|------|----------|-------------|
|
|
339
|
+
| 1 | `AUTH_ERROR` | Authentication error – invalid API token or signature |
|
|
340
|
+
| 2 | `INVALID_SERVICE_OR_PARAMS` | Invalid service or parameters |
|
|
341
|
+
| 5 | `WALLET_NOT_FOUND` | Internal wallet not found. Contact support. |
|
|
342
|
+
| 6 | `INSUFFICIENT_FUNDS` | Insufficient funds |
|
|
343
|
+
| 10 | `INVALID_TRON_ADDRESS` | Invalid TRON address |
|
|
344
|
+
| 11 | `INVALID_ENERGY_AMOUNT` | Invalid energy amount |
|
|
345
|
+
| 12 | `INVALID_DURATION` | Invalid duration |
|
|
346
|
+
| 20 | `TRANSACTION_NOT_FOUND` | Transaction/subscription not found |
|
|
347
|
+
| 21 | `CANNOT_STOP_SUBSCRIPTION` | Cannot stop subscription |
|
|
348
|
+
| 24 | `ADDRESS_NOT_ACTIVATED` | Address not activated |
|
|
349
|
+
| 25 | `ADDRESS_ALREADY_ACTIVATED` | Address already activated |
|
|
350
|
+
| 30 | `AML_CHECK_NOT_FOUND` | AML check not found |
|
|
351
|
+
| 35 | `SERVICE_NOT_AVAILABLE` | Service not available |
|
|
352
|
+
| 50 | `INVALID_BANDWIDTH_AMOUNT` | Invalid bandwidth amount |
|
|
353
|
+
| 500 | `INTERNAL_SERVER_ERROR` | Internal server error – contact support |
|
|
354
|
+
|
|
355
|
+
The constants live in `Tronzap::ErrorCode`. A code this SDK version does not know
|
|
356
|
+
is still available as a number from `ApiError#code`.
|
|
357
|
+
|
|
358
|
+
## Decimal and timestamp fields
|
|
359
|
+
|
|
360
|
+
Amounts and prices are `BigDecimal`, so they keep the exact value the API sent.
|
|
361
|
+
The API encodes money as a JSON number in some responses and as a JSON string in
|
|
362
|
+
others; both forms are read the same way. Use `to_s("F")` to print one without
|
|
363
|
+
exponent notation.
|
|
364
|
+
|
|
365
|
+
Timestamps are `Tronzap::Models::Timestamp` objects: `value` is the parsed `Time`
|
|
366
|
+
and `raw` is the text exactly as the API sent it. The several formats the API
|
|
367
|
+
emits are accepted, and times without an offset are read as UTC. An unrecognised
|
|
368
|
+
timestamp leaves `value` as `nil` instead of failing the whole response.
|
|
369
|
+
|
|
370
|
+
Enum-like fields are symbols, such as `:energy` or `:completed`. A value the API
|
|
371
|
+
may add in the future, such as a new transaction status, is reported as `:unknown`
|
|
372
|
+
instead of failing. The known values are listed in `Tronzap::Models`.
|
|
373
|
+
|
|
374
|
+
## Testing
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
bundle install
|
|
378
|
+
bundle exec rspec
|
|
379
|
+
bundle exec rubocop
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
The specs run against a local HTTP server: the exact request body and signature of
|
|
383
|
+
every endpoint, API and HTTP errors, malformed JSON, timeouts, network and TLS
|
|
384
|
+
failures, and concurrent use.
|
|
385
|
+
|
|
386
|
+
## License
|
|
387
|
+
|
|
388
|
+
The MIT License (MIT). Please see [License File](LICENSE) for more information.
|
|
389
|
+
|
|
390
|
+
## Support
|
|
391
|
+
|
|
392
|
+
For support, please contact [support@tronzap.com](mailto:support@tronzap.com).
|