bsv-sdk 0.19.1 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +89 -0
  3. data/README.md +2 -2
  4. data/lib/bsv/auth/transport.rb +1 -1
  5. data/lib/bsv/mcp/tools/broadcast_p2pkh.rb +5 -3
  6. data/lib/bsv/network/protocol.rb +4 -5
  7. data/lib/bsv/network/protocols/arc.rb +4 -30
  8. data/lib/bsv/network/protocols/arcade.rb +163 -0
  9. data/lib/bsv/network/protocols/chaintracks.rb +6 -3
  10. data/lib/bsv/network/protocols/jungle_bus.rb +6 -0
  11. data/lib/bsv/network/protocols.rb +1 -0
  12. data/lib/bsv/network/provider.rb +7 -9
  13. data/lib/bsv/network/providers/gorilla_pool.rb +18 -18
  14. data/lib/bsv/network/util.rb +44 -0
  15. data/lib/bsv/network.rb +1 -0
  16. data/lib/bsv/overlay/lookup_resolver.rb +0 -1
  17. data/lib/bsv/overlay/topic_broadcaster.rb +0 -1
  18. data/lib/bsv/primitives/curve.rb +1 -11
  19. data/lib/bsv/primitives/ecies.rb +1 -8
  20. data/lib/bsv/primitives/hex.rb +1 -1
  21. data/lib/bsv/script/script.rb +1 -1
  22. data/lib/bsv/transaction/beef.rb +0 -2
  23. data/lib/bsv/transaction/chain_tracker.rb +74 -13
  24. data/lib/bsv/transaction/chain_trackers/whats_on_chain.rb +3 -3
  25. data/lib/bsv/transaction/chain_trackers.rb +0 -10
  26. data/lib/bsv/transaction/fee_models/live_policy.rb +10 -8
  27. data/lib/bsv/transaction/merkle_path.rb +0 -2
  28. data/lib/bsv/version.rb +1 -1
  29. data/lib/bsv/wallet/errors.rb +65 -21
  30. data/lib/bsv/wallet/proto_wallet/validators.rb +7 -49
  31. data/lib/bsv/wallet/proto_wallet.rb +15 -8
  32. data/lib/bsv/wallet/serializer/abort_action.rb +38 -0
  33. data/lib/bsv/wallet/serializer/acquire_certificate.rb +171 -0
  34. data/lib/bsv/wallet/serializer/certificate.rb +184 -0
  35. data/lib/bsv/wallet/serializer/common.rb +207 -0
  36. data/lib/bsv/wallet/serializer/create_action_args.rb +259 -0
  37. data/lib/bsv/wallet/serializer/create_action_result.rb +85 -0
  38. data/lib/bsv/wallet/serializer/create_hmac.rb +67 -0
  39. data/lib/bsv/wallet/serializer/create_signature.rb +90 -0
  40. data/lib/bsv/wallet/serializer/decrypt.rb +60 -0
  41. data/lib/bsv/wallet/serializer/discover_by_attributes.rb +61 -0
  42. data/lib/bsv/wallet/serializer/discover_by_identity_key.rb +49 -0
  43. data/lib/bsv/wallet/serializer/discover_certificates_result.rb +39 -0
  44. data/lib/bsv/wallet/serializer/encrypt.rb +60 -0
  45. data/lib/bsv/wallet/serializer/get_header_for_height.rb +71 -0
  46. data/lib/bsv/wallet/serializer/get_height.rb +46 -0
  47. data/lib/bsv/wallet/serializer/get_network.rb +65 -0
  48. data/lib/bsv/wallet/serializer/get_public_key.rb +86 -0
  49. data/lib/bsv/wallet/serializer/get_version.rb +44 -0
  50. data/lib/bsv/wallet/serializer/internalize_action.rb +151 -0
  51. data/lib/bsv/wallet/serializer/list_actions.rb +348 -0
  52. data/lib/bsv/wallet/serializer/list_certificates.rb +124 -0
  53. data/lib/bsv/wallet/serializer/list_outputs.rb +167 -0
  54. data/lib/bsv/wallet/serializer/prove_certificate.rb +146 -0
  55. data/lib/bsv/wallet/serializer/relinquish_certificate.rb +56 -0
  56. data/lib/bsv/wallet/serializer/relinquish_output.rb +44 -0
  57. data/lib/bsv/wallet/serializer/reveal_counterparty_key_linkage.rb +108 -0
  58. data/lib/bsv/wallet/serializer/reveal_specific_key_linkage.rb +116 -0
  59. data/lib/bsv/wallet/serializer/sign_action_args.rb +94 -0
  60. data/lib/bsv/wallet/serializer/sign_action_result.rb +49 -0
  61. data/lib/bsv/wallet/serializer/status.rb +85 -0
  62. data/lib/bsv/wallet/serializer/verify_hmac.rb +67 -0
  63. data/lib/bsv/wallet/serializer/verify_signature.rb +101 -0
  64. data/lib/bsv/wallet/serializer.rb +180 -0
  65. data/lib/bsv/wallet/substrates/http_wallet_json.rb +129 -0
  66. data/lib/bsv/wallet/substrates/http_wallet_wire.rb +99 -0
  67. data/lib/bsv/wallet/wallet_wire.rb +20 -0
  68. data/lib/bsv/wallet/wallet_wire_processor.rb +61 -0
  69. data/lib/bsv/wallet/wallet_wire_transceiver.rb +61 -0
  70. data/lib/bsv/wallet/wire/calls.rb +79 -0
  71. data/lib/bsv/wallet/wire/frame.rb +181 -0
  72. data/lib/bsv/wallet/wire/reader_writer.rb +402 -0
  73. data/lib/bsv/wallet/wire/validation.rb +213 -0
  74. data/lib/bsv/wallet/wire.rb +13 -0
  75. data/lib/bsv/wallet.rb +17 -0
  76. metadata +47 -3
  77. data/lib/bsv/transaction/chain_trackers/chaintracks.rb +0 -83
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSV
4
+ module Wallet
5
+ module Serializer
6
+ # Shared BRC-103 result codec for discover_by_identity_key and
7
+ # discover_by_attributes (both return the same shape).
8
+ #
9
+ # Result wire layout:
10
+ # [varint: total_certificates]
11
+ # per certificate: [IdentityCertificate inline bytes (int-prefixed base cert + meta)]
12
+ module DiscoverCertificatesResult
13
+ module_function
14
+
15
+ # @param result [Hash] { total_certificates:, certificates: [IdentityCert Hash, ...] }
16
+ # @return [String] binary
17
+ def serialize(result)
18
+ certs = result[:certificates] || []
19
+ w = Wire::Writer.new
20
+ w.write_varint(certs.length)
21
+ certs.each do |cert|
22
+ cert_bytes = Certificate.serialize_identity_certificate(cert)
23
+ w.write_bytes(cert_bytes)
24
+ end
25
+ w.buf
26
+ end
27
+
28
+ # @param bytes [String] binary
29
+ # @return [Hash] { total_certificates:, certificates: [...] }
30
+ def deserialize(bytes)
31
+ r = Wire::Reader.new(bytes)
32
+ total = r.read_varint
33
+ certs = total.times.map { Certificate.deserialize_identity_certificate(r) }
34
+ { total_certificates: total, certificates: certs }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSV
4
+ module Wallet
5
+ module Serializer
6
+ # BRC-103 wire codec for the +encrypt+ call (call byte 11).
7
+ #
8
+ # Port of go-sdk/wallet/serializer/encrypt.go.
9
+ module Encrypt
10
+ # Args wire layout:
11
+ # [key-related params: protocol + key_id + counterparty + privileged]
12
+ # [VarInt plaintext_len][plaintext bytes]
13
+ # [optional_bool seek_permission]
14
+ module Args
15
+ module_function
16
+
17
+ def serialize(args)
18
+ w = BSV::Wallet::Wire::Writer.new
19
+ Common.write_key_related_params(
20
+ w,
21
+ protocol_id: args[:protocol_id],
22
+ key_id: args[:key_id],
23
+ counterparty: args[:counterparty],
24
+ privileged: args[:privileged],
25
+ privileged_reason: args[:privileged_reason]
26
+ )
27
+ plaintext = Common.to_binary(args[:plaintext])
28
+ w.write_varint(plaintext.bytesize)
29
+ w.write_bytes(plaintext)
30
+ w.write_optional_bool(args[:seek_permission])
31
+ w.buf
32
+ end
33
+
34
+ def deserialize(bytes)
35
+ r = BSV::Wallet::Wire::Reader.new(bytes)
36
+ params = Common.read_key_related_params(r)
37
+ len = r.read_varint
38
+ plaintext = r.read_bytes(len)
39
+ seek_permission = r.read_optional_bool
40
+ params.merge(plaintext: plaintext, seek_permission: seek_permission)
41
+ end
42
+ end
43
+
44
+ # Result wire layout:
45
+ # [ciphertext bytes — remaining payload]
46
+ module Result
47
+ module_function
48
+
49
+ def serialize(result)
50
+ Common.to_binary(result[:ciphertext])
51
+ end
52
+
53
+ def deserialize(bytes)
54
+ { ciphertext: bytes.b }
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSV
4
+ module Wallet
5
+ module Serializer
6
+ # BRC-103 serialiser for the get_header_for_height call (call byte 26).
7
+ #
8
+ # Wire format:
9
+ # Args: [VarInt] height
10
+ # Result: [80 bytes] raw block header
11
+ #
12
+ # Port of go-sdk/wallet/serializer/get_header.go.
13
+ module GetHeaderForHeight
14
+ HEADER_BYTES = 80
15
+
16
+ module Args
17
+ module_function
18
+
19
+ # @param args [Hash] { height: Integer }
20
+ # @return [String] binary (varint-encoded height)
21
+ def serialize(args)
22
+ BSV::Transaction::VarInt.encode(args[:height].to_i)
23
+ end
24
+
25
+ # @param bytes [String] binary
26
+ # @return [Hash] { height: Integer }
27
+ def deserialize(bytes)
28
+ raise BSV::Wallet::InvalidParameterError.new('get_header_for_height args', 'at least 1 byte') if bytes.b.empty?
29
+
30
+ height, = BSV::Transaction::VarInt.decode(bytes.b, 0)
31
+ { height: height }
32
+ end
33
+ end
34
+
35
+ module Result
36
+ module_function
37
+
38
+ # @param result [Hash] { header: String } — 80-byte binary block header
39
+ # @return [String] 80-byte binary
40
+ # @raise [InvalidParameterError] if header is not exactly 80 bytes
41
+ def serialize(result)
42
+ header = result[:header].to_s.b
43
+ unless header.bytesize == HEADER_BYTES
44
+ raise BSV::Wallet::InvalidParameterError.new(
45
+ 'get_header_for_height result header',
46
+ "exactly #{HEADER_BYTES} bytes, got #{header.bytesize}"
47
+ )
48
+ end
49
+
50
+ header
51
+ end
52
+
53
+ # @param bytes [String] binary
54
+ # @return [Hash] { header: String }
55
+ # @raise [InvalidParameterError] if payload is not exactly 80 bytes
56
+ def deserialize(bytes)
57
+ data = bytes.b
58
+ unless data.bytesize == HEADER_BYTES
59
+ raise BSV::Wallet::InvalidParameterError.new(
60
+ 'get_header_for_height result',
61
+ "exactly #{HEADER_BYTES} bytes, got #{data.bytesize}"
62
+ )
63
+ end
64
+
65
+ { header: data }
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSV
4
+ module Wallet
5
+ module Serializer
6
+ # BRC-103 serialiser for the get_height call (call byte 25).
7
+ #
8
+ # Wire format — result only (no args payload):
9
+ # [VarInt] block height (uint32 range)
10
+ #
11
+ # Port of go-sdk/wallet/serializer/get_height.go.
12
+ module GetHeight
13
+ module Args
14
+ module_function
15
+
16
+ def serialize(_args = {})
17
+ ''.b
18
+ end
19
+
20
+ def deserialize(_bytes)
21
+ {}
22
+ end
23
+ end
24
+
25
+ module Result
26
+ module_function
27
+
28
+ # @param result [Hash] { height: Integer }
29
+ # @return [String] binary (varint-encoded height)
30
+ def serialize(result)
31
+ BSV::Transaction::VarInt.encode(result[:height].to_i)
32
+ end
33
+
34
+ # @param bytes [String] binary
35
+ # @return [Hash] { height: Integer }
36
+ def deserialize(bytes)
37
+ raise BSV::Wallet::InvalidParameterError.new('get_height result', 'at least 1 byte') if bytes.b.empty?
38
+
39
+ height, = BSV::Transaction::VarInt.decode(bytes.b, 0)
40
+ { height: height }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSV
4
+ module Wallet
5
+ module Serializer
6
+ # BRC-103 serialiser for the get_network call (call byte 27).
7
+ #
8
+ # Wire format — result only (no args payload):
9
+ # [1 byte] 0x00 = mainnet, 0x01 = testnet
10
+ module GetNetwork
11
+ # Args is always empty — get_network takes no parameters.
12
+ module Args
13
+ module_function
14
+
15
+ def serialize(_args = {})
16
+ ''.b
17
+ end
18
+
19
+ def deserialize(_bytes)
20
+ {}
21
+ end
22
+ end
23
+
24
+ module Result
25
+ MAINNET_CODE = 0
26
+ TESTNET_CODE = 1
27
+
28
+ module_function
29
+
30
+ # @param result [Hash] { network: :mainnet | :testnet }
31
+ # @return [String] 1-byte binary
32
+ # @raise [InvalidParameterError] if +:network+ is not :mainnet or :testnet
33
+ def serialize(result)
34
+ code = case result[:network]
35
+ when :mainnet then MAINNET_CODE
36
+ when :testnet then TESTNET_CODE
37
+ else
38
+ raise BSV::Wallet::InvalidParameterError.new(
39
+ 'network', ":mainnet or :testnet, got #{result[:network].inspect}"
40
+ )
41
+ end
42
+ [code].pack('C')
43
+ end
44
+
45
+ # @param bytes [String] 1-byte binary
46
+ # @return [Hash] { network: :mainnet | :testnet }
47
+ # @raise [InvalidParameterError] if the byte is not 0x00 or 0x01
48
+ def deserialize(bytes)
49
+ data = bytes.b
50
+ raise BSV::Wallet::InvalidParameterError.new('get_network result', 'exactly 1 byte') unless data.bytesize == 1
51
+
52
+ case data.getbyte(0)
53
+ when MAINNET_CODE then { network: :mainnet }
54
+ when TESTNET_CODE then { network: :testnet }
55
+ else
56
+ raise BSV::Wallet::InvalidParameterError.new(
57
+ 'get_network result', "0x00 (mainnet) or 0x01 (testnet), got 0x#{data.unpack1('H*')}"
58
+ )
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSV
4
+ module Wallet
5
+ module Serializer
6
+ # BRC-103 wire codec for the +get_public_key+ call (call byte 8).
7
+ #
8
+ # Port of go-sdk/wallet/serializer/get_public_key.go.
9
+ module GetPublicKey
10
+ IDENTITY_KEY_FLAG = 1
11
+ PUBKEY_SIZE = 33
12
+
13
+ # Args wire layout:
14
+ # [1 byte: identity_key flag — 0=no, 1=yes]
15
+ # If 0: [key-related params][optional_bool for_self]
16
+ # If 1: [privileged params only]
17
+ # [optional_bool seek_permission]
18
+ module Args
19
+ module_function
20
+
21
+ def serialize(args)
22
+ identity_key = args[:identity_key]
23
+ w = BSV::Wallet::Wire::Writer.new
24
+
25
+ if identity_key
26
+ w.write_byte(IDENTITY_KEY_FLAG)
27
+ Common.write_privileged_params(w, args[:privileged], args[:privileged_reason])
28
+ else
29
+ w.write_byte(0)
30
+ Common.write_key_related_params(
31
+ w,
32
+ protocol_id: args[:protocol_id],
33
+ key_id: args[:key_id],
34
+ counterparty: args[:counterparty],
35
+ privileged: args[:privileged],
36
+ privileged_reason: args[:privileged_reason]
37
+ )
38
+ w.write_optional_bool(args[:for_self])
39
+ end
40
+
41
+ w.write_optional_bool(args[:seek_permission])
42
+ w.buf
43
+ end
44
+
45
+ def deserialize(bytes)
46
+ r = BSV::Wallet::Wire::Reader.new(bytes)
47
+ flag = r.read_byte
48
+
49
+ if flag == IDENTITY_KEY_FLAG
50
+ privileged, reason = Common.read_privileged_params(r)
51
+ seek_permission = r.read_optional_bool
52
+ {
53
+ identity_key: true,
54
+ privileged: privileged,
55
+ privileged_reason: reason,
56
+ seek_permission: seek_permission
57
+ }
58
+ else
59
+ params = Common.read_key_related_params(r)
60
+ for_self = r.read_optional_bool
61
+ seek_permission = r.read_optional_bool
62
+ params.merge(identity_key: false, for_self: for_self, seek_permission: seek_permission)
63
+ end
64
+ end
65
+ end
66
+
67
+ # Result wire layout:
68
+ # [33 bytes: compressed public key]
69
+ module Result
70
+ module_function
71
+
72
+ def serialize(result)
73
+ pubkey = result[:public_key] || ''.b
74
+ pubkey.bytesize == PUBKEY_SIZE ? pubkey.b : [pubkey.to_s].pack('H*')
75
+ end
76
+
77
+ def deserialize(bytes)
78
+ raise ArgumentError, "public key too short: #{bytes.bytesize}" if bytes.bytesize < PUBKEY_SIZE
79
+
80
+ { public_key: bytes.byteslice(0, PUBKEY_SIZE) }
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSV
4
+ module Wallet
5
+ module Serializer
6
+ # BRC-103 serialiser for the get_version call (call byte 28).
7
+ #
8
+ # Wire format — result only (no args payload):
9
+ # [N bytes] raw UTF-8 version string (no length prefix)
10
+ #
11
+ # Port of go-sdk/wallet/serializer/get_version.go — the Go SDK emits
12
+ # the string bytes directly, with no varint length prefix.
13
+ module GetVersion
14
+ module Args
15
+ module_function
16
+
17
+ def serialize(_args = {})
18
+ ''.b
19
+ end
20
+
21
+ def deserialize(_bytes)
22
+ {}
23
+ end
24
+ end
25
+
26
+ module Result
27
+ module_function
28
+
29
+ # @param result [Hash] { version: String }
30
+ # @return [String] binary (raw UTF-8 bytes)
31
+ def serialize(result)
32
+ result[:version].to_s.b
33
+ end
34
+
35
+ # @param bytes [String] binary
36
+ # @return [Hash] { version: String }
37
+ def deserialize(bytes)
38
+ { version: bytes.b.force_encoding('UTF-8') }
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSV
4
+ module Wallet
5
+ module Serializer
6
+ # BRC-103 serialiser for internalize_action (call byte 5).
7
+ #
8
+ # Wire layout (port of go-sdk/wallet/serializer/internalize_action.go):
9
+ # [varint + bytes] tx (BEEF) — length-prefixed raw bytes
10
+ # [varint] outputs count
11
+ # For each output:
12
+ # [varint] output_index
13
+ # [1 byte] protocol: 0x01=wallet_payment, 0x02=basket_insertion
14
+ # If wallet_payment:
15
+ # [33 bytes] sender_identity_key (compressed pubkey)
16
+ # [int_bytes] derivation_prefix
17
+ # [int_bytes] derivation_suffix
18
+ # If basket_insertion:
19
+ # [string] basket
20
+ # [optional_string] custom_instructions
21
+ # [string_slice] tags
22
+ # [string_slice] labels
23
+ # [string] description
24
+ # [optional_bool] seek_permission
25
+ #
26
+ # Result wire layout: empty (success is implicit from the frame error byte).
27
+ module InternalizeActionArgs
28
+ PROTOCOL_WALLET_PAYMENT = 1
29
+ PROTOCOL_BASKET_INSERTION = 2
30
+ PUBKEY_SIZE = 33
31
+
32
+ module_function
33
+
34
+ # @param args [Hash]
35
+ # @return [String] binary
36
+ def serialize(args)
37
+ w = Wire::Writer.new
38
+
39
+ tx = (args[:tx] || ''.b).b
40
+ w.write_varint(tx.bytesize)
41
+ w.write_bytes(tx)
42
+
43
+ outputs = args[:outputs] || []
44
+ w.write_varint(outputs.length)
45
+ outputs.each { |out| serialize_output(w, out) }
46
+
47
+ w.write_string_slice(args[:labels])
48
+ w.write_string(args[:description].to_s)
49
+ w.write_optional_bool(args[:seek_permission])
50
+
51
+ w.buf
52
+ end
53
+
54
+ # @param bytes [String] binary
55
+ # @return [Hash]
56
+ def deserialize(bytes)
57
+ r = Wire::Reader.new(bytes)
58
+
59
+ tx_len = r.read_varint
60
+ tx = r.read_bytes(tx_len)
61
+
62
+ output_count = r.read_varint
63
+ outputs = output_count.times.map { deserialize_output(r) }
64
+
65
+ labels = r.read_string_slice
66
+ description = r.read_string
67
+ seek_permission = r.read_optional_bool
68
+
69
+ result = { tx: tx, outputs: outputs, description: description }
70
+ result[:labels] = labels unless labels.nil?
71
+ result[:seek_permission] = seek_permission unless seek_permission.nil?
72
+ result
73
+ end
74
+
75
+ def serialize_output(writer, out)
76
+ writer.write_varint(out[:output_index].to_i)
77
+
78
+ case out[:protocol]
79
+ when :wallet_payment
80
+ writer.write_byte(PROTOCOL_WALLET_PAYMENT)
81
+ payment = out[:payment_remittance] || {}
82
+ writer.write_bytes([payment[:sender_identity_key]].pack('H*'))
83
+ writer.write_int_bytes(payment[:derivation_prefix])
84
+ writer.write_int_bytes(payment[:derivation_suffix])
85
+ when :basket_insertion
86
+ writer.write_byte(PROTOCOL_BASKET_INSERTION)
87
+ insertion = out[:insertion_remittance] || {}
88
+ writer.write_string(insertion[:basket].to_s)
89
+ writer.write_optional_string(insertion[:custom_instructions])
90
+ writer.write_string_slice(insertion[:tags])
91
+ else
92
+ raise ArgumentError, "unknown internalize protocol: #{out[:protocol]}"
93
+ end
94
+ end
95
+
96
+ def deserialize_output(reader)
97
+ output_index = reader.read_varint
98
+ protocol_byte = reader.read_byte
99
+
100
+ case protocol_byte
101
+ when PROTOCOL_WALLET_PAYMENT
102
+ key_bytes = reader.read_bytes(PUBKEY_SIZE)
103
+ prefix = reader.read_int_bytes
104
+ suffix = reader.read_int_bytes
105
+ {
106
+ output_index: output_index,
107
+ protocol: :wallet_payment,
108
+ payment_remittance: {
109
+ sender_identity_key: key_bytes.unpack1('H*'),
110
+ derivation_prefix: prefix,
111
+ derivation_suffix: suffix
112
+ }
113
+ }
114
+ when PROTOCOL_BASKET_INSERTION
115
+ basket = reader.read_string
116
+ custom = reader.read_optional_string
117
+ tags = reader.read_string_slice
118
+ result = {
119
+ output_index: output_index,
120
+ protocol: :basket_insertion,
121
+ insertion_remittance: { basket: basket }
122
+ }
123
+ result[:insertion_remittance][:custom_instructions] = custom unless custom.nil?
124
+ result[:insertion_remittance][:tags] = tags unless tags.nil?
125
+ result
126
+ else
127
+ raise ArgumentError, "invalid internalize protocol byte: #{protocol_byte}"
128
+ end
129
+ end
130
+
131
+ private_class_method :serialize_output, :deserialize_output
132
+ end
133
+
134
+ module InternalizeActionResult
135
+ module_function
136
+
137
+ # @param _result [Hash] ignored
138
+ # @return [String] empty binary
139
+ def serialize(_result = {})
140
+ ''.b
141
+ end
142
+
143
+ # @param _bytes [String] ignored
144
+ # @return [Hash] { accepted: true }
145
+ def deserialize(_bytes = nil)
146
+ { accepted: true }
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end