Class: Stellar::Util::StrKey
- Inherits:
-
Object
- Object
- Stellar::Util::StrKey
- Defined in:
- lib/stellar/util/strkey.rb
Constant Summary collapse
- VERSION_BYTES =
{ account_id: [6 << 3].pack("C"), # Base32-encodes to 'G...' seed: [18 << 3].pack("C"), # Base32-encodes to 'S...' pre_auth_tx: [19 << 3].pack("C"), # Base32-encodes to 'T...' hash_x: [23 << 3].pack("C"), # Base32-encodes to 'X...' muxed: [12 << 3].pack("C"), # Base32-encodes to 'M...' signed_payload: [15 << 3].pack("C") # Base32-encodes to 'P...' }
Class Method Summary collapse
- .check_decode(expected_version, str) ⇒ Object
- .check_encode(version, byte_str) ⇒ Object
-
.checksum(bytes) ⇒ Object
return the “XModem CRC16” (CCITT-like, but with 0-init and MSB first) packed into a string in little-endian order.
-
.decode_muxed_account(strkey) ⇒ Stellar::MuxedAccount
Returns a Stellar::MuxedAccount, forcing the ed25519 discriminant.
- .decode_signed_payload(strkey) ⇒ Stellar::SignerKey::Ed25519SignedPayload
-
.encode_muxed_account(muxed_account) ⇒ String
Converts an Stellar::MuxedAccount to its string representation, forcing the ed25519 representation.
-
.encode_signed_payload(payload) ⇒ String
“P..”-like address.
Class Method Details
.check_decode(expected_version, str) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/stellar/util/strkey.rb', line 67 def self.check_decode(expected_version, str) decoded = begin Base32.decode(str) rescue raise ArgumentError, "Invalid base32 string" end version_byte = decoded[0] payload = decoded[1...-2] check = decoded[-2..-1] version = VERSION_BYTES.key(version_byte) raise ArgumentError, "invalid encoded string" if str != Base32.encode(decoded).tr("=", "") raise ArgumentError, "Unexpected version: #{version.inspect}" if version != expected_version raise ArgumentError, "Invalid checksum" if check != checksum(decoded[0...-2]) payload end |
.check_encode(version, byte_str) ⇒ Object
16 17 18 19 20 21 22 23 24 |
# File 'lib/stellar/util/strkey.rb', line 16 def self.check_encode(version, byte_str) version_byte = VERSION_BYTES[version] raise ArgumentError, "Invalid version: #{version}" if version_byte.blank? payload = version_byte + byte_str.dup.force_encoding("BINARY") check = checksum(payload) # TODO: sort out, is it 100% safe to remove padding # SEP-23 says yes, but shit happens Base32.encode(payload + check).tr("=", "") end |
.checksum(bytes) ⇒ Object
return the “XModem CRC16” (CCITT-like, but with 0-init and MSB first) packed into a string in little-endian order
86 87 88 89 |
# File 'lib/stellar/util/strkey.rb', line 86 def self.checksum(bytes) crc = Digest::CRC16XModem.checksum(bytes) [crc].pack("S<") end |
.decode_muxed_account(strkey) ⇒ Stellar::MuxedAccount
Returns a Stellar::MuxedAccount, forcing the ed25519 discriminant
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/stellar/util/strkey.rb', line 41 def self.decode_muxed_account(strkey) case strkey when /^G[0-9A-Z]{55}$/ ed25519 = check_decode(:account_id, strkey) Stellar::MuxedAccount.ed25519(ed25519) when /^M[0-9A-Z]{68}$/ payload = check_decode(:muxed, strkey) Stellar::MuxedAccount.med25519(ed25519: payload[0, 32], id: payload[32, 8].unpack1("Q>")) else raise "cannot decode MuxedAccount from #{strkey}" end end |
.decode_signed_payload(strkey) ⇒ Stellar::SignerKey::Ed25519SignedPayload
62 63 64 65 |
# File 'lib/stellar/util/strkey.rb', line 62 def self.decode_signed_payload(strkey) raw = check_decode(:signed_payload, strkey) Stellar::SignerKey::Ed25519SignedPayload.from_xdr(raw, :raw) end |
.encode_muxed_account(muxed_account) ⇒ String
Converts an Stellar::MuxedAccount to its string representation, forcing the ed25519 representation.
29 30 31 32 33 34 35 |
# File 'lib/stellar/util/strkey.rb', line 29 def self.encode_muxed_account(muxed_account) if muxed_account.ed25519 check_encode(:account_id, muxed_account.ed25519) else check_encode(:muxed, muxed_account.med25519!.ed25519 + [muxed_account.med25519!.id].pack("Q>")) end end |
.encode_signed_payload(payload) ⇒ String
Returns “P..”-like address.
56 57 58 |
# File 'lib/stellar/util/strkey.rb', line 56 def self.encode_signed_payload(payload) check_encode(:signed_payload, payload.to_xdr) end |