gasfree_sdk 0.1.0 → 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 +4 -4
- data/.rubocop.yml +28 -3
- data/CHANGELOG.md +58 -3
- data/LICENSE.txt +119 -21
- data/README.md +211 -56
- data/examples/basic_usage.rb +26 -10
- data/examples/demo.rb +12 -10
- data/examples/simple_usage_example.rb +107 -0
- data/examples/test_tron_signer.rb +122 -0
- data/lib/gasfree_sdk/base58.rb +65 -0
- data/lib/gasfree_sdk/client.rb +184 -14
- data/lib/gasfree_sdk/crypto.rb +111 -0
- data/lib/gasfree_sdk/models/token.rb +4 -4
- data/lib/gasfree_sdk/models/transfer_response.rb +19 -19
- data/lib/gasfree_sdk/tron_eip712_signer.rb +260 -0
- data/lib/gasfree_sdk/types.rb +25 -2
- data/lib/gasfree_sdk/version.rb +1 -1
- data/lib/gasfree_sdk.rb +3 -0
- metadata +21 -2
data/lib/gasfree_sdk/client.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require "base64"
|
4
4
|
require "openssl"
|
5
5
|
require "time"
|
6
|
+
require "uri"
|
6
7
|
|
7
8
|
module GasfreeSdk
|
8
9
|
# Client for interacting with the GasFree API
|
@@ -17,45 +18,50 @@ module GasfreeSdk
|
|
17
18
|
f.request :retry, GasfreeSdk.config.retry_options
|
18
19
|
f.response :json
|
19
20
|
f.adapter Faraday.default_adapter
|
21
|
+
f.response :logger, ::Logger.new($stdout), bodies: true if ENV["DEBUG_GASFREE_SDK"]
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
# Get all supported tokens
|
24
26
|
# @return [Array<Token>] List of supported tokens
|
25
27
|
def tokens
|
26
|
-
response = get("
|
27
|
-
response.dig("data", "tokens").map
|
28
|
+
response = get("api/v1/config/token/all")
|
29
|
+
response.dig("data", "tokens").map do |token|
|
30
|
+
Models::Token.new(transform_token_data(token))
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
# Get all service providers
|
31
35
|
# @return [Array<Provider>] List of service providers
|
32
36
|
def providers
|
33
|
-
response = get("
|
34
|
-
response.dig("data", "providers").map
|
37
|
+
response = get("api/v1/config/provider/all")
|
38
|
+
response.dig("data", "providers").map do |provider|
|
39
|
+
Models::Provider.new(transform_provider_data(provider))
|
40
|
+
end
|
35
41
|
end
|
36
42
|
|
37
43
|
# Get GasFree account info
|
38
44
|
# @param account_address [String] The user's EOA address
|
39
45
|
# @return [GasFreeAddress] The GasFree account info
|
40
46
|
def address(account_address)
|
41
|
-
response = get("
|
42
|
-
Models::GasFreeAddress.new(response["data"])
|
47
|
+
response = get("api/v1/address/#{account_address}")
|
48
|
+
Models::GasFreeAddress.new(transform_address_data(response["data"]))
|
43
49
|
end
|
44
50
|
|
45
51
|
# Submit a GasFree transfer
|
46
52
|
# @param request [TransferRequest] The transfer request
|
47
53
|
# @return [TransferResponse] The transfer response
|
48
54
|
def submit_transfer(request)
|
49
|
-
response = post("
|
50
|
-
Models::TransferResponse.new(response["data"])
|
55
|
+
response = post("api/v1/gasfree/submit", transform_transfer_request_data(request.to_h))
|
56
|
+
Models::TransferResponse.new(transform_transfer_response_data(response["data"]))
|
51
57
|
end
|
52
58
|
|
53
59
|
# Get transfer status
|
54
60
|
# @param trace_id [String] The transfer trace ID
|
55
61
|
# @return [TransferResponse] The transfer status
|
56
62
|
def transfer_status(trace_id)
|
57
|
-
response = get("
|
58
|
-
Models::TransferResponse.new(response["data"])
|
63
|
+
response = get("api/v1/gasfree/#{trace_id}")
|
64
|
+
Models::TransferResponse.new(transform_transfer_response_data(response["data"]))
|
59
65
|
end
|
60
66
|
|
61
67
|
private
|
@@ -67,7 +73,7 @@ module GasfreeSdk
|
|
67
73
|
def get(path, params = {})
|
68
74
|
timestamp = Time.now.to_i
|
69
75
|
response = connection.get(path, params) do |req|
|
70
|
-
sign_request(req, "GET", path, timestamp)
|
76
|
+
sign_request(req, "GET", normalize_path(path), timestamp)
|
71
77
|
end
|
72
78
|
handle_response(response)
|
73
79
|
end
|
@@ -80,23 +86,40 @@ module GasfreeSdk
|
|
80
86
|
timestamp = Time.now.to_i
|
81
87
|
response = connection.post(path) do |req|
|
82
88
|
req.body = body
|
83
|
-
sign_request(req, "POST", path, timestamp)
|
89
|
+
sign_request(req, "POST", normalize_path(path), timestamp)
|
84
90
|
end
|
85
91
|
handle_response(response)
|
86
92
|
end
|
87
93
|
|
94
|
+
# Normalize path for signature calculation (needs leading slash)
|
95
|
+
# @param path [String] The API path
|
96
|
+
# @return [String] Normalized path
|
97
|
+
def normalize_path(path)
|
98
|
+
path.start_with?("/") ? path : "/#{path}"
|
99
|
+
end
|
100
|
+
|
88
101
|
# Sign an API request
|
89
102
|
# @param request [Faraday::Request] The request to sign
|
90
103
|
# @param method [String] HTTP method
|
91
104
|
# @param path [String] Request path
|
92
105
|
# @param timestamp [Integer] Request timestamp
|
93
|
-
def sign_request(request, method, path, timestamp)
|
106
|
+
def sign_request(request, method, path, timestamp) # rubocop:disable Metrics/AbcSize
|
94
107
|
api_key = GasfreeSdk.config.api_key
|
95
108
|
api_secret = GasfreeSdk.config.api_secret
|
96
109
|
|
97
110
|
raise AuthenticationError, "API key and secret are required" if api_key.nil? || api_secret.nil?
|
98
111
|
|
99
|
-
|
112
|
+
# Extract the base path from the endpoint URL
|
113
|
+
# For https://open-test.gasfree.io/nile/ the base path is /nile
|
114
|
+
endpoint_uri = URI(GasfreeSdk.config.api_endpoint)
|
115
|
+
base_path = endpoint_uri.path.chomp("/") # Remove trailing slash
|
116
|
+
|
117
|
+
# Combine base path with API path for signature
|
118
|
+
# e.g., /nile + /api/v1/config/token/all = /nile/api/v1/config/token/all
|
119
|
+
full_path = "#{base_path}#{path}"
|
120
|
+
|
121
|
+
# According to GasFree API documentation, the message format is: method + path + timestamp
|
122
|
+
message = "#{method}#{full_path}#{timestamp}"
|
100
123
|
signature = Base64.strict_encode64(
|
101
124
|
OpenSSL::HMAC.digest("SHA256", api_secret, message)
|
102
125
|
)
|
@@ -120,5 +143,152 @@ module GasfreeSdk
|
|
120
143
|
message: data["message"]
|
121
144
|
)
|
122
145
|
end
|
146
|
+
|
147
|
+
# Transform transfer request data from model format to API format
|
148
|
+
# @param request_data [Hash] Transfer request data from model
|
149
|
+
# @return [Hash] Transformed transfer request data for API
|
150
|
+
def transform_transfer_request_data(request_data)
|
151
|
+
{
|
152
|
+
"token" => request_data[:token],
|
153
|
+
"serviceProvider" => request_data[:service_provider], # snake_case to camelCase
|
154
|
+
"user" => request_data[:user],
|
155
|
+
"receiver" => request_data[:receiver],
|
156
|
+
"value" => request_data[:value],
|
157
|
+
"maxFee" => request_data[:max_fee], # snake_case to camelCase
|
158
|
+
"deadline" => request_data[:deadline],
|
159
|
+
"version" => request_data[:version],
|
160
|
+
"nonce" => request_data[:nonce],
|
161
|
+
"sig" => request_data[:sig]
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
# Transform token data from API format to model format
|
166
|
+
# @param token_data [Hash] Token data from API
|
167
|
+
# @return [Hash] Transformed token data
|
168
|
+
def transform_token_data(token_data)
|
169
|
+
{
|
170
|
+
token_address: token_data["tokenAddress"],
|
171
|
+
created_at: Types::JSON::Time.call(token_data["createdAt"]),
|
172
|
+
updated_at: Types::JSON::Time.call(token_data["updatedAt"]),
|
173
|
+
activate_fee: Types::JSON::Amount.call(token_data["activateFee"]),
|
174
|
+
transfer_fee: Types::JSON::Amount.call(token_data["transferFee"]),
|
175
|
+
supported: token_data["supported"],
|
176
|
+
symbol: token_data["symbol"],
|
177
|
+
decimal: token_data["decimal"]
|
178
|
+
}
|
179
|
+
end
|
180
|
+
|
181
|
+
# Transform provider data from API format to model format
|
182
|
+
# @param provider_data [Hash] Provider data from API
|
183
|
+
# @return [Hash] Transformed provider data
|
184
|
+
def transform_provider_data(provider_data)
|
185
|
+
{
|
186
|
+
address: provider_data["address"],
|
187
|
+
name: provider_data["name"],
|
188
|
+
icon: provider_data["icon"],
|
189
|
+
website: provider_data["website"],
|
190
|
+
config: transform_provider_config_data(provider_data["config"])
|
191
|
+
}
|
192
|
+
end
|
193
|
+
|
194
|
+
# Transform provider config data from API format to model format
|
195
|
+
# @param config_data [Hash] Provider config data from API
|
196
|
+
# @return [Hash] Transformed provider config data
|
197
|
+
def transform_provider_config_data(config_data)
|
198
|
+
{
|
199
|
+
max_pending_transfer: config_data["maxPendingTransfer"],
|
200
|
+
min_deadline_duration: config_data["minDeadlineDuration"],
|
201
|
+
max_deadline_duration: config_data["maxDeadlineDuration"],
|
202
|
+
default_deadline_duration: config_data["defaultDeadlineDuration"]
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
# Transform address data from API format to model format
|
207
|
+
# @param address_data [Hash] Address data from API
|
208
|
+
# @return [Hash] Transformed address data
|
209
|
+
def transform_address_data(address_data)
|
210
|
+
{
|
211
|
+
account_address: address_data["accountAddress"],
|
212
|
+
gas_free_address: address_data["gasFreeAddress"],
|
213
|
+
active: address_data["active"],
|
214
|
+
nonce: address_data["nonce"],
|
215
|
+
allow_submit: address_data["allowSubmit"],
|
216
|
+
assets: address_data["assets"]&.map { |asset| transform_asset_data(asset) } || []
|
217
|
+
}
|
218
|
+
end
|
219
|
+
|
220
|
+
# Transform asset data from API format to model format
|
221
|
+
# @param asset_data [Hash] Asset data from API
|
222
|
+
# @return [Hash] Transformed asset data
|
223
|
+
def transform_asset_data(asset_data)
|
224
|
+
{
|
225
|
+
token_address: asset_data["tokenAddress"],
|
226
|
+
token_symbol: asset_data["tokenSymbol"],
|
227
|
+
activate_fee: Types::JSON::Amount.call(asset_data["activateFee"]),
|
228
|
+
transfer_fee: Types::JSON::Amount.call(asset_data["transferFee"]),
|
229
|
+
decimal: asset_data["decimal"],
|
230
|
+
frozen: Types::JSON::Amount.call(asset_data["frozen"])
|
231
|
+
}
|
232
|
+
end
|
233
|
+
|
234
|
+
# Transform transfer response data from API format to model format
|
235
|
+
# @param response_data [Hash] Transfer response data from API
|
236
|
+
# @return [Hash] Transformed transfer response data
|
237
|
+
def transform_transfer_response_data(response_data)
|
238
|
+
basic_fields = extract_basic_transfer_fields(response_data)
|
239
|
+
transaction_fields = extract_transaction_fields(response_data)
|
240
|
+
|
241
|
+
basic_fields.merge(transaction_fields).compact
|
242
|
+
end
|
243
|
+
|
244
|
+
# Extract basic transfer fields from response data
|
245
|
+
# @param response_data [Hash] Transfer response data from API
|
246
|
+
# @return [Hash] Basic transfer fields
|
247
|
+
def extract_basic_transfer_fields(response_data)
|
248
|
+
{
|
249
|
+
id: response_data["id"],
|
250
|
+
created_at: get_field_value(response_data, "createdAt", "created_at"),
|
251
|
+
updated_at: get_field_value(response_data, "updatedAt", "updated_at"),
|
252
|
+
account_address: get_field_value(response_data, "accountAddress", "account_address"),
|
253
|
+
gas_free_address: get_field_value(response_data, "gasFreeAddress", "gas_free_address"),
|
254
|
+
provider_address: get_field_value(response_data, "providerAddress", "provider_address"),
|
255
|
+
target_address: get_field_value(response_data, "targetAddress", "target_address"),
|
256
|
+
token_address: get_field_value(response_data, "tokenAddress", "token_address"),
|
257
|
+
amount: response_data["amount"],
|
258
|
+
max_fee: get_field_value(response_data, "maxFee", "max_fee"),
|
259
|
+
signature: response_data["signature"],
|
260
|
+
nonce: response_data["nonce"],
|
261
|
+
expired_at: get_field_value(response_data, "expiredAt", "expired_at"),
|
262
|
+
state: response_data["state"]
|
263
|
+
}
|
264
|
+
end
|
265
|
+
|
266
|
+
# Extract transaction-related fields from response data
|
267
|
+
# @param response_data [Hash] Transfer response data from API
|
268
|
+
# @return [Hash] Transaction fields
|
269
|
+
def extract_transaction_fields(response_data)
|
270
|
+
{
|
271
|
+
estimated_activate_fee: get_field_value(response_data, "estimatedActivateFee", "estimated_activate_fee"),
|
272
|
+
estimated_transfer_fee: get_field_value(response_data, "estimatedTransferFee", "estimated_transfer_fee"),
|
273
|
+
txn_hash: get_field_value(response_data, "txnHash", "txn_hash"),
|
274
|
+
txn_block_num: get_field_value(response_data, "txnBlockNum", "txn_block_num"),
|
275
|
+
txn_block_timestamp: get_field_value(response_data, "txnBlockTimestamp", "txn_block_timestamp"),
|
276
|
+
txn_state: get_field_value(response_data, "txnState", "txn_state"),
|
277
|
+
txn_activate_fee: get_field_value(response_data, "txnActivateFee", "txn_activate_fee"),
|
278
|
+
txn_transfer_fee: get_field_value(response_data, "txnTransferFee", "txn_transfer_fee"),
|
279
|
+
txn_total_fee: get_field_value(response_data, "txnTotalFee", "txn_total_fee"),
|
280
|
+
txn_amount: get_field_value(response_data, "txnAmount", "txn_amount"),
|
281
|
+
txn_total_cost: get_field_value(response_data, "txnTotalCost", "txn_total_cost")
|
282
|
+
}
|
283
|
+
end
|
284
|
+
|
285
|
+
# Get field value with fallback to snake_case version
|
286
|
+
# @param data [Hash] The data hash
|
287
|
+
# @param camel_case_key [String] The camelCase key
|
288
|
+
# @param snake_case_key [String] The snake_case key
|
289
|
+
# @return [Object] The field value
|
290
|
+
def get_field_value(data, camel_case_key, snake_case_key)
|
291
|
+
data[camel_case_key] || data[snake_case_key]
|
292
|
+
end
|
123
293
|
end
|
124
294
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "digest"
|
4
|
+
|
5
|
+
module GasfreeSdk
|
6
|
+
module Crypto
|
7
|
+
# Keccak256 implementation for TRON EIP-712 signatures
|
8
|
+
class Keccak256 < Digest::Class
|
9
|
+
PILN = [10, 7, 11, 17, 18, 3, 5, 16,
|
10
|
+
8, 21, 24, 4, 15, 23, 19, 13,
|
11
|
+
12, 2, 20, 14, 22, 9, 6, 1].freeze
|
12
|
+
|
13
|
+
ROTC = [1, 3, 6, 10, 15, 21, 28, 36,
|
14
|
+
45, 55, 2, 14, 27, 41, 56, 8,
|
15
|
+
25, 43, 62, 18, 39, 61, 20, 44].freeze
|
16
|
+
|
17
|
+
RNDC = [0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
|
18
|
+
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
|
19
|
+
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
|
20
|
+
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
21
|
+
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
|
22
|
+
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
|
23
|
+
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
|
24
|
+
0x8000000000008080, 0x0000000080000001, 0x8000000080008008].freeze
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@size = 256 / 8
|
28
|
+
@buffer = "".dup # Use dup to ensure it's not frozen
|
29
|
+
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def <<(string)
|
34
|
+
@buffer << string.to_s
|
35
|
+
self
|
36
|
+
end
|
37
|
+
alias update <<
|
38
|
+
|
39
|
+
def reset
|
40
|
+
@buffer = "".dup # Create a new unfrozen string instead of clearing
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def finish # rubocop:disable Metrics/AbcSize
|
45
|
+
string = Array.new 25, 0
|
46
|
+
width = 200 - (@size * 2)
|
47
|
+
padding = "\x01".dup
|
48
|
+
|
49
|
+
buffer = @buffer.dup # Create a copy to avoid modifying the original
|
50
|
+
buffer << padding << ("\0" * (width - (buffer.size % width)))
|
51
|
+
buffer[-1] = (buffer[-1].ord | 0x80).chr
|
52
|
+
|
53
|
+
0.step buffer.size - 1, width do |j|
|
54
|
+
quads = buffer[j, width].unpack "Q*"
|
55
|
+
(width / 8).times do |i|
|
56
|
+
string[i] ^= quads[i]
|
57
|
+
end
|
58
|
+
|
59
|
+
keccak string
|
60
|
+
end
|
61
|
+
|
62
|
+
string.pack("Q*")[0, @size]
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def keccak(string) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
68
|
+
24.times.each_with_object [] do |round, a|
|
69
|
+
# Theta
|
70
|
+
5.times do |i|
|
71
|
+
a[i] = string[i] ^ string[i + 5] ^ string[i + 10] ^ string[i + 15] ^ string[i + 20]
|
72
|
+
end
|
73
|
+
|
74
|
+
5.times do |i|
|
75
|
+
t = a[(i + 4) % 5] ^ rotate(a[(i + 1) % 5], 1)
|
76
|
+
0.step 24, 5 do |j|
|
77
|
+
string[j + i] ^= t
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Rho Pi
|
82
|
+
t = string[1]
|
83
|
+
24.times do |i|
|
84
|
+
j = PILN[i]
|
85
|
+
a[0] = string[j]
|
86
|
+
string[j] = rotate t, ROTC[i]
|
87
|
+
t = a[0]
|
88
|
+
end
|
89
|
+
|
90
|
+
# Chi
|
91
|
+
0.step 24, 5 do |j|
|
92
|
+
5.times do |i|
|
93
|
+
a[i] = string[j + i]
|
94
|
+
end
|
95
|
+
|
96
|
+
5.times do |i|
|
97
|
+
string[j + i] ^= ~a[(i + 1) % 5] & a[(i + 2) % 5]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Iota
|
102
|
+
string[0] ^= RNDC[round]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def rotate(x, y) # rubocop:disable Naming/MethodParameterName
|
107
|
+
((x << y) | (x >> (64 - y))) & ((1 << 64) - 1)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -12,19 +12,19 @@ module GasfreeSdk
|
|
12
12
|
|
13
13
|
# @!attribute [r] created_at
|
14
14
|
# @return [Time] When the token was added to GasFree
|
15
|
-
attribute :created_at, Types::
|
15
|
+
attribute :created_at, Types::Time
|
16
16
|
|
17
17
|
# @!attribute [r] updated_at
|
18
18
|
# @return [Time] When the token was last updated
|
19
|
-
attribute :updated_at, Types::
|
19
|
+
attribute :updated_at, Types::Time
|
20
20
|
|
21
21
|
# @!attribute [r] activate_fee
|
22
22
|
# @return [String] The activation fee in the smallest unit of the token
|
23
|
-
attribute :activate_fee, Types::
|
23
|
+
attribute :activate_fee, Types::String
|
24
24
|
|
25
25
|
# @!attribute [r] transfer_fee
|
26
26
|
# @return [String] The transfer fee in the smallest unit of the token
|
27
|
-
attribute :transfer_fee, Types::
|
27
|
+
attribute :transfer_fee, Types::String
|
28
28
|
|
29
29
|
# @!attribute [r] supported
|
30
30
|
# @return [Boolean] Whether the token is currently supported
|
@@ -12,51 +12,51 @@ module GasfreeSdk
|
|
12
12
|
|
13
13
|
# @!attribute [r] created_at
|
14
14
|
# @return [Time] When the transfer was created
|
15
|
-
attribute :created_at, Types::JSON::Time
|
15
|
+
attribute? :created_at, Types::JSON::Time
|
16
16
|
|
17
17
|
# @!attribute [r] updated_at
|
18
18
|
# @return [Time] When the transfer was last updated
|
19
|
-
attribute :updated_at, Types::JSON::Time
|
19
|
+
attribute? :updated_at, Types::JSON::Time
|
20
20
|
|
21
21
|
# @!attribute [r] account_address
|
22
22
|
# @return [String] The user's EOA address
|
23
|
-
attribute :account_address, Types::Address
|
23
|
+
attribute? :account_address, Types::Address
|
24
24
|
|
25
25
|
# @!attribute [r] gas_free_address
|
26
26
|
# @return [String] The GasFree account address
|
27
|
-
attribute :gas_free_address, Types::Address
|
27
|
+
attribute? :gas_free_address, Types::Address
|
28
28
|
|
29
29
|
# @!attribute [r] provider_address
|
30
30
|
# @return [String] The service provider's address
|
31
|
-
attribute :provider_address, Types::Address
|
31
|
+
attribute? :provider_address, Types::Address
|
32
32
|
|
33
33
|
# @!attribute [r] target_address
|
34
34
|
# @return [String] The recipient's address
|
35
|
-
attribute :target_address, Types::Address
|
35
|
+
attribute? :target_address, Types::Address
|
36
36
|
|
37
37
|
# @!attribute [r] token_address
|
38
38
|
# @return [String] The token contract address
|
39
|
-
attribute :token_address, Types::Address
|
39
|
+
attribute? :token_address, Types::Address
|
40
40
|
|
41
41
|
# @!attribute [r] amount
|
42
42
|
# @return [String] The transfer amount
|
43
|
-
attribute :amount, Types::Amount
|
43
|
+
attribute? :amount, Types::JSON::Amount
|
44
44
|
|
45
45
|
# @!attribute [r] max_fee
|
46
46
|
# @return [String] Maximum fee limit
|
47
|
-
attribute :max_fee, Types::Amount
|
47
|
+
attribute? :max_fee, Types::JSON::Amount
|
48
48
|
|
49
49
|
# @!attribute [r] signature
|
50
50
|
# @return [String] User's signature
|
51
|
-
attribute :signature, Types::String
|
51
|
+
attribute? :signature, Types::String
|
52
52
|
|
53
53
|
# @!attribute [r] nonce
|
54
54
|
# @return [Integer] Transfer nonce
|
55
|
-
attribute :nonce, Types::Nonce
|
55
|
+
attribute? :nonce, Types::Nonce
|
56
56
|
|
57
57
|
# @!attribute [r] expired_at
|
58
58
|
# @return [Time] When the transfer expires
|
59
|
-
attribute :expired_at, Types::JSON::Time
|
59
|
+
attribute? :expired_at, Types::JSON::Time
|
60
60
|
|
61
61
|
# @!attribute [r] state
|
62
62
|
# @return [String] Current transfer state
|
@@ -64,11 +64,11 @@ module GasfreeSdk
|
|
64
64
|
|
65
65
|
# @!attribute [r] estimated_activate_fee
|
66
66
|
# @return [String] Estimated activation fee
|
67
|
-
attribute? :estimated_activate_fee, Types::Amount
|
67
|
+
attribute? :estimated_activate_fee, Types::JSON::Amount
|
68
68
|
|
69
69
|
# @!attribute [r] estimated_transfer_fee
|
70
70
|
# @return [String] Estimated transfer fee
|
71
|
-
attribute? :estimated_transfer_fee, Types::Amount
|
71
|
+
attribute? :estimated_transfer_fee, Types::JSON::Amount
|
72
72
|
|
73
73
|
# @!attribute [r] txn_hash
|
74
74
|
# @return [String] On-chain transaction hash
|
@@ -90,23 +90,23 @@ module GasfreeSdk
|
|
90
90
|
|
91
91
|
# @!attribute [r] txn_activate_fee
|
92
92
|
# @return [String] Actual activation fee
|
93
|
-
attribute? :txn_activate_fee, Types::Amount
|
93
|
+
attribute? :txn_activate_fee, Types::JSON::Amount
|
94
94
|
|
95
95
|
# @!attribute [r] txn_transfer_fee
|
96
96
|
# @return [String] Actual transfer fee
|
97
|
-
attribute? :txn_transfer_fee, Types::Amount
|
97
|
+
attribute? :txn_transfer_fee, Types::JSON::Amount
|
98
98
|
|
99
99
|
# @!attribute [r] txn_total_fee
|
100
100
|
# @return [String] Total actual fee
|
101
|
-
attribute? :txn_total_fee, Types::Amount
|
101
|
+
attribute? :txn_total_fee, Types::JSON::Amount
|
102
102
|
|
103
103
|
# @!attribute [r] txn_amount
|
104
104
|
# @return [String] Actual transferred amount
|
105
|
-
attribute? :txn_amount, Types::Amount
|
105
|
+
attribute? :txn_amount, Types::JSON::Amount
|
106
106
|
|
107
107
|
# @!attribute [r] txn_total_cost
|
108
108
|
# @return [String] Total cost including fees
|
109
|
-
attribute? :txn_total_cost, Types::Amount
|
109
|
+
attribute? :txn_total_cost, Types::JSON::Amount
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|