Module: BSV::Wallet::Client::Identity

Included in:
BSV::Wallet::Client
Defined in:
lib/bsv/wallet/client/brc100/identity.rb

Instance Method Summary collapse

Instance Method Details

#acquire_certificate(args, originator: nil) ⇒ Hash

Acquires an identity certificate via direct storage or issuance.

Parameters:

  • args (Hash)

Returns:

  • (Hash)

    the stored certificate



15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/bsv/wallet/client/brc100/identity.rb', line 15

def acquire_certificate(args, originator: nil)
  return @substrate.acquire_certificate(args, originator: originator) if @substrate

  validate_acquire_certificate!(args)

  cert = if args[:acquisition_protocol] == 'issuance'
           acquire_via_issuance(args)
         else
           acquire_via_direct(args)
         end

  @storage.store_certificate(cert)
  cert_without_keyring(cert)
end

#discover_by_attributes(args, originator: nil) ⇒ Hash

Discovers certificates matching specific attribute values.

Parameters:

  • args (Hash)

Returns:

  • (Hash)

    { total_certificates:, certificates: […] }

Raises:



124
125
126
127
128
129
130
131
132
133
# File 'lib/bsv/wallet/client/brc100/identity.rb', line 124

def discover_by_attributes(args, originator: nil)
  return @substrate.discover_by_attributes(args, originator: originator) if @substrate

  raise InvalidParameterError.new('attributes', 'a non-empty Hash') unless args[:attributes].is_a?(Hash) && !args[:attributes].empty?

  query = { attributes: args[:attributes], limit: args[:limit] || 10, offset: args[:offset] || 0 }
  total = @storage.count_certificates(query)
  certs = @storage.find_certificates(query)
  { total_certificates: total, certificates: certs.map { |c| cert_without_keyring(c) } }
end

#discover_by_identity_key(args, originator: nil) ⇒ Hash

Discovers certificates issued to a given identity key.

Parameters:

  • args (Hash)

Returns:

  • (Hash)

    { total_certificates:, certificates: […] }



109
110
111
112
113
114
115
116
117
118
# File 'lib/bsv/wallet/client/brc100/identity.rb', line 109

def discover_by_identity_key(args, originator: nil)
  return @substrate.discover_by_identity_key(args, originator: originator) if @substrate

  Validators.validate_pub_key_hex!(args[:identity_key], 'identity_key')

  query = { subject: args[:identity_key], limit: args[:limit] || 10, offset: args[:offset] || 0 }
  total = @storage.count_certificates(query)
  certs = @storage.find_certificates(query)
  { total_certificates: total, certificates: certs.map { |c| cert_without_keyring(c) } }
end

#list_certificates(args, originator: nil) ⇒ Hash

Lists identity certificates filtered by certifier and type.

Parameters:

  • args (Hash)

Returns:

  • (Hash)

    { total_certificates:, certificates: […] }

Raises:



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/bsv/wallet/client/brc100/identity.rb', line 34

def list_certificates(args, originator: nil)
  return @substrate.list_certificates(args, originator: originator) if @substrate

  raise InvalidParameterError.new('certifiers', 'a non-empty Array') unless args[:certifiers].is_a?(Array) && !args[:certifiers].empty?
  raise InvalidParameterError.new('types', 'a non-empty Array') unless args[:types].is_a?(Array) && !args[:types].empty?

  query = {
    certifiers: args[:certifiers],
    types: args[:types],
    limit: args[:limit] || 10,
    offset: args[:offset] || 0
  }
  total = @storage.count_certificates(query)
  certs = @storage.find_certificates(query)
  { total_certificates: total, certificates: certs.map { |c| cert_without_keyring(c) } }
end

#prove_certificate(args, originator: nil) ⇒ Hash

Proves select fields of an identity certificate to a verifier.

Parameters:

  • args (Hash)

Returns:

  • (Hash)

    { keyring_for_verifier: { field_name => Array<Integer> } }

Raises:



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/bsv/wallet/client/brc100/identity.rb', line 55

def prove_certificate(args, originator: nil)
  return @substrate.prove_certificate(args, originator: originator) if @substrate

  cert_arg = args[:certificate]
  fields_to_reveal = args[:fields_to_reveal]
  verifier = args[:verifier]

  raise InvalidParameterError.new('certificate', 'a Hash') unless cert_arg.is_a?(Hash)
  raise InvalidParameterError.new('fields_to_reveal', 'a non-empty Array') unless fields_to_reveal.is_a?(Array) && !fields_to_reveal.empty?

  Validators.validate_pub_key_hex!(verifier, 'verifier')

  stored = find_stored_certificate(cert_arg)
  raise WalletError, 'Certificate not found in wallet' unless stored
  raise WalletError, 'Certificate has no keyring' unless stored[:keyring]

  keyring_for_verifier = {}
  fields_to_reveal.each do |field_name|
    key_value = stored[:keyring][field_name] || stored[:keyring][field_name.to_sym]
    raise WalletError, "Keyring entry not found for field '#{field_name}'" unless key_value

    encrypted = encrypt({
                          plaintext: key_value.bytes,
                          protocol_id: [2, 'certificate field encryption'],
                          key_id: "#{cert_arg[:serial_number]} #{field_name}",
                          counterparty: verifier
                        })
    keyring_for_verifier[field_name] = encrypted[:ciphertext]
  end

  { keyring_for_verifier: keyring_for_verifier }
end

#relinquish_certificate(args, originator: nil) ⇒ Hash

Removes a certificate from the wallet.

Parameters:

  • args (Hash)

Returns:

  • (Hash)

    { relinquished: true }

Raises:



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/bsv/wallet/client/brc100/identity.rb', line 92

def relinquish_certificate(args, originator: nil)
  return @substrate.relinquish_certificate(args, originator: originator) if @substrate

  deleted = @storage.delete_certificate(
    type: args[:type],
    serial_number: args[:serial_number],
    certifier: args[:certifier]
  )
  raise WalletError, 'Certificate not found' unless deleted

  { relinquished: true }
end