bsv-sdk 0.20.0 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -0
- data/lib/bsv/mcp/tools/broadcast_p2pkh.rb +5 -3
- data/lib/bsv/network/protocols/arc.rb +4 -30
- data/lib/bsv/network/protocols/arcade.rb +163 -0
- data/lib/bsv/network/protocols/chaintracks.rb +6 -3
- data/lib/bsv/network/protocols/jungle_bus.rb +6 -0
- data/lib/bsv/network/protocols.rb +1 -0
- data/lib/bsv/network/providers/gorilla_pool.rb +18 -18
- data/lib/bsv/network/util.rb +44 -0
- data/lib/bsv/network.rb +1 -0
- data/lib/bsv/transaction/chain_tracker.rb +74 -13
- data/lib/bsv/transaction/chain_trackers.rb +0 -10
- data/lib/bsv/transaction/fee_models/live_policy.rb +10 -8
- data/lib/bsv/version.rb +1 -1
- data/lib/bsv/wallet/errors.rb +65 -21
- data/lib/bsv/wallet/proto_wallet/validators.rb +7 -49
- data/lib/bsv/wallet/proto_wallet.rb +14 -1
- data/lib/bsv/wallet/serializer/abort_action.rb +38 -0
- data/lib/bsv/wallet/serializer/acquire_certificate.rb +171 -0
- data/lib/bsv/wallet/serializer/certificate.rb +184 -0
- data/lib/bsv/wallet/serializer/common.rb +207 -0
- data/lib/bsv/wallet/serializer/create_action_args.rb +259 -0
- data/lib/bsv/wallet/serializer/create_action_result.rb +85 -0
- data/lib/bsv/wallet/serializer/create_hmac.rb +67 -0
- data/lib/bsv/wallet/serializer/create_signature.rb +90 -0
- data/lib/bsv/wallet/serializer/decrypt.rb +60 -0
- data/lib/bsv/wallet/serializer/discover_by_attributes.rb +61 -0
- data/lib/bsv/wallet/serializer/discover_by_identity_key.rb +49 -0
- data/lib/bsv/wallet/serializer/discover_certificates_result.rb +39 -0
- data/lib/bsv/wallet/serializer/encrypt.rb +60 -0
- data/lib/bsv/wallet/serializer/get_header_for_height.rb +71 -0
- data/lib/bsv/wallet/serializer/get_height.rb +46 -0
- data/lib/bsv/wallet/serializer/get_network.rb +65 -0
- data/lib/bsv/wallet/serializer/get_public_key.rb +86 -0
- data/lib/bsv/wallet/serializer/get_version.rb +44 -0
- data/lib/bsv/wallet/serializer/internalize_action.rb +151 -0
- data/lib/bsv/wallet/serializer/list_actions.rb +348 -0
- data/lib/bsv/wallet/serializer/list_certificates.rb +124 -0
- data/lib/bsv/wallet/serializer/list_outputs.rb +167 -0
- data/lib/bsv/wallet/serializer/prove_certificate.rb +146 -0
- data/lib/bsv/wallet/serializer/relinquish_certificate.rb +56 -0
- data/lib/bsv/wallet/serializer/relinquish_output.rb +44 -0
- data/lib/bsv/wallet/serializer/reveal_counterparty_key_linkage.rb +108 -0
- data/lib/bsv/wallet/serializer/reveal_specific_key_linkage.rb +116 -0
- data/lib/bsv/wallet/serializer/sign_action_args.rb +94 -0
- data/lib/bsv/wallet/serializer/sign_action_result.rb +49 -0
- data/lib/bsv/wallet/serializer/status.rb +85 -0
- data/lib/bsv/wallet/serializer/verify_hmac.rb +67 -0
- data/lib/bsv/wallet/serializer/verify_signature.rb +101 -0
- data/lib/bsv/wallet/serializer.rb +180 -0
- data/lib/bsv/wallet/substrates/http_wallet_json.rb +129 -0
- data/lib/bsv/wallet/substrates/http_wallet_wire.rb +99 -0
- data/lib/bsv/wallet/wallet_wire.rb +20 -0
- data/lib/bsv/wallet/wallet_wire_processor.rb +61 -0
- data/lib/bsv/wallet/wallet_wire_transceiver.rb +61 -0
- data/lib/bsv/wallet/wire/calls.rb +79 -0
- data/lib/bsv/wallet/wire/frame.rb +181 -0
- data/lib/bsv/wallet/wire/reader_writer.rb +402 -0
- data/lib/bsv/wallet/wire/validation.rb +213 -0
- data/lib/bsv/wallet/wire.rb +13 -0
- data/lib/bsv/wallet.rb +17 -0
- metadata +46 -2
- data/lib/bsv/transaction/chain_trackers/chaintracks.rb +0 -83
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BSV
|
|
4
|
+
module Wallet
|
|
5
|
+
module Serializer
|
|
6
|
+
# BRC-103 wire codec for the +list_outputs+ call (call byte 6).
|
|
7
|
+
#
|
|
8
|
+
# Args wire layout:
|
|
9
|
+
# [varint-str: basket]
|
|
10
|
+
# [string-slice: tags] nil → NegativeOne
|
|
11
|
+
# [1 byte: tag_query_mode] 1=all, 2=any, 0xFF=nil
|
|
12
|
+
# [1 byte: include] 1=locking_scripts, 2=entire_transactions, 0xFF=nil
|
|
13
|
+
# [optional_bool: include_custom_instructions]
|
|
14
|
+
# [optional_bool: include_tags]
|
|
15
|
+
# [optional_bool: include_labels]
|
|
16
|
+
# [optional_uint32: limit]
|
|
17
|
+
# [optional_uint32: offset]
|
|
18
|
+
# [optional_bool: seek_permission]
|
|
19
|
+
#
|
|
20
|
+
# Result wire layout:
|
|
21
|
+
# [varint: total_outputs]
|
|
22
|
+
# [varint: beef_len, or NegativeOne if nil][beef bytes]
|
|
23
|
+
# per output:
|
|
24
|
+
# [32-byte wire txid][varint vout]
|
|
25
|
+
# [varint: satoshis]
|
|
26
|
+
# [varint: locking_script_len, or NegativeOne][script bytes]
|
|
27
|
+
# [varint-str: custom_instructions] 0-length string if nil
|
|
28
|
+
# [string-slice: tags]
|
|
29
|
+
# [string-slice: labels]
|
|
30
|
+
module ListOutputs
|
|
31
|
+
TAG_QUERY_MODE_ALL = 1
|
|
32
|
+
TAG_QUERY_MODE_ANY = 2
|
|
33
|
+
INCLUDE_LOCKING_SCRIPTS = 1
|
|
34
|
+
INCLUDE_ENTIRE_TRANSACTIONS = 2
|
|
35
|
+
NEGATIVE_ONE_BYTE = 0xFF
|
|
36
|
+
|
|
37
|
+
module_function
|
|
38
|
+
|
|
39
|
+
def serialize_args(args)
|
|
40
|
+
w = Wire::Writer.new
|
|
41
|
+
w.write_str_with_varint_len(args.fetch(:basket, ''))
|
|
42
|
+
w.write_string_slice(args[:tags])
|
|
43
|
+
|
|
44
|
+
mode_byte = case args[:tag_query_mode]
|
|
45
|
+
when :all then TAG_QUERY_MODE_ALL
|
|
46
|
+
when :any then TAG_QUERY_MODE_ANY
|
|
47
|
+
else NEGATIVE_ONE_BYTE
|
|
48
|
+
end
|
|
49
|
+
w.write_byte(mode_byte)
|
|
50
|
+
|
|
51
|
+
include_byte = case args[:include]
|
|
52
|
+
when :locking_scripts then INCLUDE_LOCKING_SCRIPTS
|
|
53
|
+
when :entire_transactions then INCLUDE_ENTIRE_TRANSACTIONS
|
|
54
|
+
else NEGATIVE_ONE_BYTE
|
|
55
|
+
end
|
|
56
|
+
w.write_byte(include_byte)
|
|
57
|
+
|
|
58
|
+
w.write_optional_bool(args[:include_custom_instructions])
|
|
59
|
+
w.write_optional_bool(args[:include_tags])
|
|
60
|
+
w.write_optional_bool(args[:include_labels])
|
|
61
|
+
w.write_optional_uint32(args[:limit])
|
|
62
|
+
w.write_optional_uint32(args[:offset])
|
|
63
|
+
w.write_optional_bool(args[:seek_permission])
|
|
64
|
+
w.buf
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def deserialize_args(bytes)
|
|
68
|
+
r = Wire::Reader.new(bytes)
|
|
69
|
+
basket = r.read_str_with_varint_len
|
|
70
|
+
tags = r.read_string_slice
|
|
71
|
+
|
|
72
|
+
mode = case r.read_byte
|
|
73
|
+
when TAG_QUERY_MODE_ALL then :all
|
|
74
|
+
when TAG_QUERY_MODE_ANY then :any
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
inc = case r.read_byte
|
|
78
|
+
when INCLUDE_LOCKING_SCRIPTS then :locking_scripts
|
|
79
|
+
when INCLUDE_ENTIRE_TRANSACTIONS then :entire_transactions
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
{
|
|
83
|
+
basket: basket,
|
|
84
|
+
tags: tags,
|
|
85
|
+
tag_query_mode: mode,
|
|
86
|
+
include: inc,
|
|
87
|
+
include_custom_instructions: r.read_optional_bool,
|
|
88
|
+
include_tags: r.read_optional_bool,
|
|
89
|
+
include_labels: r.read_optional_bool,
|
|
90
|
+
limit: r.read_optional_uint32,
|
|
91
|
+
offset: r.read_optional_uint32,
|
|
92
|
+
seek_permission: r.read_optional_bool
|
|
93
|
+
}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def serialize_result(result)
|
|
97
|
+
w = Wire::Writer.new
|
|
98
|
+
outputs = result[:outputs] || []
|
|
99
|
+
w.write_varint(outputs.length)
|
|
100
|
+
|
|
101
|
+
beef = result[:beef]
|
|
102
|
+
if beef
|
|
103
|
+
w.write_int_bytes(beef.b)
|
|
104
|
+
else
|
|
105
|
+
w.write_negative_one
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
outputs.each do |output|
|
|
109
|
+
outpoint = output[:outpoint] || ''
|
|
110
|
+
txid_hex, vout = outpoint.to_s.split('.', 2)
|
|
111
|
+
w.write_outpoint(txid_hex.to_s, vout.to_i)
|
|
112
|
+
w.write_varint(output[:satoshis].to_i)
|
|
113
|
+
locking_script = output[:locking_script]
|
|
114
|
+
if locking_script && !locking_script.empty?
|
|
115
|
+
w.write_int_bytes(locking_script.b)
|
|
116
|
+
else
|
|
117
|
+
w.write_negative_one
|
|
118
|
+
end
|
|
119
|
+
w.write_optional_string(output[:custom_instructions])
|
|
120
|
+
w.write_string_slice(output[:tags])
|
|
121
|
+
w.write_string_slice(output[:labels])
|
|
122
|
+
end
|
|
123
|
+
w.buf
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def deserialize_result(bytes)
|
|
127
|
+
r = Wire::Reader.new(bytes)
|
|
128
|
+
total_outputs = r.read_varint
|
|
129
|
+
|
|
130
|
+
beef_len = r.read_varint
|
|
131
|
+
beef = if beef_len == 0xFFFF_FFFF_FFFF_FFFF
|
|
132
|
+
nil
|
|
133
|
+
else
|
|
134
|
+
r.read_bytes(beef_len)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
outputs = total_outputs.times.map do
|
|
138
|
+
outpoint_data = r.read_outpoint
|
|
139
|
+
outpoint = "#{outpoint_data[:txid_hex]}.#{outpoint_data[:vout]}"
|
|
140
|
+
satoshis = r.read_varint
|
|
141
|
+
locking_script_len = r.read_varint
|
|
142
|
+
locking_script = if locking_script_len == 0xFFFF_FFFF_FFFF_FFFF
|
|
143
|
+
nil
|
|
144
|
+
else
|
|
145
|
+
r.read_bytes(locking_script_len)
|
|
146
|
+
end
|
|
147
|
+
custom_instructions = r.read_optional_string
|
|
148
|
+
tags = r.read_string_slice
|
|
149
|
+
labels = r.read_string_slice
|
|
150
|
+
|
|
151
|
+
{
|
|
152
|
+
outpoint: outpoint,
|
|
153
|
+
satoshis: satoshis,
|
|
154
|
+
locking_script: locking_script,
|
|
155
|
+
custom_instructions: custom_instructions,
|
|
156
|
+
tags: tags,
|
|
157
|
+
labels: labels,
|
|
158
|
+
spendable: true
|
|
159
|
+
}
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
{ total_outputs: total_outputs, beef: beef, outputs: outputs }
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'base64'
|
|
4
|
+
|
|
5
|
+
module BSV
|
|
6
|
+
module Wallet
|
|
7
|
+
module Serializer
|
|
8
|
+
# BRC-103 wire codec for the +prove_certificate+ call (call byte 19).
|
|
9
|
+
#
|
|
10
|
+
# Args wire layout (matches go-sdk SerializeProveCertificateArgs):
|
|
11
|
+
# [32 bytes: cert.type]
|
|
12
|
+
# [33 bytes: cert.subject pubkey]
|
|
13
|
+
# [32 bytes: cert.serial_number]
|
|
14
|
+
# [33 bytes: cert.certifier pubkey]
|
|
15
|
+
# [36 bytes: cert.revocation_outpoint]
|
|
16
|
+
# [varint-int: cert.signature bytes] (0-length if nil)
|
|
17
|
+
# [varint: field_count] per field: [varint-int name_bytes][varint-int value_bytes]
|
|
18
|
+
# [varint: fields_to_reveal_count] per field: [varint-int name_bytes]
|
|
19
|
+
# [33 bytes: verifier pubkey]
|
|
20
|
+
# [privileged params]
|
|
21
|
+
#
|
|
22
|
+
# Result wire layout:
|
|
23
|
+
# [varint: keyring_count] per entry: [varint-int key_bytes][varint-int base64 bytes]
|
|
24
|
+
module ProveCertificate
|
|
25
|
+
CERT_TYPE_SIZE = 32
|
|
26
|
+
SERIAL_SIZE = 32
|
|
27
|
+
PUBKEY_SIZE = 33
|
|
28
|
+
|
|
29
|
+
module_function
|
|
30
|
+
|
|
31
|
+
def serialize_args(args)
|
|
32
|
+
w = Wire::Writer.new
|
|
33
|
+
cert = args[:certificate] || {}
|
|
34
|
+
|
|
35
|
+
type_bytes = Base64.strict_decode64(cert[:type].to_s)
|
|
36
|
+
w.write_bytes(type_bytes.ljust(CERT_TYPE_SIZE, "\x00").byteslice(0, CERT_TYPE_SIZE))
|
|
37
|
+
w.write_bytes([cert[:subject].to_s].pack('H*'))
|
|
38
|
+
|
|
39
|
+
serial_bytes = Base64.strict_decode64(cert[:serial_number].to_s)
|
|
40
|
+
w.write_bytes(serial_bytes.ljust(SERIAL_SIZE, "\x00").byteslice(0, SERIAL_SIZE))
|
|
41
|
+
w.write_bytes([cert[:certifier].to_s].pack('H*'))
|
|
42
|
+
|
|
43
|
+
outpoint_str = cert[:revocation_outpoint].to_s
|
|
44
|
+
if outpoint_str.empty? || outpoint_str == '.'
|
|
45
|
+
w.write_outpoint(Certificate::NULL_TXID_HEX, 0)
|
|
46
|
+
else
|
|
47
|
+
txid_hex, vout = outpoint_str.split('.', 2)
|
|
48
|
+
w.write_outpoint(txid_hex.to_s, vout.to_i)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
sig = cert[:signature]
|
|
52
|
+
if sig && !sig.to_s.empty?
|
|
53
|
+
w.write_int_bytes([sig.to_s].pack('H*'))
|
|
54
|
+
else
|
|
55
|
+
w.write_int_bytes(''.b)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
fields = cert[:fields] || {}
|
|
59
|
+
w.write_varint(fields.length)
|
|
60
|
+
fields.keys.sort.each do |k|
|
|
61
|
+
w.write_int_bytes(k.b)
|
|
62
|
+
w.write_int_bytes(fields[k].to_s.b)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
fields_to_reveal = args[:fields_to_reveal] || []
|
|
66
|
+
w.write_varint(fields_to_reveal.length)
|
|
67
|
+
fields_to_reveal.each { |f| w.write_int_bytes(f.to_s.b) }
|
|
68
|
+
|
|
69
|
+
w.write_bytes([args[:verifier].to_s].pack('H*'))
|
|
70
|
+
|
|
71
|
+
Common.write_privileged_params(w, args[:privileged], args[:privileged_reason])
|
|
72
|
+
w.buf
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def deserialize_args(bytes)
|
|
76
|
+
r = Wire::Reader.new(bytes)
|
|
77
|
+
|
|
78
|
+
type_raw = r.read_bytes(CERT_TYPE_SIZE)
|
|
79
|
+
subject = r.read_bytes(PUBKEY_SIZE).unpack1('H*')
|
|
80
|
+
serial_raw = r.read_bytes(SERIAL_SIZE)
|
|
81
|
+
certifier = r.read_bytes(PUBKEY_SIZE).unpack1('H*')
|
|
82
|
+
|
|
83
|
+
outpoint_data = r.read_outpoint
|
|
84
|
+
revocation_outpoint = "#{outpoint_data[:txid_hex]}.#{outpoint_data[:vout]}"
|
|
85
|
+
|
|
86
|
+
sig_bytes = r.read_int_bytes
|
|
87
|
+
signature = sig_bytes.empty? ? nil : sig_bytes.unpack1('H*')
|
|
88
|
+
|
|
89
|
+
field_count = r.read_varint
|
|
90
|
+
fields = {}
|
|
91
|
+
field_count.times do
|
|
92
|
+
k = r.read_int_bytes.force_encoding('UTF-8')
|
|
93
|
+
v = r.read_int_bytes.force_encoding('UTF-8')
|
|
94
|
+
fields[k] = v
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
fields_to_reveal_count = r.read_varint
|
|
98
|
+
fields_to_reveal = fields_to_reveal_count.times.map do
|
|
99
|
+
r.read_int_bytes.force_encoding('UTF-8')
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
verifier = r.read_bytes(PUBKEY_SIZE).unpack1('H*')
|
|
103
|
+
privileged, privileged_reason = Common.read_privileged_params(r)
|
|
104
|
+
|
|
105
|
+
{
|
|
106
|
+
certificate: {
|
|
107
|
+
type: Base64.strict_encode64(type_raw),
|
|
108
|
+
subject: subject,
|
|
109
|
+
serial_number: Base64.strict_encode64(serial_raw),
|
|
110
|
+
certifier: certifier,
|
|
111
|
+
revocation_outpoint: revocation_outpoint,
|
|
112
|
+
signature: signature,
|
|
113
|
+
fields: fields
|
|
114
|
+
},
|
|
115
|
+
fields_to_reveal: fields_to_reveal,
|
|
116
|
+
verifier: verifier,
|
|
117
|
+
privileged: privileged,
|
|
118
|
+
privileged_reason: privileged_reason
|
|
119
|
+
}
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def serialize_result(result)
|
|
123
|
+
w = Wire::Writer.new
|
|
124
|
+
keyring = result[:keyring_for_verifier] || {}
|
|
125
|
+
w.write_varint(keyring.length)
|
|
126
|
+
keyring.keys.sort.each do |k|
|
|
127
|
+
w.write_int_bytes(k.to_s.b)
|
|
128
|
+
w.write_int_from_base64(keyring[k].to_s)
|
|
129
|
+
end
|
|
130
|
+
w.buf
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def deserialize_result(bytes)
|
|
134
|
+
r = Wire::Reader.new(bytes)
|
|
135
|
+
count = r.read_varint
|
|
136
|
+
keyring = {}
|
|
137
|
+
count.times do
|
|
138
|
+
k = r.read_int_bytes.force_encoding('UTF-8')
|
|
139
|
+
keyring[k] = r.read_base64_int
|
|
140
|
+
end
|
|
141
|
+
{ keyring_for_verifier: keyring }
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'base64'
|
|
4
|
+
|
|
5
|
+
module BSV
|
|
6
|
+
module Wallet
|
|
7
|
+
module Serializer
|
|
8
|
+
# BRC-103 wire codec for the +relinquish_certificate+ call (call byte 20).
|
|
9
|
+
#
|
|
10
|
+
# Args wire layout:
|
|
11
|
+
# [32 bytes: type]
|
|
12
|
+
# [32 bytes: serial_number]
|
|
13
|
+
# [33 bytes: certifier pubkey]
|
|
14
|
+
#
|
|
15
|
+
# Result wire layout:
|
|
16
|
+
# [empty — relinquished is implicit from the frame error byte]
|
|
17
|
+
module RelinquishCertificate
|
|
18
|
+
CERT_TYPE_SIZE = 32
|
|
19
|
+
SERIAL_SIZE = 32
|
|
20
|
+
PUBKEY_SIZE = 33
|
|
21
|
+
|
|
22
|
+
module_function
|
|
23
|
+
|
|
24
|
+
def serialize_args(args)
|
|
25
|
+
w = Wire::Writer.new
|
|
26
|
+
type_bytes = Base64.strict_decode64(args[:type].to_s)
|
|
27
|
+
w.write_bytes(type_bytes.ljust(CERT_TYPE_SIZE, "\x00").byteslice(0, CERT_TYPE_SIZE))
|
|
28
|
+
serial_bytes = Base64.strict_decode64(args[:serial_number].to_s)
|
|
29
|
+
w.write_bytes(serial_bytes.ljust(SERIAL_SIZE, "\x00").byteslice(0, SERIAL_SIZE))
|
|
30
|
+
w.write_bytes([args[:certifier].to_s].pack('H*'))
|
|
31
|
+
w.buf
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def deserialize_args(bytes)
|
|
35
|
+
r = Wire::Reader.new(bytes)
|
|
36
|
+
type_raw = r.read_bytes(CERT_TYPE_SIZE)
|
|
37
|
+
serial_raw = r.read_bytes(SERIAL_SIZE)
|
|
38
|
+
certifier = r.read_bytes(PUBKEY_SIZE).unpack1('H*')
|
|
39
|
+
{
|
|
40
|
+
type: Base64.strict_encode64(type_raw),
|
|
41
|
+
serial_number: Base64.strict_encode64(serial_raw),
|
|
42
|
+
certifier: certifier
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def serialize_result(_result)
|
|
47
|
+
''.b
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def deserialize_result(_bytes)
|
|
51
|
+
{ relinquished: true }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BSV
|
|
4
|
+
module Wallet
|
|
5
|
+
module Serializer
|
|
6
|
+
# BRC-103 wire codec for the +relinquish_output+ call (call byte 7).
|
|
7
|
+
#
|
|
8
|
+
# Args wire layout:
|
|
9
|
+
# [varint-str: basket]
|
|
10
|
+
# [32-byte wire txid][varint vout]
|
|
11
|
+
#
|
|
12
|
+
# Result wire layout:
|
|
13
|
+
# [empty — relinquished is implicit from the frame error byte]
|
|
14
|
+
module RelinquishOutput
|
|
15
|
+
module_function
|
|
16
|
+
|
|
17
|
+
def serialize_args(args)
|
|
18
|
+
Wire::Validation.outpoint_string!('output', args[:output].to_s)
|
|
19
|
+
txid_hex, vout = args[:output].to_s.split('.', 2)
|
|
20
|
+
w = Wire::Writer.new
|
|
21
|
+
w.write_str_with_varint_len(args.fetch(:basket, ''))
|
|
22
|
+
w.write_outpoint(txid_hex, vout.to_i)
|
|
23
|
+
w.buf
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def deserialize_args(bytes)
|
|
27
|
+
r = Wire::Reader.new(bytes)
|
|
28
|
+
basket = r.read_str_with_varint_len
|
|
29
|
+
outpoint_data = r.read_outpoint
|
|
30
|
+
output = "#{outpoint_data[:txid_hex]}.#{outpoint_data[:vout]}"
|
|
31
|
+
{ basket: basket, output: output }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def serialize_result(_result)
|
|
35
|
+
''.b
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def deserialize_result(_bytes)
|
|
39
|
+
{ relinquished: true }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BSV
|
|
4
|
+
module Wallet
|
|
5
|
+
module Serializer
|
|
6
|
+
# BRC-103 wire codec for the +reveal_counterparty_key_linkage+ call (call byte 9).
|
|
7
|
+
#
|
|
8
|
+
# Port of go-sdk/wallet/serializer/reveal_counterparty_key_linkage.go.
|
|
9
|
+
module RevealCounterpartyKeyLinkage
|
|
10
|
+
PUBKEY_SIZE = 33
|
|
11
|
+
|
|
12
|
+
# Args wire layout:
|
|
13
|
+
# [privileged params]
|
|
14
|
+
# [33 bytes: counterparty compressed pubkey]
|
|
15
|
+
# [33 bytes: verifier compressed pubkey]
|
|
16
|
+
module Args
|
|
17
|
+
module_function
|
|
18
|
+
|
|
19
|
+
def serialize(args)
|
|
20
|
+
counterparty = args[:counterparty]
|
|
21
|
+
verifier = args[:verifier]
|
|
22
|
+
raise BSV::Wallet::InvalidParameterError.new('counterparty', 'a 33-byte binary pubkey or 66-char hex') unless counterparty
|
|
23
|
+
raise BSV::Wallet::InvalidParameterError.new('verifier', 'a 33-byte binary pubkey or 66-char hex') unless verifier
|
|
24
|
+
|
|
25
|
+
w = BSV::Wallet::Wire::Writer.new
|
|
26
|
+
Common.write_privileged_params(w, args[:privileged], args[:privileged_reason])
|
|
27
|
+
w.write_bytes(pubkey_bytes(counterparty))
|
|
28
|
+
w.write_bytes(pubkey_bytes(verifier))
|
|
29
|
+
w.buf
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def deserialize(bytes)
|
|
33
|
+
r = BSV::Wallet::Wire::Reader.new(bytes)
|
|
34
|
+
privileged, reason = Common.read_privileged_params(r)
|
|
35
|
+
counterparty = r.read_bytes(PUBKEY_SIZE)
|
|
36
|
+
verifier = r.read_bytes(PUBKEY_SIZE)
|
|
37
|
+
{
|
|
38
|
+
privileged: privileged,
|
|
39
|
+
privileged_reason: reason,
|
|
40
|
+
counterparty: counterparty,
|
|
41
|
+
verifier: verifier
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def pubkey_bytes(value)
|
|
46
|
+
return value.b if value.is_a?(String) && value.bytesize == PUBKEY_SIZE
|
|
47
|
+
|
|
48
|
+
[value.to_s].pack('H*')
|
|
49
|
+
end
|
|
50
|
+
private_class_method :pubkey_bytes
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Result wire layout:
|
|
54
|
+
# [33 bytes: prover pubkey]
|
|
55
|
+
# [33 bytes: verifier pubkey]
|
|
56
|
+
# [33 bytes: counterparty pubkey]
|
|
57
|
+
# [VarInt revelation_time_len][revelation_time bytes]
|
|
58
|
+
# [VarInt encrypted_linkage_len][encrypted_linkage bytes]
|
|
59
|
+
# [VarInt encrypted_linkage_proof_len][encrypted_linkage_proof bytes]
|
|
60
|
+
module Result
|
|
61
|
+
module_function
|
|
62
|
+
|
|
63
|
+
def serialize(result)
|
|
64
|
+
w = BSV::Wallet::Wire::Writer.new
|
|
65
|
+
w.write_bytes(pubkey_bytes(result[:prover]))
|
|
66
|
+
w.write_bytes(pubkey_bytes(result[:verifier]))
|
|
67
|
+
w.write_bytes(pubkey_bytes(result[:counterparty]))
|
|
68
|
+
w.write_str_with_varint_len(result[:revelation_time].to_s)
|
|
69
|
+
encrypted_linkage = Common.to_binary(result[:encrypted_linkage])
|
|
70
|
+
w.write_varint(encrypted_linkage.bytesize)
|
|
71
|
+
w.write_bytes(encrypted_linkage)
|
|
72
|
+
encrypted_linkage_proof = Common.to_binary(result[:encrypted_linkage_proof])
|
|
73
|
+
w.write_varint(encrypted_linkage_proof.bytesize)
|
|
74
|
+
w.write_bytes(encrypted_linkage_proof)
|
|
75
|
+
w.buf
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def deserialize(bytes)
|
|
79
|
+
r = BSV::Wallet::Wire::Reader.new(bytes)
|
|
80
|
+
prover = r.read_bytes(PUBKEY_SIZE)
|
|
81
|
+
verifier = r.read_bytes(PUBKEY_SIZE)
|
|
82
|
+
counterparty = r.read_bytes(PUBKEY_SIZE)
|
|
83
|
+
revelation_time = r.read_str_with_varint_len
|
|
84
|
+
el_len = r.read_varint
|
|
85
|
+
encrypted_linkage = r.read_bytes(el_len)
|
|
86
|
+
elp_len = r.read_varint
|
|
87
|
+
encrypted_linkage_proof = r.read_bytes(elp_len)
|
|
88
|
+
{
|
|
89
|
+
prover: prover,
|
|
90
|
+
verifier: verifier,
|
|
91
|
+
counterparty: counterparty,
|
|
92
|
+
revelation_time: revelation_time,
|
|
93
|
+
encrypted_linkage: encrypted_linkage,
|
|
94
|
+
encrypted_linkage_proof: encrypted_linkage_proof
|
|
95
|
+
}
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def pubkey_bytes(value)
|
|
99
|
+
return value.b if value.is_a?(String) && value.bytesize == PUBKEY_SIZE
|
|
100
|
+
|
|
101
|
+
[value.to_s].pack('H*')
|
|
102
|
+
end
|
|
103
|
+
private_class_method :pubkey_bytes
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BSV
|
|
4
|
+
module Wallet
|
|
5
|
+
module Serializer
|
|
6
|
+
# BRC-103 wire codec for the +reveal_specific_key_linkage+ call (call byte 10).
|
|
7
|
+
#
|
|
8
|
+
# Port of go-sdk/wallet/serializer/reveal_specific_key_linkage.go.
|
|
9
|
+
module RevealSpecificKeyLinkage
|
|
10
|
+
PUBKEY_SIZE = 33
|
|
11
|
+
|
|
12
|
+
# Args wire layout:
|
|
13
|
+
# [key-related params: protocol + key_id + counterparty + privileged]
|
|
14
|
+
# [33 bytes: verifier compressed pubkey]
|
|
15
|
+
module Args
|
|
16
|
+
module_function
|
|
17
|
+
|
|
18
|
+
def serialize(args)
|
|
19
|
+
verifier = args[:verifier]
|
|
20
|
+
raise BSV::Wallet::InvalidParameterError.new('verifier', 'a 33-byte binary pubkey or 66-char hex') unless verifier
|
|
21
|
+
|
|
22
|
+
w = BSV::Wallet::Wire::Writer.new
|
|
23
|
+
Common.write_key_related_params(
|
|
24
|
+
w,
|
|
25
|
+
protocol_id: args[:protocol_id],
|
|
26
|
+
key_id: args[:key_id],
|
|
27
|
+
counterparty: args[:counterparty],
|
|
28
|
+
privileged: args[:privileged],
|
|
29
|
+
privileged_reason: args[:privileged_reason]
|
|
30
|
+
)
|
|
31
|
+
w.write_bytes(pubkey_bytes(verifier))
|
|
32
|
+
w.buf
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def deserialize(bytes)
|
|
36
|
+
r = BSV::Wallet::Wire::Reader.new(bytes)
|
|
37
|
+
params = Common.read_key_related_params(r)
|
|
38
|
+
verifier = r.read_bytes(PUBKEY_SIZE)
|
|
39
|
+
params.merge(verifier: verifier)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def pubkey_bytes(value)
|
|
43
|
+
return value.b if value.is_a?(String) && value.bytesize == PUBKEY_SIZE
|
|
44
|
+
|
|
45
|
+
[value.to_s].pack('H*')
|
|
46
|
+
end
|
|
47
|
+
private_class_method :pubkey_bytes
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Result wire layout:
|
|
51
|
+
# [33 bytes: prover pubkey]
|
|
52
|
+
# [33 bytes: verifier pubkey]
|
|
53
|
+
# [33 bytes: counterparty pubkey]
|
|
54
|
+
# [1 byte: security_level][VarInt protocol_name_len][protocol_name bytes]
|
|
55
|
+
# [VarInt key_id_len][key_id bytes]
|
|
56
|
+
# [VarInt encrypted_linkage_len][encrypted_linkage bytes]
|
|
57
|
+
# [VarInt encrypted_linkage_proof_len][encrypted_linkage_proof bytes]
|
|
58
|
+
# [1 byte: proof_type]
|
|
59
|
+
module Result
|
|
60
|
+
module_function
|
|
61
|
+
|
|
62
|
+
def serialize(result)
|
|
63
|
+
w = BSV::Wallet::Wire::Writer.new
|
|
64
|
+
w.write_bytes(pubkey_bytes(result[:prover]))
|
|
65
|
+
w.write_bytes(pubkey_bytes(result[:verifier]))
|
|
66
|
+
w.write_bytes(pubkey_bytes(result[:counterparty]))
|
|
67
|
+
Common.write_protocol(w, result[:protocol_id])
|
|
68
|
+
key_id_bytes = result[:key_id].to_s.b
|
|
69
|
+
w.write_varint(key_id_bytes.bytesize)
|
|
70
|
+
w.write_bytes(key_id_bytes)
|
|
71
|
+
encrypted_linkage = Common.to_binary(result[:encrypted_linkage])
|
|
72
|
+
w.write_varint(encrypted_linkage.bytesize)
|
|
73
|
+
w.write_bytes(encrypted_linkage)
|
|
74
|
+
encrypted_linkage_proof = Common.to_binary(result[:encrypted_linkage_proof])
|
|
75
|
+
w.write_varint(encrypted_linkage_proof.bytesize)
|
|
76
|
+
w.write_bytes(encrypted_linkage_proof)
|
|
77
|
+
w.write_byte(result[:proof_type].to_i)
|
|
78
|
+
w.buf
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def deserialize(bytes)
|
|
82
|
+
r = BSV::Wallet::Wire::Reader.new(bytes)
|
|
83
|
+
prover = r.read_bytes(PUBKEY_SIZE)
|
|
84
|
+
verifier = r.read_bytes(PUBKEY_SIZE)
|
|
85
|
+
counterparty = r.read_bytes(PUBKEY_SIZE)
|
|
86
|
+
protocol_id = Common.read_protocol(r)
|
|
87
|
+
key_id_len = r.read_varint
|
|
88
|
+
key_id = r.read_bytes(key_id_len).force_encoding('UTF-8')
|
|
89
|
+
el_len = r.read_varint
|
|
90
|
+
encrypted_linkage = r.read_bytes(el_len)
|
|
91
|
+
elp_len = r.read_varint
|
|
92
|
+
encrypted_linkage_proof = r.read_bytes(elp_len)
|
|
93
|
+
proof_type = r.read_byte
|
|
94
|
+
{
|
|
95
|
+
prover: prover,
|
|
96
|
+
verifier: verifier,
|
|
97
|
+
counterparty: counterparty,
|
|
98
|
+
protocol_id: protocol_id,
|
|
99
|
+
key_id: key_id,
|
|
100
|
+
encrypted_linkage: encrypted_linkage,
|
|
101
|
+
encrypted_linkage_proof: encrypted_linkage_proof,
|
|
102
|
+
proof_type: proof_type
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def pubkey_bytes(value)
|
|
107
|
+
return value.b if value.is_a?(String) && value.bytesize == PUBKEY_SIZE
|
|
108
|
+
|
|
109
|
+
[value.to_s].pack('H*')
|
|
110
|
+
end
|
|
111
|
+
private_class_method :pubkey_bytes
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|