Module: BSV::Storage::Utils

Defined in:
lib/bsv/storage/utils.rb

Overview

Helpers for encoding and decoding UHRP (Unified Hash Resource Protocol) URLs.

A UHRP URL is a Base58Check string with a two-byte ‘xCEx00` prefix prepended to the SHA-256 hash of the content. This makes each URL self-verifying and stable across storage providers.

URL normalisation

‘normalize_url` strips the `uhrp:` scheme (case-insensitive) and the optional `//` authority prefix, matching the TS SDK contract exactly. The `web+uhrp://` variant used by some browser extension manifests is not normalised here — that diverges from the TS reference (Python normalises it; we follow TS).

Constant Summary collapse

UHRP_PREFIX =

Two-byte UHRP version prefix: 0xCE 0x00.

"\xCE\x00".b.freeze

Class Method Summary collapse

Class Method Details

.get_hash_from_url(url) ⇒ String

Decode a UHRP URL and return the 32-byte binary SHA-256 hash.

Accepts URLs with or without the ‘uhrp:` scheme and optional `//` authority.

Parameters:

  • url (String)

    UHRP URL (with or without ‘uhrp:` prefix)

Returns:

  • (String)

    32-byte binary SHA-256 hash

Raises:



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/bsv/storage/utils.rb', line 53

def get_hash_from_url(url)
  raise ArgumentError, 'URL must be a String' unless url.is_a?(String)
  raise ArgumentError, 'URL must not be empty' if url.empty?

  normalised = normalize_url(url)
  result = BSV::Primitives::Base58.check_decode(normalised, prefix_length: 2)
  raise ArgumentError, 'Bad prefix' unless result[:prefix] == UHRP_PREFIX
  raise ArgumentError, 'Invalid length!' unless result[:data].bytesize == 32

  result[:data]
end

.get_url_for_file(data) ⇒ String

Compute the SHA-256 hash of data and encode it as a UHRP URL.

Parameters:

  • data (String)

    binary file content

Returns:

  • (String)

    Base58Check-encoded UHRP URL



40
41
42
43
# File 'lib/bsv/storage/utils.rb', line 40

def get_url_for_file(data)
  hash = OpenSSL::Digest::SHA256.digest(data.b)
  get_url_for_hash(hash)
end

.get_url_for_hash(hash) ⇒ String

Encode a 32-byte binary SHA-256 hash as a UHRP URL.

Parameters:

  • hash (String)

    32-byte binary string (SHA-256 hash)

Returns:

  • (String)

    Base58Check-encoded UHRP URL

Raises:

  • (ArgumentError)

    if hash is not exactly 32 bytes



30
31
32
33
34
# File 'lib/bsv/storage/utils.rb', line 30

def get_url_for_hash(hash)
  raise ArgumentError, 'Hash length must be 32 bytes (sha256)' unless hash.bytesize == 32

  BSV::Primitives::Base58.check_encode(hash.b, prefix: UHRP_PREFIX)
end

.normalize_url(url) ⇒ String

Strip the ‘uhrp:` scheme (case-insensitive) and optional `//` from a URL.

Follows the TS SDK contract: only ‘uhrp:` and `uhrp://` are normalised. `web+uhrp://` is deliberately not stripped (TS does not strip it; Python does).

Parameters:

  • url (String)

    URL to normalise

Returns:

  • (String)

    normalised URL



72
73
74
75
76
# File 'lib/bsv/storage/utils.rb', line 72

def normalize_url(url)
  url = url.slice(5..) if url.downcase.start_with?('uhrp:')
  url = url.slice(2..) if url.start_with?('//')
  url
end

.valid_url?(url) ⇒ Boolean

Return true if url is a syntactically valid UHRP URL.

Parameters:

  • url (String)

    URL to validate

Returns:

  • (Boolean)


82
83
84
85
86
87
# File 'lib/bsv/storage/utils.rb', line 82

def valid_url?(url)
  get_hash_from_url(url)
  true
rescue ArgumentError, BSV::Primitives::Base58::ChecksumError
  false
end