chain-sdk 1.0.0.pre
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/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