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,16 @@
1
+ module DigitalBits
2
+ class PathPaymentStrictReceiveResult
3
+ # send_amount returns the actual amount paid for the corresponding
4
+ # PathPaymentOp to this result.
5
+ #
6
+ def send_amount
7
+ s = success!
8
+ return s.last.amount if s.offers.blank?
9
+
10
+ source_asset = s.offers.first.asset_bought
11
+ source_offers = s.offers.take_while { |o| o.asset_bought == source_asset }
12
+
13
+ source_offers.map(&:amount_bought).sum
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ module DigitalBits
2
+ # reopen class
3
+ class Price
4
+ MAX_PRECISION = (2**31) - 1
5
+
6
+ def self.from_f(number)
7
+ best_r = number.to_r.rationalize(1.0e-7)
8
+
9
+ if best_r.numerator > MAX_PRECISION || best_r.denominator > MAX_PRECISION
10
+ raise ArgumentError("Couldn't find price approximation")
11
+ end
12
+
13
+ new({
14
+ n: best_r.numerator,
15
+ d: best_r.denominator
16
+ })
17
+ end
18
+
19
+ def invert
20
+ self.class.new(n: d, d: n)
21
+ end
22
+
23
+ def to_d
24
+ n.to_d / d
25
+ end
26
+
27
+ def to_f
28
+ n.to_f / d
29
+ end
30
+
31
+ def to_s
32
+ "#{n} / #{d}"
33
+ end
34
+
35
+ def inspect
36
+ "#<DigitalBits::Price #{self}>"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,46 @@
1
+ module DigitalBits
2
+ class SignerKey
3
+ PREIMAGE_LENGTH = 32
4
+
5
+ def self.ed25519(keypair)
6
+ raise ArgumentError, "Bad keypair" unless keypair.is_a?(KeyPair)
7
+ new(:signer_key_type_ed25519, keypair.raw_public_key)
8
+ end
9
+
10
+ def self.preauthorized_transaction(tx)
11
+ new(:signer_key_type_pre_auth_tx, tx.hash)
12
+ end
13
+
14
+ def self.hash_x(preimage)
15
+ raise ArgumentError, "Must be string" unless preimage.is_a?(String)
16
+ raise ArgumentError, "Must be 32 bytes" unless preimage.bytesize == PREIMAGE_LENGTH
17
+
18
+ hash_x = Digest::SHA256.digest(preimage)
19
+ new(:signer_key_type_hash_x, hash_x)
20
+ end
21
+
22
+ def to_s
23
+ case switch
24
+ when SignerKeyType.signer_key_type_ed25519
25
+ address = DigitalBits::Convert.pk_to_address(self)
26
+ "ed25519: #{address}"
27
+ when SignerKeyType.signer_key_type_pre_auth_tx
28
+ tx = DigitalBits::Convert.to_hex(pre_auth_tx!)
29
+ "pre_auth_tx: #{tx}"
30
+ when SignerKeyType.signer_key_type_hash_x
31
+ hx = DigitalBits::Convert.to_hex(hash_x!)
32
+ "hash_x: #{hx}"
33
+ end
34
+ end
35
+
36
+ def inspect
37
+ # label = switch.to_s
38
+ "#<DigitalBits::SignerKey #{self}>"
39
+ end
40
+
41
+ def signature_hint
42
+ # take last 4 bytes
43
+ value.to_xdr.slice(-4, 4)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,37 @@
1
+ module DigitalBits
2
+ class << Thresholds
3
+ COMPONENTS = [:master_weight, :low, :medium, :high]
4
+ VALID_RANGE = 0..255
5
+
6
+ def make(thresholds = {})
7
+ # error if any of the needed components are not provided
8
+ if COMPONENTS.any? { |c| thresholds[c].blank? }
9
+ raise ArgumentError, "invalid thresholds hash, must have #{COMPONENTS.inspect} keys, had: #{thresholds.keys.inspect}"
10
+ end
11
+
12
+ # error if any of the needed components are not numbers 0 <= N <= 255
13
+ COMPONENTS.each do |c|
14
+ good = true
15
+
16
+ good &&= thresholds[c].is_a?(Integer)
17
+ good &&= VALID_RANGE.include? thresholds[c]
18
+
19
+ unless good
20
+ raise ArgumentError, "invalid #{c.inspect}, must be number in (0..255), got #{thresholds[c].inspect}"
21
+ end
22
+ end
23
+
24
+ thresholds.values_at(*COMPONENTS).pack("C*")
25
+ end
26
+
27
+ def parse(combined)
28
+ master_weight, low, medium, high = combined.unpack("C*")
29
+ {
30
+ master_weight: master_weight,
31
+ low: low,
32
+ medium: medium,
33
+ high: high
34
+ }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ module DigitalBits
2
+ class Transaction
3
+ include DigitalBits::Concerns::Transaction
4
+
5
+ def to_v0
6
+ ed25519 = if source_account.switch == DigitalBits::CryptoKeyType.key_type_ed25519
7
+ source_account.ed25519!
8
+ else
9
+ source_account.med25519!.ed25519
10
+ end
11
+
12
+ TransactionV0.new(
13
+ source_account_ed25519: ed25519,
14
+ seq_num: seq_num,
15
+ operations: operations,
16
+ fee: fee,
17
+ memo: memo,
18
+ time_bounds: time_bounds,
19
+ ext: ext
20
+ )
21
+ end
22
+
23
+ def signature_base
24
+ tagged_tx = DigitalBits::TransactionSignaturePayload::TaggedTransaction.new(:envelope_type_tx, self)
25
+ DigitalBits::TransactionSignaturePayload.new(
26
+ network_id: DigitalBits.current_network_id,
27
+ tagged_transaction: tagged_tx
28
+ ).to_xdr
29
+ end
30
+
31
+ def to_envelope(*key_pairs)
32
+ signatures = key_pairs.map(&method(:sign_decorated))
33
+
34
+ TransactionEnvelope.v1(signatures: signatures, tx: self)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,166 @@
1
+ module DigitalBits
2
+ class TransactionBuilder
3
+ attr_reader :source_account, :sequence_number, :base_fee, :time_bounds, :memo, :operations
4
+
5
+ class << self
6
+ # This enable user to call shortcut methods, like
7
+ # TransactionBuilder.payment(...),
8
+ # TransactionBuilder.manage_data(...) and etc.
9
+ # It reduces the boilerplate, when you just need to
10
+ # shoot a single operation in transaction
11
+ def method_missing(method_name, *args, **kwargs)
12
+ unless DigitalBits::Operation.respond_to?(method_name)
13
+ return super
14
+ end
15
+
16
+ op = DigitalBits::Operation.send(method_name, **kwargs)
17
+
18
+ new(**kwargs).add_operation(op).build
19
+ end
20
+
21
+ def respond_to_missing?(method_name, include_private = false)
22
+ DigitalBits::Operation.respond_to?(method_name) || super
23
+ end
24
+ end
25
+
26
+ def initialize(
27
+ source_account:,
28
+ sequence_number:,
29
+ base_fee: 100,
30
+ time_bounds: nil,
31
+ memo: nil,
32
+ **_ # ignore any additional parameters without errors
33
+ )
34
+ raise ArgumentError, "Bad :source_account" unless source_account.is_a?(DigitalBits::KeyPair)
35
+ raise ArgumentError, "Bad :sequence_number" unless sequence_number.is_a?(Integer) && sequence_number >= 0
36
+ raise ArgumentError, "Bad :time_bounds" unless time_bounds.is_a?(DigitalBits::TimeBounds) || time_bounds.nil?
37
+ raise ArgumentError, "Bad :base_fee" unless base_fee.is_a?(Integer) && base_fee >= 100
38
+
39
+ @source_account = source_account
40
+ @sequence_number = sequence_number
41
+ @base_fee = base_fee
42
+ @time_bounds = time_bounds
43
+
44
+ if time_bounds.nil?
45
+ set_timeout(0)
46
+ end
47
+
48
+ @memo = make_memo(memo)
49
+ @operations = []
50
+ end
51
+
52
+ def build
53
+ if @time_bounds.nil?
54
+ raise "TransactionBuilder.time_bounds must be set during initialization or by calling set_timeout"
55
+ elsif !@time_bounds.min_time.is_a?(Integer) || !@time_bounds.max_time.is_a?(Integer)
56
+ raise "TimeBounds.min_time and max_time must be Integers"
57
+ elsif @time_bounds.max_time != 0 && @time_bounds.min_time > @time_bounds.max_time
58
+ raise "Timebounds.max_time must be greater than min_time"
59
+ end
60
+
61
+ attrs = {
62
+ source_account: @source_account.muxed_account,
63
+ fee: @base_fee * @operations.length,
64
+ seq_num: @sequence_number,
65
+ time_bounds: @time_bounds,
66
+ memo: @memo,
67
+ operations: @operations,
68
+ ext: DigitalBits::Transaction::Ext.new(0)
69
+ }
70
+
71
+ @sequence_number += 1
72
+
73
+ DigitalBits::Transaction.new(attrs)
74
+ end
75
+
76
+ def build_fee_bump(inner_txe:)
77
+ if inner_txe.switch == DigitalBits::EnvelopeType.envelope_type_tx_v0
78
+ inner_txe = DigitalBits::TransactionEnvelope.v1(tx: inner_txe.tx.to_v1, signatures: inner_txe.signatures)
79
+ elsif inner_txe.switch != DigitalBits::EnvelopeType.envelope_type_tx
80
+ raise ArgumentError, "Invalid inner transaction type #{inner_txe.switch}"
81
+ end
82
+
83
+ inner_tx = inner_txe.tx
84
+ inner_ops = inner_tx.operations
85
+ inner_base_fee_rate = inner_tx.fee.fdiv(inner_ops.length)
86
+
87
+ # The fee rate for fee bump is at least the fee rate of the inner transaction
88
+ if @base_fee < inner_base_fee_rate
89
+ raise "Insufficient base_fee, it should be at least #{inner_base_fee_rate} stroops."
90
+ end
91
+
92
+ DigitalBits::FeeBumpTransaction.new(
93
+ fee_source: @source_account.muxed_account,
94
+ fee: @base_fee * (inner_ops.length + 1),
95
+ inner_tx: DigitalBits::FeeBumpTransaction::InnerTx.new(:envelope_type_tx, inner_txe.v1!),
96
+ ext: DigitalBits::FeeBumpTransaction::Ext.new(0)
97
+ )
98
+ end
99
+
100
+ def add_operation(operation)
101
+ raise ArgumentError, "Bad operation" unless operation.is_a? DigitalBits::Operation
102
+ @operations.push(operation)
103
+ self
104
+ end
105
+
106
+ def clear_operations
107
+ @operations.clear
108
+ self
109
+ end
110
+
111
+ def set_source_account(account_kp)
112
+ raise ArgumentError, "Bad source account" unless account_kp.is_a?(DigitalBits::KeyPair)
113
+ @source_account = account_kp
114
+ self
115
+ end
116
+
117
+ def set_sequence_number(seq_num)
118
+ raise ArgumentError, "Bad sequence number" unless seq_num.is_a?(Integer) && seq_num >= 0
119
+ @sequence_number = seq_num
120
+ self
121
+ end
122
+
123
+ def set_timeout(timeout)
124
+ if !timeout.is_a?(Integer) || timeout < 0
125
+ raise ArgumentError, "Timeout must be a non-negative integer"
126
+ end
127
+
128
+ if @time_bounds.nil?
129
+ @time_bounds = DigitalBits::TimeBounds.new(min_time: 0, max_time: nil)
130
+ end
131
+
132
+ @time_bounds.max_time = timeout == 0 ? timeout : Time.now.to_i + timeout
133
+
134
+ self
135
+ end
136
+
137
+ def set_memo(memo)
138
+ @memo = make_memo(memo)
139
+ self
140
+ end
141
+
142
+ def set_base_fee(base_fee)
143
+ raise ArgumentError, "Bad base fee" unless base_fee.is_a?(Integer) && base_fee >= 100
144
+ @base_fee = base_fee
145
+ self
146
+ end
147
+
148
+ def make_memo(memo)
149
+ case memo
150
+ when DigitalBits::Memo
151
+ memo
152
+ when nil
153
+ Memo.new(:memo_none)
154
+ when Integer
155
+ Memo.new(:memo_id, memo)
156
+ when String
157
+ Memo.new(:memo_text, memo)
158
+ when Array
159
+ t, val = *memo
160
+ Memo.new(:"memo_#{t}", val)
161
+ else
162
+ raise ArgumentError, "Bad :memo"
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,35 @@
1
+ module DigitalBits
2
+ class TransactionEnvelope
3
+ delegate :tx, :signatures, to: :value
4
+ delegate :hash, to: :tx
5
+
6
+ # Checks to ensure that every signature for the envelope is
7
+ # a valid signature of one of the provided `key_pairs`
8
+ #
9
+ # NOTE: this does not do any authorization checks, which requires access to
10
+ # the current ledger state.
11
+ #
12
+ # @param key_pairs [Array<DigitalBits::KeyPair>] The key pairs to check the envelopes signatures against
13
+ #
14
+ # @return [Boolean] true if all signatures are from the provided key_pairs and validly sign the tx's hash
15
+ def signed_correctly?(*key_pairs)
16
+ return false if signatures.empty?
17
+
18
+ tx_hash = tx.hash
19
+ keys_by_hint = key_pairs.index_by(&:signature_hint)
20
+
21
+ signatures.all? do |sig|
22
+ key_pair = keys_by_hint[sig.hint]
23
+ break false if key_pair.nil?
24
+
25
+ key_pair.verify(sig.signature, tx_hash)
26
+ end
27
+ end
28
+
29
+ def merge(other)
30
+ merged_tx = tx.merge(other.tx)
31
+ merged_tx.signatures = [signatures, other.signatures]
32
+ merged_tx
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,43 @@
1
+ module DigitalBits
2
+ class TransactionV0
3
+ include DigitalBits::Concerns::Transaction
4
+
5
+ def to_v1
6
+ Transaction.new(**attributes.except(:source_account_ed25519), source_account: source_account)
7
+ end
8
+
9
+ def to_envelope(*key_pairs)
10
+ signatures = (key_pairs || []).map(&method(:sign_decorated))
11
+
12
+ TransactionEnvelope.v0(signatures: signatures, tx: self)
13
+ end
14
+
15
+ def signature_base_prefix
16
+ val = DigitalBits::EnvelopeType.envelope_type_tx_v0
17
+
18
+ DigitalBits.current_network_id + DigitalBits::EnvelopeType.to_xdr(val)
19
+ end
20
+
21
+ # Backwards Compatibility: Use ENVELOPE_TYPE_TX to sign ENVELOPE_TYPE_TX_V0
22
+ # we need a Transaction to generate the signature base
23
+ def signature_base
24
+ tx = DigitalBits::Transaction.from_xdr(
25
+ # TransactionV0 is a transaction with the AccountID discriminant
26
+ # stripped off, we need to put it back to build a valid transaction
27
+ # which we can use to build a TransactionSignaturePayloadTaggedTransaction
28
+ DigitalBits::PublicKeyType.to_xdr(DigitalBits::PublicKeyType.public_key_type_ed25519) + to_xdr
29
+ )
30
+
31
+ tagged_tx = DigitalBits::TransactionSignaturePayload::TaggedTransaction.new(:envelope_type_tx, tx)
32
+
33
+ DigitalBits::TransactionSignaturePayload.new(
34
+ network_id: DigitalBits.current_network_id,
35
+ tagged_transaction: tagged_tx
36
+ ).to_xdr
37
+ end
38
+
39
+ def source_account
40
+ DigitalBits::MuxedAccount.ed25519(source_account_ed25519)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ module DigitalBits
2
+ class TrustLineFlags
3
+ # Converts an array of DigitalBits::TrustLineFlags members into
4
+ # an integers suitable for use in in a SetTrustLineFlagsOp.
5
+ #
6
+ # @param flags [Array<DigitalBits::TrustLineFlags>] the flags to combine
7
+ #
8
+ # @return [Fixnum] the combined result
9
+ def self.make_mask(flags)
10
+ normalize(flags).map(&:value).inject(&:|) || 0
11
+ end
12
+
13
+ # Converts an integer used in SetTrustLineFlagsOp on the set/clear flag options
14
+ # into an array of DigitalBits::TrustLineFlags members
15
+ #
16
+ # @param combined [Fixnum]
17
+ # @return [Array<DigitalBits::AccountFlags>]
18
+ def self.parse_mask(combined)
19
+ members.values.select { |m| (m.value & combined) != 0 }
20
+ end
21
+
22
+ # Converts each element of the input array to DigitalBits::TrustLineFlags instance.
23
+ #
24
+ # @param [Array<DigitalBits::TrustLineFlags,Symbol,#to_s>] input
25
+ # @return [Array<DigitalBits::TrustLineFlags>]
26
+ # @raise [TypeError] if any element of the input cannot be converted
27
+ def self.normalize(input)
28
+ input.map do |val|
29
+ case val
30
+ when DigitalBits::TrustLineFlags
31
+ val
32
+ when ->(_) { members.key?(val.to_s) }
33
+ from_name(val.to_s)
34
+ when ->(_) { members.key?("#{val}_flag") }
35
+ from_name("#{val}_flag")
36
+ else
37
+ raise TypeError, "unknown trustline flag: #{val}"
38
+ end
39
+ end
40
+ end
41
+
42
+ def self.set_clear_masks(flags)
43
+ set_flags = []
44
+ clear_flags = []
45
+
46
+ Hash(flags).each do |flag, value|
47
+ value.present? ? set_flags.push(flag) : clear_flags.push(flag)
48
+ end
49
+
50
+ {set_flags: make_mask(set_flags), clear_flags: make_mask(clear_flags)}
51
+ end
52
+ end
53
+ end