Implement NIP-19 bech32-encoded private and public keys
https://github.com/nostr-protocol/nips/blob/master/19.md
This commit is contained in:
@@ -8,8 +8,8 @@ RSpec.describe Nostr::Crypto do
|
||||
describe '#sign_event' do
|
||||
let(:keypair) do
|
||||
Nostr::KeyPair.new(
|
||||
public_key: '8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca',
|
||||
private_key: '3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757'
|
||||
public_key: Nostr::PublicKey.new('8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca'),
|
||||
private_key: Nostr::PrivateKey.new('3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757')
|
||||
)
|
||||
end
|
||||
|
||||
@@ -34,15 +34,15 @@ RSpec.describe Nostr::Crypto do
|
||||
describe '#encrypt_text' do
|
||||
let(:sender_keypair) do
|
||||
Nostr::KeyPair.new(
|
||||
public_key: '8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca',
|
||||
private_key: '3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757'
|
||||
public_key: Nostr::PublicKey.new('8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca'),
|
||||
private_key: Nostr::PrivateKey.new('3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757')
|
||||
)
|
||||
end
|
||||
|
||||
let(:recipient_keypair) do
|
||||
Nostr::KeyPair.new(
|
||||
public_key: '6c31422248998e300a1a457167565da7d15d0da96651296ee2791c29c11b6aa0',
|
||||
private_key: '22cea01c33eccf30fdd54cb6728f814f6de00c778aafd721e017f4582545f9cf'
|
||||
public_key: Nostr::PublicKey.new('6c31422248998e300a1a457167565da7d15d0da96651296ee2791c29c11b6aa0'),
|
||||
private_key: Nostr::PrivateKey.new('22cea01c33eccf30fdd54cb6728f814f6de00c778aafd721e017f4582545f9cf')
|
||||
)
|
||||
end
|
||||
|
||||
@@ -57,15 +57,15 @@ RSpec.describe Nostr::Crypto do
|
||||
describe '#descrypt_text' do
|
||||
let(:sender_keypair) do
|
||||
Nostr::KeyPair.new(
|
||||
public_key: '8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca',
|
||||
private_key: '3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757'
|
||||
public_key: Nostr::PublicKey.new('8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca'),
|
||||
private_key: Nostr::PrivateKey.new('3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757')
|
||||
)
|
||||
end
|
||||
|
||||
let(:recipient_keypair) do
|
||||
Nostr::KeyPair.new(
|
||||
public_key: '6c31422248998e300a1a457167565da7d15d0da96651296ee2791c29c11b6aa0',
|
||||
private_key: '22cea01c33eccf30fdd54cb6728f814f6de00c778aafd721e017f4582545f9cf'
|
||||
public_key: Nostr::PublicKey.new('6c31422248998e300a1a457167565da7d15d0da96651296ee2791c29c11b6aa0'),
|
||||
private_key: Nostr::PrivateKey.new('22cea01c33eccf30fdd54cb6728f814f6de00c778aafd721e017f4582545f9cf')
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
15
spec/nostr/errors/invalid_hrp_error_spec.rb
Normal file
15
spec/nostr/errors/invalid_hrp_error_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Nostr::InvalidHRPError do
|
||||
describe '#initialize' do
|
||||
let(:given_hrp) { 'nwrong' }
|
||||
let(:allowed_hrp) { 'nsec' }
|
||||
let(:error) { described_class.new(given_hrp, allowed_hrp) }
|
||||
|
||||
it 'builds a useful error message' do
|
||||
expect(error.message).to eq("Invalid hrp: nwrong. The allowed hrp value for this kind of entity is 'nsec'.")
|
||||
end
|
||||
end
|
||||
end
|
||||
14
spec/nostr/errors/invalid_key_format_error_spec.rb
Normal file
14
spec/nostr/errors/invalid_key_format_error_spec.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Nostr::InvalidKeyFormatError do
|
||||
describe '#initialize' do
|
||||
let(:key_kind) { 'private' }
|
||||
let(:error) { described_class.new(key_kind) }
|
||||
|
||||
it 'builds a useful error message' do
|
||||
expect(error.message).to eq('Only lowercase hexadecimal characters are allowed in private keys.')
|
||||
end
|
||||
end
|
||||
end
|
||||
14
spec/nostr/errors/invalid_key_length_error_spec.rb
Normal file
14
spec/nostr/errors/invalid_key_length_error_spec.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Nostr::InvalidKeyLengthError do
|
||||
describe '#initialize' do
|
||||
let(:key_kind) { 'private' }
|
||||
let(:error) { described_class.new(key_kind) }
|
||||
|
||||
it 'builds a useful error message' do
|
||||
expect(error.message).to eq('Invalid private key length. It should have 64 characters.')
|
||||
end
|
||||
end
|
||||
end
|
||||
14
spec/nostr/errors/invalid_key_type_error_spec.rb
Normal file
14
spec/nostr/errors/invalid_key_type_error_spec.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Nostr::InvalidKeyTypeError do
|
||||
describe '#initialize' do
|
||||
let(:key_kind) { 'private' }
|
||||
let(:error) { described_class.new(key_kind) }
|
||||
|
||||
it 'builds a useful error message' do
|
||||
expect(error.message).to eq('Invalid private key type')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -233,8 +233,8 @@ RSpec.describe Nostr::Event do
|
||||
end
|
||||
let(:keypair) do
|
||||
Nostr::KeyPair.new(
|
||||
public_key: '8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca',
|
||||
private_key: '3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757'
|
||||
public_key: Nostr::PublicKey.new('8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca'),
|
||||
private_key: Nostr::PrivateKey.new('3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757')
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -6,15 +6,15 @@ RSpec.describe Nostr::Events::EncryptedDirectMessage do
|
||||
describe '.new' do
|
||||
let(:sender_keypair) do
|
||||
Nostr::KeyPair.new(
|
||||
public_key: '8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca',
|
||||
private_key: '3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757'
|
||||
public_key: Nostr::PublicKey.new('8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca'),
|
||||
private_key: Nostr::PrivateKey.new('3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757')
|
||||
)
|
||||
end
|
||||
|
||||
let(:recipient_keypair) do
|
||||
Nostr::KeyPair.new(
|
||||
public_key: '6c31422248998e300a1a457167565da7d15d0da96651296ee2791c29c11b6aa0',
|
||||
private_key: '22cea01c33eccf30fdd54cb6728f814f6de00c778aafd721e017f4582545f9cf'
|
||||
public_key: Nostr::PublicKey.new('6c31422248998e300a1a457167565da7d15d0da96651296ee2791c29c11b6aa0'),
|
||||
private_key: Nostr::PrivateKey.new('22cea01c33eccf30fdd54cb6728f814f6de00c778aafd721e017f4582545f9cf')
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -5,19 +5,43 @@ require 'spec_helper'
|
||||
RSpec.describe Nostr::KeyPair do
|
||||
let(:keypair) do
|
||||
described_class.new(
|
||||
private_key: '893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900',
|
||||
public_key: '2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558'
|
||||
private_key: Nostr::PrivateKey.new('893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900'),
|
||||
public_key: Nostr::PublicKey.new('2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558')
|
||||
)
|
||||
end
|
||||
|
||||
describe '.new' do
|
||||
it 'creates an instance of a key pair' do
|
||||
keypair = described_class.new(
|
||||
private_key: '893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900',
|
||||
public_key: '2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558'
|
||||
)
|
||||
context 'when private_key is not an instance of PrivateKey' do
|
||||
it 'raises an error' do
|
||||
expect do
|
||||
described_class.new(
|
||||
private_key: '893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900',
|
||||
public_key: Nostr::PublicKey.new('2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558')
|
||||
)
|
||||
end.to raise_error(ArgumentError, 'private_key is not an instance of PrivateKey')
|
||||
end
|
||||
end
|
||||
|
||||
expect(keypair).to be_an_instance_of(described_class)
|
||||
context 'when public_key is not an instance of PublicKey' do
|
||||
it 'raises an error' do
|
||||
expect do
|
||||
described_class.new(
|
||||
private_key: Nostr::PrivateKey.new('893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900'),
|
||||
public_key: '2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558'
|
||||
)
|
||||
end.to raise_error(ArgumentError, 'public_key is not an instance of PublicKey')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when private_key is an instance of PrivateKey and public_key is an instance of PublicKey' do
|
||||
it 'creates an instance of a key pair' do
|
||||
keypair = described_class.new(
|
||||
private_key: Nostr::PrivateKey.new('893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900'),
|
||||
public_key: Nostr::PublicKey.new('2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558')
|
||||
)
|
||||
|
||||
expect(keypair).to be_an_instance_of(described_class)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
73
spec/nostr/key_spec.rb
Normal file
73
spec/nostr/key_spec.rb
Normal file
@@ -0,0 +1,73 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Nostr::Key do
|
||||
let(:subclass) do
|
||||
Class.new(Nostr::Key) do
|
||||
def self.hrp
|
||||
'npub'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def validate_hex_value(_hex_value) = nil
|
||||
end
|
||||
end
|
||||
|
||||
let(:valid_hex) { 'a' * 64 }
|
||||
|
||||
describe '.new' do
|
||||
it 'raises an error because this is an abstract class' do
|
||||
expect { described_class.new(valid_hex) }.to raise_error(/Subclasses must implement this method/)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.from_bech32' do
|
||||
context 'when given a valid Bech32 value' do
|
||||
let(:valid_bech32) { 'npub10elfcs4fr0l0r8af98jlmgdh9c8tcxjvz9qkw038js35mp4dma8qzvjptg' }
|
||||
|
||||
it 'creates a new key' do
|
||||
expect { subclass.from_bech32(valid_bech32) }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given an invalid Bech32 value' do
|
||||
let(:invalid_bech32) { 'this is obviously not valid' }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subclass.from_bech32(invalid_bech32) }.to raise_error(ArgumentError, /Invalid nip19 string\./)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.hrp' do
|
||||
context 'when called on the abstract class' do
|
||||
it 'raises an error because this is an abstract method' do
|
||||
expect { described_class.hrp }.to raise_error(/Subclasses must implement this method/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when called on a subclass' do
|
||||
it 'returns the human readable part of a Bech32 string' do
|
||||
expect(subclass.hrp).to eq('npub')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_bech32' do
|
||||
let(:key) { subclass.new(valid_hex) }
|
||||
|
||||
it 'returns a bech32 string representation of the key' do
|
||||
expect(key.to_bech32).to match(/^npub[0-9a-z]+$/)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#validate_hex_value' do
|
||||
let(:invalid_hex) { 'g' * 64 }
|
||||
|
||||
it 'raises an error because this is an abstract method' do
|
||||
expect { described_class.new(invalid_hex) }.to raise_error(/Subclasses must implement this method/)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,6 +13,31 @@ RSpec.describe Nostr::Keygen do
|
||||
end
|
||||
end
|
||||
|
||||
describe '.get_key_pair_from_private_key' do
|
||||
context 'when given a private key' do
|
||||
let(:private_key) { Nostr::PrivateKey.new('893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900') }
|
||||
|
||||
it 'generates a key pair' do
|
||||
keypair = keygen.get_key_pair_from_private_key(private_key)
|
||||
|
||||
aggregate_failures do
|
||||
expect(keypair.private_key).to be_an_instance_of(Nostr::PrivateKey)
|
||||
expect(keypair.public_key).to be_an_instance_of(Nostr::PublicKey)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given another kind of value' do
|
||||
let(:not_a_private_key) { 'something else' }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { keygen.get_key_pair_from_private_key(not_a_private_key) }.to raise_error(
|
||||
ArgumentError, 'private_key is not an instance of PrivateKey'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#generate_key_pair' do
|
||||
it 'generates a private/public key pair' do
|
||||
keypair = keygen.generate_key_pair
|
||||
@@ -33,11 +58,24 @@ RSpec.describe Nostr::Keygen do
|
||||
end
|
||||
|
||||
describe '#extract_public_key' do
|
||||
it 'extracts a public key from a private key' do
|
||||
private_key = '893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900'
|
||||
public_key = keygen.extract_public_key(private_key)
|
||||
context 'when the given value is not a private key' do
|
||||
let(:not_a_private_key) { 'something else' }
|
||||
|
||||
expect(public_key).to eq('2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558')
|
||||
it 'raises an error' do
|
||||
expect { keygen.extract_public_key(not_a_private_key) }.to raise_error(
|
||||
ArgumentError, 'private_key is not an instance of PrivateKey'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given value is a private key' do
|
||||
let(:private_key) { Nostr::PrivateKey.new('893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900') }
|
||||
|
||||
it 'extracts a public key from a private key' do
|
||||
public_key = keygen.extract_public_key(private_key)
|
||||
|
||||
expect(public_key).to eq('2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
82
spec/nostr/private_key_spec.rb
Normal file
82
spec/nostr/private_key_spec.rb
Normal file
@@ -0,0 +1,82 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Nostr::PrivateKey do
|
||||
let(:valid_hex) { '67dea2ed018072d675f5415ecfaed7d2597555e202d85b3d65ea4e58d2d92ffa' }
|
||||
let(:private_key) { described_class.new(valid_hex) }
|
||||
|
||||
describe '.new' do
|
||||
context 'when the private key is not a string' do
|
||||
it 'raises an InvalidKeyTypeError' do
|
||||
expect { described_class.new(1234) }.to raise_error(
|
||||
Nostr::InvalidKeyTypeError,
|
||||
'Invalid private key type'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the private key's length is not 64 characters" do
|
||||
it 'raises an InvalidKeyLengthError' do
|
||||
expect { described_class.new('a' * 65) }.to raise_error(
|
||||
Nostr::InvalidKeyLengthError,
|
||||
'Invalid private key length. It should have 64 characters.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the private key contains non-hexadecimal characters' do
|
||||
it 'raises an InvalidKeyFormatError' do
|
||||
expect { described_class.new('g' * 64) }.to raise_error(
|
||||
Nostr::InvalidKeyFormatError,
|
||||
'Only lowercase hexadecimal characters are allowed in private keys.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the private key contains uppercase characters' do
|
||||
it 'raises an InvalidKeyFormatError' do
|
||||
expect { described_class.new('A' * 64) }.to raise_error(
|
||||
Nostr::InvalidKeyFormatError,
|
||||
'Only lowercase hexadecimal characters are allowed in private keys.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the private key is valid' do
|
||||
it 'does not raise any error' do
|
||||
expect { described_class.new('a' * 64) }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.from_bech32' do
|
||||
context 'when given a valid Bech32 value' do
|
||||
let(:valid_bech32) { 'nsec1vl029mgpspedva04g90vltkh6fvh240zqtv9k0t9af8935ke9laqsnlfe5' }
|
||||
|
||||
it 'instantiates a private key from a Bech32 encoded string' do
|
||||
expect(described_class.from_bech32(valid_bech32)).to eq(valid_hex)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given an invalid Bech32 value' do
|
||||
let(:invalid_bech32) { 'this is obviously not valid' }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { described_class.from_bech32(invalid_bech32) }.to raise_error(ArgumentError, /Invalid nip19 string\./)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.hrp' do
|
||||
it 'returns the human readable part of a Bech32 string' do
|
||||
expect(described_class.hrp).to eq('nsec')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_bech32' do
|
||||
it 'converts the hex key to bech32' do
|
||||
expect(private_key.to_bech32).to eq('nsec1vl029mgpspedva04g90vltkh6fvh240zqtv9k0t9af8935ke9laqsnlfe5')
|
||||
end
|
||||
end
|
||||
end
|
||||
82
spec/nostr/public_key_spec.rb
Normal file
82
spec/nostr/public_key_spec.rb
Normal file
@@ -0,0 +1,82 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Nostr::PublicKey do
|
||||
let(:valid_hex) { '7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e' }
|
||||
let(:public_key) { described_class.new(valid_hex) }
|
||||
|
||||
describe '.new' do
|
||||
context 'when the public key is not a string' do
|
||||
it 'raises an InvalidKeyTypeError' do
|
||||
expect { described_class.new(1234) }.to raise_error(
|
||||
Nostr::InvalidKeyTypeError,
|
||||
'Invalid public key type'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the public key's length is not 64 characters" do
|
||||
it 'raises an InvalidKeyLengthError' do
|
||||
expect { described_class.new('a' * 65) }.to raise_error(
|
||||
Nostr::InvalidKeyLengthError,
|
||||
'Invalid public key length. It should have 64 characters.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the public key contains non-hexadecimal characters' do
|
||||
it 'raises an InvalidKeyFormatError' do
|
||||
expect { described_class.new('g' * 64) }.to raise_error(
|
||||
Nostr::InvalidKeyFormatError,
|
||||
'Only lowercase hexadecimal characters are allowed in public keys.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the public key contains uppercase characters' do
|
||||
it 'raises an InvalidKeyFormatError' do
|
||||
expect { described_class.new('A' * 64) }.to raise_error(
|
||||
Nostr::InvalidKeyFormatError,
|
||||
'Only lowercase hexadecimal characters are allowed in public keys.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the public key is valid' do
|
||||
it 'does not raise any error' do
|
||||
expect { described_class.new('a' * 64) }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.from_bech32' do
|
||||
context 'when given a valid Bech32 value' do
|
||||
let(:valid_bech32) { 'npub10elfcs4fr0l0r8af98jlmgdh9c8tcxjvz9qkw038js35mp4dma8qzvjptg' }
|
||||
|
||||
it 'instantiates a public key from a Bech32 encoded string' do
|
||||
expect(described_class.from_bech32(valid_bech32)).to eq(valid_hex)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given an invalid Bech32 value' do
|
||||
let(:invalid_bech32) { 'this is obviously not valid' }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { described_class.from_bech32(invalid_bech32) }.to raise_error(ArgumentError, /Invalid nip19 string\./)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.hrp' do
|
||||
it 'returns the human readable part of a Bech32 string' do
|
||||
expect(described_class.hrp).to eq('npub')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_bech32' do
|
||||
it 'converts the hex key to bech32' do
|
||||
expect(public_key.to_bech32).to eq('npub10elfcs4fr0l0r8af98jlmgdh9c8tcxjvz9qkw038js35mp4dma8qzvjptg')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,8 +5,8 @@ require 'spec_helper'
|
||||
RSpec.describe Nostr::User do
|
||||
let(:keypair) do
|
||||
Nostr::KeyPair.new(
|
||||
private_key: '893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900',
|
||||
public_key: '2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558'
|
||||
private_key: Nostr::PrivateKey.new('893c4cc8088924796b41dc788f7e2f746734497010b1a9f005c1faad7074b900'),
|
||||
public_key: Nostr::PublicKey.new('2d7661527d573cc8e84f665fa971dd969ba51e2526df00c149ff8e40a58f9558')
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user