# Class BSV::Wallet::ProtoWallet <a id="class-BSV-Wallet-ProtoWallet"></a>

**Inherits:** `Object`
**Includes:** `BSV::Wallet::Interface::BRC100`

Minimal cryptographic wallet implementing the BRC-100 interface.

ProtoWallet is a direct, in-process implementation of the BRC-100 crypto
operations. It requires no external gem, no storage, and no blockchain access
— making it suitable for use inside the SDK itself (e.g. the Auth module) as
well as lightweight applications that need cryptographic operations without
full wallet infrastructure.

## Supported BRC-100 areas

*   *Public key management* — {#get_public_key},
    {#reveal_counterparty_key_linkage}, {#reveal_specific_key_linkage}
*   **Cryptography** — {#encrypt}, {#decrypt}, {#create_hmac}, {#verify_hmac},
    {#create_signature}, {#verify_signature}
*   *Certificates (read-only stub)* — {#list_certificates} returns an empty
    list; {#prove_certificate} raises {UnsupportedActionError}

## NOT supported

The following BRC-100 areas are not implemented and will raise
`NotImplementedError`:

*   Transactions (`create_action`, `sign_action`, `list_actions`, etc.)
*   Output management (`list_outputs`, `relinquish_output`, etc.)
*   Authentication (<code>authenticated?</code>, `wait_for_authentication`)
*   Blockchain / network data (`get_height`, `get_header_for_height`, etc.)
*   Certificate acquisition / discovery (`acquire_certificate`,
    `discover_by_identity_key`, etc.)

For full wallet functionality, use the <code>bsv-wallet</code> gem. See
<code>docs/sdk/wallet.md</code> for usage guidance.

## Construction

Pass a {BSV::Primitives::PrivateKey} or the special string
<code>'anyone'</code>. The <code>'anyone'</code> variant uses a well-known key
(private key = 1) and is suitable for verifying or encrypting data that should
be readable by any party — it must not be used where secrecy is required.

**@example Normal usage**
```ruby
wallet = BSV::Wallet::ProtoWallet.new(BSV::Primitives::PrivateKey.generate)
sig = wallet.create_signature(protocol_id: [1, 'my-app'], key_id: 'msg-1',
                              data: 'hello'.bytes)
```

**@example Anyone wallet**
```ruby
wallet = BSV::Wallet::ProtoWallet.new('anyone')
pub = wallet.get_public_key(identity_key: true)
```

## Public Instance Methods
### `abort_action(reference:, originator: = nil)` <a id="method-i-abort_action"></a> <a id="abort_action-instance_method"></a>
Aborts a transaction that has not yet been finalized.
- **@raise** [NotImplementedError]

### `acquire_certificate(type:, certifier:, acquisition_protocol:, fields:, serial_number: = nil, revocation_outpoint: = nil, signature: = nil, certifier_url: = nil, keyring_revealer: = nil, keyring_for_subject: = nil, privileged: = false, privileged_reason: = nil, originator: = nil)` <a id="method-i-acquire_certificate"></a> <a id="acquire_certificate-instance_method"></a>
Acquires an identity certificate from a certifier or by direct receipt.
- **@param** `acquisition_protocol` [Symbol] :direct or :issuance
- **@param** `fields` [Hash{String => String}] certificate field names to values
- **@raise** [NotImplementedError]

### `authenticated?(originator: = nil)` <a id="method-i-authenticated-3F"></a> <a id="authenticated?-instance_method"></a>
Checks whether the user is authenticated.
- **@raise** [NotImplementedError]
- **@return** [Boolean]

### `create_action(description:, input_beef: = nil, inputs: = nil, outputs: = nil, lock_time: = nil, version: = nil, labels: = nil, sign_and_process: = true, accept_delayed_broadcast: = true, trust_self: = nil, known_txids: = nil, return_txid_only: = false, no_send: = false, no_send_change: = nil, send_with: = nil, randomize_outputs: = true, originator: = nil)` <a id="method-i-create_action"></a> <a id="create_action-instance_method"></a>
Creates a new Bitcoin transaction.
- **@param** `description` [String] human-readable description (5-50 chars)
- **@param** `inputs` [Array<Hash>] optional inputs to consume
- :outpoint [String] txid.index being consumed
- :unlocking_script [String] hex unlocking script
- :unlocking_script_length [Integer] length, if script provided later via {#sign_action}
- :input_description [String] what this input consumes (5-50 chars)
- :sequence_number [Integer] optional sequence number
- **@param** `outputs` [Array<Hash>] optional outputs to create
- :locking_script [String] hex locking script
- :satoshis [Integer] output value
- :output_description [String] what this output represents (5-50 chars)
- :basket [String] optional basket name for UTXO tracking
- :custom_instructions [String] application-specific context
- :tags [Array<String>] output tags for filtering
- **@raise** [NotImplementedError]
- **@return** [Hash] BRC-100 spec-mandated keys: :txid (display-order hex), :tx, :no_send_change,
:send_with_results, :signable_transaction

### `create_hmac(data:, protocol_id:, key_id:, counterparty: = nil, privileged: = false, privileged_reason: = nil, seek_permission: = true, originator: = nil)` <a id="method-i-create_hmac"></a> <a id="create_hmac-instance_method"></a>
Creates an HMAC-SHA256 using a derived symmetric key.
- **@param** `data` [Array<Integer>] byte array to authenticate
- **@param** `protocol_id` [Array] [security_level, protocol_name]
- **@param** `key_id` [String] key identifier
- **@param** `counterparty` [String] pubkey hex, 'self', or 'anyone'
- **@return** [Hash] { hmac: Array<Integer> }

### `create_signature(protocol_id:, key_id:, data: = nil, hash_to_directly_sign: = nil, counterparty: = nil, privileged: = false, privileged_reason: = nil, seek_permission: = true, originator: = nil)` <a id="method-i-create_signature"></a> <a id="create_signature-instance_method"></a>
Creates an ECDSA signature using a derived private key.
- **@param** `protocol_id` [Array] [security_level, protocol_name]
- **@param** `key_id` [String] key identifier
- **@param** `data` [Array<Integer>] data to hash and sign
- **@param** `hash_to_directly_sign` [Array<Integer>] pre-computed 32-byte hash
- **@param** `counterparty` [String] pubkey hex, 'self', or 'anyone'
- **@return** [Hash] { signature: Array<Integer> } DER-encoded signature as byte array

### `decrypt(ciphertext:, protocol_id:, key_id:, counterparty: = nil, privileged: = false, privileged_reason: = nil, seek_permission: = true, originator: = nil)` <a id="method-i-decrypt"></a> <a id="decrypt-instance_method"></a>
Decrypts ciphertext using AES-256-GCM with a derived symmetric key.
- **@param** `ciphertext` [Array<Integer>] byte array to decrypt
- **@param** `protocol_id` [Array] [security_level, protocol_name]
- **@param** `key_id` [String] key identifier
- **@param** `counterparty` [String] pubkey hex, 'self', or 'anyone'
- **@return** [Hash] { plaintext: Array<Integer> }

### `discover_by_attributes(attributes:, limit: = 10, offset: = 0, seek_permission: = true, originator: = nil)` <a id="method-i-discover_by_attributes"></a> <a id="discover_by_attributes-instance_method"></a>
Discovers certificates matching specific attribute values.
- **@param** `attributes` [Hash{String => String}] field name/value pairs to match
- **@raise** [NotImplementedError]

### `discover_by_identity_key(identity_key:, limit: = 10, offset: = 0, seek_permission: = true, originator: = nil)` <a id="method-i-discover_by_identity_key"></a> <a id="discover_by_identity_key-instance_method"></a>
Discovers certificates issued to a given identity key.
- **@raise** [NotImplementedError]

### `encrypt(plaintext:, protocol_id:, key_id:, counterparty: = nil, privileged: = false, privileged_reason: = nil, seek_permission: = true, originator: = nil)` <a id="method-i-encrypt"></a> <a id="encrypt-instance_method"></a>
Encrypts plaintext using AES-256-GCM with a derived symmetric key.
- **@param** `plaintext` [Array<Integer>] byte array to encrypt
- **@param** `protocol_id` [Array] [security_level, protocol_name]
- **@param** `key_id` [String] key identifier
- **@param** `counterparty` [String] pubkey hex, 'self', or 'anyone'
- **@return** [Hash] { ciphertext: Array<Integer> }

### `get_header_for_height(height:, originator: = nil)` <a id="method-i-get_header_for_height"></a> <a id="get_header_for_height-instance_method"></a>
Returns the 80-byte block header at the given height.
- **@raise** [NotImplementedError]

### `get_height(originator: = nil)` <a id="method-i-get_height"></a> <a id="get_height-instance_method"></a>
Returns the current blockchain height.
- **@raise** [NotImplementedError]

### `get_network(originator: = nil)` <a id="method-i-get_network"></a> <a id="get_network-instance_method"></a>
Returns the network (:mainnet or :testnet).
- **@raise** [NotImplementedError]

### `get_public_key(identity_key: = false, protocol_id: = nil, key_id: = nil, counterparty: = nil, for_self: = false, privileged: = false, privileged_reason: = nil, seek_permission: = true, originator: = nil)` <a id="method-i-get_public_key"></a> <a id="get_public_key-instance_method"></a>
Returns a derived or identity public key.
- **@param** `identity_key` [Boolean] return the root identity key
- **@param** `protocol_id` [Array] [security_level, protocol_name]
- **@param** `key_id` [String] key identifier
- **@param** `counterparty` [String] pubkey hex, 'self', or 'anyone'
- **@param** `for_self` [Boolean] derive from own identity
- **@return** [Hash] { public_key: String } hex-encoded compressed public key

### `get_version(originator: = nil)` <a id="method-i-get_version"></a> <a id="get_version-instance_method"></a>
Returns the wallet version string.
- **@raise** [NotImplementedError]

### `initialize(root_key)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@param** `root_key` [BSV::Primitives::PrivateKey, String] a private key or 'anyone'
- **@return** [ProtoWallet] a new instance of ProtoWallet

### `internalize_action(tx:, outputs:, description:, labels: = nil, seek_permission: = true, originator: = nil)` <a id="method-i-internalize_action"></a> <a id="internalize_action-instance_method"></a>
Internalizes a transaction — labels it, pays outputs to the wallet balance,
inserts outputs into baskets, and/or tags them.
- **@param** `tx` [Array<Integer>] Atomic BEEF-formatted transaction (byte array)
- **@param** `outputs` [Array<Hash>] metadata per output
- :output_index [Integer] index within the transaction
- :protocol [Symbol] :wallet_payment or :basket_insertion
- :payment_remittance [Hash] for payments: { derivation_prefix:, derivation_suffix:, sender_identity_key: }
- :insertion_remittance [Hash] for insertions: { basket:, custom_instructions:, tags: }
- **@raise** [NotImplementedError]

### `list_actions(labels:, label_query_mode: = :any, include_labels: = false, include_inputs: = false, include_input_source_locking_scripts: = false, include_input_unlocking_scripts: = false, include_outputs: = false, include_output_locking_scripts: = false, limit: = 10, offset: = 0, seek_permission: = true, originator: = nil)` <a id="method-i-list_actions"></a> <a id="list_actions-instance_method"></a>
Lists transactions matching the specified labels.
- **@raise** [NotImplementedError]
- **@return** [Hash] :total_actions, :actions

### `list_certificates(certifiers: = nil, types: = nil, limit: = 10, offset: = 0, privileged: = false, privileged_reason: = nil, originator: = nil)` <a id="method-i-list_certificates"></a> <a id="list_certificates-instance_method"></a>
Returns an empty certificate list.

ProtoWallet has no storage, so there are never any certificates.
- **@return** [Hash] { certificates: [] }

### `list_outputs(basket:, tags: = nil, tag_query_mode: = :any, include: = nil, include_custom_instructions: = false, include_tags: = false, include_labels: = false, limit: = 10, offset: = 0, seek_permission: = true, originator: = nil)` <a id="method-i-list_outputs"></a> <a id="list_outputs-instance_method"></a>
Lists spendable outputs in a basket.
- **@param** `include` [Symbol] nil, :locking_scripts, or :entire_transactions
- **@raise** [NotImplementedError]
- **@return** [Hash] :total_outputs, :beef, :outputs

### `prove_certificate(certificate: = nil, fields_to_reveal: = nil, verifier: = nil, privileged: = false, privileged_reason: = nil, originator: = nil)` <a id="method-i-prove_certificate"></a> <a id="prove_certificate-instance_method"></a>
Not supported — ProtoWallet has no certificate storage.
- **@raise** [UnsupportedActionError] always

### `relinquish_certificate(type:, serial_number:, certifier:, originator: = nil)` <a id="method-i-relinquish_certificate"></a> <a id="relinquish_certificate-instance_method"></a>
Removes a certificate from the wallet.
- **@raise** [NotImplementedError]

### `relinquish_output(basket:, output:, originator: = nil)` <a id="method-i-relinquish_output"></a> <a id="relinquish_output-instance_method"></a>
Removes an output from a basket without spending it.
- **@raise** [NotImplementedError]

### `reveal_counterparty_key_linkage(counterparty:, verifier:, privileged: = false, privileged_reason: = nil, originator: = nil)` <a id="method-i-reveal_counterparty_key_linkage"></a> <a id="reveal_counterparty_key_linkage-instance_method"></a>
Reveals counterparty key linkage to a verifier (BRC-69 Method 1).
- **@param** `counterparty` [String] counterparty public key hex (not 'self' or 'anyone')
- **@param** `verifier` [String] verifier public key hex
- **@raise** [InvalidParameterError]
- **@return** [Hash] { prover:, verifier:, counterparty:, revelation_time:,
encrypted_linkage:, encrypted_linkage_proof: }

### `reveal_specific_key_linkage(counterparty:, verifier:, protocol_id:, key_id:, privileged: = false, privileged_reason: = nil, originator: = nil)` <a id="method-i-reveal_specific_key_linkage"></a> <a id="reveal_specific_key_linkage-instance_method"></a>
Reveals specific key linkage for a particular interaction (BRC-69 Method 2).
- **@param** `counterparty` [String] counterparty public key hex
- **@param** `verifier` [String] verifier public key hex
- **@param** `protocol_id` [Array] [security_level, protocol_name]
- **@param** `key_id` [String] key identifier
- **@raise** [InvalidParameterError]
- **@return** [Hash] { prover:, verifier:, counterparty:, protocol_id:, key_id:,
encrypted_linkage:, encrypted_linkage_proof:, proof_type: }

### `sign_action(spends:, reference:, accept_delayed_broadcast: = true, return_txid_only: = false, no_send: = false, send_with: = nil, originator: = nil)` <a id="method-i-sign_action"></a> <a id="sign_action-instance_method"></a>
Signs a transaction previously created with {#create_action}.
- **@param** `spends` [Hash{Integer => Hash}] input index => { unlocking_script:, sequence_number: }
- **@param** `reference` [String] reference returned by {#create_action}
- **@raise** [NotImplementedError]

### `verify_hmac(data:, hmac:, protocol_id:, key_id:, counterparty: = nil, privileged: = false, privileged_reason: = nil, seek_permission: = true, originator: = nil)` <a id="method-i-verify_hmac"></a> <a id="verify_hmac-instance_method"></a>
Verifies an HMAC-SHA256 using a derived symmetric key.
- **@param** `data` [Array<Integer>] byte array that was authenticated
- **@param** `hmac` [Array<Integer>] HMAC to verify
- **@param** `protocol_id` [Array] [security_level, protocol_name]
- **@param** `key_id` [String] key identifier
- **@param** `counterparty` [String] pubkey hex, 'self', or 'anyone'
- **@raise** [InvalidHmacError] if the HMAC does not match
- **@return** [Hash] { valid: true }

### `verify_signature(signature:, protocol_id:, key_id:, data: = nil, hash_to_directly_verify: = nil, counterparty: = nil, for_self: = false, privileged: = false, privileged_reason: = nil, seek_permission: = true, originator: = nil)` <a id="method-i-verify_signature"></a> <a id="verify_signature-instance_method"></a>
Verifies an ECDSA signature using a derived public key.
- **@param** `signature` [Array<Integer>] DER-encoded signature as byte array
- **@param** `protocol_id` [Array] [security_level, protocol_name]
- **@param** `key_id` [String] key identifier
- **@param** `data` [Array<Integer>] original data that was signed
- **@param** `hash_to_directly_verify` [Array<Integer>] pre-computed 32-byte hash
- **@param** `counterparty` [String] pubkey hex, 'self', or 'anyone'
- **@param** `for_self` [Boolean] verify own derived key (default false)
- **@raise** [InvalidSignatureError] if the signature does not verify
- **@return** [Hash] { valid: true }

### `wait_for_authentication(originator: = nil)` <a id="method-i-wait_for_authentication"></a> <a id="wait_for_authentication-instance_method"></a>
Blocks until the user is authenticated.
- **@raise** [NotImplementedError]
