cardano-bech32 0.1.0 → 0.3.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/CODE_OF_CONDUCT.md +1 -1
- data/README.md +8 -8
- data/lib/cardano/bech32/gov_action.rb +77 -0
- data/lib/cardano/bech32/version.rb +7 -0
- data/lib/cardano/bech32.rb +11 -0
- data/sig/cardano/bech32.rbs +6 -0
- metadata +5 -5
- data/lib/cardano_bech32/gov_action.rb +0 -75
- data/lib/cardano_bech32/version.rb +0 -5
- data/lib/cardano_bech32.rb +0 -9
- data/sig/cardano_bech32.rbs +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3cc7e539a8a0e31cc6e25a42a84ba58419f9ce689be6be07f6e92cc8d6f4a04c
|
|
4
|
+
data.tar.gz: 04a8ff0509d920547f2e9f181e7659c3743fee575bf7f11ea61c35f9c0111fb2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 90641e5ad5e7a0bfcd19e061fa8a02ed8442a9f25a7e023cc43ce447e7536270ae06029fdaef142ab92fe55be914d731d21ee7476236f359de1ebed5cfdd88eb
|
|
7
|
+
data.tar.gz: 29b7495b3e916622a6d3792fc412f2bc8471879c1d8a4f4ec9ba3e135c66ff0e814366fceefabe7472a2a9e6f0c1ac4b4870921f3952b1318f0516891892d28c
|
data/CODE_OF_CONDUCT.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Code of Conduct
|
|
2
2
|
|
|
3
|
-
"
|
|
3
|
+
"cardano-bech32" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
|
|
4
4
|
|
|
5
5
|
* Participants will be tolerant of opposing views.
|
|
6
6
|
* Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# cardano-bech32
|
|
2
2
|
|
|
3
3
|
A small, focused Ruby library for encoding and decoding Cardano Bech32 identifiers.
|
|
4
4
|
This gem deliberately avoids higher-level ledger concerns and focuses solely on correct, specification-compliant Bech32 handling.
|
|
@@ -43,18 +43,18 @@ tx_id (32 bytes) || index (1 byte)
|
|
|
43
43
|
#### Encoding
|
|
44
44
|
|
|
45
45
|
```ruby
|
|
46
|
-
require "
|
|
46
|
+
require "cardano/bech32"
|
|
47
47
|
|
|
48
48
|
txref = "b2a591ac219ce6dcca5847e0248015209c7cb0436aa6bd6863d0c1f152a60bc5#0"
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
Cardano::Bech32::GovAction.encode(txref)
|
|
51
51
|
# => "gov_action1k2jertppnnndejjcglszfqq4yzw8evzrd2nt66rr6rqlz54xp0zsq05ecsn"
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
#### Decoding
|
|
55
55
|
|
|
56
56
|
```ruby
|
|
57
|
-
|
|
57
|
+
Cardano::Bech32::GovAction.decode(
|
|
58
58
|
"gov_action1k2jertppnnndejjcglszfqq4yzw8evzrd2nt66rr6rqlz54xp0zsq05ecsn"
|
|
59
59
|
)
|
|
60
60
|
# => {
|
|
@@ -71,7 +71,7 @@ Validation checks:
|
|
|
71
71
|
* Correct payload length (33 bytes)
|
|
72
72
|
|
|
73
73
|
```ruby
|
|
74
|
-
|
|
74
|
+
Cardano::Bech32::GovAction.valid?("gov_action1k2jertppnnndejjcglszfqq4yzw8evzrd2nt66rr6rqlz54xp0zsq05ecsn")
|
|
75
75
|
# => true
|
|
76
76
|
```
|
|
77
77
|
|
|
@@ -86,8 +86,8 @@ explicit, typed errors:
|
|
|
86
86
|
```ruby
|
|
87
87
|
# Example
|
|
88
88
|
begin
|
|
89
|
-
|
|
90
|
-
rescue
|
|
89
|
+
Cardano::Bech32::GovAction.encode("invalid")
|
|
90
|
+
rescue Cardano::Bech32::GovAction::Error => e
|
|
91
91
|
puts e.message
|
|
92
92
|
end
|
|
93
93
|
|
|
@@ -109,4 +109,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
109
109
|
|
|
110
110
|
## Code of Conduct
|
|
111
111
|
|
|
112
|
-
Everyone interacting in the
|
|
112
|
+
Everyone interacting in the Cardano::Bech32 project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/cardano_bech32/blob/main/CODE_OF_CONDUCT.md).
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bech32"
|
|
4
|
+
|
|
5
|
+
module Cardano
|
|
6
|
+
module Bech32
|
|
7
|
+
# Bech32 encoding for governance action references.
|
|
8
|
+
# A governance action reference is of the form "txid#index"
|
|
9
|
+
# where txid is a 32-byte hex string and index is a 0..255 integer
|
|
10
|
+
# The Bech32 encoding has HRP "gov_action" and a payload of 33 bytes:
|
|
11
|
+
# - 32 bytes: txid (binary)
|
|
12
|
+
# - 1 byte: index (binary)
|
|
13
|
+
#
|
|
14
|
+
module GovAction
|
|
15
|
+
HRP = "gov_action"
|
|
16
|
+
TX_ID_BYTES = 32
|
|
17
|
+
INDEX_BYTES = 1
|
|
18
|
+
TOTAL_BYTES = TX_ID_BYTES + INDEX_BYTES
|
|
19
|
+
|
|
20
|
+
class Error < StandardError; end
|
|
21
|
+
class InvalidFormat < Error; end
|
|
22
|
+
class InvalidPayload < Error; end
|
|
23
|
+
|
|
24
|
+
def self.encode(tx_ref)
|
|
25
|
+
txid_hex, index_str = tx_ref.split("#", 2)
|
|
26
|
+
raise InvalidFormat, "expected txid#index" unless txid_hex && index_str
|
|
27
|
+
|
|
28
|
+
txid_bytes = hex_to_bytes(txid_hex)
|
|
29
|
+
index = Integer(index_str)
|
|
30
|
+
|
|
31
|
+
raise InvalidPayload, "txid must be 32 bytes" unless txid_bytes.bytesize == TX_ID_BYTES
|
|
32
|
+
raise InvalidPayload, "index must be 0..255" unless index.between?(0, 255)
|
|
33
|
+
|
|
34
|
+
payload = txid_bytes + [index].pack("C")
|
|
35
|
+
|
|
36
|
+
# Convert to 5-bit array
|
|
37
|
+
# args: data (array of integers), from_bits, to_bits, pad (boolean)
|
|
38
|
+
data_5bit = ::Bech32.convert_bits(payload.bytes, 8, 5, true)
|
|
39
|
+
::Bech32.encode(HRP, data_5bit, ::Bech32::Encoding::BECH32)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.decode(bech32)
|
|
43
|
+
hrp, data = ::Bech32.decode(bech32)
|
|
44
|
+
raise InvalidFormat, "invalid HRP" unless hrp == HRP
|
|
45
|
+
|
|
46
|
+
# Convert to 5-bit array
|
|
47
|
+
# args: data (array of integers), from_bits, to_bits, pad (boolean)
|
|
48
|
+
bytes = ::Bech32.convert_bits(data, 5, 8, false)
|
|
49
|
+
raise InvalidPayload, "invalid payload length" unless bytes.length == TOTAL_BYTES
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
tx_id: bytes_to_hex(bytes[0, TX_ID_BYTES]),
|
|
53
|
+
index: bytes.last
|
|
54
|
+
}
|
|
55
|
+
rescue ArgumentError
|
|
56
|
+
raise InvalidFormat, "invalid bech32 encoding"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.valid?(bech32)
|
|
60
|
+
decode(bech32)
|
|
61
|
+
true
|
|
62
|
+
rescue Error
|
|
63
|
+
false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.hex_to_bytes(hex)
|
|
67
|
+
raise InvalidFormat, "invalid hex" unless hex.match?(/\A[0-9a-fA-F]{64}\z/)
|
|
68
|
+
|
|
69
|
+
[hex].pack("H*")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.bytes_to_hex(bytes)
|
|
73
|
+
bytes.pack("C*").unpack1("H*")
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cardano-bech32
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Robin Böning
|
|
@@ -52,10 +52,10 @@ files:
|
|
|
52
52
|
- LICENSE.txt
|
|
53
53
|
- README.md
|
|
54
54
|
- Rakefile
|
|
55
|
-
- lib/
|
|
56
|
-
- lib/
|
|
57
|
-
- lib/
|
|
58
|
-
- sig/
|
|
55
|
+
- lib/cardano/bech32.rb
|
|
56
|
+
- lib/cardano/bech32/gov_action.rb
|
|
57
|
+
- lib/cardano/bech32/version.rb
|
|
58
|
+
- sig/cardano/bech32.rbs
|
|
59
59
|
homepage: https://github.com/lacepool/cardano-bech32
|
|
60
60
|
licenses:
|
|
61
61
|
- MIT
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bech32"
|
|
4
|
-
|
|
5
|
-
module CardanoBech32
|
|
6
|
-
# Bech32 encoding for governance action references.
|
|
7
|
-
# A governance action reference is of the form "txid#index"
|
|
8
|
-
# where txid is a 32-byte hex string and index is a 0..255 integer
|
|
9
|
-
# The Bech32 encoding has HRP "gov_action" and a payload of 33 bytes:
|
|
10
|
-
# - 32 bytes: txid (binary)
|
|
11
|
-
# - 1 byte: index (binary)
|
|
12
|
-
#
|
|
13
|
-
module GovAction
|
|
14
|
-
HRP = "gov_action"
|
|
15
|
-
TX_ID_BYTES = 32
|
|
16
|
-
INDEX_BYTES = 1
|
|
17
|
-
TOTAL_BYTES = TX_ID_BYTES + INDEX_BYTES
|
|
18
|
-
|
|
19
|
-
class Error < StandardError; end
|
|
20
|
-
class InvalidFormat < Error; end
|
|
21
|
-
class InvalidPayload < Error; end
|
|
22
|
-
|
|
23
|
-
def self.encode(tx_ref)
|
|
24
|
-
txid_hex, index_str = tx_ref.split("#", 2)
|
|
25
|
-
raise InvalidFormat, "expected txid#index" unless txid_hex && index_str
|
|
26
|
-
|
|
27
|
-
txid_bytes = hex_to_bytes(txid_hex)
|
|
28
|
-
index = Integer(index_str)
|
|
29
|
-
|
|
30
|
-
raise InvalidPayload, "txid must be 32 bytes" unless txid_bytes.bytesize == TX_ID_BYTES
|
|
31
|
-
raise InvalidPayload, "index must be 0..255" unless index.between?(0, 255)
|
|
32
|
-
|
|
33
|
-
payload = txid_bytes + [index].pack("C")
|
|
34
|
-
|
|
35
|
-
# Convert to 5-bit array
|
|
36
|
-
# args: data (array of integers), from_bits, to_bits, pad (boolean)
|
|
37
|
-
data_5bit = Bech32.convert_bits(payload.bytes, 8, 5, true)
|
|
38
|
-
Bech32.encode(HRP, data_5bit, Bech32::Encoding::BECH32)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def self.decode(bech32)
|
|
42
|
-
hrp, data = Bech32.decode(bech32)
|
|
43
|
-
raise InvalidFormat, "invalid HRP" unless hrp == HRP
|
|
44
|
-
|
|
45
|
-
# Convert to 5-bit array
|
|
46
|
-
# args: data (array of integers), from_bits, to_bits, pad (boolean)
|
|
47
|
-
bytes = Bech32.convert_bits(data, 5, 8, false)
|
|
48
|
-
raise InvalidPayload, "invalid payload length" unless bytes.length == TOTAL_BYTES
|
|
49
|
-
|
|
50
|
-
{
|
|
51
|
-
tx_id: bytes_to_hex(bytes[0, TX_ID_BYTES]),
|
|
52
|
-
index: bytes.last
|
|
53
|
-
}
|
|
54
|
-
rescue ArgumentError
|
|
55
|
-
raise InvalidFormat, "invalid bech32 encoding"
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def self.valid?(bech32)
|
|
59
|
-
decode(bech32)
|
|
60
|
-
true
|
|
61
|
-
rescue Error
|
|
62
|
-
false
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def self.hex_to_bytes(hex)
|
|
66
|
-
raise InvalidFormat, "invalid hex" unless hex.match?(/\A[0-9a-fA-F]{64}\z/)
|
|
67
|
-
|
|
68
|
-
[hex].pack("H*")
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def self.bytes_to_hex(bytes)
|
|
72
|
-
bytes.pack("C*").unpack1("H*")
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
data/lib/cardano_bech32.rb
DELETED
data/sig/cardano_bech32.rbs
DELETED