base/lib/stellar/key_pair.rb
module Stellar
class KeyPair
module FactoryMethods
def from_seed(seed)
seed_bytes = Util::StrKey.check_decode(:seed, seed)
from_raw_seed seed_bytes
end
def from_address(address)
pk_bytes = Util::StrKey.check_decode(:account_id, address)
from_public_key(pk_bytes)
end
def from_raw_seed(seed_bytes)
secret_key = RbNaCl::SigningKey.new(seed_bytes)
public_key = secret_key.verify_key
new(public_key, secret_key)
end
def from_public_key(pk_bytes)
public_key = RbNaCl::VerifyKey.new(pk_bytes)
new(public_key)
end
def random
secret_key = RbNaCl::SigningKey.generate
public_key = secret_key.verify_key
new(public_key, secret_key)
end
def from_network_passphrase(passphrase)
network_id = Digest::SHA256.digest(passphrase)
from_raw_seed network_id
end
def master
from_raw_seed(Stellar.current_network_id)
end
end
extend FactoryMethods
# @param [RbNaCl::VerifyKey] public_key
# @param [RbNaCl::SigningKey, nil] secret_key
def initialize(public_key, secret_key = nil)
@public_key = public_key
@secret_key = secret_key
end
def address
Util::StrKey.check_encode(:account_id, raw_public_key)
end
def seed
Util::StrKey.check_encode(:seed, raw_seed)
end
def account_id
Stellar::AccountID.new :public_key_type_ed25519, raw_public_key
end
def muxed_account
Stellar::MuxedAccount.new :key_type_ed25519, raw_public_key
end
def public_key
Stellar::PublicKey.new :public_key_type_ed25519, raw_public_key
end
def signer_key
Stellar::SignerKey.new :signer_key_type_ed25519, raw_public_key
end
def signature_hint
# take last 4 bytes
account_id.to_xdr.slice(-4, 4)
end
def raw_public_key
@public_key.to_bytes
end
def raw_seed
raise "no private key" if @secret_key.nil?
@secret_key.to_bytes
end
def rbnacl_signing_key
@secret_key
end
def rbnacl_verify_key
@public_key
end
def sign?
!@secret_key.nil?
end
def sign(message)
raise NotImplementedError, "no private key, signing is not available" unless sign?
@secret_key.sign(message)
end
def sign_decorated(message)
raw_signature = sign(message)
Stellar::DecoratedSignature.new({
hint: signature_hint,
signature: raw_signature
})
end
def verify(signature, message)
@public_key.verify(signature, message)
rescue RbNaCl::LengthError
false
rescue RbNaCl::BadSignatureError
false
end
def to_keypair
self
end
def ==(other)
other.is_a?(KeyPair) && other.rbnacl_verify_key == @public_key && other.rbnacl_signing_key == @secret_key
end
def hash
[public_key, secret_key].hash
end
end
end