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,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BSV
|
|
4
|
+
module Wallet
|
|
5
|
+
module Serializer
|
|
6
|
+
# BRC-103 wire codec for the +create_signature+ call (call byte 15).
|
|
7
|
+
#
|
|
8
|
+
# Port of go-sdk/wallet/serializer/create_signature.go.
|
|
9
|
+
module CreateSignature
|
|
10
|
+
HASH_SIZE = 32
|
|
11
|
+
|
|
12
|
+
# Args wire layout:
|
|
13
|
+
# [key-related params]
|
|
14
|
+
# [1 byte: data-type flag — 1=data, 2=hash_to_directly_sign]
|
|
15
|
+
# If flag=1: [VarInt data_len][data bytes]
|
|
16
|
+
# If flag=2: [32 bytes: hash]
|
|
17
|
+
# [optional_bool seek_permission]
|
|
18
|
+
module Args
|
|
19
|
+
module_function
|
|
20
|
+
|
|
21
|
+
def serialize(args)
|
|
22
|
+
data = args[:data] && Common.to_binary(args[:data])
|
|
23
|
+
hash = args[:hash_to_directly_sign] && Common.to_binary(args[:hash_to_directly_sign])
|
|
24
|
+
|
|
25
|
+
if data && hash
|
|
26
|
+
raise BSV::Wallet::InvalidParameterError.new(
|
|
27
|
+
'data and hash_to_directly_sign',
|
|
28
|
+
'not both provided — supply one or the other'
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
raise BSV::Wallet::InvalidParameterError.new('data or hash_to_directly_sign', 'present') unless data || hash
|
|
32
|
+
|
|
33
|
+
w = BSV::Wallet::Wire::Writer.new
|
|
34
|
+
Common.write_key_related_params(
|
|
35
|
+
w,
|
|
36
|
+
protocol_id: args[:protocol_id],
|
|
37
|
+
key_id: args[:key_id],
|
|
38
|
+
counterparty: args[:counterparty],
|
|
39
|
+
privileged: args[:privileged],
|
|
40
|
+
privileged_reason: args[:privileged_reason]
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if data
|
|
44
|
+
w.write_byte(1)
|
|
45
|
+
w.write_varint(data.bytesize)
|
|
46
|
+
w.write_bytes(data)
|
|
47
|
+
else
|
|
48
|
+
w.write_byte(2)
|
|
49
|
+
w.write_bytes(hash)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
w.write_optional_bool(args[:seek_permission])
|
|
53
|
+
w.buf
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def deserialize(bytes)
|
|
57
|
+
r = BSV::Wallet::Wire::Reader.new(bytes)
|
|
58
|
+
params = Common.read_key_related_params(r)
|
|
59
|
+
flag = r.read_byte
|
|
60
|
+
payload = case flag
|
|
61
|
+
when 1
|
|
62
|
+
len = r.read_varint
|
|
63
|
+
{ data: r.read_bytes(len) }
|
|
64
|
+
when 2
|
|
65
|
+
{ hash_to_directly_sign: r.read_bytes(HASH_SIZE) }
|
|
66
|
+
else
|
|
67
|
+
raise ArgumentError, "invalid data-type flag: #{flag}"
|
|
68
|
+
end
|
|
69
|
+
seek_permission = r.read_optional_bool
|
|
70
|
+
params.merge(payload).merge(seek_permission: seek_permission)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Result wire layout:
|
|
75
|
+
# [DER signature bytes — remaining payload]
|
|
76
|
+
module Result
|
|
77
|
+
module_function
|
|
78
|
+
|
|
79
|
+
def serialize(result)
|
|
80
|
+
Common.to_binary(result[:signature])
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def deserialize(bytes)
|
|
84
|
+
{ signature: bytes.b }
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
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 +decrypt+ call (call byte 12).
|
|
7
|
+
#
|
|
8
|
+
# Port of go-sdk/wallet/serializer/decrypt.go.
|
|
9
|
+
module Decrypt
|
|
10
|
+
# Args wire layout:
|
|
11
|
+
# [key-related params]
|
|
12
|
+
# [VarInt ciphertext_len][ciphertext 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
|
+
ciphertext = Common.to_binary(args[:ciphertext])
|
|
28
|
+
w.write_varint(ciphertext.bytesize)
|
|
29
|
+
w.write_bytes(ciphertext)
|
|
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
|
+
ciphertext = r.read_bytes(len)
|
|
39
|
+
seek_permission = r.read_optional_bool
|
|
40
|
+
params.merge(ciphertext: ciphertext, seek_permission: seek_permission)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Result wire layout:
|
|
45
|
+
# [plaintext bytes — remaining payload]
|
|
46
|
+
module Result
|
|
47
|
+
module_function
|
|
48
|
+
|
|
49
|
+
def serialize(result)
|
|
50
|
+
Common.to_binary(result[:plaintext])
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def deserialize(bytes)
|
|
54
|
+
{ plaintext: bytes.b }
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BSV
|
|
4
|
+
module Wallet
|
|
5
|
+
module Serializer
|
|
6
|
+
# BRC-103 wire codec for the +discover_by_attributes+ call (call byte 22).
|
|
7
|
+
#
|
|
8
|
+
# Args wire layout:
|
|
9
|
+
# [varint: attribute_count] per entry: [varint-int key_bytes][varint-int value_bytes]
|
|
10
|
+
# [optional_uint32: limit]
|
|
11
|
+
# [optional_uint32: offset]
|
|
12
|
+
# [optional_bool: seek_permission]
|
|
13
|
+
#
|
|
14
|
+
# Result wire layout: see DiscoverCertificatesResult.
|
|
15
|
+
#
|
|
16
|
+
# Keys are written in sorted order (matching Go sort.Strings) to ensure
|
|
17
|
+
# deterministic encoding across SDK implementations.
|
|
18
|
+
module DiscoverByAttributes
|
|
19
|
+
module_function
|
|
20
|
+
|
|
21
|
+
def serialize_args(args)
|
|
22
|
+
w = Wire::Writer.new
|
|
23
|
+
attributes = args[:attributes] || {}
|
|
24
|
+
w.write_varint(attributes.length)
|
|
25
|
+
attributes.keys.sort.each do |k|
|
|
26
|
+
w.write_int_bytes(k.to_s.b)
|
|
27
|
+
w.write_int_bytes(attributes[k].to_s.b)
|
|
28
|
+
end
|
|
29
|
+
w.write_optional_uint32(args[:limit])
|
|
30
|
+
w.write_optional_uint32(args[:offset])
|
|
31
|
+
w.write_optional_bool(args[:seek_permission])
|
|
32
|
+
w.buf
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def deserialize_args(bytes)
|
|
36
|
+
r = Wire::Reader.new(bytes)
|
|
37
|
+
count = r.read_varint
|
|
38
|
+
attributes = {}
|
|
39
|
+
count.times do
|
|
40
|
+
k = r.read_int_bytes.force_encoding('UTF-8')
|
|
41
|
+
v = r.read_int_bytes.force_encoding('UTF-8')
|
|
42
|
+
attributes[k] = v
|
|
43
|
+
end
|
|
44
|
+
limit = r.read_optional_uint32
|
|
45
|
+
offset = r.read_optional_uint32
|
|
46
|
+
seek_permission = r.read_optional_bool
|
|
47
|
+
{ attributes: attributes, limit: limit, offset: offset,
|
|
48
|
+
seek_permission: seek_permission }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def serialize_result(result)
|
|
52
|
+
DiscoverCertificatesResult.serialize(result)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def deserialize_result(bytes)
|
|
56
|
+
DiscoverCertificatesResult.deserialize(bytes)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BSV
|
|
4
|
+
module Wallet
|
|
5
|
+
module Serializer
|
|
6
|
+
# BRC-103 wire codec for the +discover_by_identity_key+ call (call byte 21).
|
|
7
|
+
#
|
|
8
|
+
# Args wire layout:
|
|
9
|
+
# [33 bytes: identity_key compressed pubkey]
|
|
10
|
+
# [optional_uint32: limit]
|
|
11
|
+
# [optional_uint32: offset]
|
|
12
|
+
# [optional_bool: seek_permission]
|
|
13
|
+
#
|
|
14
|
+
# Result wire layout: see DiscoverCertificatesResult.
|
|
15
|
+
module DiscoverByIdentityKey
|
|
16
|
+
PUBKEY_SIZE = 33
|
|
17
|
+
|
|
18
|
+
module_function
|
|
19
|
+
|
|
20
|
+
def serialize_args(args)
|
|
21
|
+
w = Wire::Writer.new
|
|
22
|
+
w.write_bytes([args[:identity_key].to_s].pack('H*'))
|
|
23
|
+
w.write_optional_uint32(args[:limit])
|
|
24
|
+
w.write_optional_uint32(args[:offset])
|
|
25
|
+
w.write_optional_bool(args[:seek_permission])
|
|
26
|
+
w.buf
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def deserialize_args(bytes)
|
|
30
|
+
r = Wire::Reader.new(bytes)
|
|
31
|
+
identity_key = r.read_bytes(PUBKEY_SIZE).unpack1('H*')
|
|
32
|
+
limit = r.read_optional_uint32
|
|
33
|
+
offset = r.read_optional_uint32
|
|
34
|
+
seek_permission = r.read_optional_bool
|
|
35
|
+
{ identity_key: identity_key, limit: limit, offset: offset,
|
|
36
|
+
seek_permission: seek_permission }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def serialize_result(result)
|
|
40
|
+
DiscoverCertificatesResult.serialize(result)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def deserialize_result(bytes)
|
|
44
|
+
DiscoverCertificatesResult.deserialize(bytes)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -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
|