Retrieving Public Key Information

Overview

OP_NET provides methods to retrieve public key information for addresses on the network. These operations support unified address resolution across different Bitcoin address formats including P2TR, P2PKH, P2WPKH, and P2OP. The provider also exposes ML-DSA quantum-resistant key data when available, enabling applications to work with both classical and post-quantum cryptographic identities.

Single Address Lookup

Using getPublicKeyInfo()

The getPublicKeyInfo() method resolves a single address to its corresponding public key information. The method accepts an address string or Address object and a boolean indicating whether the address belongs to a contract.

The returned Address object provides access to various address formats and key data, including the hex representation, P2TR address, and ML-DSA public key when available.

Method Signature

typescript
getPublicKeyInfo() signature
async getPublicKeyInfo(
    addressRaw: string | Address,  // Address to look up
    isContract: boolean            // Whether address is a contract
): Promise<Address>

Basic Public Key Query

typescript
Basic Public Key Query
import { JSONRpcProvider } from 'opnet';
import { networks, Address } from '@btc-vision/bitcoin';

const network = networks.regtest;
const provider = new JSONRpcProvider({ url: 'https://regtest.opnet.org', network });

// Get public key info for an address
const address = await provider.getPublicKeyInfo(
    'bc1p...taproot-address...',
    false  // Not a contract
);

console.log('Address:', address.toHex());
console.log('P2TR:', address.p2tr(network));

Contract Public Key Query

typescript
Contract Public Key Query
import { JSONRpcProvider } from 'opnet';
import { networks, Address } from '@btc-vision/bitcoin';

const network = networks.regtest;
const provider = new JSONRpcProvider({ url: 'https://regtest.opnet.org', network });

// For contract addresses, set isContract to true
const contractAddress = await provider.getPublicKeyInfo(
    'bc1p...contract-address...',
    true  // Is a contract
);

console.log('Contract public key:', contractAddress.toHex());

Multiple Address Lookup

Using getPublicKeysInfo()

The getPublicKeysInfo() method resolves multiple addresses to their corresponding public key information in a single request. The method accepts a single address or an array of addresses, a boolean indicating whether the addresses belong to contracts, and an optional flag to log errors for addresses that fail lookup.

The returned AddressesInfo object is a map of input addresses to their resolved Address instances. Addresses that fail lookup are omitted from the result; enable logErrors to output failure details to the console.

Method Signature

typescript
getPublicKeysInfo() signature
async getPublicKeysInfo(
    addresses: string | string[] | Address | Address[],
    isContract: boolean = false,
    logErrors: boolean = false
): Promise<AddressesInfo>

Multiple Public Key Query With Error Handling

typescript
Multiple Public Key Query
import { JSONRpcProvider } from 'opnet';
import { networks, Address } from '@btc-vision/bitcoin';

const network = networks.regtest;
const provider = new JSONRpcProvider({ url: 'https://regtest.opnet.org', network });

const addresses = [
    'bc1p...address1...',
    'bc1p...address2...',
    'bc1q...address3...',
];

const results = await provider.getPublicKeysInfo(
    addresses,
    false,
    true  // Enable error logging
);

// Results is a map of input -> Address
for (const [input, address] of Object.entries(results)) {
    console.log(`${input} => ${address.toHex()}`);
}

// Check for missing addresses
for (const addr of addresses) {
    if (!(addr in results)) {
        console.log(`Address not found: ${addr}`);
    }
}

Raw Public Key Data

Using getPublicKeysInfoRaw()

The getPublicKeysInfoRaw() method retrieves public key information directly from the API without transforming the response into Address objects. This method is useful when access to the raw API response is required or when custom processing of the key data is needed.

The method accepts a single address or an array of addresses and returns an IPublicKeyInfoResult object containing the raw response data. This includes fields such as tweakedPubkey, originalPubKey, mldsaPublicKey, and mldsaHashedPublicKey when available.

Method Signature

typescript
getPublicKeysInfoRaw() signature
async getPublicKeysInfoRaw(
    addresses: string | string[] | Address | Address[]
): Promise<IPublicKeyInfoResult>

PublicKeyInfo Structure

typescript
PublicKeyInfo structure
interface PublicKeyInfo {
    // Public keys
    originalPubKey?: string;     // Original (untweaked) public key
    tweakedPubkey?: string;      // Tweaked public key for Taproot

    // Address formats
    p2tr?: string;               // Pay-to-Taproot address
    p2op?: string;               // OPNet P2OP address
    p2pkh?: string;              // Pay-to-Public-Key-Hash (legacy)
    p2pkhUncompressed?: string;  // P2PKH with uncompressed key
    p2pkhHybrid?: string;        // P2PKH with hybrid key
    p2shp2wpkh?: string;         // P2SH-wrapped P2WPKH
    p2wpkh?: string;             // Pay-to-Witness-Public-Key-Hash

    // Internal
    lowByte?: number;            // Low byte of public key

    // ML-DSA (quantum-resistant)
    mldsaHashedPublicKey?: string;     // Hashed ML-DSA public key
    mldsaLevel?: MLDSASecurityLevel;   // ML-DSA security level
    mldsaPublicKey?: string | null;    // Full ML-DSA public key
}

Raw API Response

typescript
Raw API response
import { JSONRpcProvider } from 'opnet';
import { networks, Address } from '@btc-vision/bitcoin';

const network = networks.regtest;
const provider = new JSONRpcProvider({ url: 'https://regtest.opnet.org', network });

const rawInfo = await provider.getPublicKeysInfoRaw([
    'bc1p...address...',
]);

// Raw info contains all address formats
for (const [key, info] of Object.entries(rawInfo)) {
    if ('error' in info) {
        console.log(`Error for ${key}: ${info.error}`);
        continue;
    }

    console.log(`Public Key Info for ${key}:`);
    console.log('  Original PubKey:', info.originalPubKey);
    console.log('  Tweaked PubKey:', info.tweakedPubkey);
    console.log('  P2TR:', info.p2tr);
    console.log('  P2OP:', info.p2op);
    console.log('  P2WPKH:', info.p2wpkh);
    console.log('  P2PKH:', info.p2pkh);

    // ML-DSA info (quantum-resistant)
    if (info.mldsaHashedPublicKey) {
        console.log('  ML-DSA Level:', info.mldsaLevel);
        console.log('  ML-DSA Hashed PK:', info.mldsaHashedPublicKey);
    }
}

CSV1 Address Lookup

Using getCSV1ForAddress()

The getCSV1ForAddress() method returns the CSV1 address for a given address. CSV addresses are used for time-locked transactions and provide an additional layer of security by requiring a minimum block delay before funds can be spent.

The method accepts an Address object and returns an IP2WSHAddress representing the CSV1 address.

Method Signature

typescript
getCSV1ForAddress() signature
getCSV1ForAddress(address: Address): IP2WSHAddress

IP2WSHAddress Structure

typescript
IP2WSHAddress structure
interface IP2WSHAddress {
    address: string;
    witnessScript: Uint8Array;
}

Get CSV1 Address

typescript
Get CSV1 Address
import { Address, toHex, networks } from '@btc-vision/bitcoin';
import { JSONRpcProvider } from 'opnet';

const network = networks.regtest;
const provider = new JSONRpcProvider({ url: 'https://regtest.opnet.org', network });

const address = Address.fromString('bc1p...taproot-address...');
const csv1Address = provider.getCSV1ForAddress(address);

console.log('CSV1 Address:', csv1Address.address);
console.log('Redeem Script:', csv1Address.redeemScript ? toHex(csv1Address.redeemScript) : undefined);