stellar_base-rails 0.5.6 → 0.6.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/README.md +2 -0
- data/app/concepts/stellar_base/deposit_requests/contracts/create.rb +41 -0
- data/app/concepts/stellar_base/deposit_requests/deposit_request_policy.rb +14 -0
- data/app/concepts/stellar_base/deposit_requests/operations/create.rb +73 -0
- data/app/concepts/stellar_base/withdrawal_requests/operations/create.rb +1 -9
- data/app/controllers/stellar_base/deposit_controller.rb +24 -0
- data/app/models/stellar_base/deposit_request.rb +4 -0
- data/app/representers/stellar_base/application_representer.rb +5 -0
- data/app/representers/stellar_base/deposit_request_representer.rb +13 -0
- data/app/representers/stellar_base/withdrawal_request_representer.rb +15 -0
- data/app/services/stellar_base/configured_class_runner.rb +13 -0
- data/app/services/stellar_base/deposit_requests/find_depositable_asset.rb +12 -0
- data/app/services/stellar_base/gen_memo_for.rb +17 -0
- data/app/twins/stellar_base/application_twin.rb +5 -0
- data/app/twins/stellar_base/deposit_request_twin.rb +13 -0
- data/app/twins/stellar_base/withdrawal_request_twin.rb +15 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20180925045927_create_stellar_base_deposit_requests.rb +28 -0
- data/lib/stellar_base.rb +22 -4
- data/lib/stellar_base/factories/deposit_requests.rb +17 -0
- data/lib/stellar_base/version.rb +1 -1
- metadata +18 -7
- data/app/representers/application_representer.rb +0 -3
- data/app/representers/withdrawal_request_representer.rb +0 -13
- data/app/services/stellar_base/withdrawal_requests/gen_memo.rb +0 -19
- data/app/twins/application_twin.rb +0 -3
- data/app/twins/withdrawal_request_twin.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdcf37c86d71ffbb7830e3040033107afb8f31522425c8cc94e24d3c67097c8f
|
4
|
+
data.tar.gz: 34b17e584937960171db869cd9d8660647e22d9689c5fd1d05864342a7afc85c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e5caa243016431428f00c29a14ed7437afab21e0e3560b366e8e64152596479e0394735e142669a7c6019c983d980cd6b9bec1b5ba09ae3c3a7c745a35ed287
|
7
|
+
data.tar.gz: bc4d072cc0ea013fbcf828b2421111d387e26a3e11413d34db1a614388f325b4a585fda98920af36ee932fc76dac76871fbf177a073711d0b07310c526daa3e8
|
data/README.md
CHANGED
@@ -36,6 +36,8 @@ StellarBase.configure do |c|
|
|
36
36
|
end
|
37
37
|
```
|
38
38
|
|
39
|
+
To use the public network, ensure that you set the `Stellar` network to the [appropriate value](https://github.com/stellar/ruby-stellar-sdk#usage).
|
40
|
+
|
39
41
|
#### c.modules
|
40
42
|
You can supply what endpoints you want to activate with the gem
|
41
43
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module StellarBase
|
2
|
+
module DepositRequests
|
3
|
+
module Contracts
|
4
|
+
class Create < ApplicationContract
|
5
|
+
|
6
|
+
property :asset_code
|
7
|
+
property :account_id
|
8
|
+
property :memo_type
|
9
|
+
property :memo
|
10
|
+
property :email_address
|
11
|
+
property :deposit_type
|
12
|
+
|
13
|
+
validates(
|
14
|
+
:asset_code,
|
15
|
+
:account_id,
|
16
|
+
presence: true,
|
17
|
+
)
|
18
|
+
validate :check_valid_asset_code
|
19
|
+
|
20
|
+
def check_valid_asset_code
|
21
|
+
asset_codes = StellarBase.configuration.depositable_assets.dup
|
22
|
+
|
23
|
+
if asset_codes.nil?
|
24
|
+
errors.add(:asset_code, "no assets configured for deposits")
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
asset_codes.map! { |asset| asset[:asset_code] }
|
29
|
+
|
30
|
+
return if asset_codes.include? asset_code
|
31
|
+
|
32
|
+
errors.add(
|
33
|
+
:asset_code,
|
34
|
+
"invalid asset_code. Valid asset_codes: #{asset_codes.join(', ')}",
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module StellarBase
|
2
|
+
module DepositRequests
|
3
|
+
module Operations
|
4
|
+
class Create < ApplicationOperation
|
5
|
+
|
6
|
+
DEFAULT_ETA = (10 * 60).freeze
|
7
|
+
|
8
|
+
step self::Policy::Pundit(DepositRequestPolicy, :create?)
|
9
|
+
step Model(DepositRequest, :new)
|
10
|
+
step :setup_params!
|
11
|
+
step Contract::Build(constant: Contracts::Create)
|
12
|
+
step Contract::Validate(key: :deposit_request)
|
13
|
+
step Contract::Persist(method: :sync)
|
14
|
+
step :find_depositable_asset_details!
|
15
|
+
step :determine_how!
|
16
|
+
step :determine_max_amount!
|
17
|
+
success :set_defaults!
|
18
|
+
step Contract::Persist(method: :save)
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def setup_params!(options, params:, **)
|
23
|
+
params[:deposit_request].merge!({
|
24
|
+
account_id: params[:deposit_request][:account],
|
25
|
+
deposit_type: params[:deposit_request][:type],
|
26
|
+
memo: memo_from(params[:deposit_request]),
|
27
|
+
memo_type: memo_type_from(params[:deposit_request]),
|
28
|
+
})
|
29
|
+
end
|
30
|
+
|
31
|
+
def find_depositable_asset_details!(options, params:, **)
|
32
|
+
details = FindDepositableAsset.(params[:deposit_request][:asset_code])
|
33
|
+
params[:deposit_asset_details] = details.presence || {}
|
34
|
+
end
|
35
|
+
|
36
|
+
def determine_how!(options, params:, **)
|
37
|
+
details = params[:deposit_asset_details]
|
38
|
+
options["model"].deposit_address =
|
39
|
+
ConfiguredClassRunner.(details[:how_from])
|
40
|
+
end
|
41
|
+
|
42
|
+
def determine_max_amount!(options, params:, **)
|
43
|
+
details = params[:deposit_asset_details]
|
44
|
+
options["model"].max_amount =
|
45
|
+
ConfiguredClassRunner.(details[:max_amount_from])
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_defaults!(options, params:, **)
|
49
|
+
details = params[:deposit_asset_details]
|
50
|
+
|
51
|
+
options["model"].asset_type = details[:type]
|
52
|
+
options["model"].issuer = details[:issuer]
|
53
|
+
options["model"].eta = DEFAULT_ETA
|
54
|
+
options["model"].min_amount = 0.0
|
55
|
+
|
56
|
+
# Make Deposits free unless we want it configured
|
57
|
+
options["model"].fee_fixed = details[:fee_fixed] || 0.0
|
58
|
+
options["model"].fee_percent = details[:fee_percent] || 0.0
|
59
|
+
end
|
60
|
+
|
61
|
+
def memo_type_from(params)
|
62
|
+
return "text" if params[:memo_type].blank?
|
63
|
+
params[:memo_type]
|
64
|
+
end
|
65
|
+
|
66
|
+
def memo_from(params)
|
67
|
+
return GenMemoFor.(DepositRequest) if params[:memo].blank?
|
68
|
+
params[:memo]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -42,7 +42,7 @@ module StellarBase
|
|
42
42
|
options["model"].account_id =
|
43
43
|
StellarBase.configuration.distribution_account
|
44
44
|
options["model"].memo_type = "text"
|
45
|
-
options["model"].memo =
|
45
|
+
options["model"].memo = GenMemoFor.(WithdrawalRequest)
|
46
46
|
options["model"].eta = DEFAULT_ETA
|
47
47
|
options["model"].min_amount = 0.0
|
48
48
|
options["model"].max_amount =
|
@@ -54,14 +54,6 @@ module StellarBase
|
|
54
54
|
options["model"].fee_network = fee_network
|
55
55
|
end
|
56
56
|
|
57
|
-
def get_balance_from(balance_checker_class)
|
58
|
-
if balance_checker_present?
|
59
|
-
return balance_checker_class.constantize.send(:call)
|
60
|
-
end
|
61
|
-
|
62
|
-
nil
|
63
|
-
end
|
64
|
-
|
65
57
|
end
|
66
58
|
end
|
67
59
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module StellarBase
|
2
|
+
class DepositController < ApplicationController
|
3
|
+
|
4
|
+
def create
|
5
|
+
op = DepositRequests::Operations::Create.(deposit_request: params)
|
6
|
+
|
7
|
+
respond_to do |f|
|
8
|
+
f.json do
|
9
|
+
if op.success?
|
10
|
+
twin = DepositRequestTwin.new(op["model"])
|
11
|
+
representer = DepositRequestRepresenter.new(twin)
|
12
|
+
render json: representer
|
13
|
+
else
|
14
|
+
render(
|
15
|
+
json: { error: op["contract.default"].errors },
|
16
|
+
status: :unprocessable_entity,
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module StellarBase
|
2
|
+
class DepositRequestRepresenter < ApplicationRepresenter
|
3
|
+
|
4
|
+
property :deposit_address, as: :how
|
5
|
+
property :eta
|
6
|
+
property :min_amount
|
7
|
+
property :max_amount
|
8
|
+
property :fee_fixed
|
9
|
+
property :fee_percent
|
10
|
+
property :extra_info
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module StellarBase
|
2
|
+
class WithdrawalRequestRepresenter < ApplicationRepresenter
|
3
|
+
|
4
|
+
property :account_id
|
5
|
+
property :memo_type
|
6
|
+
property :memo
|
7
|
+
property :min_amount
|
8
|
+
property :max_amount
|
9
|
+
property :fee_fixed
|
10
|
+
property :fee_percent
|
11
|
+
property :fee_network
|
12
|
+
property :extra_info
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module StellarBase
|
2
|
+
module DepositRequests
|
3
|
+
class FindDepositableAsset
|
4
|
+
|
5
|
+
def self.call(asset_code)
|
6
|
+
depositable_assets = StellarBase.configuration.depositable_assets
|
7
|
+
depositable_assets.find {|asset| asset[:asset_code] == asset_code }
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module StellarBase
|
2
|
+
class WithdrawalRequestTwin < ApplicationTwin
|
3
|
+
|
4
|
+
property :account_id
|
5
|
+
property :memo_type
|
6
|
+
property :memo
|
7
|
+
property :min_amount
|
8
|
+
property :max_amount
|
9
|
+
property :fee_fixed
|
10
|
+
property :fee_percent
|
11
|
+
property :fee_network
|
12
|
+
property :extra_info
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
class CreateStellarBaseDepositRequests < ActiveRecord::Migration[5.2]
|
2
|
+
|
3
|
+
def change
|
4
|
+
create_table :stellar_base_deposit_requests do |t|
|
5
|
+
t.string :asset_type, null: false
|
6
|
+
t.string :asset_code, null: false
|
7
|
+
t.string :memo_type
|
8
|
+
t.string :memo
|
9
|
+
t.string :account_id, null: false
|
10
|
+
t.string :issuer, null: false
|
11
|
+
t.string :email_address
|
12
|
+
t.string :deposit_address, null: false
|
13
|
+
t.string :deposit_type
|
14
|
+
t.integer :eta
|
15
|
+
t.decimal :min_amount, null: false, default: 0.0
|
16
|
+
t.decimal :max_amount
|
17
|
+
t.decimal :fee_fixed, null: false, default: 0.0
|
18
|
+
t.decimal :fee_percent, null: false, default: 0.0
|
19
|
+
t.string :extra_info
|
20
|
+
|
21
|
+
t.timestamps
|
22
|
+
t.index(%i[asset_type asset_code], {
|
23
|
+
name: :index_stellar_base_deposit_requests_on_asset,
|
24
|
+
})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/lib/stellar_base.rb
CHANGED
@@ -30,26 +30,44 @@ module StellarBase
|
|
30
30
|
has :withdrawable_assets, classes: [NilClass, Array, String, Pathname]
|
31
31
|
has :on_withdraw
|
32
32
|
|
33
|
+
has :depositable_assets, classes: [NilClass, Array, String, Pathname]
|
34
|
+
|
33
35
|
has :stellar_toml, classes: Hash, default: {}
|
34
36
|
end
|
35
37
|
|
36
38
|
after_configuration_change do
|
37
39
|
self.convert_config_withdraw!
|
40
|
+
self.convert_config_deposit!
|
38
41
|
end
|
39
42
|
|
43
|
+
|
40
44
|
def self.included_module?(module_name)
|
41
45
|
self.configuration.modules&.include?(module_name)
|
42
46
|
end
|
43
47
|
|
48
|
+
def self.convert_config_deposit!
|
49
|
+
depositable_assets = self.configuration.depositable_assets
|
50
|
+
return if depositable_assets.is_a?(Array) || depositable_assets.nil?
|
51
|
+
|
52
|
+
self.configuration.depositable_assets =
|
53
|
+
convert_config!(depositable_assets)
|
54
|
+
end
|
55
|
+
|
44
56
|
def self.convert_config_withdraw!
|
45
57
|
withdrawable_assets = self.configuration.withdrawable_assets
|
46
58
|
return if withdrawable_assets.is_a?(Array) || withdrawable_assets.nil?
|
47
59
|
|
48
|
-
array_of_hashes = try_from_yaml_file_path(withdrawable_assets) ||
|
49
|
-
try_from_json(withdrawable_assets)
|
50
|
-
|
51
60
|
self.configuration.withdrawable_assets =
|
52
|
-
|
61
|
+
convert_config!(withdrawable_assets)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def self.convert_config!(asset_config)
|
67
|
+
array_of_hashes = try_from_yaml_file_path(asset_config) ||
|
68
|
+
try_from_json(asset_config)
|
69
|
+
|
70
|
+
array_of_hashes.map(&:with_indifferent_access)
|
53
71
|
end
|
54
72
|
|
55
73
|
def self.try_from_json(str)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
|
3
|
+
factory :stellar_base_deposit_request, class: "StellarBase::DepositRequest" do
|
4
|
+
deposit_address { "dep-addr" }
|
5
|
+
issuer { "issuer-addr" }
|
6
|
+
memo_type { "text" }
|
7
|
+
memo { "ABAC" }
|
8
|
+
min_amount { 0 }
|
9
|
+
max_amount { 0 }
|
10
|
+
email_address { "test@test.com" }
|
11
|
+
account_id { "G-STELLAR-ACCT" }
|
12
|
+
deposit_type { "" }
|
13
|
+
fee_fixed { 0 }
|
14
|
+
fee_percent { 0 }
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/lib/stellar_base/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stellar_base-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ace Subido
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: disposable
|
@@ -294,11 +294,15 @@ files:
|
|
294
294
|
- app/concepts/stellar_base/bridge_callbacks/bridge_callback_policy.rb
|
295
295
|
- app/concepts/stellar_base/bridge_callbacks/contracts/create.rb
|
296
296
|
- app/concepts/stellar_base/bridge_callbacks/operations/create.rb
|
297
|
+
- app/concepts/stellar_base/deposit_requests/contracts/create.rb
|
298
|
+
- app/concepts/stellar_base/deposit_requests/deposit_request_policy.rb
|
299
|
+
- app/concepts/stellar_base/deposit_requests/operations/create.rb
|
297
300
|
- app/concepts/stellar_base/withdrawal_requests/contracts/create.rb
|
298
301
|
- app/concepts/stellar_base/withdrawal_requests/operations/create.rb
|
299
302
|
- app/concepts/stellar_base/withdrawal_requests/withdrawal_request_policy.rb
|
300
303
|
- app/controllers/stellar_base/application_controller.rb
|
301
304
|
- app/controllers/stellar_base/bridge_callbacks_controller.rb
|
305
|
+
- app/controllers/stellar_base/deposit_controller.rb
|
302
306
|
- app/controllers/stellar_base/home_controller.rb
|
303
307
|
- app/controllers/stellar_base/withdraw_controller.rb
|
304
308
|
- app/helpers/stellar_base/application_helper.rb
|
@@ -306,10 +310,12 @@ files:
|
|
306
310
|
- app/mailers/stellar_base/application_mailer.rb
|
307
311
|
- app/models/stellar_base/application_record.rb
|
308
312
|
- app/models/stellar_base/bridge_callback.rb
|
313
|
+
- app/models/stellar_base/deposit_request.rb
|
309
314
|
- app/models/stellar_base/stellar_toml.rb
|
310
315
|
- app/models/stellar_base/withdrawal_request.rb
|
311
|
-
- app/representers/application_representer.rb
|
312
|
-
- app/representers/
|
316
|
+
- app/representers/stellar_base/application_representer.rb
|
317
|
+
- app/representers/stellar_base/deposit_request_representer.rb
|
318
|
+
- app/representers/stellar_base/withdrawal_request_representer.rb
|
313
319
|
- app/services/stellar_base/bridge_callbacks/check.rb
|
314
320
|
- app/services/stellar_base/bridge_callbacks/compare.rb
|
315
321
|
- app/services/stellar_base/bridge_callbacks/get_operation.rb
|
@@ -322,27 +328,32 @@ files:
|
|
322
328
|
- app/services/stellar_base/bridge_callbacks/mac_payloads/encode_params.rb
|
323
329
|
- app/services/stellar_base/bridge_callbacks/process.rb
|
324
330
|
- app/services/stellar_base/bridge_callbacks/verify_mac_payload.rb
|
331
|
+
- app/services/stellar_base/configured_class_runner.rb
|
332
|
+
- app/services/stellar_base/deposit_requests/find_depositable_asset.rb
|
333
|
+
- app/services/stellar_base/gen_memo_for.rb
|
325
334
|
- app/services/stellar_base/gen_random_string.rb
|
326
335
|
- app/services/stellar_base/withdrawal_requests/call_on_withdraw.rb
|
327
336
|
- app/services/stellar_base/withdrawal_requests/determine_fee.rb
|
328
337
|
- app/services/stellar_base/withdrawal_requests/determine_max_amount.rb
|
329
338
|
- app/services/stellar_base/withdrawal_requests/find_withdrawable_asset.rb
|
330
339
|
- app/services/stellar_base/withdrawal_requests/find_withdrawal_request.rb
|
331
|
-
- app/services/stellar_base/withdrawal_requests/gen_memo.rb
|
332
340
|
- app/services/stellar_base/withdrawal_requests/process.rb
|
333
|
-
- app/twins/application_twin.rb
|
334
|
-
- app/twins/
|
341
|
+
- app/twins/stellar_base/application_twin.rb
|
342
|
+
- app/twins/stellar_base/deposit_request_twin.rb
|
343
|
+
- app/twins/stellar_base/withdrawal_request_twin.rb
|
335
344
|
- app/views/layouts/stellar_base/application.html.erb
|
336
345
|
- config/routes.rb
|
337
346
|
- config/spring.rb
|
338
347
|
- db/migrate/20180816014433_create_stellar_base_bridge_callbacks.rb
|
339
348
|
- db/migrate/20180816110314_create_stellar_base_withdrawal_requests.rb
|
340
349
|
- db/migrate/20180816135847_unique_stellar_base_bridge_callbacks_operation_id.rb
|
350
|
+
- db/migrate/20180925045927_create_stellar_base_deposit_requests.rb
|
341
351
|
- lib/stellar_base-rails.rb
|
342
352
|
- lib/stellar_base.rb
|
343
353
|
- lib/stellar_base/engine.rb
|
344
354
|
- lib/stellar_base/factories.rb
|
345
355
|
- lib/stellar_base/factories/bridge_callbacks.rb
|
356
|
+
- lib/stellar_base/factories/deposit_requests.rb
|
346
357
|
- lib/stellar_base/factories/withdrawal_requests.rb
|
347
358
|
- lib/stellar_base/horizon_client.rb
|
348
359
|
- lib/stellar_base/rails/routes.rb
|
@@ -1,13 +0,0 @@
|
|
1
|
-
class WithdrawalRequestRepresenter < ApplicationRepresenter
|
2
|
-
|
3
|
-
property :account_id
|
4
|
-
property :memo_type
|
5
|
-
property :memo
|
6
|
-
property :min_amount
|
7
|
-
property :max_amount
|
8
|
-
property :fee_fixed
|
9
|
-
property :fee_percent
|
10
|
-
property :fee_network
|
11
|
-
property :extra_info
|
12
|
-
|
13
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module StellarBase
|
2
|
-
module WithdrawalRequests
|
3
|
-
class GenMemo
|
4
|
-
|
5
|
-
LENGTH = 8
|
6
|
-
|
7
|
-
def self.call
|
8
|
-
loop do
|
9
|
-
memo = GenRandomString.(length: LENGTH)
|
10
|
-
if !WithdrawalRequest.exists?(memo: memo)
|
11
|
-
return memo
|
12
|
-
break
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
class WithdrawalRequestTwin < ApplicationTwin
|
2
|
-
|
3
|
-
property :account_id
|
4
|
-
property :memo_type
|
5
|
-
property :memo
|
6
|
-
property :min_amount
|
7
|
-
property :max_amount
|
8
|
-
property :fee_fixed
|
9
|
-
property :fee_percent
|
10
|
-
property :fee_network
|
11
|
-
property :extra_info
|
12
|
-
|
13
|
-
end
|