bsv-sdk 0.17.0 → 0.18.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/lib/bsv/auth/get_verifiable_certificates.rb +6 -6
- data/lib/bsv/auth/peer.rb +10 -4
- data/lib/bsv/auth/session_manager.rb +81 -5
- data/lib/bsv/identity/client.rb +4 -2
- data/lib/bsv/mcp/tools/broadcast_p2pkh.rb +2 -2
- data/lib/bsv/mcp/tools/check_balance.rb +2 -2
- data/lib/bsv/mcp/tools/fetch_utxos.rb +2 -2
- data/lib/bsv/network/broadcast_error.rb +1 -0
- data/lib/bsv/network/broadcast_response.rb +3 -1
- data/lib/bsv/network/protocol.rb +56 -4
- data/lib/bsv/network/protocols/arc.rb +31 -11
- data/lib/bsv/network/protocols/chaintracks.rb +6 -2
- data/lib/bsv/network/protocols/jungle_bus.rb +52 -0
- data/lib/bsv/network/protocols/ordinals.rb +110 -8
- data/lib/bsv/network/protocols/taal_binary.rb +17 -4
- data/lib/bsv/network/protocols/woc_rest.rb +164 -84
- data/lib/bsv/network/protocols.rb +3 -3
- data/lib/bsv/network/provider.rb +36 -5
- data/lib/bsv/network/providers/gorilla_pool.rb +42 -20
- data/lib/bsv/network/providers/taal.rb +38 -15
- data/lib/bsv/network/providers/whats_on_chain.rb +42 -21
- data/lib/bsv/network/utxo.rb +8 -2
- data/lib/bsv/overlay/lookup_resolver.rb +5 -5
- data/lib/bsv/overlay/topic_broadcaster.rb +1 -1
- data/lib/bsv/overlay/types.rb +1 -0
- data/lib/bsv/registry/client.rb +8 -8
- data/lib/bsv/registry/types.rb +1 -0
- data/lib/bsv/transaction/beef.rb +139 -102
- data/lib/bsv/transaction/transaction.rb +31 -19
- data/lib/bsv/version.rb +1 -1
- data/lib/bsv/wallet/proto_wallet.rb +44 -8
- data/lib/bsv/wire_format.rb +40 -14
- metadata +4 -3
|
@@ -4,56 +4,78 @@ module BSV
|
|
|
4
4
|
module Network
|
|
5
5
|
module Providers
|
|
6
6
|
# GorillaPool returns pre-configured Provider instances using the GorillaPool
|
|
7
|
-
# ARCADE infrastructure for ARC and Chaintracks,
|
|
8
|
-
# API for transaction and merkle path lookups
|
|
7
|
+
# ARCADE infrastructure for ARC and Chaintracks, the GorillaPool Ordinals
|
|
8
|
+
# API for transaction and merkle path lookups, and JungleBus for indexed
|
|
9
|
+
# transaction data and block headers.
|
|
9
10
|
#
|
|
10
|
-
# Mainnet composes
|
|
11
|
+
# Mainnet composes four protocols:
|
|
11
12
|
# - ARC at +https://arcade.gorillapool.io+
|
|
12
13
|
# - Chaintracks at +https://arcade.gorillapool.io+
|
|
13
14
|
# - Ordinals at +https://ordinals.gorillapool.io+
|
|
15
|
+
# - JungleBus at +https://junglebus.gorillapool.io+
|
|
14
16
|
#
|
|
15
|
-
# Testnet provides ARC
|
|
17
|
+
# Testnet provides ARC and Chaintracks at +https://testnet.arcade.gorillapool.io+.
|
|
16
18
|
#
|
|
17
19
|
# == Example
|
|
18
20
|
#
|
|
19
21
|
# provider = BSV::Network::Providers::GorillaPool.mainnet
|
|
20
22
|
# provider.call(:broadcast, tx)
|
|
21
23
|
#
|
|
22
|
-
# provider = BSV::Network::Providers::GorillaPool.
|
|
24
|
+
# provider = BSV::Network::Providers::GorillaPool.mainnet(auth: { bearer: 'token' })
|
|
23
25
|
# provider.call(:broadcast, tx)
|
|
26
|
+
#
|
|
27
|
+
# # Legacy api_key: shorthand — still supported
|
|
28
|
+
# provider = BSV::Network::Providers::GorillaPool.testnet(api_key: 'my-key')
|
|
24
29
|
class GorillaPool
|
|
25
|
-
#
|
|
30
|
+
# Default requests-per-second limit for unauthenticated use.
|
|
31
|
+
DEFAULT_RATE_LIMIT = 3
|
|
32
|
+
|
|
33
|
+
# Returns a mainnet Provider configured with ARC, Chaintracks, Ordinals, and JungleBus.
|
|
34
|
+
#
|
|
35
|
+
# Auth is forwarded to all four protocols so each can authenticate independently.
|
|
26
36
|
#
|
|
27
|
-
# @param
|
|
37
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and all protocols
|
|
38
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+
|
|
39
|
+
# @param opts [Hash] keyword arguments forwarded to each protocol constructor
|
|
28
40
|
# @return [Provider]
|
|
29
|
-
def self.mainnet(**opts)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
def self.mainnet(auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
42
|
+
resolved_auth = auth || (opts[:api_key] ? { bearer: opts[:api_key] } : :none)
|
|
43
|
+
common = opts.slice(:api_key, :http_client).merge(auth: auth)
|
|
44
|
+
Provider.new('GorillaPool', auth: resolved_auth, rate_limit: rate_limit) do |p|
|
|
45
|
+
p.protocol Protocols::ARC, base_url: 'https://arcade.gorillapool.io', auth: auth, **opts
|
|
33
46
|
p.protocol Protocols::Chaintracks, base_url: 'https://arcade.gorillapool.io', **common
|
|
34
47
|
p.protocol Protocols::Ordinals, base_url: 'https://ordinals.gorillapool.io', **common
|
|
48
|
+
p.protocol Protocols::JungleBus, base_url: 'https://junglebus.gorillapool.io', **common
|
|
35
49
|
end
|
|
36
50
|
end
|
|
37
51
|
|
|
38
52
|
# Returns a testnet Provider configured with ARC and Chaintracks.
|
|
39
53
|
#
|
|
40
|
-
#
|
|
54
|
+
# Auth is forwarded to both protocols.
|
|
55
|
+
#
|
|
56
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and all protocols
|
|
57
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+
|
|
58
|
+
# @param opts [Hash] keyword arguments forwarded to each protocol constructor
|
|
41
59
|
# @return [Provider]
|
|
42
|
-
def self.testnet(**opts)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
60
|
+
def self.testnet(auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
61
|
+
resolved_auth = auth || (opts[:api_key] ? { bearer: opts[:api_key] } : :none)
|
|
62
|
+
common = opts.slice(:api_key, :http_client).merge(auth: auth)
|
|
63
|
+
Provider.new('GorillaPool', auth: resolved_auth, rate_limit: rate_limit) do |p|
|
|
64
|
+
p.protocol Protocols::ARC, base_url: 'https://testnet.arcade.gorillapool.io', auth: auth, **opts
|
|
46
65
|
p.protocol Protocols::Chaintracks, base_url: 'https://testnet.arcade.gorillapool.io', **common
|
|
47
66
|
end
|
|
48
67
|
end
|
|
49
68
|
|
|
50
69
|
# Returns a mainnet or testnet Provider depending on the +testnet:+ flag.
|
|
51
70
|
#
|
|
52
|
-
# @param testnet
|
|
53
|
-
# @param
|
|
71
|
+
# @param testnet [Boolean] when true, returns the testnet Provider
|
|
72
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and all protocols
|
|
73
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+
|
|
74
|
+
# @param opts [Hash] keyword arguments forwarded to each protocol constructor
|
|
54
75
|
# @return [Provider]
|
|
55
|
-
def self.default(testnet: false, **opts)
|
|
56
|
-
|
|
76
|
+
def self.default(testnet: false, auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
77
|
+
kwargs = { auth: auth, rate_limit: rate_limit, **opts }
|
|
78
|
+
testnet ? testnet(**kwargs) : mainnet(**kwargs)
|
|
57
79
|
end
|
|
58
80
|
end
|
|
59
81
|
end
|
|
@@ -14,42 +14,65 @@ module BSV
|
|
|
14
14
|
# To use TAALBinary directly, call +provider.protocol_for(:broadcast)+ on the
|
|
15
15
|
# TAALBinary instance via +provider.protocols.last+, or build a custom Provider.
|
|
16
16
|
#
|
|
17
|
+
# TAAL requires an API key for production use. The default rate limit is +nil+
|
|
18
|
+
# (unconstrained) because the effective limit depends on the subscription tier.
|
|
19
|
+
#
|
|
17
20
|
# There is no TAAL testnet default — TAAL does not publish a supported testnet ARC URL.
|
|
18
21
|
#
|
|
19
22
|
# == Example
|
|
20
23
|
#
|
|
21
|
-
# provider = BSV::Network::Providers::TAAL.mainnet(
|
|
24
|
+
# provider = BSV::Network::Providers::TAAL.mainnet(auth: { bearer: 'mainnet_...' })
|
|
22
25
|
# provider.call(:broadcast, tx)
|
|
26
|
+
#
|
|
27
|
+
# # Legacy api_key: shorthand — still supported
|
|
28
|
+
# provider = BSV::Network::Providers::TAAL.mainnet(api_key: 'mainnet_...')
|
|
23
29
|
class TAAL
|
|
30
|
+
# Default requests-per-second limit.
|
|
31
|
+
# +nil+ because the effective limit depends on the TAAL subscription tier.
|
|
32
|
+
DEFAULT_RATE_LIMIT = nil
|
|
33
|
+
|
|
24
34
|
# Returns a mainnet Provider configured with ARC and TAALBinary.
|
|
25
35
|
#
|
|
26
|
-
#
|
|
36
|
+
# Auth is forwarded to both protocols. ARC uses Bearer tokens;
|
|
37
|
+
# TAALBinary uses raw API keys. Each protocol's constructor handles
|
|
38
|
+
# the translation appropriate to its endpoint.
|
|
39
|
+
#
|
|
40
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and all protocols
|
|
41
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+ (nil)
|
|
42
|
+
# @param opts [Hash] keyword arguments forwarded to each protocol constructor
|
|
27
43
|
# @return [Provider]
|
|
28
|
-
def self.mainnet(**opts)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
p.protocol Protocols::
|
|
44
|
+
def self.mainnet(auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
45
|
+
resolved_auth = auth || (opts[:api_key] ? { bearer: opts[:api_key] } : :none)
|
|
46
|
+
common = opts.slice(:api_key, :http_client).merge(auth: auth)
|
|
47
|
+
Provider.new('TAAL', auth: resolved_auth, rate_limit: rate_limit) do |p|
|
|
48
|
+
p.protocol Protocols::ARC, base_url: 'https://arc.taal.com', auth: auth, **opts
|
|
49
|
+
p.protocol Protocols::TAALBinary, base_url: 'https://api.taal.com', **common
|
|
33
50
|
end
|
|
34
51
|
end
|
|
35
52
|
|
|
36
53
|
# Returns a testnet Provider configured with ARC only.
|
|
37
54
|
#
|
|
38
|
-
# @param
|
|
55
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and ARC protocol
|
|
56
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+ (nil)
|
|
57
|
+
# @param opts [Hash] keyword arguments forwarded to the ARC protocol constructor
|
|
39
58
|
# @return [Provider]
|
|
40
|
-
def self.testnet(**opts)
|
|
41
|
-
|
|
42
|
-
|
|
59
|
+
def self.testnet(auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
60
|
+
resolved_auth = auth || (opts[:api_key] ? { bearer: opts[:api_key] } : :none)
|
|
61
|
+
Provider.new('TAAL', auth: resolved_auth, rate_limit: rate_limit) do |p|
|
|
62
|
+
p.protocol Protocols::ARC, base_url: 'https://arc-test.taal.com', auth: auth, **opts
|
|
43
63
|
end
|
|
44
64
|
end
|
|
45
65
|
|
|
46
66
|
# Returns a mainnet or testnet Provider depending on the +testnet:+ flag.
|
|
47
67
|
#
|
|
48
|
-
# @param testnet
|
|
49
|
-
# @param
|
|
68
|
+
# @param testnet [Boolean] when true, returns the testnet Provider
|
|
69
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and all protocols
|
|
70
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+ (nil)
|
|
71
|
+
# @param opts [Hash] keyword arguments forwarded to each protocol constructor
|
|
50
72
|
# @return [Provider]
|
|
51
|
-
def self.default(testnet: false, **opts)
|
|
52
|
-
|
|
73
|
+
def self.default(testnet: false, auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
74
|
+
kwargs = { auth: auth, rate_limit: rate_limit, **opts }
|
|
75
|
+
testnet ? testnet(**kwargs) : mainnet(**kwargs)
|
|
53
76
|
end
|
|
54
77
|
end
|
|
55
78
|
end
|
|
@@ -15,55 +15,76 @@ module BSV
|
|
|
15
15
|
# provider = BSV::Network::Providers::WhatsOnChain.mainnet
|
|
16
16
|
# provider.call(:get_tx, 'abc123...')
|
|
17
17
|
#
|
|
18
|
-
# provider = BSV::Network::Providers::WhatsOnChain.
|
|
18
|
+
# provider = BSV::Network::Providers::WhatsOnChain.mainnet(auth: { api_key: 'my-key' })
|
|
19
19
|
# provider.call(:broadcast, tx)
|
|
20
|
+
#
|
|
21
|
+
# # Legacy api_key: shorthand — still supported
|
|
22
|
+
# provider = BSV::Network::Providers::WhatsOnChain.testnet(api_key: 'my-key')
|
|
20
23
|
class WhatsOnChain
|
|
24
|
+
# Default requests-per-second limit for unauthenticated use.
|
|
25
|
+
DEFAULT_RATE_LIMIT = 3
|
|
26
|
+
|
|
21
27
|
# Returns a mainnet Provider configured with WoCREST.
|
|
22
28
|
#
|
|
23
|
-
# @param
|
|
29
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and WoCREST protocol
|
|
30
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+
|
|
31
|
+
# @param opts [Hash] keyword arguments forwarded to the WoCREST protocol constructor
|
|
24
32
|
# @return [Provider]
|
|
25
|
-
def self.mainnet(**opts)
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
def self.mainnet(auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
34
|
+
resolved_auth = auth || (opts[:api_key] ? { api_key: opts[:api_key] } : :none)
|
|
35
|
+
Provider.new('WhatsOnChain', auth: resolved_auth, rate_limit: rate_limit) do |p|
|
|
36
|
+
p.protocol Protocols::WoCREST, base_url: 'https://api.whatsonchain.com/v1/bsv/main',
|
|
37
|
+
auth: auth, **opts
|
|
28
38
|
end
|
|
29
39
|
end
|
|
30
40
|
|
|
31
41
|
# Returns a testnet Provider configured with WoCREST.
|
|
32
42
|
#
|
|
33
|
-
# @param
|
|
43
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and WoCREST protocol
|
|
44
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+
|
|
45
|
+
# @param opts [Hash] keyword arguments forwarded to the WoCREST protocol constructor
|
|
34
46
|
# @return [Provider]
|
|
35
|
-
def self.testnet(**opts)
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
def self.testnet(auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
48
|
+
resolved_auth = auth || (opts[:api_key] ? { api_key: opts[:api_key] } : :none)
|
|
49
|
+
Provider.new('WhatsOnChain', auth: resolved_auth, rate_limit: rate_limit) do |p|
|
|
50
|
+
p.protocol Protocols::WoCREST, base_url: 'https://api.whatsonchain.com/v1/bsv/test',
|
|
51
|
+
auth: auth, **opts
|
|
38
52
|
end
|
|
39
53
|
end
|
|
40
54
|
|
|
41
55
|
# Returns a Provider for the BSV Scaling Test Network (STN).
|
|
42
56
|
#
|
|
43
|
-
# @param
|
|
57
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and WoCREST protocol
|
|
58
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+
|
|
59
|
+
# @param opts [Hash] keyword arguments forwarded to the WoCREST protocol constructor
|
|
44
60
|
# @return [Provider]
|
|
45
|
-
def self.stn(**opts)
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
def self.stn(auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
62
|
+
resolved_auth = auth || (opts[:api_key] ? { api_key: opts[:api_key] } : :none)
|
|
63
|
+
Provider.new('WhatsOnChain', auth: resolved_auth, rate_limit: rate_limit) do |p|
|
|
64
|
+
p.protocol Protocols::WoCREST, base_url: 'https://api.whatsonchain.com/v1/bsv/stn',
|
|
65
|
+
auth: auth, **opts
|
|
48
66
|
end
|
|
49
67
|
end
|
|
50
68
|
|
|
51
69
|
# Returns a Provider for the given network.
|
|
52
70
|
#
|
|
53
|
-
# @param testnet
|
|
54
|
-
# @param network
|
|
55
|
-
# @param
|
|
71
|
+
# @param testnet [Boolean] when true, returns the testnet Provider
|
|
72
|
+
# @param network [Symbol, nil] explicit network (:main, :test, :stn) — overrides +testnet:+
|
|
73
|
+
# @param auth [Hash, Symbol, nil] auth config forwarded to Provider and WoCREST protocol
|
|
74
|
+
# @param rate_limit [Numeric, nil] requests per second; defaults to +DEFAULT_RATE_LIMIT+
|
|
75
|
+
# @param opts [Hash] keyword arguments forwarded to the WoCREST protocol constructor
|
|
56
76
|
# @return [Provider]
|
|
57
|
-
def self.default(testnet: false, network: nil, **opts)
|
|
77
|
+
def self.default(testnet: false, network: nil, auth: nil, rate_limit: DEFAULT_RATE_LIMIT, **opts)
|
|
78
|
+
kwargs = { auth: auth, rate_limit: rate_limit, **opts }
|
|
58
79
|
if network
|
|
59
80
|
case network.to_sym
|
|
60
|
-
when :main, :mainnet then mainnet(**
|
|
61
|
-
when :test, :testnet then testnet(**
|
|
62
|
-
when :stn then stn(**
|
|
81
|
+
when :main, :mainnet then mainnet(**kwargs)
|
|
82
|
+
when :test, :testnet then testnet(**kwargs)
|
|
83
|
+
when :stn then stn(**kwargs)
|
|
63
84
|
else raise ArgumentError, "unknown network: #{network}"
|
|
64
85
|
end
|
|
65
86
|
else
|
|
66
|
-
testnet ? testnet(**
|
|
87
|
+
testnet ? testnet(**kwargs) : mainnet(**kwargs)
|
|
67
88
|
end
|
|
68
89
|
end
|
|
69
90
|
end
|
data/lib/bsv/network/utxo.rb
CHANGED
|
@@ -5,10 +5,16 @@ module BSV
|
|
|
5
5
|
class UTXO
|
|
6
6
|
attr_reader :tx_hash, :tx_pos, :satoshis, :height
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
# @param tx_hash [String] transaction ID
|
|
9
|
+
# @param tx_pos [Integer] output index
|
|
10
|
+
# @param satoshis [Integer] output value in satoshis (accepts +value+ as alias)
|
|
11
|
+
# @param height [Integer, nil] block height (0 or nil = unconfirmed)
|
|
12
|
+
def initialize(tx_hash:, tx_pos:, satoshis: nil, value: nil, height: nil)
|
|
9
13
|
@tx_hash = tx_hash
|
|
10
14
|
@tx_pos = tx_pos
|
|
11
|
-
@satoshis = satoshis
|
|
15
|
+
@satoshis = satoshis || value
|
|
16
|
+
raise ArgumentError, 'satoshis or value is required' if @satoshis.nil?
|
|
17
|
+
|
|
12
18
|
@height = height
|
|
13
19
|
end
|
|
14
20
|
|
|
@@ -203,7 +203,7 @@ module BSV
|
|
|
203
203
|
|
|
204
204
|
# Get the last (subject) transaction — typically the most recent entry
|
|
205
205
|
beef_tx = beef.transactions.last
|
|
206
|
-
return nil
|
|
206
|
+
return nil if beef_tx.nil? || beef_tx.is_a?(BSV::Transaction::Beef::TxidOnlyEntry)
|
|
207
207
|
|
|
208
208
|
tx = beef_tx.transaction
|
|
209
209
|
txout = tx.outputs[output_index]
|
|
@@ -334,17 +334,17 @@ module BSV
|
|
|
334
334
|
beef_data = output['beef'] || output[:beef]
|
|
335
335
|
output_index = (output['outputIndex'] || output[:output_index] || 0).to_i
|
|
336
336
|
|
|
337
|
-
# Overlay API boundary: outpoint key uses display-order
|
|
338
|
-
|
|
337
|
+
# Overlay API boundary: outpoint key uses display-order hex txid
|
|
338
|
+
dtxid_hex =
|
|
339
339
|
begin
|
|
340
340
|
beef = parse_beef(beef_data)
|
|
341
341
|
last = beef&.transactions&.last
|
|
342
|
-
last&.
|
|
342
|
+
last&.dtxid
|
|
343
343
|
rescue StandardError
|
|
344
344
|
nil
|
|
345
345
|
end
|
|
346
346
|
|
|
347
|
-
|
|
347
|
+
dtxid_hex ? "#{dtxid_hex}.#{output_index}" : output.object_id.to_s
|
|
348
348
|
end
|
|
349
349
|
|
|
350
350
|
# ---- Validation ----
|
|
@@ -199,7 +199,7 @@ module BSV
|
|
|
199
199
|
return nil unless beef
|
|
200
200
|
|
|
201
201
|
beef_tx = beef.transactions.last
|
|
202
|
-
return nil
|
|
202
|
+
return nil if beef_tx.nil? || beef_tx.is_a?(BSV::Transaction::Beef::TxidOnlyEntry)
|
|
203
203
|
|
|
204
204
|
tx = beef_tx.transaction
|
|
205
205
|
txout = tx.outputs[output_index]
|
data/lib/bsv/overlay/types.rb
CHANGED
|
@@ -102,6 +102,7 @@ module BSV
|
|
|
102
102
|
# @param description [String, nil]
|
|
103
103
|
def initialize(status:, txid: nil, message: nil, code: nil, description: nil)
|
|
104
104
|
@status = status
|
|
105
|
+
BSV::Primitives::Hex.validate_dtxid_hex!(txid, name: 'overlay broadcast txid') if txid
|
|
105
106
|
@txid = txid
|
|
106
107
|
@message = message
|
|
107
108
|
@code = code
|
data/lib/bsv/registry/client.rb
CHANGED
|
@@ -406,21 +406,21 @@ module BSV
|
|
|
406
406
|
return nil if output_idx.negative? || beef_raw.nil?
|
|
407
407
|
|
|
408
408
|
beef = BSV::Transaction::Beef.from_binary(beef_raw)
|
|
409
|
-
|
|
410
|
-
return nil
|
|
409
|
+
beef_tx = beef.transactions.last
|
|
410
|
+
return nil if beef_tx.nil? || beef_tx.is_a?(BSV::Transaction::Beef::TxidOnlyEntry)
|
|
411
411
|
|
|
412
|
-
locking_script =
|
|
412
|
+
locking_script = beef_tx.transaction.outputs[output_idx]&.locking_script
|
|
413
413
|
return nil unless locking_script
|
|
414
414
|
|
|
415
415
|
definition_data = parse_locking_script(definition_type, locking_script)
|
|
416
416
|
|
|
417
417
|
RegisteredDefinition.new(
|
|
418
418
|
definition_data: definition_data,
|
|
419
|
-
txid:
|
|
419
|
+
txid: beef_tx.transaction.txid_hex, # Registry API boundary: display-order hex txid
|
|
420
420
|
output_index: output_idx,
|
|
421
421
|
locking_script: locking_script.to_hex,
|
|
422
422
|
beef: beef_raw,
|
|
423
|
-
satoshis:
|
|
423
|
+
satoshis: beef_tx.transaction.outputs[output_idx].satoshis
|
|
424
424
|
)
|
|
425
425
|
end
|
|
426
426
|
|
|
@@ -439,10 +439,10 @@ module BSV
|
|
|
439
439
|
txid, output_idx_str = outpoint_str.split('.')
|
|
440
440
|
output_idx = output_idx_str.to_i
|
|
441
441
|
|
|
442
|
-
|
|
443
|
-
return nil
|
|
442
|
+
beef_tx = beef.transactions.last
|
|
443
|
+
return nil if beef_tx.nil? || beef_tx.is_a?(BSV::Transaction::Beef::TxidOnlyEntry)
|
|
444
444
|
|
|
445
|
-
locking_script =
|
|
445
|
+
locking_script = beef_tx.transaction.outputs[output_idx]&.locking_script
|
|
446
446
|
return nil unless locking_script
|
|
447
447
|
|
|
448
448
|
definition_data = parse_locking_script(definition_type, locking_script)
|
data/lib/bsv/registry/types.rb
CHANGED
|
@@ -217,6 +217,7 @@ module BSV
|
|
|
217
217
|
def initialize(definition_data:, txid:, output_index:, locking_script:, beef:, satoshis: 1)
|
|
218
218
|
@definition_data = definition_data
|
|
219
219
|
@definition_type = definition_data.definition_type
|
|
220
|
+
BSV::Primitives::Hex.validate_dtxid_hex!(txid, name: 'registry definition txid')
|
|
220
221
|
@txid = txid
|
|
221
222
|
@output_index = output_index
|
|
222
223
|
@locking_script = locking_script
|