digitalbits-base 0.27.1
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/LICENSE +202 -0
- data/README.md +84 -0
- data/generated/digitalbits-base-generated.rb +228 -0
- data/generated/digitalbits/account_entry.rb +55 -0
- data/generated/digitalbits/account_entry/ext.rb +28 -0
- data/generated/digitalbits/account_entry_extension_v1.rb +32 -0
- data/generated/digitalbits/account_entry_extension_v1/ext.rb +28 -0
- data/generated/digitalbits/account_entry_extension_v2.rb +34 -0
- data/generated/digitalbits/account_entry_extension_v2/ext.rb +24 -0
- data/generated/digitalbits/account_flags.rb +31 -0
- data/generated/digitalbits/account_merge_result.rb +26 -0
- data/generated/digitalbits/account_merge_result_code.rb +37 -0
- data/generated/digitalbits/allow_trust_op.rb +39 -0
- data/generated/digitalbits/allow_trust_op/asset.rb +33 -0
- data/generated/digitalbits/allow_trust_result.rb +25 -0
- data/generated/digitalbits/allow_trust_result_code.rb +33 -0
- data/generated/digitalbits/asset.rb +47 -0
- data/generated/digitalbits/asset/alpha_num12.rb +22 -0
- data/generated/digitalbits/asset/alpha_num4.rb +22 -0
- data/generated/digitalbits/asset_type.rb +24 -0
- data/generated/digitalbits/auth.rb +20 -0
- data/generated/digitalbits/auth_cert.rb +22 -0
- data/generated/digitalbits/authenticated_message.rb +32 -0
- data/generated/digitalbits/authenticated_message/v0.rb +24 -0
- data/generated/digitalbits/begin_sponsoring_future_reserves_op.rb +18 -0
- data/generated/digitalbits/begin_sponsoring_future_reserves_result.rb +25 -0
- data/generated/digitalbits/begin_sponsoring_future_reserves_result_code.rb +29 -0
- data/generated/digitalbits/bucket_entry.rb +34 -0
- data/generated/digitalbits/bucket_entry_type.rb +28 -0
- data/generated/digitalbits/bucket_metadata.rb +32 -0
- data/generated/digitalbits/bucket_metadata/ext.rb +24 -0
- data/generated/digitalbits/bump_sequence_op.rb +18 -0
- data/generated/digitalbits/bump_sequence_result.rb +25 -0
- data/generated/digitalbits/bump_sequence_result_code.rb +24 -0
- data/generated/digitalbits/change_trust_op.rb +22 -0
- data/generated/digitalbits/change_trust_result.rb +25 -0
- data/generated/digitalbits/change_trust_result_code.rb +34 -0
- data/generated/digitalbits/claim_claimable_balance_op.rb +18 -0
- data/generated/digitalbits/claim_claimable_balance_result.rb +25 -0
- data/generated/digitalbits/claim_claimable_balance_result_code.rb +31 -0
- data/generated/digitalbits/claim_offer_atom.rb +33 -0
- data/generated/digitalbits/claim_predicate.rb +43 -0
- data/generated/digitalbits/claim_predicate_type.rb +30 -0
- data/generated/digitalbits/claimable_balance_entry.rb +44 -0
- data/generated/digitalbits/claimable_balance_entry/ext.rb +24 -0
- data/generated/digitalbits/claimable_balance_id.rb +23 -0
- data/generated/digitalbits/claimable_balance_id_type.rb +20 -0
- data/generated/digitalbits/claimant.rb +31 -0
- data/generated/digitalbits/claimant/v0.rb +22 -0
- data/generated/digitalbits/claimant_type.rb +20 -0
- data/generated/digitalbits/create_account_op.rb +20 -0
- data/generated/digitalbits/create_account_result.rb +25 -0
- data/generated/digitalbits/create_account_result_code.rb +32 -0
- data/generated/digitalbits/create_claimable_balance_op.rb +22 -0
- data/generated/digitalbits/create_claimable_balance_result.rb +27 -0
- data/generated/digitalbits/create_claimable_balance_result_code.rb +30 -0
- data/generated/digitalbits/create_passive_sell_offer_op.rb +24 -0
- data/generated/digitalbits/crypto_key_type.rb +28 -0
- data/generated/digitalbits/curve25519_public.rb +18 -0
- data/generated/digitalbits/curve25519_secret.rb +18 -0
- data/generated/digitalbits/data_entry.rb +35 -0
- data/generated/digitalbits/data_entry/ext.rb +24 -0
- data/generated/digitalbits/decorated_signature.rb +20 -0
- data/generated/digitalbits/digital_bits_message.rb +84 -0
- data/generated/digitalbits/digital_bits_value.rb +43 -0
- data/generated/digitalbits/digital_bits_value/ext.rb +28 -0
- data/generated/digitalbits/digital_bits_value_type.rb +22 -0
- data/generated/digitalbits/dont_have.rb +20 -0
- data/generated/digitalbits/end_sponsoring_future_reserves_result.rb +25 -0
- data/generated/digitalbits/end_sponsoring_future_reserves_result_code.rb +25 -0
- data/generated/digitalbits/envelope_type.rb +32 -0
- data/generated/digitalbits/error.rb +20 -0
- data/generated/digitalbits/error_code.rb +28 -0
- data/generated/digitalbits/fee_bump_transaction.rb +39 -0
- data/generated/digitalbits/fee_bump_transaction/ext.rb +24 -0
- data/generated/digitalbits/fee_bump_transaction/inner_tx.rb +25 -0
- data/generated/digitalbits/fee_bump_transaction_envelope.rb +22 -0
- data/generated/digitalbits/hello.rb +34 -0
- data/generated/digitalbits/hmac_sha256_key.rb +18 -0
- data/generated/digitalbits/hmac_sha256_mac.rb +18 -0
- data/generated/digitalbits/inflation_payout.rb +20 -0
- data/generated/digitalbits/inflation_result.rb +26 -0
- data/generated/digitalbits/inflation_result_code.rb +24 -0
- data/generated/digitalbits/inner_transaction_result.rb +57 -0
- data/generated/digitalbits/inner_transaction_result/ext.rb +24 -0
- data/generated/digitalbits/inner_transaction_result/result.rb +54 -0
- data/generated/digitalbits/inner_transaction_result_pair.rb +20 -0
- data/generated/digitalbits/ip_addr_type.rb +22 -0
- data/generated/digitalbits/ledger_close_meta.rb +23 -0
- data/generated/digitalbits/ledger_close_meta_v0.rb +35 -0
- data/generated/digitalbits/ledger_close_value_signature.rb +20 -0
- data/generated/digitalbits/ledger_entry.rb +50 -0
- data/generated/digitalbits/ledger_entry/data.rb +41 -0
- data/generated/digitalbits/ledger_entry/ext.rb +28 -0
- data/generated/digitalbits/ledger_entry_change.rb +35 -0
- data/generated/digitalbits/ledger_entry_change_type.rb +26 -0
- data/generated/digitalbits/ledger_entry_extension_v1.rb +30 -0
- data/generated/digitalbits/ledger_entry_extension_v1/ext.rb +24 -0
- data/generated/digitalbits/ledger_entry_type.rb +28 -0
- data/generated/digitalbits/ledger_header.rb +69 -0
- data/generated/digitalbits/ledger_header/ext.rb +24 -0
- data/generated/digitalbits/ledger_header_history_entry.rb +33 -0
- data/generated/digitalbits/ledger_header_history_entry/ext.rb +24 -0
- data/generated/digitalbits/ledger_key.rb +69 -0
- data/generated/digitalbits/ledger_key/account.rb +20 -0
- data/generated/digitalbits/ledger_key/claimable_balance.rb +20 -0
- data/generated/digitalbits/ledger_key/data.rb +22 -0
- data/generated/digitalbits/ledger_key/offer.rb +22 -0
- data/generated/digitalbits/ledger_key/trust_line.rb +22 -0
- data/generated/digitalbits/ledger_scp_messages.rb +20 -0
- data/generated/digitalbits/ledger_upgrade.rb +35 -0
- data/generated/digitalbits/ledger_upgrade_type.rb +26 -0
- data/generated/digitalbits/liabilities.rb +20 -0
- data/generated/digitalbits/manage_buy_offer_op.rb +29 -0
- data/generated/digitalbits/manage_buy_offer_result.rb +26 -0
- data/generated/digitalbits/manage_buy_offer_result_code.rb +51 -0
- data/generated/digitalbits/manage_data_op.rb +20 -0
- data/generated/digitalbits/manage_data_result.rb +25 -0
- data/generated/digitalbits/manage_data_result_code.rb +32 -0
- data/generated/digitalbits/manage_offer_effect.rb +24 -0
- data/generated/digitalbits/manage_offer_success_result.rb +34 -0
- data/generated/digitalbits/manage_offer_success_result/offer.rb +30 -0
- data/generated/digitalbits/manage_sell_offer_op.rb +28 -0
- data/generated/digitalbits/manage_sell_offer_result.rb +26 -0
- data/generated/digitalbits/manage_sell_offer_result_code.rb +54 -0
- data/generated/digitalbits/memo.rb +38 -0
- data/generated/digitalbits/memo_type.rb +28 -0
- data/generated/digitalbits/message_type.rb +56 -0
- data/generated/digitalbits/muxed_account.rb +35 -0
- data/generated/digitalbits/muxed_account/med25519.rb +22 -0
- data/generated/digitalbits/offer_entry.rb +49 -0
- data/generated/digitalbits/offer_entry/ext.rb +24 -0
- data/generated/digitalbits/offer_entry_flags.rb +21 -0
- data/generated/digitalbits/operation.rb +69 -0
- data/generated/digitalbits/operation/body.rb +95 -0
- data/generated/digitalbits/operation_id.rb +32 -0
- data/generated/digitalbits/operation_id/id.rb +24 -0
- data/generated/digitalbits/operation_meta.rb +18 -0
- data/generated/digitalbits/operation_result.rb +71 -0
- data/generated/digitalbits/operation_result/tr.rb +97 -0
- data/generated/digitalbits/operation_result_code.rb +33 -0
- data/generated/digitalbits/operation_type.rb +56 -0
- data/generated/digitalbits/path_payment_strict_receive_op.rb +32 -0
- data/generated/digitalbits/path_payment_strict_receive_result.rb +39 -0
- data/generated/digitalbits/path_payment_strict_receive_result/success.rb +22 -0
- data/generated/digitalbits/path_payment_strict_receive_result_code.rb +56 -0
- data/generated/digitalbits/path_payment_strict_send_op.rb +32 -0
- data/generated/digitalbits/path_payment_strict_send_result.rb +38 -0
- data/generated/digitalbits/path_payment_strict_send_result/success.rb +22 -0
- data/generated/digitalbits/path_payment_strict_send_result_code.rb +55 -0
- data/generated/digitalbits/payment_op.rb +22 -0
- data/generated/digitalbits/payment_result.rb +25 -0
- data/generated/digitalbits/payment_result_code.rb +41 -0
- data/generated/digitalbits/peer_address.rb +33 -0
- data/generated/digitalbits/peer_address/ip.rb +29 -0
- data/generated/digitalbits/peer_stats.rb +48 -0
- data/generated/digitalbits/price.rb +20 -0
- data/generated/digitalbits/public_key.rb +23 -0
- data/generated/digitalbits/public_key_type.rb +20 -0
- data/generated/digitalbits/revoke_sponsorship_op.rb +36 -0
- data/generated/digitalbits/revoke_sponsorship_op/signer.rb +22 -0
- data/generated/digitalbits/revoke_sponsorship_result.rb +25 -0
- data/generated/digitalbits/revoke_sponsorship_result_code.rb +31 -0
- data/generated/digitalbits/revoke_sponsorship_type.rb +22 -0
- data/generated/digitalbits/scp_ballot.rb +20 -0
- data/generated/digitalbits/scp_envelope.rb +20 -0
- data/generated/digitalbits/scp_history_entry.rb +23 -0
- data/generated/digitalbits/scp_history_entry_v0.rb +20 -0
- data/generated/digitalbits/scp_nomination.rb +22 -0
- data/generated/digitalbits/scp_quorum_set.rb +22 -0
- data/generated/digitalbits/scp_statement.rb +58 -0
- data/generated/digitalbits/scp_statement/pledges.rb +63 -0
- data/generated/digitalbits/scp_statement/pledges/confirm.rb +30 -0
- data/generated/digitalbits/scp_statement/pledges/externalize.rb +26 -0
- data/generated/digitalbits/scp_statement/pledges/prepare.rb +32 -0
- data/generated/digitalbits/scp_statement_type.rb +26 -0
- data/generated/digitalbits/set_options_op.rb +41 -0
- data/generated/digitalbits/set_options_result.rb +25 -0
- data/generated/digitalbits/set_options_result_code.rb +40 -0
- data/generated/digitalbits/signed_survey_request_message.rb +20 -0
- data/generated/digitalbits/signed_survey_response_message.rb +20 -0
- data/generated/digitalbits/signer.rb +20 -0
- data/generated/digitalbits/signer_key.rb +33 -0
- data/generated/digitalbits/signer_key_type.rb +24 -0
- data/generated/digitalbits/simple_payment_result.rb +22 -0
- data/generated/digitalbits/survey_message_command_type.rb +20 -0
- data/generated/digitalbits/survey_request_message.rb +26 -0
- data/generated/digitalbits/survey_response_body.rb +23 -0
- data/generated/digitalbits/survey_response_message.rb +26 -0
- data/generated/digitalbits/threshold_indexes.rb +26 -0
- data/generated/digitalbits/time_bounds.rb +20 -0
- data/generated/digitalbits/topology_response_body.rb +25 -0
- data/generated/digitalbits/transaction.rb +50 -0
- data/generated/digitalbits/transaction/ext.rb +24 -0
- data/generated/digitalbits/transaction_envelope.rb +31 -0
- data/generated/digitalbits/transaction_history_entry.rb +33 -0
- data/generated/digitalbits/transaction_history_entry/ext.rb +24 -0
- data/generated/digitalbits/transaction_history_result_entry.rb +33 -0
- data/generated/digitalbits/transaction_history_result_entry/ext.rb +24 -0
- data/generated/digitalbits/transaction_meta.rb +31 -0
- data/generated/digitalbits/transaction_meta_v1.rb +20 -0
- data/generated/digitalbits/transaction_meta_v2.rb +24 -0
- data/generated/digitalbits/transaction_result.rb +46 -0
- data/generated/digitalbits/transaction_result/ext.rb +24 -0
- data/generated/digitalbits/transaction_result/result.rb +36 -0
- data/generated/digitalbits/transaction_result_code.rb +54 -0
- data/generated/digitalbits/transaction_result_meta.rb +22 -0
- data/generated/digitalbits/transaction_result_pair.rb +20 -0
- data/generated/digitalbits/transaction_result_set.rb +18 -0
- data/generated/digitalbits/transaction_set.rb +20 -0
- data/generated/digitalbits/transaction_signature_payload.rb +32 -0
- data/generated/digitalbits/transaction_signature_payload/tagged_transaction.rb +30 -0
- data/generated/digitalbits/transaction_v0.rb +39 -0
- data/generated/digitalbits/transaction_v0/ext.rb +24 -0
- data/generated/digitalbits/transaction_v0_envelope.rb +22 -0
- data/generated/digitalbits/transaction_v1_envelope.rb +22 -0
- data/generated/digitalbits/trust_line_entry.rb +53 -0
- data/generated/digitalbits/trust_line_entry/ext.rb +42 -0
- data/generated/digitalbits/trust_line_entry/ext/v1.rb +34 -0
- data/generated/digitalbits/trust_line_entry/ext/v1/ext.rb +28 -0
- data/generated/digitalbits/trust_line_flags.rb +25 -0
- data/generated/digitalbits/upgrade_entry_meta.rb +20 -0
- data/lib/digitalbits-base.rb +51 -0
- data/lib/digitalbits/account_flags.rb +26 -0
- data/lib/digitalbits/asset.rb +81 -0
- data/lib/digitalbits/base.rb +1 -0
- data/lib/digitalbits/claim_predicate.rb +197 -0
- data/lib/digitalbits/compat.rb +9 -0
- data/lib/digitalbits/concerns/transaction.rb +50 -0
- data/lib/digitalbits/convert.rb +32 -0
- data/lib/digitalbits/dsl.rb +93 -0
- data/lib/digitalbits/ext/xdr.rb +50 -0
- data/lib/digitalbits/factories.rb +59 -0
- data/lib/digitalbits/fee_bump_transaction.rb +21 -0
- data/lib/digitalbits/key_pair.rb +126 -0
- data/lib/digitalbits/ledger_key.rb +32 -0
- data/lib/digitalbits/muxed_account.rb +16 -0
- data/lib/digitalbits/networks.rb +43 -0
- data/lib/digitalbits/operation.rb +603 -0
- data/lib/digitalbits/path_payment_strict_receive_result.rb +16 -0
- data/lib/digitalbits/price.rb +39 -0
- data/lib/digitalbits/signer_key.rb +46 -0
- data/lib/digitalbits/thresholds.rb +37 -0
- data/lib/digitalbits/transaction.rb +37 -0
- data/lib/digitalbits/transaction_builder.rb +166 -0
- data/lib/digitalbits/transaction_envelope.rb +35 -0
- data/lib/digitalbits/transaction_v0.rb +43 -0
- data/lib/digitalbits/trust_line_flags.rb +53 -0
- data/lib/digitalbits/util/strkey.rb +70 -0
- data/lib/digitalbits/version.rb +3 -0
- metadata +459 -0
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
require "bigdecimal"
|
|
2
|
+
|
|
3
|
+
module DigitalBits
|
|
4
|
+
class Operation
|
|
5
|
+
MAX_INT64 = 2**63 - 1
|
|
6
|
+
TRUST_LINE_FLAGS_MAPPING = {
|
|
7
|
+
full: DigitalBits::TrustLineFlags.authorized_flag,
|
|
8
|
+
maintain_liabilities: DigitalBits::TrustLineFlags.authorized_to_maintain_liabilities_flag,
|
|
9
|
+
clawback_enabled: DigitalBits::TrustLineFlags.trustline_clawback_enabled_flag
|
|
10
|
+
}.freeze
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
include DigitalBits::DSL
|
|
14
|
+
#
|
|
15
|
+
# Construct a new DigitalBits::Operation from the provided
|
|
16
|
+
# source account and body
|
|
17
|
+
#
|
|
18
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
19
|
+
# @option attributes [DigitalBits::KeyPair] :source_account
|
|
20
|
+
# @option attributes [DigitalBits::Operation::Body] :body
|
|
21
|
+
#
|
|
22
|
+
# @return [DigitalBits::Operation] the built operation
|
|
23
|
+
def make(attributes = {})
|
|
24
|
+
source_account = attributes[:source_account]
|
|
25
|
+
|
|
26
|
+
if source_account && !source_account.is_a?(DigitalBits::KeyPair)
|
|
27
|
+
raise ArgumentError, "Bad :source_account"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
body = DigitalBits::Operation::Body.new(*attributes[:body])
|
|
31
|
+
|
|
32
|
+
DigitalBits::Operation.new(
|
|
33
|
+
body: body,
|
|
34
|
+
source_account: source_account&.muxed_account
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# Helper method to create a valid PaymentOp, wrapped
|
|
40
|
+
# in the necessary XDR structs to be included within a
|
|
41
|
+
# transactions `operations` array.
|
|
42
|
+
#
|
|
43
|
+
# @see DigitalBits::Asset
|
|
44
|
+
#
|
|
45
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
46
|
+
# @option attributes [DigitalBits::KeyPair] :destination the receiver of the payment
|
|
47
|
+
# @option attributes [Array] :amount the amount to pay
|
|
48
|
+
# @return [DigitalBits::Operation] the built operation, containing a
|
|
49
|
+
# DigitalBits::PaymentOp body
|
|
50
|
+
def payment(attributes = {})
|
|
51
|
+
destination = attributes[:destination]
|
|
52
|
+
asset, amount = get_asset_amount(attributes[:amount])
|
|
53
|
+
|
|
54
|
+
raise ArgumentError unless destination.is_a?(KeyPair)
|
|
55
|
+
|
|
56
|
+
op = PaymentOp.new
|
|
57
|
+
op.asset = asset
|
|
58
|
+
op.amount = amount
|
|
59
|
+
op.destination = destination.muxed_account
|
|
60
|
+
|
|
61
|
+
make(attributes.merge({
|
|
62
|
+
body: [:payment, op]
|
|
63
|
+
}))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# Helper method to create a valid PathPaymentStrictReceiveOp, wrapped
|
|
68
|
+
# in the necessary XDR structs to be included within a
|
|
69
|
+
# transactions `operations` array.
|
|
70
|
+
#
|
|
71
|
+
# @deprecated Please use Operation.path_payment_strict_receive
|
|
72
|
+
#
|
|
73
|
+
# @see DigitalBits::Asset
|
|
74
|
+
#
|
|
75
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
76
|
+
# @option attributes [DigitalBits::KeyPair] :destination the receiver of the payment
|
|
77
|
+
# @option attributes [Array] :amount the destination asset and the amount to pay
|
|
78
|
+
# @option attributes [Array] :with the source asset and maximum allowed source amount to pay with
|
|
79
|
+
# @option attributes [Array<DigitalBits::Asset>] :path the payment path to use
|
|
80
|
+
#
|
|
81
|
+
# @return [DigitalBits::Operation] the built operation, containing a DigitalBits::PaymentOp body
|
|
82
|
+
#
|
|
83
|
+
def path_payment(attributes = {})
|
|
84
|
+
path_payment_strict_receive(attributes)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
#
|
|
88
|
+
# Helper method to create a valid PathPaymentStrictReceiveOp, wrapped
|
|
89
|
+
# in the necessary XDR structs to be included within a
|
|
90
|
+
# transactions `operations` array.
|
|
91
|
+
#
|
|
92
|
+
# @see DigitalBits::Asset
|
|
93
|
+
#
|
|
94
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
95
|
+
# @option attributes [DigitalBits::KeyPair] :destination the receiver of the payment
|
|
96
|
+
# @option attributes [Array] :amount the destination asset and the amount to pay
|
|
97
|
+
# @option attributes [Array] :with the source asset and maximum allowed source amount to pay with
|
|
98
|
+
# @option attributes [Array<DigitalBits::Asset>] :path the payment path to use
|
|
99
|
+
#
|
|
100
|
+
# @return [DigitalBits::Operation] the built operation, containing a DigitalBits::PaymentOp body
|
|
101
|
+
#
|
|
102
|
+
def path_payment_strict_receive(attributes = {})
|
|
103
|
+
destination = attributes[:destination]
|
|
104
|
+
asset, amount = get_asset_amount(attributes[:amount])
|
|
105
|
+
send_asset, send_max = get_asset_amount(attributes[:with])
|
|
106
|
+
path = (attributes[:path] || []).map { |p|
|
|
107
|
+
p.is_a?(Array) ? DigitalBits::Asset.send(*p) : p
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
raise ArgumentError unless destination.is_a?(KeyPair)
|
|
111
|
+
|
|
112
|
+
op = PathPaymentStrictReceiveOp.new
|
|
113
|
+
op.send_asset = send_asset
|
|
114
|
+
op.send_max = send_max
|
|
115
|
+
op.destination = destination.muxed_account
|
|
116
|
+
op.dest_asset = asset
|
|
117
|
+
op.dest_amount = amount
|
|
118
|
+
op.path = path
|
|
119
|
+
|
|
120
|
+
make(attributes.merge({
|
|
121
|
+
body: [:path_payment_strict_receive, op]
|
|
122
|
+
}))
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
#
|
|
126
|
+
# Helper method to create a valid PathPaymentStrictSendOp, wrapped
|
|
127
|
+
# in the necessary XDR structs to be included within a
|
|
128
|
+
# transactions `operations` array.
|
|
129
|
+
#
|
|
130
|
+
# @see DigitalBits::Asset
|
|
131
|
+
#
|
|
132
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
133
|
+
# @option attributes [DigitalBits::KeyPair] :destination the receiver of the payment
|
|
134
|
+
# @option attributes [Array] :amount the destination asset and the minimum amount of destination asset to be received
|
|
135
|
+
# @option attributes [Array] :with the source asset and amount to pay with
|
|
136
|
+
# @option attributes [Array<DigitalBits::Asset>] :path the payment path to use
|
|
137
|
+
#
|
|
138
|
+
# @return [DigitalBits::Operation] the built operation, containing a DigitalBits::PaymentOp body
|
|
139
|
+
#
|
|
140
|
+
def path_payment_strict_send(attributes = {})
|
|
141
|
+
destination = attributes[:destination]
|
|
142
|
+
asset, dest_min = get_asset_amount(attributes[:amount])
|
|
143
|
+
send_asset, send_amount = get_asset_amount(attributes[:with])
|
|
144
|
+
path = (attributes[:path] || []).map { |p|
|
|
145
|
+
p.is_a?(Array) ? DigitalBits::Asset.send(*p) : p
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
raise ArgumentError unless destination.is_a?(KeyPair)
|
|
149
|
+
|
|
150
|
+
op = PathPaymentStrictSendOp.new
|
|
151
|
+
op.send_asset = send_asset
|
|
152
|
+
op.send_amount = send_amount
|
|
153
|
+
op.destination = destination.muxed_account
|
|
154
|
+
op.dest_asset = asset
|
|
155
|
+
op.dest_min = dest_min
|
|
156
|
+
op.path = path
|
|
157
|
+
|
|
158
|
+
make(attributes.merge({
|
|
159
|
+
body: [:path_payment_strict_send, op]
|
|
160
|
+
}))
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def create_account(attributes = {})
|
|
164
|
+
destination = attributes[:destination]
|
|
165
|
+
starting_balance = interpret_amount(attributes[:starting_balance])
|
|
166
|
+
|
|
167
|
+
raise ArgumentError unless destination.is_a?(KeyPair)
|
|
168
|
+
|
|
169
|
+
op = CreateAccountOp.new
|
|
170
|
+
op.destination = destination.account_id
|
|
171
|
+
op.starting_balance = starting_balance
|
|
172
|
+
|
|
173
|
+
make(attributes.merge({
|
|
174
|
+
body: [:create_account, op]
|
|
175
|
+
}))
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Helper method to create a valid ChangeTrustOp, wrapped
|
|
179
|
+
# in the necessary XDR structs to be included within a
|
|
180
|
+
# transactions `operations` array.
|
|
181
|
+
#
|
|
182
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
183
|
+
# @option attributes [DigitalBits::Asset] :line the asset to trust
|
|
184
|
+
# @option attributes [Fixnum] :limit the maximum amount to trust, defaults to max int64,
|
|
185
|
+
# if the limit is set to 0 it deletes the trustline.
|
|
186
|
+
#
|
|
187
|
+
# @return [DigitalBits::Operation] the built operation, containing a
|
|
188
|
+
# DigitalBits::ChangeTrustOp body
|
|
189
|
+
def change_trust(attributes = {})
|
|
190
|
+
line = attributes[:line]
|
|
191
|
+
unless line.is_a?(Asset)
|
|
192
|
+
unless Asset::TYPES.include?(line[0])
|
|
193
|
+
fail ArgumentError, "must be one of #{Asset::TYPES}"
|
|
194
|
+
end
|
|
195
|
+
line = Asset.send(*line)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
limit = attributes.key?(:limit) ? interpret_amount(attributes[:limit]) : MAX_INT64
|
|
199
|
+
|
|
200
|
+
raise ArgumentError, "Bad :limit #{limit}" unless limit.is_a?(Integer)
|
|
201
|
+
|
|
202
|
+
op = ChangeTrustOp.new(line: line, limit: limit)
|
|
203
|
+
|
|
204
|
+
make(attributes.merge({
|
|
205
|
+
body: [:change_trust, op]
|
|
206
|
+
}))
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Helper method to create a valid CreateClaimableBalanceOp, ready to be used
|
|
210
|
+
# within a transactions `operations` array.
|
|
211
|
+
#
|
|
212
|
+
# @see DigitalBits::DSL::Claimant
|
|
213
|
+
#
|
|
214
|
+
# @param asset [Asset] the asset to transfer to a claimable balance
|
|
215
|
+
# @param amount [Fixnum] the amount of `asset` to put into a claimable balance
|
|
216
|
+
# @param claimants [Array<Claimant>] accounts authorized to claim the balance in the future
|
|
217
|
+
#
|
|
218
|
+
# @return [Operation] the built operation
|
|
219
|
+
def create_claimable_balance(asset:, amount:, claimants:, **attributes)
|
|
220
|
+
op = CreateClaimableBalanceOp.new(asset: asset, amount: amount, claimants: claimants)
|
|
221
|
+
|
|
222
|
+
make(attributes.merge(body: [:create_claimable_balance, op]))
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Helper method to create a valid CreateClaimableBalanceOp, ready to be used
|
|
226
|
+
# within a transactions `operations` array.
|
|
227
|
+
#
|
|
228
|
+
# @see DigitalBits::DSL::Claimant
|
|
229
|
+
#
|
|
230
|
+
# @param balance_id [ClaimableBalanceID] unique ID of claimable balance
|
|
231
|
+
#
|
|
232
|
+
# @return [Operation] the built operation, containing a DigitalBits::ChangeTrustOp body
|
|
233
|
+
def claim_claimable_balance(balance_id:, **attributes)
|
|
234
|
+
op = ClaimClaimableBalanceOp.new(balance_id: balance_id)
|
|
235
|
+
|
|
236
|
+
make(attributes.merge(body: [:claim_claimable_balance, op]))
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def begin_sponsoring_future_reserves(sponsored:, **attributes)
|
|
240
|
+
op = BeginSponsoringFutureReservesOp.new(
|
|
241
|
+
sponsored_id: KeyPair(sponsored).account_id
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
make(attributes.merge(body: [:begin_sponsoring_future_reserves, op]))
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def end_sponsoring_future_reserves(**attributes)
|
|
248
|
+
make(attributes.merge(body: [:end_sponsoring_future_reserves]))
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# @param sponsored [#to_keypair] owner of sponsored entry
|
|
252
|
+
def revoke_sponsorship(sponsored:, **attributes)
|
|
253
|
+
key_fields = attributes.slice(:offer_id, :data_name, :balance_id, :asset, :signer)
|
|
254
|
+
raise ArgumentError, "conflicting attributes: #{key_fields.keys.join(", ")}" if key_fields.size > 1
|
|
255
|
+
account_id = KeyPair(sponsored).account_id
|
|
256
|
+
key, value = key_fields.first
|
|
257
|
+
op = if key == :signer
|
|
258
|
+
RevokeSponsorshipOp.signer(account_id: account_id, signer_key: SignerKey(value))
|
|
259
|
+
else
|
|
260
|
+
RevokeSponsorshipOp.ledger_key(LedgerKey.from(account_id: account_id, **key_fields))
|
|
261
|
+
end
|
|
262
|
+
make(attributes.merge(body: [:revoke_sponsorship, op]))
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def manage_sell_offer(attributes = {})
|
|
266
|
+
buying = attributes[:buying]
|
|
267
|
+
if buying.is_a?(Array)
|
|
268
|
+
buying = Asset.send(*buying)
|
|
269
|
+
end
|
|
270
|
+
selling = attributes[:selling]
|
|
271
|
+
if selling.is_a?(Array)
|
|
272
|
+
selling = Asset.send(*selling)
|
|
273
|
+
end
|
|
274
|
+
amount = interpret_amount(attributes[:amount])
|
|
275
|
+
offer_id = attributes[:offer_id] || 0
|
|
276
|
+
price = interpret_price(attributes[:price])
|
|
277
|
+
|
|
278
|
+
op = ManageSellOfferOp.new({
|
|
279
|
+
buying: buying,
|
|
280
|
+
selling: selling,
|
|
281
|
+
amount: amount,
|
|
282
|
+
price: price,
|
|
283
|
+
offer_id: offer_id
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
make(attributes.merge({
|
|
287
|
+
body: [:manage_sell_offer, op]
|
|
288
|
+
}))
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def manage_buy_offer(attributes = {})
|
|
292
|
+
buying = attributes[:buying]
|
|
293
|
+
if buying.is_a?(Array)
|
|
294
|
+
buying = Asset.send(*buying)
|
|
295
|
+
end
|
|
296
|
+
selling = attributes[:selling]
|
|
297
|
+
if selling.is_a?(Array)
|
|
298
|
+
selling = Asset.send(*selling)
|
|
299
|
+
end
|
|
300
|
+
amount = interpret_amount(attributes[:amount])
|
|
301
|
+
offer_id = attributes[:offer_id] || 0
|
|
302
|
+
price = interpret_price(attributes[:price])
|
|
303
|
+
|
|
304
|
+
op = ManageBuyOfferOp.new({
|
|
305
|
+
buying: buying,
|
|
306
|
+
selling: selling,
|
|
307
|
+
buy_amount: amount,
|
|
308
|
+
price: price,
|
|
309
|
+
offer_id: offer_id
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
make(attributes.merge({
|
|
313
|
+
body: [:manage_buy_offer, op]
|
|
314
|
+
}))
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def create_passive_sell_offer(attributes = {})
|
|
318
|
+
buying = attributes[:buying]
|
|
319
|
+
if buying.is_a?(Array)
|
|
320
|
+
buying = Asset.send(*buying)
|
|
321
|
+
end
|
|
322
|
+
selling = attributes[:selling]
|
|
323
|
+
if selling.is_a?(Array)
|
|
324
|
+
selling = Asset.send(*selling)
|
|
325
|
+
end
|
|
326
|
+
amount = interpret_amount(attributes[:amount])
|
|
327
|
+
price = interpret_price(attributes[:price])
|
|
328
|
+
|
|
329
|
+
op = CreatePassiveSellOfferOp.new({
|
|
330
|
+
buying: buying,
|
|
331
|
+
selling: selling,
|
|
332
|
+
amount: amount,
|
|
333
|
+
price: price
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
make(attributes.merge({
|
|
337
|
+
body: [:create_passive_sell_offer, op]
|
|
338
|
+
}))
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
#
|
|
342
|
+
# Helper method to create a valid SetOptionsOp, wrapped
|
|
343
|
+
# in the necessary XDR structs to be included within a
|
|
344
|
+
# transactions `operations` array.
|
|
345
|
+
#
|
|
346
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
347
|
+
# @option attributes [DigitalBits::KeyPair] :inflation_dest
|
|
348
|
+
# @option attributes [Array<DigitalBits::AccountFlags>] :set flags to set
|
|
349
|
+
# @option attributes [Array<DigitalBits::AccountFlags>] :clear flags to clear
|
|
350
|
+
# @option attributes [String] :thresholds
|
|
351
|
+
# @option attributes [DigitalBits::Signer] :signer
|
|
352
|
+
#
|
|
353
|
+
# @return [DigitalBits::Operation] the built operation, containing a
|
|
354
|
+
# DigitalBits::SetOptionsOp body
|
|
355
|
+
def set_options(attributes = {})
|
|
356
|
+
op = SetOptionsOp.new
|
|
357
|
+
op.set_flags = DigitalBits::AccountFlags.make_mask attributes[:set]
|
|
358
|
+
op.clear_flags = DigitalBits::AccountFlags.make_mask attributes[:clear]
|
|
359
|
+
op.master_weight = attributes[:master_weight]
|
|
360
|
+
op.low_threshold = attributes[:low_threshold]
|
|
361
|
+
op.med_threshold = attributes[:med_threshold]
|
|
362
|
+
op.high_threshold = attributes[:high_threshold]
|
|
363
|
+
|
|
364
|
+
op.signer = attributes[:signer]
|
|
365
|
+
op.home_domain = attributes[:home_domain]
|
|
366
|
+
|
|
367
|
+
inflation_dest = attributes[:inflation_dest]
|
|
368
|
+
if inflation_dest
|
|
369
|
+
raise ArgumentError, "Bad :inflation_dest" unless inflation_dest.is_a?(DigitalBits::KeyPair)
|
|
370
|
+
op.inflation_dest = inflation_dest.account_id
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
make(attributes.merge({
|
|
374
|
+
body: [:set_options, op]
|
|
375
|
+
}))
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# @param asset [DigitalBits::Asset]
|
|
379
|
+
# @param trustor [DigitalBits::KeyPair]
|
|
380
|
+
# @param flags [{String, Symbol, DigitalBits::TrustLineFlags => true, false}] flags to to set or clear
|
|
381
|
+
# @param source_account [DigitalBits::KeyPair] source account (default is `nil`, which will use the source account of transaction)
|
|
382
|
+
def set_trust_line_flags(asset:, trustor:, flags: {}, source_account: nil)
|
|
383
|
+
op = DigitalBits::SetTrustLineFlagsOp.new
|
|
384
|
+
op.trustor = KeyPair(trustor).account_id
|
|
385
|
+
op.asset = Asset(asset)
|
|
386
|
+
op.attributes = DigitalBits::TrustLineFlags.set_clear_masks(flags)
|
|
387
|
+
|
|
388
|
+
make(
|
|
389
|
+
source_account: source_account,
|
|
390
|
+
body: [:set_trust_line_flags, op]
|
|
391
|
+
)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# DEPRECATED in favor of `set_trustline_flags`
|
|
395
|
+
#
|
|
396
|
+
# Helper method to create a valid AllowTrustOp, wrapped
|
|
397
|
+
# in the necessary XDR structs to be included within a
|
|
398
|
+
# transactions `operations` array.
|
|
399
|
+
#
|
|
400
|
+
# @deprecated Use `set_trustline_flags` operation
|
|
401
|
+
#
|
|
402
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
403
|
+
# @option attributes [DigitalBits::KeyPair] :trustor
|
|
404
|
+
# @option attributes [DigitalBits::Asset] :asset
|
|
405
|
+
# @option attributes [Symbol, Boolean] :authorize :full, maintain_liabilities or :none
|
|
406
|
+
#
|
|
407
|
+
# @return [DigitalBits::Operation] the built operation, containing a
|
|
408
|
+
# DigitalBits::AllowTrustOp body
|
|
409
|
+
def allow_trust(attributes = {})
|
|
410
|
+
op = AllowTrustOp.new
|
|
411
|
+
|
|
412
|
+
trustor = attributes[:trustor]
|
|
413
|
+
# we handle booleans here for the backward compatibility
|
|
414
|
+
authorize = attributes[:authorize].yield_self { |value| value == true ? :full : value }
|
|
415
|
+
asset = attributes[:asset]
|
|
416
|
+
if asset.is_a?(Array)
|
|
417
|
+
asset = Asset.send(*asset)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
raise ArgumentError, "Bad :trustor" unless trustor.is_a?(DigitalBits::KeyPair)
|
|
421
|
+
|
|
422
|
+
allowed_flags = TRUST_LINE_FLAGS_MAPPING.slice(:full, :maintain_liabilities)
|
|
423
|
+
|
|
424
|
+
# we handle booleans here for the backward compatibility
|
|
425
|
+
op.authorize = if allowed_flags.key?(authorize)
|
|
426
|
+
allowed_flags[authorize].value
|
|
427
|
+
elsif [:none, false].include?(authorize)
|
|
428
|
+
0
|
|
429
|
+
else
|
|
430
|
+
raise ArgumentError, "Bad :authorize, supported values: :full, :maintain_liabilities, :none"
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
raise ArgumentError, "Bad :asset" unless asset.type == DigitalBits::AssetType.asset_type_credit_alphanum4
|
|
434
|
+
|
|
435
|
+
op.trustor = trustor.account_id
|
|
436
|
+
op.asset = AssetCode.new(:asset_type_credit_alphanum4, asset.code)
|
|
437
|
+
|
|
438
|
+
make(attributes.merge({
|
|
439
|
+
body: [:allow_trust, op]
|
|
440
|
+
}))
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
#
|
|
444
|
+
# Helper method to create an account merge operation
|
|
445
|
+
#
|
|
446
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
447
|
+
# @option attributes [DigitalBits::KeyPair] :destination
|
|
448
|
+
#
|
|
449
|
+
# @return [DigitalBits::Operation] the built operation
|
|
450
|
+
def account_merge(attributes = {})
|
|
451
|
+
destination = attributes[:destination]
|
|
452
|
+
|
|
453
|
+
raise ArgumentError, "Bad :destination" unless destination.is_a?(KeyPair)
|
|
454
|
+
|
|
455
|
+
# TODO: add source_account support
|
|
456
|
+
make(attributes.merge({
|
|
457
|
+
body: [:account_merge, destination.muxed_account]
|
|
458
|
+
}))
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
#
|
|
462
|
+
# Helper method to create an inflation operation
|
|
463
|
+
#
|
|
464
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
465
|
+
# @option attributes [Integer] :sequence
|
|
466
|
+
#
|
|
467
|
+
# @return [DigitalBits::Operation] the built operation
|
|
468
|
+
def inflation(attributes = {})
|
|
469
|
+
sequence = attributes[:sequence]
|
|
470
|
+
|
|
471
|
+
raise ArgumentError, "Bad :sequence #{sequence}" unless sequence.is_a?(Integer)
|
|
472
|
+
|
|
473
|
+
# TODO: add source_account support
|
|
474
|
+
make(attributes.merge({
|
|
475
|
+
body: [:inflation]
|
|
476
|
+
}))
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
#
|
|
480
|
+
# Helper method to create an manage data operation
|
|
481
|
+
#
|
|
482
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
483
|
+
# @option attributes [Integer] :sequence
|
|
484
|
+
#
|
|
485
|
+
# @return [DigitalBits::Operation] the built operation
|
|
486
|
+
def manage_data(attributes = {})
|
|
487
|
+
op = ManageDataOp.new
|
|
488
|
+
|
|
489
|
+
name = attributes[:name]
|
|
490
|
+
value = attributes[:value]
|
|
491
|
+
|
|
492
|
+
raise ArgumentError, "Invalid :name" unless name.is_a?(String)
|
|
493
|
+
raise ArgumentError, ":name too long" unless name.bytesize <= 64
|
|
494
|
+
|
|
495
|
+
if value.present?
|
|
496
|
+
raise ArgumentError, ":value too long" unless value.bytesize <= 64
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
op.data_name = name
|
|
500
|
+
op.data_value = value
|
|
501
|
+
|
|
502
|
+
make(attributes.merge({
|
|
503
|
+
body: [:manage_data, op]
|
|
504
|
+
}))
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
def bump_sequence(attributes = {})
|
|
508
|
+
op = BumpSequenceOp.new
|
|
509
|
+
|
|
510
|
+
bump_to = attributes[:bump_to]
|
|
511
|
+
|
|
512
|
+
raise ArgumentError, ":bump_to too big" unless bump_to <= MAX_INT64
|
|
513
|
+
|
|
514
|
+
op.bump_to = bump_to
|
|
515
|
+
|
|
516
|
+
make(attributes.merge({
|
|
517
|
+
body: [:bump_sequence, op]
|
|
518
|
+
}))
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
def clawback(source_account:, from:, amount:)
|
|
522
|
+
asset, amount = get_asset_amount(amount)
|
|
523
|
+
|
|
524
|
+
if amount == 0
|
|
525
|
+
raise ArgumentError, "Amount can not be zero"
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
if amount < 0
|
|
529
|
+
raise ArgumentError, "Negative amount is not allowed"
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
op = ClawbackOp.new(
|
|
533
|
+
amount: amount,
|
|
534
|
+
from: from.muxed_account,
|
|
535
|
+
asset: asset
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
make({
|
|
539
|
+
source_account: source_account,
|
|
540
|
+
body: [:clawback, op]
|
|
541
|
+
})
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
# Helper method to create clawback claimable balance operation
|
|
545
|
+
#
|
|
546
|
+
# @param [DigitalBits::KeyPair] source_account the attributes to create the operation with
|
|
547
|
+
# @param [String] balance_id `ClaimableBalanceID`, serialized in hex
|
|
548
|
+
#
|
|
549
|
+
# @return [DigitalBits::Operation] the built operation
|
|
550
|
+
def clawback_claimable_balance(source_account:, balance_id:)
|
|
551
|
+
balance_id = DigitalBits::ClaimableBalanceID.from_xdr(balance_id, :hex)
|
|
552
|
+
op = ClawbackClaimableBalanceOp.new(balance_id: balance_id)
|
|
553
|
+
|
|
554
|
+
make(
|
|
555
|
+
source_account: source_account,
|
|
556
|
+
body: [:clawback_claimable_balance, op]
|
|
557
|
+
)
|
|
558
|
+
rescue XDR::ReadError
|
|
559
|
+
raise ArgumentError, "Claimable balance id '#{balance_id}' is invalid"
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
private
|
|
563
|
+
|
|
564
|
+
def get_asset_amount(values)
|
|
565
|
+
amount = interpret_amount(values.last)
|
|
566
|
+
asset = if values[0].is_a?(DigitalBits::Asset)
|
|
567
|
+
values.first
|
|
568
|
+
else
|
|
569
|
+
DigitalBits::Asset.send(*values[0...-1])
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
[asset, amount]
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
def interpret_amount(amount)
|
|
576
|
+
case amount
|
|
577
|
+
when String
|
|
578
|
+
(BigDecimal(amount) * DigitalBits::ONE).floor
|
|
579
|
+
when Integer
|
|
580
|
+
amount * DigitalBits::ONE
|
|
581
|
+
when Numeric
|
|
582
|
+
(amount * DigitalBits::ONE).floor
|
|
583
|
+
else
|
|
584
|
+
raise ArgumentError, "Invalid amount type: #{amount.class}. Must be String or Numeric"
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
def interpret_price(price)
|
|
589
|
+
case price
|
|
590
|
+
when String
|
|
591
|
+
bd = BigDecimal(price)
|
|
592
|
+
Price.from_f(bd)
|
|
593
|
+
when Numeric
|
|
594
|
+
Price.from_f(price)
|
|
595
|
+
when DigitalBits::Price
|
|
596
|
+
price
|
|
597
|
+
else
|
|
598
|
+
raise ArgumentError, "Invalid price type: #{price.class}. Must be String, Numeric, or DigitalBits::Price"
|
|
599
|
+
end
|
|
600
|
+
end
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
end
|