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
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Models
|
|
5
|
+
# A rate energy is delivered at for a direct recharge.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] duration
|
|
8
|
+
# @return [Integer] rental duration in hours
|
|
9
|
+
# @!attribute [r] min_energy
|
|
10
|
+
# @return [Integer] smallest energy amount this rate applies to
|
|
11
|
+
# @!attribute [r] max_energy
|
|
12
|
+
# @return [Integer] largest energy amount this rate applies to
|
|
13
|
+
# @!attribute [r] price
|
|
14
|
+
# @return [BigDecimal] price per unit of energy, in TRX
|
|
15
|
+
# @!attribute [r] price_32k
|
|
16
|
+
# @return [BigDecimal] price of 32 000 energy, in TRX
|
|
17
|
+
# @!attribute [r] price_65k
|
|
18
|
+
# @return [BigDecimal] price of 65 000 energy, in TRX
|
|
19
|
+
# @!attribute [r] price_131k
|
|
20
|
+
# @return [BigDecimal] price of 131 000 energy, in TRX
|
|
21
|
+
DirectRechargeRate = Data.define(:duration, :min_energy, :max_energy,
|
|
22
|
+
:price, :price_32k, :price_65k, :price_131k) do
|
|
23
|
+
# @api private
|
|
24
|
+
def self.from_api(value)
|
|
25
|
+
data = Coerce.object(value, "direct recharge rate")
|
|
26
|
+
new(
|
|
27
|
+
duration: Coerce.integer(data["duration"], "duration"),
|
|
28
|
+
min_energy: Coerce.integer(data["min_energy"], "min_energy"),
|
|
29
|
+
max_energy: Coerce.integer(data["max_energy"], "max_energy"),
|
|
30
|
+
price: Coerce.decimal(data["price"], "price"),
|
|
31
|
+
price_32k: Coerce.decimal(data["price_32k"], "price_32k"),
|
|
32
|
+
price_65k: Coerce.decimal(data["price_65k"], "price_65k"),
|
|
33
|
+
price_131k: Coerce.decimal(data["price_131k"], "price_131k")
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Models
|
|
5
|
+
# An energy price tier. Energy is priced per unit.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] duration
|
|
8
|
+
# @return [Integer] rental duration in hours
|
|
9
|
+
# @!attribute [r] min_amount
|
|
10
|
+
# @return [Integer] smallest amount this tier applies to
|
|
11
|
+
# @!attribute [r] max_amount
|
|
12
|
+
# @return [Integer] largest amount this tier applies to
|
|
13
|
+
# @!attribute [r] min_energy
|
|
14
|
+
# @return [Integer] smallest energy amount this tier applies to
|
|
15
|
+
# @!attribute [r] max_energy
|
|
16
|
+
# @return [Integer] largest energy amount this tier applies to
|
|
17
|
+
# @!attribute [r] price
|
|
18
|
+
# @return [BigDecimal] price per unit of energy, in TRX
|
|
19
|
+
# @!attribute [r] price_32k
|
|
20
|
+
# @return [BigDecimal] price of 32 000 energy, in TRX
|
|
21
|
+
# @!attribute [r] price_65k
|
|
22
|
+
# @return [BigDecimal] price of 65 000 energy, in TRX
|
|
23
|
+
# @!attribute [r] price_131k
|
|
24
|
+
# @return [BigDecimal] price of 131 000 energy, in TRX
|
|
25
|
+
EnergyRate = Data.define(:duration, :min_amount, :max_amount, :min_energy, :max_energy,
|
|
26
|
+
:price, :price_32k, :price_65k, :price_131k) do
|
|
27
|
+
# @api private
|
|
28
|
+
def self.from_api(value)
|
|
29
|
+
data = Coerce.object(value, "energy rate")
|
|
30
|
+
new(
|
|
31
|
+
duration: Coerce.integer(data["duration"], "duration"),
|
|
32
|
+
min_amount: Coerce.integer(data["min_amount"], "min_amount"),
|
|
33
|
+
max_amount: Coerce.integer(data["max_amount"], "max_amount"),
|
|
34
|
+
min_energy: Coerce.integer(data["min_energy"], "min_energy"),
|
|
35
|
+
max_energy: Coerce.integer(data["max_energy"], "max_energy"),
|
|
36
|
+
price: Coerce.decimal(data["price"], "price"),
|
|
37
|
+
price_32k: Coerce.decimal(data["price_32k"], "price_32k"),
|
|
38
|
+
price_65k: Coerce.decimal(data["price_65k"], "price_65k"),
|
|
39
|
+
price_131k: Coerce.decimal(data["price_131k"], "price_131k")
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
# Value objects nested in API responses, and the symbols enum-like fields take.
|
|
5
|
+
#
|
|
6
|
+
# Enum-like fields are symbols. A value this SDK version does not recognise is reported as +:unknown+.
|
|
7
|
+
module Models
|
|
8
|
+
# Services a transaction is created for.
|
|
9
|
+
SERVICES = %i[energy bandwidth resource_bundle activate_address].freeze
|
|
10
|
+
|
|
11
|
+
# Transaction states: +:new+ → +:pending+ → +:success+ or +:failed+.
|
|
12
|
+
TRANSACTION_STATUSES = %i[new pending success failed].freeze
|
|
13
|
+
|
|
14
|
+
# What an AML check screens: a wallet address or a transaction hash.
|
|
15
|
+
AML_CHECK_TYPES = %i[address hash].freeze
|
|
16
|
+
|
|
17
|
+
# Directions of a screened transaction: incoming (+:deposit+) or outgoing (+:withdrawal+) funds.
|
|
18
|
+
AML_DIRECTIONS = %i[deposit withdrawal].freeze
|
|
19
|
+
|
|
20
|
+
# AML check states.
|
|
21
|
+
AML_STATUSES = %i[pending processing completed failed].freeze
|
|
22
|
+
|
|
23
|
+
# AML risk levels.
|
|
24
|
+
AML_RISK_LEVELS = %i[low medium high].freeze
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Models
|
|
5
|
+
# The resources a transaction buys. A resource the transaction does not include is 0.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] energy
|
|
8
|
+
# @return [Integer] energy bought
|
|
9
|
+
# @!attribute [r] bandwidth
|
|
10
|
+
# @return [Integer] bandwidth bought
|
|
11
|
+
ResourceAmounts = Data.define(:energy, :bandwidth)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Models
|
|
5
|
+
# A timestamp as the API sent it, together with its parsed value.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] raw
|
|
8
|
+
# @return [String] the text exactly as the API sent it
|
|
9
|
+
# @!attribute [r] value
|
|
10
|
+
# @return [Time, nil] the parsed time, or +nil+ when {raw} is in a format the SDK does not recognise
|
|
11
|
+
Timestamp = Data.define(:raw, :value) do
|
|
12
|
+
# Parses a timestamp in any of the formats the API emits: RFC 3339 with or without an offset, a
|
|
13
|
+
# space-separated date and time, a bare date, or Unix seconds. Times without an offset are read as UTC.
|
|
14
|
+
#
|
|
15
|
+
# @param raw [String]
|
|
16
|
+
# @return [Timestamp]
|
|
17
|
+
def self.parse(raw)
|
|
18
|
+
raise ArgumentError, "raw must be a String" unless raw.is_a?(String)
|
|
19
|
+
|
|
20
|
+
new(raw: raw.dup.freeze, value: parse_time(raw.strip))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.parse_time(text)
|
|
24
|
+
if (match = /\A(\d{4})-(\d{2})-(\d{2})[T\ ](\d{2}):(\d{2})
|
|
25
|
+
(?::(\d{2}(?:\.\d+)?))?\s*(Z|[+-]\d{2}(?::?\d{2})?)?\z/ix.match(text))
|
|
26
|
+
date_time(match)
|
|
27
|
+
elsif (match = /\A(\d{4})-(\d{2})-(\d{2})\z/.match(text))
|
|
28
|
+
calendar_day(Time.utc(*match.captures.map(&:to_i)), *match.captures)
|
|
29
|
+
elsif /\A\d{1,12}\z/.match?(text)
|
|
30
|
+
Time.at(text.to_i).utc
|
|
31
|
+
end
|
|
32
|
+
rescue ArgumentError
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.date_time(match)
|
|
37
|
+
year, month, day, hour, minute, second, zone = match.captures
|
|
38
|
+
zone = "+00:00" if zone.nil? || zone.casecmp?("z")
|
|
39
|
+
zone = "#{zone}:00" if zone.length == 3
|
|
40
|
+
time = Time.new(year.to_i, month.to_i, day.to_i, hour.to_i, minute.to_i, Rational(second || "0"), zone)
|
|
41
|
+
calendar_day(time, year, month, day)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Time rolls an impossible date such as February 30 over into the next month instead of rejecting it.
|
|
45
|
+
def self.calendar_day(time, year, month, day)
|
|
46
|
+
time if [time.year, time.month, time.day] == [year.to_i, month.to_i, day.to_i]
|
|
47
|
+
end
|
|
48
|
+
private_class_method :parse_time, :date_time, :calendar_day
|
|
49
|
+
|
|
50
|
+
# @return [String] the parsed time in ISO 8601, or the raw text when it could not be parsed
|
|
51
|
+
def to_s
|
|
52
|
+
return raw unless value
|
|
53
|
+
|
|
54
|
+
value.iso8601(value.subsec.zero? ? 0 : 6)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Models
|
|
5
|
+
# The parameters a transaction was created with.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] address
|
|
8
|
+
# @return [String] the TRON address that receives the resources
|
|
9
|
+
# @!attribute [r] duration
|
|
10
|
+
# @return [Integer] rental duration in hours
|
|
11
|
+
# @!attribute [r] amounts
|
|
12
|
+
# @return [ResourceAmounts] the resources the transaction buys
|
|
13
|
+
# @!attribute [r] activate_address
|
|
14
|
+
# @return [Boolean] whether the transaction also activates the address
|
|
15
|
+
TransactionParams = Data.define(:address, :duration, :amounts, :activate_address) do
|
|
16
|
+
# @api private
|
|
17
|
+
def self.from_api(value, service)
|
|
18
|
+
data = Coerce.object(value, "params")
|
|
19
|
+
new(
|
|
20
|
+
address: Coerce.text(data["address"], "params.address"),
|
|
21
|
+
duration: Coerce.integer(data["duration"], "params.duration"),
|
|
22
|
+
amounts: amounts(data, service),
|
|
23
|
+
activate_address: Coerce.boolean(data["activate_address"], "params.activate_address")
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Older transactions carry params.amount / params.energy_amount instead of params.amounts.
|
|
28
|
+
def self.amounts(data, service)
|
|
29
|
+
amounts = Coerce.object(data["amounts"], "params.amounts")
|
|
30
|
+
energy = Coerce.integer(amounts["energy"], "params.amounts.energy")
|
|
31
|
+
bandwidth = Coerce.integer(amounts["bandwidth"], "params.amounts.bandwidth")
|
|
32
|
+
if energy.zero? && bandwidth.zero?
|
|
33
|
+
energy = Coerce.integer(data["energy_amount"], "params.energy_amount")
|
|
34
|
+
amount = Coerce.integer(data["amount"], "params.amount")
|
|
35
|
+
if service == :bandwidth
|
|
36
|
+
bandwidth = amount
|
|
37
|
+
elsif energy.zero?
|
|
38
|
+
energy = amount
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
ResourceAmounts.new(energy: energy, bandwidth: bandwidth)
|
|
42
|
+
end
|
|
43
|
+
private_class_method :amounts
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Requests
|
|
5
|
+
# A TRON address to activate.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] address
|
|
8
|
+
# @return [String] the TRON address to activate
|
|
9
|
+
# @!attribute [r] external_id
|
|
10
|
+
# @return [String, nil] your own ID for the transaction, to look it up with {CheckTransaction.by_external_id}
|
|
11
|
+
AddressActivation = Data.define(:address, :external_id) do
|
|
12
|
+
# @param address [String]
|
|
13
|
+
# @param external_id [String, nil]
|
|
14
|
+
# @raise [ArgumentError]
|
|
15
|
+
def initialize(address:, external_id: nil)
|
|
16
|
+
super(
|
|
17
|
+
address: Validation.string(address, "address"),
|
|
18
|
+
external_id: Validation.optional_string(external_id, "external_id")
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @api private
|
|
23
|
+
def body
|
|
24
|
+
Validation.transaction("activate_address", { "address" => address }, external_id)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Requests
|
|
5
|
+
# An address or a transaction hash to screen.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] type
|
|
8
|
+
# @return [Symbol] what to screen, one of {Models::AML_CHECK_TYPES}
|
|
9
|
+
# @!attribute [r] network
|
|
10
|
+
# @return [String] the network code, for example +TRX+, +BTC+ or +ETH+
|
|
11
|
+
# @!attribute [r] address
|
|
12
|
+
# @return [String] the wallet address
|
|
13
|
+
# @!attribute [r] transaction_hash
|
|
14
|
+
# @return [String, nil] the transaction hash, required when {type} is +:hash+
|
|
15
|
+
# @!attribute [r] direction
|
|
16
|
+
# @return [Symbol, nil] the transaction direction for a hash check, one of {Models::AML_DIRECTIONS}
|
|
17
|
+
AmlCheck = Data.define(:type, :network, :address, :transaction_hash, :direction) do
|
|
18
|
+
# @param type [Symbol, String] +:address+ or +:hash+
|
|
19
|
+
# @param network [String]
|
|
20
|
+
# @param address [String]
|
|
21
|
+
# @param transaction_hash [String, nil]
|
|
22
|
+
# @param direction [Symbol, String, nil] +:deposit+ or +:withdrawal+
|
|
23
|
+
# @raise [ArgumentError]
|
|
24
|
+
def initialize(type:, network:, address:, transaction_hash: nil, direction: nil)
|
|
25
|
+
type = Validation.one_of(type, Models::AML_CHECK_TYPES, "type")
|
|
26
|
+
transaction_hash = Validation.optional_string(transaction_hash, "transaction_hash")
|
|
27
|
+
raise ArgumentError, "transaction_hash is required for a hash check" if type == :hash && !transaction_hash
|
|
28
|
+
|
|
29
|
+
super(
|
|
30
|
+
type: type,
|
|
31
|
+
network: Validation.string(network, "network"),
|
|
32
|
+
address: Validation.string(address, "address"),
|
|
33
|
+
transaction_hash: transaction_hash,
|
|
34
|
+
direction: Validation.optional_one_of(direction, Models::AML_DIRECTIONS, "direction")
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Screens a wallet address.
|
|
39
|
+
#
|
|
40
|
+
# @param network [String] the network code, for example +TRX+
|
|
41
|
+
# @param address [String]
|
|
42
|
+
# @return [AmlCheck]
|
|
43
|
+
def self.for_address(network, address)
|
|
44
|
+
new(type: :address, network: network, address: address)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Screens a transaction.
|
|
48
|
+
#
|
|
49
|
+
# @param network [String] the network code, for example +BTC+
|
|
50
|
+
# @param address [String]
|
|
51
|
+
# @param transaction_hash [String]
|
|
52
|
+
# @param direction [Symbol, String, nil] +:deposit+ or +:withdrawal+
|
|
53
|
+
# @return [AmlCheck]
|
|
54
|
+
def self.for_hash(network, address, transaction_hash, direction: nil)
|
|
55
|
+
new(type: :hash, network: network, address: address, transaction_hash: transaction_hash,
|
|
56
|
+
direction: direction)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @api private
|
|
60
|
+
def body
|
|
61
|
+
body = { "type" => type.name, "network" => network, "address" => address }
|
|
62
|
+
body["hash"] = transaction_hash if transaction_hash
|
|
63
|
+
body["direction"] = direction.name if direction
|
|
64
|
+
body
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Requests
|
|
5
|
+
# A page of AML check history to return.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] page
|
|
8
|
+
# @return [Integer] the page number, starting at 1
|
|
9
|
+
# @!attribute [r] per_page
|
|
10
|
+
# @return [Integer] the page size
|
|
11
|
+
# @!attribute [r] status
|
|
12
|
+
# @return [Symbol, nil] only checks in this state, one of {Models::AML_STATUSES}, or all checks when +nil+
|
|
13
|
+
AmlHistory = Data.define(:page, :per_page, :status) do
|
|
14
|
+
# @param page [Integer]
|
|
15
|
+
# @param per_page [Integer]
|
|
16
|
+
# @param status [Symbol, String, nil]
|
|
17
|
+
# @raise [ArgumentError]
|
|
18
|
+
def initialize(page: 1, per_page: 10, status: nil)
|
|
19
|
+
super(
|
|
20
|
+
page: Validation.positive_integer(page, "page"),
|
|
21
|
+
per_page: Validation.positive_integer(per_page, "per_page"),
|
|
22
|
+
status: Validation.optional_one_of(status, Models::AML_STATUSES, "status")
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
def body
|
|
28
|
+
body = { "page" => page, "per_page" => per_page }
|
|
29
|
+
body["status"] = status.name if status
|
|
30
|
+
body
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Requests
|
|
5
|
+
# A bandwidth purchase. Bandwidth is rented for one hour.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] address
|
|
8
|
+
# @return [String] the TRON address that receives the bandwidth
|
|
9
|
+
# @!attribute [r] bandwidth
|
|
10
|
+
# @return [Integer] the amount of bandwidth to buy
|
|
11
|
+
# @!attribute [r] external_id
|
|
12
|
+
# @return [String, nil] your own ID for the transaction, to look it up with {CheckTransaction.by_external_id}
|
|
13
|
+
BandwidthTransaction = Data.define(:address, :bandwidth, :external_id) do
|
|
14
|
+
# @param address [String]
|
|
15
|
+
# @param bandwidth [Integer]
|
|
16
|
+
# @param external_id [String, nil]
|
|
17
|
+
# @raise [ArgumentError]
|
|
18
|
+
def initialize(address:, bandwidth:, external_id: nil)
|
|
19
|
+
super(
|
|
20
|
+
address: Validation.string(address, "address"),
|
|
21
|
+
bandwidth: Validation.positive_integer(bandwidth, "bandwidth"),
|
|
22
|
+
external_id: Validation.optional_string(external_id, "external_id")
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
def body
|
|
28
|
+
params = { "address" => address, "amounts" => { "bandwidth" => bandwidth }, "duration" => 1 }
|
|
29
|
+
Validation.transaction("bandwidth", params, external_id)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Requests
|
|
5
|
+
# An energy purchase to price.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] address
|
|
8
|
+
# @return [String] the TRON address that would receive the energy
|
|
9
|
+
# @!attribute [r] energy
|
|
10
|
+
# @return [Integer] the amount of energy
|
|
11
|
+
# @!attribute [r] duration
|
|
12
|
+
# @return [Integer] rental duration in hours, one of the durations {Client#get_services} lists
|
|
13
|
+
Calculate = Data.define(:address, :energy, :duration) do
|
|
14
|
+
# @param address [String]
|
|
15
|
+
# @param energy [Integer]
|
|
16
|
+
# @param duration [Integer]
|
|
17
|
+
# @raise [ArgumentError]
|
|
18
|
+
def initialize(address:, energy:, duration: 1)
|
|
19
|
+
super(
|
|
20
|
+
address: Validation.string(address, "address"),
|
|
21
|
+
energy: Validation.positive_integer(energy, "energy"),
|
|
22
|
+
duration: Validation.positive_integer(duration, "duration")
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
def body
|
|
28
|
+
{ "address" => address, "amount" => energy, "duration" => duration }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Requests
|
|
5
|
+
# The transaction to look up, by its TronZap ID, your external ID, or both.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] id
|
|
8
|
+
# @return [String, nil] the transaction ID assigned by TronZap
|
|
9
|
+
# @!attribute [r] external_id
|
|
10
|
+
# @return [String, nil] the external ID you passed when creating the transaction
|
|
11
|
+
CheckTransaction = Data.define(:id, :external_id) do
|
|
12
|
+
# @param id [String, nil]
|
|
13
|
+
# @param external_id [String, nil]
|
|
14
|
+
# @raise [ArgumentError] when neither is given
|
|
15
|
+
def initialize(id: nil, external_id: nil)
|
|
16
|
+
id = Validation.optional_string(id, "id")
|
|
17
|
+
external_id = Validation.optional_string(external_id, "external_id")
|
|
18
|
+
raise ArgumentError, "either id or external_id is required" if id.nil? && external_id.nil?
|
|
19
|
+
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Looks a transaction up by its TronZap ID.
|
|
24
|
+
#
|
|
25
|
+
# @param id [String]
|
|
26
|
+
# @return [CheckTransaction]
|
|
27
|
+
def self.by_id(id)
|
|
28
|
+
new(id: id)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Looks a transaction up by the external ID you passed when creating it.
|
|
32
|
+
#
|
|
33
|
+
# @param external_id [String]
|
|
34
|
+
# @return [CheckTransaction]
|
|
35
|
+
def self.by_external_id(external_id)
|
|
36
|
+
new(external_id: external_id)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @api private
|
|
40
|
+
def body
|
|
41
|
+
body = {}
|
|
42
|
+
body["id"] = id if id
|
|
43
|
+
body["external_id"] = external_id if external_id
|
|
44
|
+
body
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Requests
|
|
5
|
+
# An energy purchase.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] address
|
|
8
|
+
# @return [String] the TRON address that receives the energy
|
|
9
|
+
# @!attribute [r] energy
|
|
10
|
+
# @return [Integer] the amount of energy to buy
|
|
11
|
+
# @!attribute [r] duration
|
|
12
|
+
# @return [Integer] rental duration in hours, one of the durations {Client#get_services} lists
|
|
13
|
+
# @!attribute [r] external_id
|
|
14
|
+
# @return [String, nil] your own ID for the transaction, to look it up with {CheckTransaction.by_external_id}
|
|
15
|
+
# @!attribute [r] activate_address
|
|
16
|
+
# @return [Boolean] whether to activate the address in the same transaction
|
|
17
|
+
EnergyTransaction = Data.define(:address, :energy, :duration, :external_id, :activate_address) do
|
|
18
|
+
# @param address [String]
|
|
19
|
+
# @param energy [Integer]
|
|
20
|
+
# @param duration [Integer]
|
|
21
|
+
# @param external_id [String, nil]
|
|
22
|
+
# @param activate_address [Boolean]
|
|
23
|
+
# @raise [ArgumentError]
|
|
24
|
+
def initialize(address:, energy:, duration: 1, external_id: nil, activate_address: false)
|
|
25
|
+
super(
|
|
26
|
+
address: Validation.string(address, "address"),
|
|
27
|
+
energy: Validation.positive_integer(energy, "energy"),
|
|
28
|
+
duration: Validation.positive_integer(duration, "duration"),
|
|
29
|
+
external_id: Validation.optional_string(external_id, "external_id"),
|
|
30
|
+
activate_address: Validation.boolean(activate_address, "activate_address")
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @api private
|
|
35
|
+
def body
|
|
36
|
+
params = { "address" => address, "amounts" => { "energy" => energy }, "duration" => duration }
|
|
37
|
+
params["activate_address"] = true if activate_address
|
|
38
|
+
Validation.transaction("energy", params, external_id)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
# The USDT (TRC20) contract address. The API estimates a transfer of this token when
|
|
5
|
+
# {Requests::EstimateEnergy#contract_address} is not set.
|
|
6
|
+
USDT_CONTRACT_ADDRESS = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
|
|
7
|
+
|
|
8
|
+
module Requests
|
|
9
|
+
# A token transfer to estimate the energy for.
|
|
10
|
+
#
|
|
11
|
+
# @!attribute [r] from_address
|
|
12
|
+
# @return [String] the sender's TRON address
|
|
13
|
+
# @!attribute [r] to_address
|
|
14
|
+
# @return [String] the recipient's TRON address
|
|
15
|
+
# @!attribute [r] contract_address
|
|
16
|
+
# @return [String, nil] the token contract address. When not set the API estimates a USDT (TRC20) transfer.
|
|
17
|
+
EstimateEnergy = Data.define(:from_address, :to_address, :contract_address) do
|
|
18
|
+
# @param from_address [String]
|
|
19
|
+
# @param to_address [String]
|
|
20
|
+
# @param contract_address [String, nil]
|
|
21
|
+
# @raise [ArgumentError]
|
|
22
|
+
def initialize(from_address:, to_address:, contract_address: nil)
|
|
23
|
+
super(
|
|
24
|
+
from_address: Validation.string(from_address, "from_address"),
|
|
25
|
+
to_address: Validation.string(to_address, "to_address"),
|
|
26
|
+
contract_address: Validation.optional_string(contract_address, "contract_address")
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @api private
|
|
31
|
+
def body
|
|
32
|
+
body = { "from_address" => from_address, "to_address" => to_address }
|
|
33
|
+
body["contract_address"] = contract_address if contract_address
|
|
34
|
+
body
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
module Requests
|
|
5
|
+
# A purchase of energy and bandwidth in one transaction.
|
|
6
|
+
#
|
|
7
|
+
# @!attribute [r] address
|
|
8
|
+
# @return [String] the TRON address that receives the resources
|
|
9
|
+
# @!attribute [r] energy
|
|
10
|
+
# @return [Integer] the amount of energy to buy
|
|
11
|
+
# @!attribute [r] bandwidth
|
|
12
|
+
# @return [Integer] the amount of bandwidth to buy
|
|
13
|
+
# @!attribute [r] duration
|
|
14
|
+
# @return [Integer] rental duration in hours
|
|
15
|
+
# @!attribute [r] external_id
|
|
16
|
+
# @return [String, nil] your own ID for the transaction, to look it up with {CheckTransaction.by_external_id}
|
|
17
|
+
# @!attribute [r] activate_address
|
|
18
|
+
# @return [Boolean] whether to activate the address in the same transaction
|
|
19
|
+
ResourceBundleTransaction = Data.define(:address, :energy, :bandwidth, :duration, :external_id,
|
|
20
|
+
:activate_address) do
|
|
21
|
+
# @param address [String]
|
|
22
|
+
# @param energy [Integer]
|
|
23
|
+
# @param bandwidth [Integer]
|
|
24
|
+
# @param duration [Integer]
|
|
25
|
+
# @param external_id [String, nil]
|
|
26
|
+
# @param activate_address [Boolean]
|
|
27
|
+
# @raise [ArgumentError]
|
|
28
|
+
def initialize(address:, energy:, bandwidth:, duration: 1, external_id: nil, activate_address: false)
|
|
29
|
+
super(
|
|
30
|
+
address: Validation.string(address, "address"),
|
|
31
|
+
energy: Validation.positive_integer(energy, "energy"),
|
|
32
|
+
bandwidth: Validation.positive_integer(bandwidth, "bandwidth"),
|
|
33
|
+
duration: Validation.positive_integer(duration, "duration"),
|
|
34
|
+
external_id: Validation.optional_string(external_id, "external_id"),
|
|
35
|
+
activate_address: Validation.boolean(activate_address, "activate_address")
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @api private
|
|
40
|
+
def body
|
|
41
|
+
params = {
|
|
42
|
+
"address" => address,
|
|
43
|
+
"amounts" => { "energy" => energy, "bandwidth" => bandwidth },
|
|
44
|
+
"duration" => duration
|
|
45
|
+
}
|
|
46
|
+
params["activate_address"] = true if activate_address
|
|
47
|
+
Validation.transaction("resource_bundle", params, external_id)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tronzap
|
|
4
|
+
# Parameters of {Client} calls. A request validates its values when it is created, so an invalid one raises
|
|
5
|
+
# +ArgumentError+ and never reaches the API.
|
|
6
|
+
module Requests
|
|
7
|
+
# @api private
|
|
8
|
+
module Validation
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def string(value, name)
|
|
12
|
+
raise ArgumentError, "#{name} is required" unless value.is_a?(String) && !value.strip.empty?
|
|
13
|
+
|
|
14
|
+
value.dup.freeze
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def optional_string(value, name)
|
|
18
|
+
return nil if value.nil?
|
|
19
|
+
raise ArgumentError, "#{name} must be a non-blank String when set" unless value.is_a?(String) &&
|
|
20
|
+
!value.strip.empty?
|
|
21
|
+
|
|
22
|
+
value.dup.freeze
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def positive_integer(value, name)
|
|
26
|
+
raise ArgumentError, "#{name} must be a positive Integer, got #{value.inspect}" unless value.is_a?(Integer) &&
|
|
27
|
+
value.positive?
|
|
28
|
+
|
|
29
|
+
value
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def boolean(value, name)
|
|
33
|
+
raise ArgumentError, "#{name} must be true or false, got #{value.inspect}" unless [true, false].include?(value)
|
|
34
|
+
|
|
35
|
+
value
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def one_of(value, allowed, name)
|
|
39
|
+
symbol = value.is_a?(String) ? allowed.find { |item| item.name == value } : value
|
|
40
|
+
return symbol if allowed.include?(symbol)
|
|
41
|
+
|
|
42
|
+
raise ArgumentError, "#{name} must be one of #{allowed.map(&:inspect).join(", ")}, got #{value.inspect}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def optional_one_of(value, allowed, name)
|
|
46
|
+
value.nil? ? nil : one_of(value, allowed, name)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def transaction(service, params, external_id)
|
|
50
|
+
body = { "service" => service, "params" => params }
|
|
51
|
+
body["external_id"] = external_id if external_id
|
|
52
|
+
body
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|