digitalbits-base 0.27.1

Sign up to get free protection for your applications and to get access to all the features.
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