chain-sdk 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +33 -0
- data/lib/chain/access_token.rb +66 -0
- data/lib/chain/account.rb +101 -0
- data/lib/chain/asset.rb +103 -0
- data/lib/chain/balance.rb +36 -0
- data/lib/chain/batch_response.rb +21 -0
- data/lib/chain/client.rb +75 -0
- data/lib/chain/client_module.rb +11 -0
- data/lib/chain/config.rb +121 -0
- data/lib/chain/connection.rb +187 -0
- data/lib/chain/constants.rb +4 -0
- data/lib/chain/control_program.rb +10 -0
- data/lib/chain/errors.rb +80 -0
- data/lib/chain/hsm_signer.rb +91 -0
- data/lib/chain/mock_hsm.rb +65 -0
- data/lib/chain/query.rb +50 -0
- data/lib/chain/response_object.rb +81 -0
- data/lib/chain/transaction.rb +472 -0
- data/lib/chain/transaction_feed.rb +100 -0
- data/lib/chain/unspent_output.rb +90 -0
- data/lib/chain/version.rb +3 -0
- data/lib/chain.rb +3 -0
- metadata +119 -0
@@ -0,0 +1,472 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
require_relative './client_module'
|
5
|
+
require_relative './query'
|
6
|
+
require_relative './response_object'
|
7
|
+
|
8
|
+
module Chain
|
9
|
+
class Transaction < ResponseObject
|
10
|
+
|
11
|
+
# @!attribute [r] id
|
12
|
+
# Unique transaction identifier.
|
13
|
+
# @return [String]
|
14
|
+
attrib :id
|
15
|
+
|
16
|
+
# @!attribute [r] timestamp
|
17
|
+
# Time of transaction.
|
18
|
+
# @return [Time]
|
19
|
+
attrib(:timestamp) { |raw| Time.parse(raw) }
|
20
|
+
|
21
|
+
# @!attribute [r] block_id
|
22
|
+
# Unique identifier, or block hash, of the block containing a transaction.
|
23
|
+
# @return [String]
|
24
|
+
attrib :block_id
|
25
|
+
|
26
|
+
# @!attribute [r] block_height
|
27
|
+
# Height of the block containing a transaction.
|
28
|
+
# @return [Integer]
|
29
|
+
attrib :block_height
|
30
|
+
|
31
|
+
# @!attribute [r] position
|
32
|
+
# Position of a transaction within the block.
|
33
|
+
# @return [Integer]
|
34
|
+
attrib :position
|
35
|
+
|
36
|
+
# @!attribute [r] reference_data
|
37
|
+
# User specified, unstructured data embedded within a transaction.
|
38
|
+
# @return [Hash]
|
39
|
+
attrib :reference_data
|
40
|
+
|
41
|
+
# @!attribute [r] is_local
|
42
|
+
# A flag indicating one or more inputs or outputs are local.
|
43
|
+
# @return [Boolean]
|
44
|
+
attrib :is_local
|
45
|
+
|
46
|
+
# @!attribute [r] inputs
|
47
|
+
# List of specified inputs for a transaction.
|
48
|
+
# @return [Array<Input>]
|
49
|
+
attrib(:inputs) { |raw| raw.map { |v| Input.new(v) } }
|
50
|
+
|
51
|
+
# @!attribute [r] outputs
|
52
|
+
# List of specified outputs for a transaction.
|
53
|
+
# @return [Array<Output>]
|
54
|
+
attrib(:outputs) { |raw| raw.map { |v| Output.new(v) } }
|
55
|
+
|
56
|
+
class ClientModule < Chain::ClientModule
|
57
|
+
# @param [Builder] builder
|
58
|
+
# @yield Block defining transaction actions.
|
59
|
+
# @return [Template]
|
60
|
+
def build(builder = nil, &block)
|
61
|
+
if builder.nil?
|
62
|
+
builder = Builder.new(&block)
|
63
|
+
end
|
64
|
+
|
65
|
+
client.conn.singleton_batch_request(
|
66
|
+
'build-transaction',
|
67
|
+
[builder]
|
68
|
+
) { |item| Template.new(item) }
|
69
|
+
end
|
70
|
+
|
71
|
+
# @param [Array<Builder>] builders
|
72
|
+
# @return [Array<Template>]
|
73
|
+
def build_batch(builders)
|
74
|
+
client.conn.batch_request(
|
75
|
+
'build-transaction',
|
76
|
+
builders
|
77
|
+
) { |item| Template.new(item) }
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param [Template] template
|
81
|
+
# @return [SubmitResponse]
|
82
|
+
def submit(template)
|
83
|
+
client.conn.singleton_batch_request(
|
84
|
+
'submit-transaction',
|
85
|
+
{transactions: [template]}
|
86
|
+
) { |item| SubmitResponse.new(item) }
|
87
|
+
end
|
88
|
+
|
89
|
+
# @param [Array<Template>] templates
|
90
|
+
# @return [Array<SubmitResponse>]
|
91
|
+
def submit_batch(templates)
|
92
|
+
client.conn.batch_request(
|
93
|
+
'submit-transaction',
|
94
|
+
{transactions: templates}
|
95
|
+
) { |item| SubmitResponse.new(item) }
|
96
|
+
end
|
97
|
+
|
98
|
+
# @param [Hash] query
|
99
|
+
# @return [Query]
|
100
|
+
def query(query = {})
|
101
|
+
Query.new(client, query)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class Query < Chain::Query
|
106
|
+
def fetch(query)
|
107
|
+
client.conn.request('list-transactions', query)
|
108
|
+
end
|
109
|
+
|
110
|
+
def translate(raw)
|
111
|
+
Transaction.new(raw)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class Input < ResponseObject
|
116
|
+
# @!attribute [r] type
|
117
|
+
# The type of the input.
|
118
|
+
#
|
119
|
+
# Possible values are "issue", "spend".
|
120
|
+
# @return [String]
|
121
|
+
attrib :type
|
122
|
+
|
123
|
+
# @!attribute [r] asset_id
|
124
|
+
# The id of the asset being issued or spent.
|
125
|
+
# @return [String]
|
126
|
+
attrib :asset_id
|
127
|
+
|
128
|
+
# @!attribute [r] asset_alias
|
129
|
+
# The alias of the asset being issued or spent (possibly null).
|
130
|
+
# @return [String]
|
131
|
+
attrib :asset_alias
|
132
|
+
|
133
|
+
# @!attribute [r] asset_definition
|
134
|
+
# The definition of the asset being issued or spent (possibly null).
|
135
|
+
# @return [Hash]
|
136
|
+
attrib :asset_definition
|
137
|
+
|
138
|
+
# @!attribute [r] asset_tags
|
139
|
+
# The tags of the asset being issued or spent (possibly null).
|
140
|
+
# @return [Hash]
|
141
|
+
attrib :asset_tags
|
142
|
+
|
143
|
+
# @!attribute [r] asset_is_local
|
144
|
+
# A flag indicating whether the asset being issued or spent is local.
|
145
|
+
# @return [Boolean]
|
146
|
+
attrib :asset_is_local
|
147
|
+
|
148
|
+
# @!attribute [r] amount
|
149
|
+
# The number of units of the asset being issued or spent.
|
150
|
+
# @return [Integer]
|
151
|
+
attrib :amount
|
152
|
+
|
153
|
+
# @!attribute [r] spent_output
|
154
|
+
# The output consumed by this input.
|
155
|
+
# @return [SpentOutput]
|
156
|
+
attrib(:spent_output) { |raw| SpentOutput.new(raw) }
|
157
|
+
|
158
|
+
# @!attribute [r] account_id
|
159
|
+
# The id of the account transferring the asset (possibly null if the
|
160
|
+
# input is an issuance or an unspent output is specified).
|
161
|
+
# @return [String]
|
162
|
+
attrib :account_id
|
163
|
+
|
164
|
+
# @!attribute [r] account_alias
|
165
|
+
# The alias of the account transferring the asset (possibly null if the
|
166
|
+
# input is an issuance or an unspent output is specified).
|
167
|
+
# @return [String]
|
168
|
+
attrib :account_alias
|
169
|
+
|
170
|
+
# @!attribute [r] account_tags
|
171
|
+
# The tags associated with the account (possibly null).
|
172
|
+
# @return [String]
|
173
|
+
attrib :account_tags
|
174
|
+
|
175
|
+
# @!attribute [r] input_witness
|
176
|
+
# @return [String]
|
177
|
+
attrib :input_witness
|
178
|
+
|
179
|
+
# @!attribute [r] issuance_program
|
180
|
+
# A program specifying a predicate for issuing an asset (possibly null
|
181
|
+
# if input is not an issuance).
|
182
|
+
# @return [String]
|
183
|
+
attrib :issuance_program
|
184
|
+
|
185
|
+
# @!attribute [r] control_program
|
186
|
+
# @return [String]
|
187
|
+
attrib :control_program
|
188
|
+
|
189
|
+
# @!attribute [r] reference_data
|
190
|
+
# User specified, unstructured data embedded within an input
|
191
|
+
# (possibly null).
|
192
|
+
# @return [Hash]
|
193
|
+
attrib :reference_data
|
194
|
+
|
195
|
+
# @!attribute [r] is_local
|
196
|
+
# A flag indicating if the input is local.
|
197
|
+
# @return [Boolean]
|
198
|
+
attrib :is_local
|
199
|
+
|
200
|
+
class SpentOutput < ResponseObject
|
201
|
+
# @!attribute [r] transaction_id
|
202
|
+
# Unique transaction identifier.
|
203
|
+
# @return [String]
|
204
|
+
attrib :transaction_id
|
205
|
+
|
206
|
+
# @!attribute [r] position
|
207
|
+
# Position of an output within the transaction.
|
208
|
+
# @return [Integer]
|
209
|
+
attrib :position
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
class Output < ResponseObject
|
214
|
+
# @!attribute [r] type
|
215
|
+
# The type of the output.
|
216
|
+
#
|
217
|
+
# Possible values are "control" and "retire".
|
218
|
+
# @return [String]
|
219
|
+
attrib :type
|
220
|
+
|
221
|
+
# @!attribute [r] purpose
|
222
|
+
# The purpose of the output.
|
223
|
+
#
|
224
|
+
# Possible values are "receive" and "change".
|
225
|
+
# @return [String]
|
226
|
+
attrib :purpose
|
227
|
+
|
228
|
+
# @!attribute [r] position
|
229
|
+
# The output's position in a transaction's list of outputs.
|
230
|
+
# @return [Integer]
|
231
|
+
attrib :position
|
232
|
+
|
233
|
+
# @!attribute [r] asset_id
|
234
|
+
# The id of the asset being controlled.
|
235
|
+
# @return [String]
|
236
|
+
attrib :asset_id
|
237
|
+
|
238
|
+
# @!attribute [r] asset_alias
|
239
|
+
# The alias of the asset being controlled (possibly null).
|
240
|
+
# @return [String]
|
241
|
+
attrib :asset_alias
|
242
|
+
|
243
|
+
# @!attribute [r] asset_definition
|
244
|
+
# The definition of the asset being controlled (possibly null).
|
245
|
+
# @return [Hash]
|
246
|
+
attrib :asset_definition
|
247
|
+
|
248
|
+
# @!attribute [r] asset_tags
|
249
|
+
# The tags of the asset being controlled (possibly null).
|
250
|
+
# @return [Hash]
|
251
|
+
attrib :asset_tags
|
252
|
+
|
253
|
+
# @!attribute [r] asset_is_local
|
254
|
+
# A flag indicating whether the asset being controlled is local.
|
255
|
+
# @return [Boolean]
|
256
|
+
attrib :asset_is_local
|
257
|
+
|
258
|
+
# @!attribute [r] amount
|
259
|
+
# The number of units of the asset being controlled.
|
260
|
+
# @return [Integer]
|
261
|
+
attrib :amount
|
262
|
+
|
263
|
+
# @!attribute [r] account_id
|
264
|
+
# The id of the account controlling this output (possibly null if a
|
265
|
+
# control program is specified).
|
266
|
+
# @return [String]
|
267
|
+
attrib :account_id
|
268
|
+
|
269
|
+
# @!attribute [r] account_alias
|
270
|
+
# The alias of the account controlling this output (possibly null if
|
271
|
+
# a control program is specified).
|
272
|
+
# @return [String]
|
273
|
+
attrib :account_alias
|
274
|
+
|
275
|
+
# @!attribute [r] account_tags
|
276
|
+
# The tags associated with the account controlling this output
|
277
|
+
# (possibly null if a control program is specified).
|
278
|
+
# @return [Hash]
|
279
|
+
attrib :account_tags
|
280
|
+
|
281
|
+
# @!attribute [r] control_program
|
282
|
+
# The control program which must be satisfied to transfer this output.
|
283
|
+
# @return [String]
|
284
|
+
attrib :control_program
|
285
|
+
|
286
|
+
# @!attribute [r] reference_data
|
287
|
+
# User specified, unstructured data embedded within an input
|
288
|
+
# (possibly null).
|
289
|
+
# @return [Hash]
|
290
|
+
attrib :reference_data
|
291
|
+
|
292
|
+
# @!attribute [r] is_local
|
293
|
+
# A flag indicating if the output is local.
|
294
|
+
# @return [Boolean]
|
295
|
+
attrib :is_local
|
296
|
+
end
|
297
|
+
|
298
|
+
class Builder
|
299
|
+
def initialize(&block)
|
300
|
+
block.call(self) if block
|
301
|
+
end
|
302
|
+
|
303
|
+
# @return [Array<Hash>]
|
304
|
+
def actions
|
305
|
+
@actions ||= []
|
306
|
+
end
|
307
|
+
|
308
|
+
# @param [Template, String] template_or_raw_tx
|
309
|
+
# @return [Builder]
|
310
|
+
def base_transaction(template_or_raw_tx)
|
311
|
+
if template_or_raw_tx.is_a?(Transaction::Template)
|
312
|
+
@base_transaction = template_or_raw_tx.raw_transaction
|
313
|
+
else
|
314
|
+
@base_transaction = template_or_raw_tx
|
315
|
+
end
|
316
|
+
self
|
317
|
+
end
|
318
|
+
|
319
|
+
# @return [Builder]
|
320
|
+
def ttl(ttl)
|
321
|
+
@ttl = ttl
|
322
|
+
self
|
323
|
+
end
|
324
|
+
|
325
|
+
# @return [Hash]
|
326
|
+
def to_h
|
327
|
+
{
|
328
|
+
actions: actions,
|
329
|
+
base_transaction: @base_transaction,
|
330
|
+
ttl: @ttl,
|
331
|
+
}
|
332
|
+
end
|
333
|
+
|
334
|
+
# @return [String]
|
335
|
+
def to_json(opts = nil)
|
336
|
+
to_h.to_json(opts)
|
337
|
+
end
|
338
|
+
|
339
|
+
# Add an action to the tranasction builder
|
340
|
+
# @param [Hash] params Action parameters containing a type field and the
|
341
|
+
# required parameters for that type
|
342
|
+
# @return [Builder]
|
343
|
+
def add_action(params)
|
344
|
+
# Some actions require an idempotency token, so we'll add it here as a
|
345
|
+
# generic parameter.
|
346
|
+
params = {client_token: SecureRandom.uuid}.merge(params)
|
347
|
+
actions << params
|
348
|
+
self
|
349
|
+
end
|
350
|
+
|
351
|
+
# Sets the transaction-level reference data.
|
352
|
+
# May only be used once per transaction.
|
353
|
+
# @param [Hash] reference_data User specified, unstructured data to
|
354
|
+
# be embedded in a transaction
|
355
|
+
# @return [Builder]
|
356
|
+
def transaction_reference_data(reference_data)
|
357
|
+
add_action(
|
358
|
+
type: :set_transaction_reference_data,
|
359
|
+
reference_data: reference_data,
|
360
|
+
)
|
361
|
+
end
|
362
|
+
|
363
|
+
# Add an issuance action.
|
364
|
+
# @param [Hash] params Action parameters
|
365
|
+
# @option params [String] :asset_id Asset ID specifiying the asset to be issued.
|
366
|
+
# You must specify either an ID or an alias.
|
367
|
+
# @option params [String] :asset_alias Asset alias specifying the asset to be issued.
|
368
|
+
# You must specify either an ID or an alias.
|
369
|
+
# @option params [Integer] :amount amount of the asset to be issued
|
370
|
+
# @return [Builder]
|
371
|
+
def issue(params)
|
372
|
+
add_action(params.merge(type: :issue))
|
373
|
+
end
|
374
|
+
|
375
|
+
# Add a spend action taken on a particular account.
|
376
|
+
# @param [Hash] params Action parameters
|
377
|
+
# @option params [String] :asset_id Asset ID specifiying the asset to be spent.
|
378
|
+
# You must specify either an ID or an alias.
|
379
|
+
# @option params [String] :asset_alias Asset alias specifying the asset to be spent.
|
380
|
+
# You must specify either an ID or an alias.
|
381
|
+
# @option params [String] :account_id Account ID specifiying the account spending the asset.
|
382
|
+
# You must specify either an ID or an alias.
|
383
|
+
# @option params [String] :account_alias Account alias specifying the account spending the asset.
|
384
|
+
# You must specify either an ID or an alias.
|
385
|
+
# @option params [Integer] :amount amount of the asset to be spent.
|
386
|
+
# @return [Builder]
|
387
|
+
def spend_from_account(params)
|
388
|
+
add_action(params.merge(type: :spend_account))
|
389
|
+
end
|
390
|
+
|
391
|
+
# Add a spend action taken on a particular unspent output.
|
392
|
+
# @param [Hash] params Action parameters
|
393
|
+
# @option params [String] :transaction_id Transaction ID specifying the tranasction to select an output from.
|
394
|
+
# @option params [Integer] :position Position of the output within the transaction to be spent.
|
395
|
+
# @return [Builder]
|
396
|
+
def spend_account_unspent_output(params)
|
397
|
+
add_action(params.merge(type: :spend_account_unspent_output))
|
398
|
+
end
|
399
|
+
|
400
|
+
# Add a control action taken on a particular account.
|
401
|
+
# @param [Hash] params Action parameters
|
402
|
+
# @option params [String] :asset_id Asset ID specifiying the asset to be controlled.
|
403
|
+
# You must specify either an ID or an alias.
|
404
|
+
# @option params [String] :asset_alias Asset alias specifying the asset to be controlled.
|
405
|
+
# You must specify either an ID or an alias.
|
406
|
+
# @option params [String] :account_id Account ID specifiying the account controlling the asset.
|
407
|
+
# You must specify either an ID or an alias.
|
408
|
+
# @option params [String] :account_alias Account alias specifying the account controlling the asset.
|
409
|
+
# You must specify either an ID or an alias.
|
410
|
+
# @option params [Integer] :amount amount of the asset to be controlled.
|
411
|
+
# @return [Builder]
|
412
|
+
def control_with_account(params)
|
413
|
+
add_action(params.merge(type: :control_account))
|
414
|
+
end
|
415
|
+
|
416
|
+
# Add a control action taken on a control program.
|
417
|
+
# @param [Hash] params Action parameters
|
418
|
+
# @option params [String] :asset_id Asset ID specifiying the asset to be controlled.
|
419
|
+
# You must specify either an ID or an alias.
|
420
|
+
# @option params [String] :asset_alias Asset alias specifying the asset to be controlled.
|
421
|
+
# You must specify either an ID or an alias.
|
422
|
+
# @option params [String] :control_program The control program to be used
|
423
|
+
# @option params [Integer] :amount amount of the asset to be controlled.
|
424
|
+
# @return [Builder]
|
425
|
+
def control_with_program(params)
|
426
|
+
add_action(params.merge(type: :control_program))
|
427
|
+
end
|
428
|
+
|
429
|
+
# Add a retire action.
|
430
|
+
# @param [Hash] params Action parameters
|
431
|
+
# @option params [String] :asset_id Asset ID specifiying the asset to be retired.
|
432
|
+
# You must specify either an ID or an alias.
|
433
|
+
# @option params [String] :asset_alias Asset alias specifying the asset to be retired.
|
434
|
+
# You must specify either an ID or an alias.
|
435
|
+
# @option params [Integer] :amount Amount of the asset to be retired.
|
436
|
+
# @return [Builder]
|
437
|
+
def retire(params)
|
438
|
+
add_action(params.merge(
|
439
|
+
type: :control_program,
|
440
|
+
control_program: '6a'
|
441
|
+
))
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
class SubmitResponse < ResponseObject
|
446
|
+
# @!attribute [r] id
|
447
|
+
# @return [String]
|
448
|
+
attrib :id
|
449
|
+
end
|
450
|
+
|
451
|
+
class Template < ResponseObject
|
452
|
+
# @!attribute [r] raw_transaction
|
453
|
+
# @return [String]
|
454
|
+
attrib :raw_transaction
|
455
|
+
|
456
|
+
# @!attribute [r] signing_instructions
|
457
|
+
# @return [String]
|
458
|
+
attrib :signing_instructions
|
459
|
+
|
460
|
+
# @return [Template]
|
461
|
+
def allow_additional_actions
|
462
|
+
@allow_additional_actions = true
|
463
|
+
self
|
464
|
+
end
|
465
|
+
|
466
|
+
# @return [Hash]
|
467
|
+
def to_h
|
468
|
+
super.merge(allow_additional_actions: @allow_additional_actions)
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
require_relative './client_module'
|
4
|
+
require_relative './connection'
|
5
|
+
require_relative './constants'
|
6
|
+
require_relative './response_object'
|
7
|
+
|
8
|
+
module Chain
|
9
|
+
class TransactionFeed < ResponseObject
|
10
|
+
|
11
|
+
# @!attribute [r] id
|
12
|
+
# Unique transaction feed identifier.
|
13
|
+
# @return [String]
|
14
|
+
attrib :id
|
15
|
+
|
16
|
+
# @!attribute [r] alias
|
17
|
+
# User specified, unique identifier.
|
18
|
+
# @return [String]
|
19
|
+
attrib :alias
|
20
|
+
|
21
|
+
# @!attribute [r] filter
|
22
|
+
# @return [String]
|
23
|
+
attrib :filter
|
24
|
+
|
25
|
+
# @!attribute [r] after
|
26
|
+
# @return [String]
|
27
|
+
attrib :after
|
28
|
+
|
29
|
+
def initialize(raw_attribs, base_conn)
|
30
|
+
super(raw_attribs)
|
31
|
+
|
32
|
+
# The consume/ack cycle should run on its own thread, so make a copy of
|
33
|
+
# the base connection so this feed has an exclusive HTTP connection.
|
34
|
+
@conn = Connection.new(base_conn.opts)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [Fixnum] timeout value in seconds
|
38
|
+
# @yield [Transaction] block process individual transactions
|
39
|
+
# @yieldparam [Transaction] tx
|
40
|
+
# @return [void]
|
41
|
+
def consume(timeout: 24*60*60)
|
42
|
+
query = {
|
43
|
+
filter: filter,
|
44
|
+
after: after,
|
45
|
+
timeout: (timeout * 1000).to_i, # milliseconds
|
46
|
+
ascending_with_long_poll: true
|
47
|
+
}
|
48
|
+
|
49
|
+
longpoll = Connection.new(@conn.opts.merge(read_timeout: timeout))
|
50
|
+
|
51
|
+
loop do
|
52
|
+
page = longpoll.request('list-transactions', query)
|
53
|
+
query = page['next']
|
54
|
+
|
55
|
+
page['items'].each do |raw_tx|
|
56
|
+
tx = Transaction.new(raw_tx)
|
57
|
+
|
58
|
+
# Memoize the cursor value for this transaction in case the user
|
59
|
+
# decides to ack. The format of the cursor value is specified in the
|
60
|
+
# core/query package.
|
61
|
+
@next_after = "#{tx.block_height}:#{tx.position}-#{MAX_BLOCK_HEIGHT}"
|
62
|
+
|
63
|
+
yield tx
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def ack
|
69
|
+
raise 'ack must be called at most once per cycle in a consume loop' unless @next_after
|
70
|
+
|
71
|
+
@conn.request(
|
72
|
+
'update-transaction-feed',
|
73
|
+
id: id,
|
74
|
+
after: @next_after,
|
75
|
+
previous_after: after,
|
76
|
+
)
|
77
|
+
|
78
|
+
self.after = @next_after
|
79
|
+
@next_after = nil
|
80
|
+
end
|
81
|
+
|
82
|
+
class ClientModule < Chain::ClientModule
|
83
|
+
|
84
|
+
# @param [Hash] opts
|
85
|
+
# @return [TransactionFeed]
|
86
|
+
def create(opts)
|
87
|
+
opts = {client_token: SecureRandom.uuid()}.merge(opts)
|
88
|
+
TransactionFeed.new(client.conn.request('create-transaction-feed', opts), client.conn)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @param [Hash] opts
|
92
|
+
# @return [TransactionFeed]
|
93
|
+
def get(opts)
|
94
|
+
TransactionFeed.new(client.conn.request('get-transaction-feed', opts), client.conn)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require_relative './client_module'
|
2
|
+
require_relative './response_object'
|
3
|
+
require_relative './query'
|
4
|
+
|
5
|
+
module Chain
|
6
|
+
class UnspentOutput < ResponseObject
|
7
|
+
|
8
|
+
# @!attribute [r] type
|
9
|
+
# @return [String]
|
10
|
+
attrib :type
|
11
|
+
|
12
|
+
# @!attribute [r] purpose
|
13
|
+
# @return [String]
|
14
|
+
attrib :purpose
|
15
|
+
|
16
|
+
# @!attribute [r] transaction_id
|
17
|
+
# @return [String]
|
18
|
+
attrib :transaction_id
|
19
|
+
|
20
|
+
# @!attribute [r] position
|
21
|
+
# @return [Integer]
|
22
|
+
attrib :position
|
23
|
+
|
24
|
+
# @!attribute [r] asset_id
|
25
|
+
# @return [String]
|
26
|
+
attrib :asset_id
|
27
|
+
|
28
|
+
# @!attribute [r] asset_alias
|
29
|
+
# @return [String]
|
30
|
+
attrib :asset_alias
|
31
|
+
|
32
|
+
# @!attribute [r] asset_definition
|
33
|
+
# @return [Hash]
|
34
|
+
attrib :asset_definition
|
35
|
+
|
36
|
+
# @!attribute [r] asset_tags
|
37
|
+
# @return [Hash]
|
38
|
+
attrib :asset_tags
|
39
|
+
|
40
|
+
# @!attribute [r] asset_is_local
|
41
|
+
# @return [Boolean]
|
42
|
+
attrib :asset_is_local
|
43
|
+
|
44
|
+
# @!attribute [r] amount
|
45
|
+
# @return [Integer]
|
46
|
+
attrib :amount
|
47
|
+
|
48
|
+
# @!attribute [r] account_id
|
49
|
+
# @return [String]
|
50
|
+
attrib :account_id
|
51
|
+
|
52
|
+
# @!attribute [r] account_alias
|
53
|
+
# @return [String]
|
54
|
+
attrib :account_alias
|
55
|
+
|
56
|
+
# @!attribute [r] account_tags
|
57
|
+
# @return [Hash]
|
58
|
+
attrib :account_tags
|
59
|
+
|
60
|
+
# @!attribute [r] control_program
|
61
|
+
# @return [String]
|
62
|
+
attrib :control_program
|
63
|
+
|
64
|
+
# @!attribute [r] reference_data
|
65
|
+
# @return [Hash]
|
66
|
+
attrib :reference_data
|
67
|
+
|
68
|
+
# @!attribute [r] is_local
|
69
|
+
# @return [Boolean]
|
70
|
+
attrib :is_local
|
71
|
+
|
72
|
+
class ClientModule < Chain::ClientModule
|
73
|
+
# @param [Hash] query
|
74
|
+
# @return Query
|
75
|
+
def query(query = {})
|
76
|
+
Query.new(client, query)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Query < Chain::Query
|
81
|
+
def fetch(query)
|
82
|
+
client.conn.request('list-unspent-outputs', query)
|
83
|
+
end
|
84
|
+
|
85
|
+
def translate(raw)
|
86
|
+
UnspentOutput.new(raw)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/chain.rb
ADDED