import type { BitcoinConnection, NetworkName } from '@did-btcr2/bitcoin'; import type { DocumentBytes, HashBytes, KeyBytes, PatchOperation } from '@did-btcr2/common'; import type { Signer } from '@did-btcr2/keypair'; import type { BroadcastOptions, Btcr2DidDocument, CASAnnouncement, DidCreateOptions, ResolutionOptions, SignedBTCR2Update, SMTProof } from '@did-btcr2/method'; import type { DidResolutionResult, DidVerificationMethod } from '@web5/dids'; import type { BitcoinApi } from './bitcoin.js'; import type { CasApi } from './cas.js'; import type { GenesisDocumentSpec } from './genesis.js'; import type { Logger } from './types.js'; /** * Result of {@link DidMethodApi.createExternalFromDocument}: the EXTERNAL * identifier, the genesis bytes it encodes, and the initial DID document. * @public */ export interface ExternalCreateResult { /** The EXTERNAL (`x`) identifier. */ did: string; /** The SHA-256 hash of the canonical genesis document: the genesis bytes of `did`. */ genesisBytes: HashBytes; /** * The initial DID document: the genesis document with `did` in place of the * placeholder id. Pass it to {@link DidMethodApi.getBeacons} for the beacon * addresses to fund. */ didDocument: Btcr2DidDocument; } /** * Policy for publishing update artifacts to the configured CAS during * {@link DidMethodApi.update}. CAS publication is optional and never required: * every update, for every beacon type, can be completed and distributed via * sidecar alone. Publishing is opt-in, so the default is `'never'`. * * - `'never'` (default): publish nothing. The caller distributes the returned * artifacts (signed update, announcement, proof) via sidecar themselves. * - `'auto'`: best-effort. Publish the signed update (all beacon types) and the * CAS Announcement (CAS beacons) when a writable CAS is configured; otherwise * skip publication silently for every beacon type and return the artifacts for * sidecar distribution. Never blocks an update for lack of a writable CAS. * - `'always'`: require a writable CAS. A read-only or absent CAS throws * up-front for every beacon type. Use this to opt into a hard guarantee that * the artifacts reached the CAS. * @public */ export type PublishToCasMode = 'auto' | 'always' | 'never'; /** * Result of {@link DidMethodApi.update}: the signed update plus every broadcast * artifact a resolver (or a sidecar distributor) needs afterwards. * @public */ export interface DidUpdateResult { /** The signed update that was broadcast. */ signedUpdate: SignedBTCR2Update; /** Transaction id of the on-chain beacon signal. */ txid: string; /** * The CAS Announcement whose hash rode in the OP_RETURN output (CAS beacons * only). Capture it for sidecar distribution when it was not published to CAS. */ announcement?: CASAnnouncement; /** * SMT inclusion proof for the update, with the leaf nonce embedded (SMT * beacons only). Not content-addressable; always distribute via sidecar. */ proof?: SMTProof; /** Which artifacts were published to the configured CAS. */ publishedToCas: { /** The canonical signed update bytes were published. */ update: boolean; /** The canonical CAS Announcement bytes were published (CAS beacons only). */ announcement: boolean; }; } /** * A beacon service on a DID document, reduced to what a caller funding the * beacon needs: the service id, the beacon type, and the bare Bitcoin address. * @public */ export interface BeaconInfo { /** The beacon service id, as spelled in the DID document. */ id: string; /** Beacon type: `SingletonBeacon`, `CASBeacon`, or `SMTBeacon`. */ type: string; /** The Bitcoin address to fund, with the `bitcoin:` URI scheme removed. */ address: string; } /** * DID method operations sub-facade: create, resolve, update, deactivate. * * Lazily initialized by {@link DidBtcr2Api} because it depends on * {@link BitcoinApi} which requires network configuration. * @public */ export declare class DidMethodApi { #private; /** * The JSON Patch operation that deactivates a DID document: it sets the * `deactivated` flag that resolvers halt on. Deactivation is not a separate * primitive in did:btcr2; it is an ordinary update carrying exactly this * patch, which is what {@link DidMethodApi.deactivate} broadcasts. The * constant is the `DEACTIVATION_PATCH` of `@did-btcr2/method`. */ static readonly DEACTIVATION_PATCH: Readonly; /** * The network an identifier is minted for when the caller names none and no * Bitcoin connection is configured to inherit one from. Regtest, so that an * offline facade can never hand out a mainnet beacon address by omission. * Every creation path on the api, {@link DidBtcr2Api.generateDid} included, * falls back to this one value. */ static readonly FALLBACK_NETWORK: NetworkName; constructor(btc?: BitcoinApi, cas?: CasApi, logger?: Logger); /** * The network new DIDs are minted on when the caller names none: the network * of the configured Bitcoin connection, else * {@link DidMethodApi.FALLBACK_NETWORK}. Never `undefined`: an offline * facade mints regtest identifiers, not mainnet ones. */ get defaultNetwork(): NetworkName; /** * Create a deterministic (k1) DID from a public key. * Sets idType to KEY automatically. * * When `options.network` is omitted, the DID is minted for the network of the * configured Bitcoin connection, so it targets the same chain this facade * reads. With no Bitcoin connection configured it is minted for * {@link DidMethodApi.FALLBACK_NETWORK} (regtest), never mainnet. * @param genesisBytes The compressed public key bytes (33 bytes). * @param options Creation options (idType is set for you). * @returns The created DID identifier string. */ createDeterministic(genesisBytes: KeyBytes, options?: Omit): string; /** * Create a non-deterministic (x1) DID from external genesis document bytes. * Sets idType to EXTERNAL automatically. * * When `options.network` is omitted, the DID is minted for the network of the * configured Bitcoin connection. With no Bitcoin connection configured it is * minted for {@link DidMethodApi.FALLBACK_NETWORK} (regtest), never mainnet. * @param genesisBytes The genesis document bytes. * @param options Creation options (idType is set for you). * @returns The created DID identifier string. */ createExternal(genesisBytes: DocumentBytes, options?: Omit): string; /** * The DID document a DID resolves to before any update has been announced, * computed with zero I/O: no Bitcoin connection, no CAS, no network at all. * * For KEY (`k`) identifiers the whole document, beacon services included, is * a pure function of the public key inside the identifier. That matters for * bootstrapping: the beacon address a caller must fund before their first * update is knowable offline, so it need not be fetched from a chain the DID * has not touched yet. For EXTERNAL (`x`) identifiers the genesis document is * the caller's own input and must be supplied; it is validated against the * hash inside the identifier. * @param did The DID whose initial document to derive. * @param genesisDocument The genesis document (EXTERNAL DIDs only). * @returns The initial DID document. */ getInitialDocument(did: string, genesisDocument?: object): Btcr2DidDocument; /** * The beacon services of a DID document, each paired with the Bitcoin address * that must hold a confirmed UTXO before that beacon can broadcast a signal. * Combine with {@link DidMethodApi.getInitialDocument} to learn the address * to fund without any chain round-trip. * @param document The DID document to read beacon services from. * @returns One {@link BeaconInfo} per beacon service on the document. */ getBeacons(document: Btcr2DidDocument): BeaconInfo[]; /** * Build a Genesis Document from keys, beacons, and services, with zero I/O. * * The document carries the placeholder id `did:btcr2:_`, one Multikey * verification method per key, the verification relationships, one beacon * service per beacon, and the other services. Its canonical SHA-256 hash is * the genesis bytes of an EXTERNAL (`x`) identifier; pass the document to * {@link DidMethodApi.createExternalFromDocument} to mint one. The caller * keeps the document: an EXTERNAL identifier resolves only with it. * * When `spec.network` is omitted, the beacon addresses are derived for the * network of the configured Bitcoin connection, else for * {@link DidMethodApi.FALLBACK_NETWORK} (regtest), never mainnet. When * `spec.beacons` is omitted, the document gets one Singleton beacon with the * P2WPKH address of the first key. The builder refuses a spec with no * `capabilityInvocation` method or no beacon: such a DID can never be updated. * @param spec The keys, beacons, and services. See {@link GenesisDocumentSpec}. * @returns The genesis document. * @throws {DidDocumentError} If the spec is not valid. */ buildGenesisDocument(spec: Omit & { network?: NetworkName; }): Btcr2DidDocument; /** * Create an EXTERNAL (`x`) DID from its genesis document, with zero I/O. * * The document must be a Genesis Document: a JSON object with the id * `did:btcr2:_`, the two required contexts, and the placeholder in every * verification method and service id. The api hashes the document as given * (JCS canonical form, SHA-256), encodes the identifier for the network, and * derives the initial DID document, which validates the document as a DID * document. Hash the same JSON you keep or publish: a document with one * changed byte hashes to a different identifier. * * When `options.network` is omitted, the DID is minted for the network of the * configured Bitcoin connection, else for {@link DidMethodApi.FALLBACK_NETWORK} * (regtest), never mainnet. The network is not checked against the beacon * addresses of the document. * @param genesisDocument The genesis document. * @param options Creation options (idType is set for you). * @returns The identifier, its genesis bytes, and the initial DID document. * @throws {DidDocumentError} If the document is not a valid genesis document. */ createExternalFromDocument(genesisDocument: object, options?: Omit): ExternalCreateResult; /** * Resolve a DID by driving the sans-I/O `Resolver` state machine (from @did-btcr2/method). * If a Bitcoin connection is configured on the API, it is used automatically * to fetch beacon signals. Sidecar data flows through `options.sidecar`. * If the DID names a network other than the connection's, resolution is * refused before any chain read. * * A failure rejects with a plain `Error` whose `cause` chain carries the * typed failure: `ResolveError` of type `NOT_FOUND` when the genesis * document of an EXTERNAL DID is not in the sidecar and the CAS does not * return it, `MISSING_UPDATE_DATA` when a signed update or a CAS * announcement is not in the sidecar and the CAS does not return it. * @param did The DID to resolve. * @param options Resolution options. * @returns The resolution result. `didResolutionMetadata.contentType` is * `application/did`, the media type of a bare DID document. */ resolve(did: string, options?: ResolutionOptions): Promise; /** * Update an existing DID document by driving the sans-I/O {@link Updater} state * machine (from @did-btcr2/method). This method handles the I/O side: * - Signing: supplies the {@link Signer} to `NeedSigningKey`. * - Funding: reads the UTXOs at the beacon address and refuses the update if * none is spendable. A spendable UTXO is confirmed and above the dust * limit. The beacon applies the same rule at broadcast. * - CAS publication: publishes the signed update (and, for CAS beacons, the * announcement) to the configured CAS per the `publishToCas` policy, * **before** the on-chain broadcast, so any OP_RETURN update hash is * fetchable from CAS at resolution time without sidecar data. * - Broadcast: establishes a beacon via {@link BeaconFactory} and calls * `broadcastSignal()` with the bitcoin connection configured on the API. * - Network check: refuses the update if the DID names a network other * than the connection's, before any I/O. * * A deactivated source document is refused before anything else runs. * Resolution halts at the deactivation, so an update signed on top of it * would spend a beacon UTXO on an announcement no resolver ever reads. * Every write path (`updateDid`, `UpdateBuilder.execute`, `deactivate`) * passes through here, so the refusal holds for all of them. * * The caller can omit `verificationMethodId` and `beaconId`. The api then * derives them, after the guards above and before any signature. The * verification method is the one method on the source document that * publishes the signer's key. The Updater refuses every other method, so * the signer's key identifies the method. * * The beacon is the only beacon service, with no chain read. If the * document has several beacon services, the beacon is the one whose * address holds a spendable UTXO. If no method or no beacon matches, the * api refuses the update. If several match, the api refuses the update and * names the candidates. * * For multi-party aggregation of SMT/CAS beacons, the caller should drive the * Updater directly and delegate `NeedBroadcast` to the aggregation runner * rather than using this high-level method. * * @param params The update parameters. * @returns The broadcast artifacts: signed update, signal txid, per-beacon-type * sidecar data, and which artifacts were published to CAS. */ update({ sourceDocument, patches, sourceVersionId, verificationMethodId, beaconId, signer, bitcoin, publishToCas, broadcastOptions, }: { sourceDocument: Btcr2DidDocument; patches: PatchOperation[]; sourceVersionId: number; verificationMethodId?: string; beaconId?: string; signer: Signer; bitcoin?: BitcoinConnection; publishToCas?: PublishToCasMode; broadcastOptions?: BroadcastOptions; }): Promise; /** * Get the signing method from a DID document by method ID. * @param didDocument The DID document. * @param methodId The method ID (if omitted, the first signing method is returned). * @returns The found signing method. */ getSigningMethod(didDocument: Btcr2DidDocument, methodId?: string): DidVerificationMethod; /** * Create a fluent builder for a DID update operation. * @param sourceDocument The current DID document to update. * @returns An {@link UpdateBuilder} for chaining update parameters. * * @example * ```ts * const { signedUpdate, txid } = await api.btcr2 * .buildUpdate(currentDoc) * .patch({ op: 'add', path: '/service/1', value: newService }) * .version(2) * .verificationMethodId(`${currentDoc.id}#initialKey`) * .beacon(currentDoc.service[0].id) * .signer(new LocalSigner(secretKey)) * .execute(); * ``` */ buildUpdate(sourceDocument: Btcr2DidDocument): UpdateBuilder; /** * Deactivate a DID by broadcasting an update that sets the `deactivated` * flag ({@link DidMethodApi.DEACTIVATION_PATCH}). Deactivation is an * ordinary update in did:btcr2: it rides the same sign / CAS-publication / * beacon-broadcast path as {@link DidMethodApi.update}, and resolvers halt * at the flag. * * Deactivation is irreversible. An already-deactivated source document is * refused up-front: a second deactivation would sign and broadcast a * well-formed update that no resolver can ever read back, because * resolution stops at the first deactivation. * * The caller can omit `verificationMethodId` and `beaconId`. * {@link DidMethodApi.update} derives them. * * @param params The update parameters minus `patches` (the deactivation * patch is supplied for you). * @returns The broadcast artifacts, exactly as {@link DidMethodApi.update}. */ deactivate(params: { sourceDocument: Btcr2DidDocument; sourceVersionId: number; verificationMethodId?: string; beaconId?: string; signer: Signer; bitcoin?: BitcoinConnection; publishToCas?: PublishToCasMode; broadcastOptions?: BroadcastOptions; }): Promise; } /** * Fluent builder for DID update operations. Reduces the cognitive load of * the 7-parameter `update()` call by letting callers chain named steps. * * Created via {@link DidMethodApi.buildUpdate}. * @public */ export declare class UpdateBuilder { #private; /** @internal */ constructor(methodApi: DidMethodApi, sourceDocument: Btcr2DidDocument); /** Add a single JSON Patch operation. Can be called multiple times. */ patch(op: PatchOperation): this; /** Set all patches at once (replaces any previously added). */ patches(ops: PatchOperation[]): this; /** Set the source version ID. */ version(id: number): this; /** Set the verification method ID used for signing the update. */ verificationMethodId(methodId: string): this; /** Set the beacon ID for the update announcement. */ beacon(beaconId: string): this; /** * Set the {@link Signer} that produces the update's BIP-340 Schnorr proof * and the beacon transaction's ECDSA input signature. Use `LocalSigner` * for in-process secret keys, `KeyManagerSigner` for KMS-managed keys * (AWS, Vault, HSM, etc.), or any custom adapter implementing the `Signer` * interface. */ signer(s: Signer): this; /** Override the Bitcoin connection for this update. */ bitcoin(connection: BitcoinConnection): this; /** Set the CAS publication policy for this update (default `'never'`; opt-in). */ publishToCas(mode: PublishToCasMode): this; /** Set beacon broadcast options (fee estimator, change address). */ broadcastOptions(options: BroadcastOptions): this; /** * Execute the update. * @throws {Error} If required fields (version, verificationMethodId, beacon, signer) are missing. */ execute(): Promise; } //# sourceMappingURL=method.d.ts.map