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.
Files changed (252) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +202 -0
  3. data/README.md +84 -0
  4. data/generated/digitalbits-base-generated.rb +228 -0
  5. data/generated/digitalbits/account_entry.rb +55 -0
  6. data/generated/digitalbits/account_entry/ext.rb +28 -0
  7. data/generated/digitalbits/account_entry_extension_v1.rb +32 -0
  8. data/generated/digitalbits/account_entry_extension_v1/ext.rb +28 -0
  9. data/generated/digitalbits/account_entry_extension_v2.rb +34 -0
  10. data/generated/digitalbits/account_entry_extension_v2/ext.rb +24 -0
  11. data/generated/digitalbits/account_flags.rb +31 -0
  12. data/generated/digitalbits/account_merge_result.rb +26 -0
  13. data/generated/digitalbits/account_merge_result_code.rb +37 -0
  14. data/generated/digitalbits/allow_trust_op.rb +39 -0
  15. data/generated/digitalbits/allow_trust_op/asset.rb +33 -0
  16. data/generated/digitalbits/allow_trust_result.rb +25 -0
  17. data/generated/digitalbits/allow_trust_result_code.rb +33 -0
  18. data/generated/digitalbits/asset.rb +47 -0
  19. data/generated/digitalbits/asset/alpha_num12.rb +22 -0
  20. data/generated/digitalbits/asset/alpha_num4.rb +22 -0
  21. data/generated/digitalbits/asset_type.rb +24 -0
  22. data/generated/digitalbits/auth.rb +20 -0
  23. data/generated/digitalbits/auth_cert.rb +22 -0
  24. data/generated/digitalbits/authenticated_message.rb +32 -0
  25. data/generated/digitalbits/authenticated_message/v0.rb +24 -0
  26. data/generated/digitalbits/begin_sponsoring_future_reserves_op.rb +18 -0
  27. data/generated/digitalbits/begin_sponsoring_future_reserves_result.rb +25 -0
  28. data/generated/digitalbits/begin_sponsoring_future_reserves_result_code.rb +29 -0
  29. data/generated/digitalbits/bucket_entry.rb +34 -0
  30. data/generated/digitalbits/bucket_entry_type.rb +28 -0
  31. data/generated/digitalbits/bucket_metadata.rb +32 -0
  32. data/generated/digitalbits/bucket_metadata/ext.rb +24 -0
  33. data/generated/digitalbits/bump_sequence_op.rb +18 -0
  34. data/generated/digitalbits/bump_sequence_result.rb +25 -0
  35. data/generated/digitalbits/bump_sequence_result_code.rb +24 -0
  36. data/generated/digitalbits/change_trust_op.rb +22 -0
  37. data/generated/digitalbits/change_trust_result.rb +25 -0
  38. data/generated/digitalbits/change_trust_result_code.rb +34 -0
  39. data/generated/digitalbits/claim_claimable_balance_op.rb +18 -0
  40. data/generated/digitalbits/claim_claimable_balance_result.rb +25 -0
  41. data/generated/digitalbits/claim_claimable_balance_result_code.rb +31 -0
  42. data/generated/digitalbits/claim_offer_atom.rb +33 -0
  43. data/generated/digitalbits/claim_predicate.rb +43 -0
  44. data/generated/digitalbits/claim_predicate_type.rb +30 -0
  45. data/generated/digitalbits/claimable_balance_entry.rb +44 -0
  46. data/generated/digitalbits/claimable_balance_entry/ext.rb +24 -0
  47. data/generated/digitalbits/claimable_balance_id.rb +23 -0
  48. data/generated/digitalbits/claimable_balance_id_type.rb +20 -0
  49. data/generated/digitalbits/claimant.rb +31 -0
  50. data/generated/digitalbits/claimant/v0.rb +22 -0
  51. data/generated/digitalbits/claimant_type.rb +20 -0
  52. data/generated/digitalbits/create_account_op.rb +20 -0
  53. data/generated/digitalbits/create_account_result.rb +25 -0
  54. data/generated/digitalbits/create_account_result_code.rb +32 -0
  55. data/generated/digitalbits/create_claimable_balance_op.rb +22 -0
  56. data/generated/digitalbits/create_claimable_balance_result.rb +27 -0
  57. data/generated/digitalbits/create_claimable_balance_result_code.rb +30 -0
  58. data/generated/digitalbits/create_passive_sell_offer_op.rb +24 -0
  59. data/generated/digitalbits/crypto_key_type.rb +28 -0
  60. data/generated/digitalbits/curve25519_public.rb +18 -0
  61. data/generated/digitalbits/curve25519_secret.rb +18 -0
  62. data/generated/digitalbits/data_entry.rb +35 -0
  63. data/generated/digitalbits/data_entry/ext.rb +24 -0
  64. data/generated/digitalbits/decorated_signature.rb +20 -0
  65. data/generated/digitalbits/digital_bits_message.rb +84 -0
  66. data/generated/digitalbits/digital_bits_value.rb +43 -0
  67. data/generated/digitalbits/digital_bits_value/ext.rb +28 -0
  68. data/generated/digitalbits/digital_bits_value_type.rb +22 -0
  69. data/generated/digitalbits/dont_have.rb +20 -0
  70. data/generated/digitalbits/end_sponsoring_future_reserves_result.rb +25 -0
  71. data/generated/digitalbits/end_sponsoring_future_reserves_result_code.rb +25 -0
  72. data/generated/digitalbits/envelope_type.rb +32 -0
  73. data/generated/digitalbits/error.rb +20 -0
  74. data/generated/digitalbits/error_code.rb +28 -0
  75. data/generated/digitalbits/fee_bump_transaction.rb +39 -0
  76. data/generated/digitalbits/fee_bump_transaction/ext.rb +24 -0
  77. data/generated/digitalbits/fee_bump_transaction/inner_tx.rb +25 -0
  78. data/generated/digitalbits/fee_bump_transaction_envelope.rb +22 -0
  79. data/generated/digitalbits/hello.rb +34 -0
  80. data/generated/digitalbits/hmac_sha256_key.rb +18 -0
  81. data/generated/digitalbits/hmac_sha256_mac.rb +18 -0
  82. data/generated/digitalbits/inflation_payout.rb +20 -0
  83. data/generated/digitalbits/inflation_result.rb +26 -0
  84. data/generated/digitalbits/inflation_result_code.rb +24 -0
  85. data/generated/digitalbits/inner_transaction_result.rb +57 -0
  86. data/generated/digitalbits/inner_transaction_result/ext.rb +24 -0
  87. data/generated/digitalbits/inner_transaction_result/result.rb +54 -0
  88. data/generated/digitalbits/inner_transaction_result_pair.rb +20 -0
  89. data/generated/digitalbits/ip_addr_type.rb +22 -0
  90. data/generated/digitalbits/ledger_close_meta.rb +23 -0
  91. data/generated/digitalbits/ledger_close_meta_v0.rb +35 -0
  92. data/generated/digitalbits/ledger_close_value_signature.rb +20 -0
  93. data/generated/digitalbits/ledger_entry.rb +50 -0
  94. data/generated/digitalbits/ledger_entry/data.rb +41 -0
  95. data/generated/digitalbits/ledger_entry/ext.rb +28 -0
  96. data/generated/digitalbits/ledger_entry_change.rb +35 -0
  97. data/generated/digitalbits/ledger_entry_change_type.rb +26 -0
  98. data/generated/digitalbits/ledger_entry_extension_v1.rb +30 -0
  99. data/generated/digitalbits/ledger_entry_extension_v1/ext.rb +24 -0
  100. data/generated/digitalbits/ledger_entry_type.rb +28 -0
  101. data/generated/digitalbits/ledger_header.rb +69 -0
  102. data/generated/digitalbits/ledger_header/ext.rb +24 -0
  103. data/generated/digitalbits/ledger_header_history_entry.rb +33 -0
  104. data/generated/digitalbits/ledger_header_history_entry/ext.rb +24 -0
  105. data/generated/digitalbits/ledger_key.rb +69 -0
  106. data/generated/digitalbits/ledger_key/account.rb +20 -0
  107. data/generated/digitalbits/ledger_key/claimable_balance.rb +20 -0
  108. data/generated/digitalbits/ledger_key/data.rb +22 -0
  109. data/generated/digitalbits/ledger_key/offer.rb +22 -0
  110. data/generated/digitalbits/ledger_key/trust_line.rb +22 -0
  111. data/generated/digitalbits/ledger_scp_messages.rb +20 -0
  112. data/generated/digitalbits/ledger_upgrade.rb +35 -0
  113. data/generated/digitalbits/ledger_upgrade_type.rb +26 -0
  114. data/generated/digitalbits/liabilities.rb +20 -0
  115. data/generated/digitalbits/manage_buy_offer_op.rb +29 -0
  116. data/generated/digitalbits/manage_buy_offer_result.rb +26 -0
  117. data/generated/digitalbits/manage_buy_offer_result_code.rb +51 -0
  118. data/generated/digitalbits/manage_data_op.rb +20 -0
  119. data/generated/digitalbits/manage_data_result.rb +25 -0
  120. data/generated/digitalbits/manage_data_result_code.rb +32 -0
  121. data/generated/digitalbits/manage_offer_effect.rb +24 -0
  122. data/generated/digitalbits/manage_offer_success_result.rb +34 -0
  123. data/generated/digitalbits/manage_offer_success_result/offer.rb +30 -0
  124. data/generated/digitalbits/manage_sell_offer_op.rb +28 -0
  125. data/generated/digitalbits/manage_sell_offer_result.rb +26 -0
  126. data/generated/digitalbits/manage_sell_offer_result_code.rb +54 -0
  127. data/generated/digitalbits/memo.rb +38 -0
  128. data/generated/digitalbits/memo_type.rb +28 -0
  129. data/generated/digitalbits/message_type.rb +56 -0
  130. data/generated/digitalbits/muxed_account.rb +35 -0
  131. data/generated/digitalbits/muxed_account/med25519.rb +22 -0
  132. data/generated/digitalbits/offer_entry.rb +49 -0
  133. data/generated/digitalbits/offer_entry/ext.rb +24 -0
  134. data/generated/digitalbits/offer_entry_flags.rb +21 -0
  135. data/generated/digitalbits/operation.rb +69 -0
  136. data/generated/digitalbits/operation/body.rb +95 -0
  137. data/generated/digitalbits/operation_id.rb +32 -0
  138. data/generated/digitalbits/operation_id/id.rb +24 -0
  139. data/generated/digitalbits/operation_meta.rb +18 -0
  140. data/generated/digitalbits/operation_result.rb +71 -0
  141. data/generated/digitalbits/operation_result/tr.rb +97 -0
  142. data/generated/digitalbits/operation_result_code.rb +33 -0
  143. data/generated/digitalbits/operation_type.rb +56 -0
  144. data/generated/digitalbits/path_payment_strict_receive_op.rb +32 -0
  145. data/generated/digitalbits/path_payment_strict_receive_result.rb +39 -0
  146. data/generated/digitalbits/path_payment_strict_receive_result/success.rb +22 -0
  147. data/generated/digitalbits/path_payment_strict_receive_result_code.rb +56 -0
  148. data/generated/digitalbits/path_payment_strict_send_op.rb +32 -0
  149. data/generated/digitalbits/path_payment_strict_send_result.rb +38 -0
  150. data/generated/digitalbits/path_payment_strict_send_result/success.rb +22 -0
  151. data/generated/digitalbits/path_payment_strict_send_result_code.rb +55 -0
  152. data/generated/digitalbits/payment_op.rb +22 -0
  153. data/generated/digitalbits/payment_result.rb +25 -0
  154. data/generated/digitalbits/payment_result_code.rb +41 -0
  155. data/generated/digitalbits/peer_address.rb +33 -0
  156. data/generated/digitalbits/peer_address/ip.rb +29 -0
  157. data/generated/digitalbits/peer_stats.rb +48 -0
  158. data/generated/digitalbits/price.rb +20 -0
  159. data/generated/digitalbits/public_key.rb +23 -0
  160. data/generated/digitalbits/public_key_type.rb +20 -0
  161. data/generated/digitalbits/revoke_sponsorship_op.rb +36 -0
  162. data/generated/digitalbits/revoke_sponsorship_op/signer.rb +22 -0
  163. data/generated/digitalbits/revoke_sponsorship_result.rb +25 -0
  164. data/generated/digitalbits/revoke_sponsorship_result_code.rb +31 -0
  165. data/generated/digitalbits/revoke_sponsorship_type.rb +22 -0
  166. data/generated/digitalbits/scp_ballot.rb +20 -0
  167. data/generated/digitalbits/scp_envelope.rb +20 -0
  168. data/generated/digitalbits/scp_history_entry.rb +23 -0
  169. data/generated/digitalbits/scp_history_entry_v0.rb +20 -0
  170. data/generated/digitalbits/scp_nomination.rb +22 -0
  171. data/generated/digitalbits/scp_quorum_set.rb +22 -0
  172. data/generated/digitalbits/scp_statement.rb +58 -0
  173. data/generated/digitalbits/scp_statement/pledges.rb +63 -0
  174. data/generated/digitalbits/scp_statement/pledges/confirm.rb +30 -0
  175. data/generated/digitalbits/scp_statement/pledges/externalize.rb +26 -0
  176. data/generated/digitalbits/scp_statement/pledges/prepare.rb +32 -0
  177. data/generated/digitalbits/scp_statement_type.rb +26 -0
  178. data/generated/digitalbits/set_options_op.rb +41 -0
  179. data/generated/digitalbits/set_options_result.rb +25 -0
  180. data/generated/digitalbits/set_options_result_code.rb +40 -0
  181. data/generated/digitalbits/signed_survey_request_message.rb +20 -0
  182. data/generated/digitalbits/signed_survey_response_message.rb +20 -0
  183. data/generated/digitalbits/signer.rb +20 -0
  184. data/generated/digitalbits/signer_key.rb +33 -0
  185. data/generated/digitalbits/signer_key_type.rb +24 -0
  186. data/generated/digitalbits/simple_payment_result.rb +22 -0
  187. data/generated/digitalbits/survey_message_command_type.rb +20 -0
  188. data/generated/digitalbits/survey_request_message.rb +26 -0
  189. data/generated/digitalbits/survey_response_body.rb +23 -0
  190. data/generated/digitalbits/survey_response_message.rb +26 -0
  191. data/generated/digitalbits/threshold_indexes.rb +26 -0
  192. data/generated/digitalbits/time_bounds.rb +20 -0
  193. data/generated/digitalbits/topology_response_body.rb +25 -0
  194. data/generated/digitalbits/transaction.rb +50 -0
  195. data/generated/digitalbits/transaction/ext.rb +24 -0
  196. data/generated/digitalbits/transaction_envelope.rb +31 -0
  197. data/generated/digitalbits/transaction_history_entry.rb +33 -0
  198. data/generated/digitalbits/transaction_history_entry/ext.rb +24 -0
  199. data/generated/digitalbits/transaction_history_result_entry.rb +33 -0
  200. data/generated/digitalbits/transaction_history_result_entry/ext.rb +24 -0
  201. data/generated/digitalbits/transaction_meta.rb +31 -0
  202. data/generated/digitalbits/transaction_meta_v1.rb +20 -0
  203. data/generated/digitalbits/transaction_meta_v2.rb +24 -0
  204. data/generated/digitalbits/transaction_result.rb +46 -0
  205. data/generated/digitalbits/transaction_result/ext.rb +24 -0
  206. data/generated/digitalbits/transaction_result/result.rb +36 -0
  207. data/generated/digitalbits/transaction_result_code.rb +54 -0
  208. data/generated/digitalbits/transaction_result_meta.rb +22 -0
  209. data/generated/digitalbits/transaction_result_pair.rb +20 -0
  210. data/generated/digitalbits/transaction_result_set.rb +18 -0
  211. data/generated/digitalbits/transaction_set.rb +20 -0
  212. data/generated/digitalbits/transaction_signature_payload.rb +32 -0
  213. data/generated/digitalbits/transaction_signature_payload/tagged_transaction.rb +30 -0
  214. data/generated/digitalbits/transaction_v0.rb +39 -0
  215. data/generated/digitalbits/transaction_v0/ext.rb +24 -0
  216. data/generated/digitalbits/transaction_v0_envelope.rb +22 -0
  217. data/generated/digitalbits/transaction_v1_envelope.rb +22 -0
  218. data/generated/digitalbits/trust_line_entry.rb +53 -0
  219. data/generated/digitalbits/trust_line_entry/ext.rb +42 -0
  220. data/generated/digitalbits/trust_line_entry/ext/v1.rb +34 -0
  221. data/generated/digitalbits/trust_line_entry/ext/v1/ext.rb +28 -0
  222. data/generated/digitalbits/trust_line_flags.rb +25 -0
  223. data/generated/digitalbits/upgrade_entry_meta.rb +20 -0
  224. data/lib/digitalbits-base.rb +51 -0
  225. data/lib/digitalbits/account_flags.rb +26 -0
  226. data/lib/digitalbits/asset.rb +81 -0
  227. data/lib/digitalbits/base.rb +1 -0
  228. data/lib/digitalbits/claim_predicate.rb +197 -0
  229. data/lib/digitalbits/compat.rb +9 -0
  230. data/lib/digitalbits/concerns/transaction.rb +50 -0
  231. data/lib/digitalbits/convert.rb +32 -0
  232. data/lib/digitalbits/dsl.rb +93 -0
  233. data/lib/digitalbits/ext/xdr.rb +50 -0
  234. data/lib/digitalbits/factories.rb +59 -0
  235. data/lib/digitalbits/fee_bump_transaction.rb +21 -0
  236. data/lib/digitalbits/key_pair.rb +126 -0
  237. data/lib/digitalbits/ledger_key.rb +32 -0
  238. data/lib/digitalbits/muxed_account.rb +16 -0
  239. data/lib/digitalbits/networks.rb +43 -0
  240. data/lib/digitalbits/operation.rb +603 -0
  241. data/lib/digitalbits/path_payment_strict_receive_result.rb +16 -0
  242. data/lib/digitalbits/price.rb +39 -0
  243. data/lib/digitalbits/signer_key.rb +46 -0
  244. data/lib/digitalbits/thresholds.rb +37 -0
  245. data/lib/digitalbits/transaction.rb +37 -0
  246. data/lib/digitalbits/transaction_builder.rb +166 -0
  247. data/lib/digitalbits/transaction_envelope.rb +35 -0
  248. data/lib/digitalbits/transaction_v0.rb +43 -0
  249. data/lib/digitalbits/trust_line_flags.rb +53 -0
  250. data/lib/digitalbits/util/strkey.rb +70 -0
  251. data/lib/digitalbits/version.rb +3 -0
  252. 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