import { WalletInterface, WalletProtocol, Base64String, PubKeyHex } from '@bsv/sdk'; /** Line item type for spending authorization requests. */ export type LineItemType = 'input' | 'output' | 'fee'; /** Security level for DPACP protocol permissions. */ export type SecurityLevel = 0 | 1 | 2; /** * A permissions module handles request/response transformation for a specific P-protocol or P-basket scheme under BRC-98/99. * Modules are registered in the config mapped by their scheme ID. */ export interface PermissionsModule { /** * Transforms the request before it's passed to the underlying wallet. * Can check and enforce permissions, throw errors, or modify any arguments as needed prior to invocation. * * @param req - The incoming request with method, args, and originator * @returns Transformed arguments that will be passed to the underlying wallet */ onRequest: (req: { method: string; args: object; originator: string; }) => Promise<{ args: object; }>; /** * Transforms the response from the underlying wallet before returning to caller. * * @param res - The response from the underlying wallet * @param context - Metadata about the original request (method, originator) * @returns Transformed response to return to the caller */ onResponse: (res: any, context: { method: string; originator: string; }) => Promise; } /** * Describes a group of permissions that can be requested together. * This structure is based on BRC-73. */ export interface GroupedPermissions { description?: string; spendingAuthorization?: { amount: number; description: string; }; protocolPermissions?: Array<{ protocolID: WalletProtocol; counterparty?: string; description: string; }>; basketAccess?: Array<{ basket: string; description: string; }>; certificateAccess?: Array<{ type: string; fields: string[]; verifierPublicKey: string; description: string; }>; } /** * The object passed to the UI when a grouped permission is requested. */ export interface GroupedPermissionRequest { originator: string; requestID: string; permissions: GroupedPermissions; } /** * Signature for functions that handle a grouped permission request event. */ export type GroupedPermissionEventHandler = (request: GroupedPermissionRequest) => void | Promise; export interface CounterpartyPermissions { description?: string; protocols: Array<{ protocolName: string; protocolID?: WalletProtocol; description?: string; }>; } export interface CounterpartyPermissionRequest { originator: string; requestID: string; counterparty: PubKeyHex; counterpartyLabel?: string; permissions: CounterpartyPermissions; } export type CounterpartyPermissionEventHandler = (request: CounterpartyPermissionRequest) => void | Promise; /** * Describes a single requested permission that the user must either grant or deny. * * Four categories of permission are supported, each with a unique protocol: * 1) protocol - "DPACP" (Domain Protocol Access Control Protocol) * 2) basket - "DBAP" (Domain Basket Access Protocol) * 3) certificate - "DCAP" (Domain Certificate Access Protocol) * 4) spending - "DSAP" (Domain Spending Authorization Protocol) * * This model underpins "requests" made to the user for permission, which the user can * either grant or deny. The manager can then create on-chain tokens (PushDrop outputs) * if permission is granted. Denying requests cause the underlying operation to throw, * and no token is created. An "ephemeral" grant is also possible, denoting a one-time * authorization without an associated persistent on-chain token. */ export interface PermissionRequest { type: 'protocol' | 'basket' | 'certificate' | 'spending'; originator: string; displayOriginator?: string; usageType?: string; privileged?: boolean; protocolID?: WalletProtocol; counterparty?: string; basket?: string; certificate?: { verifier: string; certType: string; fields: string[]; }; spending?: { satoshis: number; lineItems?: Array<{ type: LineItemType; description: string; satoshis: number; }>; }; reason?: string; renewal?: boolean; previousToken?: PermissionToken; } /** * Signature for functions that handle a permission request event, e.g. "Please ask the user to allow basket X". */ export type PermissionEventHandler = (request: PermissionRequest & { requestID: string; }) => void | Promise; /** * Data structure representing an on-chain permission token. * It is typically stored as a single unspent PushDrop output in a special "internal" admin basket belonging to * the user, held in their underlying wallet. * * It can represent any of the four permission categories by having the relevant fields: * - DPACP: originator, privileged, protocol, securityLevel, counterparty * - DBAP: originator, basketName * - DCAP: originator, privileged, verifier, certType, certFields * - DSAP: originator, authorizedAmount */ export interface PermissionToken { /** The transaction ID where this token resides. */ txid: string; /** The current transaction encapsulating the token. */ tx: number[]; /** The output index within that transaction. */ outputIndex: number; /** The exact script hex for the locking script. */ outputScript: string; /** The amount of satoshis assigned to the permission output (often 1). */ satoshis: number; /** The originator domain or FQDN that is allowed to use this permission. */ originator: string; /** * The raw, unnormalized originator string captured at the time the permission * token was created. This is preserved so we can continue to recognize legacy * permissions that were stored with different casing or explicit default ports. */ rawOriginator?: string; /** The expiration time for this token in UNIX epoch seconds. (0 or omitted for spending authorizations, which are indefinite) */ expiry: number; /** Whether this token grants privileged usage (for protocol or certificate). */ privileged?: boolean; /** The protocol name, if this is a DPACP token. */ protocol?: string; /** The security level (0,1,2) for DPACP. */ securityLevel?: SecurityLevel; /** The counterparty, for DPACP. */ counterparty?: string; /** The name of a basket, if this is a DBAP token. */ basketName?: string; /** The certificate type, if this is a DCAP token. */ certType?: string; /** The certificate fields that this token covers, if DCAP token. */ certFields?: string[]; /** The "verifier" public key string, if DCAP. */ verifier?: string; /** For DSAP, the maximum authorized spending for the month. */ authorizedAmount?: number; } /** * The set of callbacks that external code can bind to, e.g. to display UI prompts or logs * when a permission is requested. */ export interface WalletPermissionsManagerCallbacks { onProtocolPermissionRequested?: PermissionEventHandler[]; onBasketAccessRequested?: PermissionEventHandler[]; onCertificateAccessRequested?: PermissionEventHandler[]; onSpendingAuthorizationRequested?: PermissionEventHandler[]; onGroupedPermissionRequested?: GroupedPermissionEventHandler[]; onCounterpartyPermissionRequested?: CounterpartyPermissionEventHandler[]; } /** * Configuration object for the WalletPermissionsManager. If a given option is `false`, * the manager will skip or alter certain permission checks or behaviors. * * By default, all of these are `true` unless specified otherwise. This is the most secure configuration. */ export interface PermissionsManagerConfig { /** * A map of P-basket/protocol permission scheme modules. * * Keys are scheme IDs (e.g., "btms"), values are PermissionsModule instances. * * Each module handles basket/protocol names of the form: `p ` * * The WalletPermissionManager detects P-prefix baskets/protocols and delegates * request/response transformation to the corresponding module. * * If no module exists for a given schemeID, the wallet will reject access. */ permissionModules?: Record; /** * For `createSignature` and `verifySignature`, * require a "protocol usage" permission check? */ seekProtocolPermissionsForSigning?: boolean; /** * For methods that perform encryption (encrypt/decrypt), require * a "protocol usage" permission check? */ seekProtocolPermissionsForEncrypting?: boolean; /** * For methods that perform HMAC creation or verification (createHmac, verifyHmac), * require a "protocol usage" permission check? */ seekProtocolPermissionsForHMAC?: boolean; /** * For revealing counterparty-level or specific key linkage revelation information, * should we require permission? */ seekPermissionsForKeyLinkageRevelation?: boolean; /** * For revealing any user public key (getPublicKey) **other** than the identity key, * should we require permission? */ seekPermissionsForPublicKeyRevelation?: boolean; /** * If getPublicKey is requested with `identityKey=true`, do we require permission? */ seekPermissionsForIdentityKeyRevelation?: boolean; /** * If discoverByIdentityKey / discoverByAttributes are called, do we require permission * for "identity resolution" usage? */ seekPermissionsForIdentityResolution?: boolean; /** * When we do internalizeAction with `basket insertion`, or include outputs in baskets * with `createAction, do we ask for basket permission? */ seekBasketInsertionPermissions?: boolean; /** * When relinquishOutput is called, do we ask for basket permission? */ seekBasketRemovalPermissions?: boolean; /** * When listOutputs is called, do we ask for basket permission? */ seekBasketListingPermissions?: boolean; /** * When createAction is called with labels, do we ask for "label usage" permission? */ seekPermissionWhenApplyingActionLabels?: boolean; /** * When listActions is called with labels, do we ask for "label usage" permission? */ seekPermissionWhenListingActionsByLabel?: boolean; /** * If proving a certificate (proveCertificate) or revealing certificate fields, * do we require a "certificate access" permission? */ seekCertificateDisclosurePermissions?: boolean; /** * If acquiring a certificate (acquireCertificate), do we require a permission check? */ seekCertificateAcquisitionPermissions?: boolean; /** * If relinquishing a certificate (relinquishCertificate), do we require a permission check? */ seekCertificateRelinquishmentPermissions?: boolean; /** * If listing a user's certificates (listCertificates), do we require a permission check? */ seekCertificateListingPermissions?: boolean; /** * Should transaction descriptions, input descriptions, and output descriptions be encrypted * when before they are passed to the underlying wallet, and transparently decrypted when retrieved? */ encryptWalletMetadata?: boolean; /** * If the originator tries to spend wallet funds (netSpent > 0 in createAction), * do we seek spending authorization? */ seekSpendingPermissions?: boolean; /** * If true, triggers a grouped permission request flow based on the originator's `manifest.json`. */ seekGroupedPermission?: boolean; /** * If false, permissions are checked without regard for whether we are in * privileged mode. Privileged status is ignored with respect to whether * permissions are granted. Internally, they are always sought and checked * with privileged=false, regardless of the actual value. */ differentiatePrivilegedOperations?: boolean; /** * An allowlist mapping counterparty identity public keys (hex) * to protocol names that are automatically permitted * without prompting the user. */ whitelistedCounterparties?: { [counterparty: PubKeyHex]: string[]; }; } /** * @class WalletPermissionsManager * * Wraps an underlying BRC-100 `Wallet` implementation with permissions management capabilities. * The manager intercepts calls from external applications (identified by originators), checks if the request is allowed, * and if not, orchestrates user permission flows. It creates or renews on-chain tokens in special * admin baskets to track these authorizations. Finally, it proxies the actual call to the underlying wallet. * * ### Key Responsibilities: * - **Permission Checking**: Before standard wallet operations (e.g. `encrypt`), * the manager checks if a valid permission token exists. If not, it attempts to request permission from the user. * - **On-Chain Tokens**: When permission is granted, the manager stores it as an unspent "PushDrop" output. * This can be spent later to revoke or renew the permission. * - **Callbacks**: The manager triggers user-defined callbacks on permission requests (to show a UI prompt), * on grants/denials, and on internal processes. * * ### Implementation Notes: * - The manager follows the BRC-100 `createAction` + `signAction` pattern for building or spending these tokens. * - Token revocation or renewal uses standard BRC-100 flows: we build a transaction that consumes * the old token UTXO and outputs a new one (or none, if fully revoked). */ export declare class WalletPermissionsManager implements WalletInterface { /** A reference to the BRC-100 wallet instance. */ private readonly underlying; /** The "admin" domain or FQDN that is implicitly allowed to do everything. */ private readonly adminOriginator; /** * Event callbacks that external code can subscribe to, e.g. to show a UI prompt * or log events. Each event can have multiple handlers. */ private readonly callbacks; /** * We queue parallel requests for the same resource so that only one * user prompt is created for a single resource. If multiple calls come * in at once for the same "protocol:domain:privileged:counterparty" etc., * they get merged. * * The key is a string derived from the operation; the value is an object with a reference to the * associated request and an array of pending promise resolve/reject pairs, one for each active * operation that's waiting on the particular resource described by the key. */ private readonly activeRequests; /** Cache recently confirmed permissions to avoid repeated lookups. */ private readonly permissionCache; private readonly recentGrants; private readonly manifestCache; private readonly manifestFetchInProgress; private static readonly MANIFEST_CACHE_TTL_MS; private readonly groupedPermissionFlowTail; private readonly pactEstablishedCache; /** How long a cached permission remains valid (5 minutes). */ private static readonly CACHE_TTL_MS; /** Window during which freshly granted permissions are auto-allowed (except spending). */ private static readonly RECENT_GRANT_COVER_MS; /** Default ports used when normalizing originator values. */ private static readonly DEFAULT_PORTS; /** * Configuration that determines whether to skip or apply various checks and encryption. */ private readonly config; /** * Constructs a new Permissions Manager instance. * * @param underlyingWallet The underlying BRC-100 wallet, where requests are forwarded after permission is granted * @param adminOriginator The domain or FQDN that is automatically allowed everything * @param config A set of boolean flags controlling how strictly permissions are enforced */ constructor(underlyingWallet: WalletInterface, adminOriginator: string, config?: PermissionsManagerConfig); /** * Delegates a wallet method call to a P-module if the basket or protocol name uses a P-scheme. * Handles the full request/response transformation flow. * * @param basketOrProtocolName - The basket or protocol name to check for p-module delegation * @param method - The wallet method name being called * @param args - The original args passed to the method * @param originator - The originator of the request * @param underlyingCall - Callback that executes the underlying wallet method with transformed args * @returns The transformed response, or null if not a P-basket/protocol (caller should continue normal flow) */ private delegateToPModuleIfNeeded; /** * Adds a permission module for the given schemeID if needed, throwing if unsupported. */ private addPModuleByScheme; /** * Splits labels into P and non-P lists, registering any P-modules encountered. * * P-labels follow BRC-111 format: `p ` * - Must start with "p " (lowercase p + space) * - Module ID must be at least 1 character with no spaces * - Single space separates module ID from payload * - Payload must be at least 1 character * * @example Valid: "p btms token123", "p invoicing invoice 2026-02-02" * @example Invalid: "p btms" (no payload), "p btms " (empty payload), "p data" (empty moduleId) * * @param labels - Array of label strings to process * @param pModulesByScheme - Map to populate with discovered p-modules * @returns Array of non-P labels for normal permission checks * @throws Error if p-label format is invalid or module is unsupported */ private splitLabelsByPermissionModule; /** * Decrypts custom instructions in listOutputs results if encryption is configured. */ private decryptListOutputsMetadata; /** * Decrypts metadata in listActions results if encryption is configured. */ private decryptListActionsMetadata; private decryptSingleActionMetadata; private decryptActionOutputMetadata; /** * Binds a callback function to a named event, such as `onProtocolPermissionRequested`. * * @param eventName The name of the event to listen to * @param handler A function that handles the event * @returns A numeric ID you can use to unbind later */ bindCallback(eventName: keyof WalletPermissionsManagerCallbacks, handler: PermissionEventHandler | GroupedPermissionEventHandler | CounterpartyPermissionEventHandler): number; /** * Unbinds a previously registered callback by either its numeric ID (returned by `bindCallback`) * or by exact function reference. * * @param eventName The event name, e.g. "onProtocolPermissionRequested" * @param reference Either the numeric ID or the function reference * @returns True if successfully unbound, false otherwise */ unbindCallback(eventName: keyof WalletPermissionsManagerCallbacks, reference: number | Function): boolean; /** * Internally triggers a named event, calling all subscribed listeners. * Each callback is awaited in turn (though errors are swallowed so that * one failing callback doesn't prevent the others). * * @param eventName The event name * @param param The parameter object passed to all listeners */ private callEvent; /** * Grants a previously requested permission. * This method: * 1) Resolves all pending promise calls waiting on this request * 2) Optionally creates or renews an on-chain PushDrop token (unless `ephemeral===true`) * * @param params requestID to identify which request is granted, plus optional expiry * or `ephemeral` usage, etc. */ grantPermission(params: { requestID: string; expiry?: number; ephemeral?: boolean; amount?: number; }): Promise; /** * Denies a previously requested permission. * This method rejects all pending promise calls waiting on that request * * @param requestID requestID identifying which request to deny */ denyPermission(requestID: string): Promise; /** * Grants a previously requested grouped permission. * @param params.requestID The ID of the request being granted. * @param params.granted A subset of the originally requested permissions that the user has granted. * @param params.expiry An optional expiry time (in seconds) for the new permission tokens. */ grantGroupedPermission(params: { requestID: string; granted: Partial; expiry?: number; }): Promise; /** * Denies a previously requested grouped permission. * @param requestID The ID of the request being denied. */ /** * Validates that every entry in `granted` was part of the original `requested` set. * Throws an error on the first mismatch. */ private validateGrantedPermissionsSubset; private denyActiveRequest; denyGroupedPermission(requestID: string): Promise; dismissGroupedPermission(requestID: string): Promise; grantCounterpartyPermission(params: { requestID: string; granted: Partial; expiry?: number; }): Promise; denyCounterpartyPermission(requestID: string): Promise; /** * Ensures the originator has protocol usage permission. * If no valid (unexpired) permission token is found, triggers a permission request flow. */ ensureProtocolPermission({ originator, privileged, protocolID, counterparty, reason, seekPermission, usageType }: { originator: string; privileged: boolean; protocolID: WalletProtocol; counterparty: string; reason?: string; seekPermission?: boolean; usageType: 'signing' | 'encrypting' | 'hmac' | 'publicKey' | 'identityKey' | 'linkageRevelation' | 'generic'; }): Promise; /** * Ensures the originator has basket usage permission for the specified basket. * If not, triggers a permission request flow. */ ensureBasketAccess({ originator, basket, reason, seekPermission, usageType }: { originator: string; basket: string; reason?: string; seekPermission?: boolean; usageType: 'insertion' | 'removal' | 'listing'; }): Promise; /** Returns false when the basket usageType does NOT need a permission check (config-gated). */ private isBasketUsageRequired; /** * Ensures the originator has a valid certificate permission. * This is relevant when revealing certificate fields in DCAP contexts. */ ensureCertificateAccess({ originator, privileged, verifier, certType, fields, reason, seekPermission, usageType }: { originator: string; privileged: boolean; verifier: string; certType: string; fields: string[]; reason?: string; seekPermission?: boolean; usageType: 'disclosure'; }): Promise; /** * Ensures the originator has spending authorization (DSAP) for a certain satoshi amount. * If the existing token limit is insufficient, attempts to renew. If no token, attempts to create one. */ ensureSpendingAuthorization({ originator, satoshis, lineItems, reason, seekPermission }: { originator: string; satoshis: number; lineItems?: Array<{ type: LineItemType; description: string; satoshis: number; }>; reason?: string; seekPermission?: boolean; }): Promise; /** * Ensures the originator has label usage permission. * If no valid (unexpired) permission token is found, triggers a permission request flow. */ ensureLabelAccess({ originator, label, reason, seekPermission, usageType }: { originator: string; label: string; reason?: string; seekPermission?: boolean; usageType: 'apply' | 'list'; }): Promise; /** * Returns true when the given usageType is configured to skip permission checks. */ private isProtocolUsageTypeExempted; private isProtocolInCounterpartyPermissions; private validateCounterpartyPermissions; private fetchManifestPermissions; private fetchManifestGroupPermissions; private filterAlreadyGrantedPermissions; private hasAnyPermissionsToRequest; private hasGroupedPermissionRequestedHandlers; private hasCounterpartyPermissionRequestedHandlers; private hasPactEstablished; private markPactEstablished; private maybeRequestPact; private joinOrCreatePactRequest; private maybeRequestPeerGroupedLevel2ProtocolPermissions; private withGroupedPermissionFlowLock; private checkSpecificPermissionAfterGroupFlow; private isRequestIncludedInGroupPermissions; private maybeRequestGroupedPermissions; /** * Joins an existing grouped permission request (piggybacks on the existing promise), or creates * a new one and fires the onGroupedPermissionRequested event. */ private joinOrCreateGroupedRequest; /** * A central method that triggers the permission request flow. * - It checks if there's already an active request for the same key * - If so, we wait on that existing request rather than creating a duplicative one * - Otherwise we create a new request queue, call the relevant "onXXXRequested" event, * and return a promise that resolves once permission is granted or rejects if denied. */ private requestPermissionFlow; /** Returns true when an active-request queue already has pending waiters for this key. */ private isPiggybacking; /** Appends to an existing request queue and waits for resolution. */ private piggybackOnExistingQueue; /** Runs the grouped-permission flow (with or without a lock) and checks post-group satisfaction. */ private resolveGroupedFlow; /** Creates a new active-request queue entry, fires the event, and returns the promise. */ private enqueueAndFireEvent; /** Fires the appropriate onXXXRequested event based on the request type. */ private firePermissionRequestEvent; /** * We will use a administrative "permission token encryption" protocol to store fields * in each permission's PushDrop script. This ensures that only the user's wallet * can decrypt them. In practice, this data is not super sensitive, but we still * follow the principle of least exposure. */ private static readonly PERM_TOKEN_ENCRYPTION_PROTOCOL; /** * Similarly, we will use a "metadata encryption" protocol to preserve the confidentiality * of transaction descriptions and input/output descriptions from lower storage layers. */ private static readonly METADATA_ENCRYPTION_PROTOCOL; /** We always use `keyID="1"` and `counterparty="self"` for these encryption ops. */ private encryptPermissionTokenField; private decryptPermissionTokenField; /** * Encrypts wallet metadata if configured to do so, otherwise returns the original plaintext for storage. * @param plaintext The metadata to encrypt if configured to do so * @returns The encrypted metadata, or the original value if encryption was disabled. */ private maybeEncryptMetadata; /** * Attempts to decrypt metadata. if decryption fails, assumes the value is already plaintext and returns it. * @param ciphertext The metadata to attempt decryption for. * @returns The decrypted metadata. If decryption fails, returns the original value instead. */ private maybeDecryptMetadata; /** Helper to see if a token's expiry is in the past. */ private isTokenExpired; /** Decrypts the standard 6 fields from a protocol (DPACP) PushDrop script. */ private decryptProtocolTokenFields; /** Parses outpoint string "txid.vout" into [txid, outputIndex]. */ private parseOutpoint; /** Normalizes a txid string to lowercase. */ private normalizeTxid; /** Reverses a 32-byte hex txid (for endian normalization). */ private reverseHexTxid; /** * Returns true when an outpoint string (e.g. "txid.vout" or "txid:vout") refers to `token`. */ private tokenMatchesOutpointString; /** * Finds the index of the tx input that spends the given permission token. * Handles multiple potential field names for TXID and vout. */ private findInputIndexForToken; /** Looks for a DPACP permission token matching origin/domain, privileged, protocol, cpty. */ private findProtocolToken; /** Finds ALL DPACP permission tokens matching origin/domain, privileged, protocol, cpty. Never filters by expiry. */ private findAllProtocolTokens; /** Looks for a DBAP token matching (originator, basket). */ private findBasketToken; /** Looks for a DCAP token matching (origin, privileged, verifier, certType, fields subset). */ private findCertificateToken; /** Looks for a DSAP token matching origin, returning the first one found. */ private findSpendingToken; /** * Returns the current month and year in UTC as a string in the format "YYYY-MM". * * @returns {string} The current month and year in UTC. */ private getCurrentMonthYearUTC; /** * Returns spending for an originator in the current calendar month. */ querySpentSince(token: PermissionToken): Promise; /** * Creates a brand-new permission token as a single-output PushDrop script in the relevant admin basket. * * The main difference between each type of token is in the "fields" we store in the PushDrop script. * * @param r The permission request * @param expiry The expiry epoch time * @param amount For DSAP, the authorized spending limit */ private createPermissionOnChain; private mapWithConcurrency; private runBestEffortBatches; private runBestEffortChunk; private buildPermissionOutput; private createPermissionTokensBestEffort; private renewPermissionTokensBestEffort; private coalescePermissionTokens; /** * Renews a permission token by spending the old token as input and creating a new token output. * This invalidates the old token and replaces it with a new one. * * @param oldToken The old token to consume * @param r The permission request being renewed * @param newExpiry The new expiry epoch time * @param newAmount For DSAP, the new authorized amount */ private renewPermissionOnChain; /** * Builds the encrypted array of fields for a PushDrop permission token * (protocol / basket / certificate / spending). */ private buildPushdropFields; /** * Helper to build an array of tags for the new output, matching the user request's * origin, basket, privileged, protocol name, etc. */ private buildTagsForRequest; /** * Lists all protocol permission tokens (DPACP) with optional filters. * @param originator Optional originator domain to filter by * @param privileged Optional boolean to filter by privileged status * @param protocolName Optional protocol name to filter by * @param protocolSecurityLevel Optional protocol security level to filter by * @param counterparty Optional counterparty to filter by * @returns Array of permission tokens that match the filter criteria */ listProtocolPermissions({ originator, privileged, protocolName, protocolSecurityLevel, counterparty }?: { originator?: string; privileged?: boolean; protocolName?: string; protocolSecurityLevel?: number; counterparty?: string; }): Promise; /** Builds the base tag array for protocol permission listing. */ private buildProtocolFilterTags; /** Decodes and appends protocol permission tokens from a listOutputs result. */ private collectProtocolTokens; /** * Returns true if the originator already holds a valid unexpired protocol permission. * This calls `ensureProtocolPermission` with `seekPermission=false`, so it won't prompt. */ hasProtocolPermission(params: { originator: string; privileged: boolean; protocolID: WalletProtocol; counterparty: string; }): Promise; /** * Lists basket permission tokens (DBAP) for a given originator or basket (or for all if not specified). * @param params.originator Optional originator to filter by * @param params.basket Optional basket name to filter by * @returns Array of permission tokens that match the filter criteria */ listBasketAccess(params?: { originator?: string; basket?: string; }): Promise; /** * Returns `true` if the originator already holds a valid unexpired basket permission for `basket`. */ hasBasketAccess(params: { originator: string; basket: string; }): Promise; /** * Lists spending authorization tokens (DSAP) for a given originator (or all). */ listSpendingAuthorizations(params: { originator?: string; }): Promise; /** * Returns `true` if the originator already holds a valid spending authorization token * with enough available monthly spend. We do not prompt (seekPermission=false). */ hasSpendingAuthorization(params: { originator: string; satoshis: number; }): Promise; /** * Lists certificate permission tokens (DCAP) with optional filters. * @param originator Optional originator domain to filter by * @param privileged Optional boolean to filter by privileged status * @param certType Optional certificate type to filter by * @param verifier Optional verifier to filter by * @returns Array of permission tokens that match the filter criteria */ listCertificateAccess(params?: { originator?: string; privileged?: boolean; certType?: Base64String; verifier?: PubKeyHex; }): Promise; /** Decodes and appends certificate permission tokens from a listOutputs result. */ private collectCertificateTokens; /** * Returns `true` if the originator already holds a valid unexpired certificate access * for the given certType/fields. Does not prompt the user. */ hasCertificateAccess(params: { originator: string; privileged: boolean; verifier: string; certType: string; fields: string[]; }): Promise; revokePermissions(oldTokens: PermissionToken[]): Promise; revokeAllForOriginator(originator: string, opts?: { protocol?: boolean; basket?: boolean; certificate?: boolean; spending?: boolean; }): Promise; private revokePermissionTokensBestEffort; private revokePermissionTokensChunk; /** * Revokes a permission token by spending it with no replacement output. * The manager builds a BRC-100 transaction that consumes the token, effectively invalidating it. */ revokePermission(oldToken: PermissionToken): Promise; createAction(args: Parameters[0], originator?: string): ReturnType; /** Scans outputs to split P-scheme baskets from regular baskets; registers P-modules as a side effect. */ private collectNonPBaskets; /** Enforces signAndProcess=false for non-admin originators; throws if admin override is missing. */ private enforceSignAndProcess; /** Encrypts all description/instruction fields in args in-place; returns original (plaintext) copies. */ private encryptActionMetadata; /** Calls underlying createAction, chaining P-module request/response transforms when needed. */ private callCreateActionWithPModules; /** * Computes the net satoshis the originator is spending in a createAction call, * accounting for foreign (originator-provided) inputs and outputs plus the fee. * Also builds the line items list for the spending authorization request. */ private computeNetSpend; signAction(...args: Parameters): ReturnType; abortAction(...args: Parameters): ReturnType; listActions(...args: Parameters): ReturnType; internalizeAction(...args: Parameters): ReturnType; listOutputs(...args: Parameters): ReturnType; relinquishOutput(...args: Parameters): ReturnType; getPublicKey(...args: Parameters): ReturnType; revealCounterpartyKeyLinkage(...args: Parameters): ReturnType; revealSpecificKeyLinkage(...args: Parameters): ReturnType; encrypt(...args: Parameters): ReturnType; decrypt(...args: Parameters): ReturnType; createHmac(...args: Parameters): ReturnType; verifyHmac(...args: Parameters): ReturnType; createSignature(...args: Parameters): ReturnType; verifySignature(...args: Parameters): ReturnType; acquireCertificate(...args: Parameters): ReturnType; listCertificates(...args: Parameters): ReturnType; proveCertificate(...args: Parameters): ReturnType; relinquishCertificate(...args: Parameters): ReturnType; discoverByIdentityKey(...args: Parameters): ReturnType; discoverByAttributes(...args: Parameters): ReturnType; isAuthenticated(...args: Parameters): ReturnType; waitForAuthentication(...args: Parameters): ReturnType; getHeight(...args: Parameters): ReturnType; getHeaderForHeight(...args: Parameters): ReturnType; getNetwork(...args: Parameters): ReturnType; getVersion(...args: Parameters): ReturnType; /** Returns true if the specified origin is the admin originator. */ private isAdminOriginator; /** * Checks if the given protocol is admin-reserved per BRC-100 rules: * * - Must not start with `admin` (admin-reserved) * - Must not start with `p ` (allows for future specially permissioned protocols) * * If it violates these rules and the caller is not admin, we consider it "admin-only." */ private isAdminProtocol; /** * Checks if the given label is admin-reserved per BRC-100 rules: * * - Must not start with `admin` (admin-reserved) * - Must not start with `p ` (permissioned labels requiring a permission module) * * If it violates these rules and the caller is not admin, we consider it "admin-only." */ private isAdminLabel; /** * Checks if the given basket is admin-reserved per BRC-100 rules: * * - Must not start with `admin` * - Must not be `default` (some wallets use this for internal operations) * - Must not start with `p ` (future specially permissioned baskets) */ private isAdminBasket; /** * Returns true if we have a cached record that the permission identified by * `key` is valid and unexpired. */ private isPermissionCached; /** Caches the fact that the permission for `key` is valid until `expiry`. */ private cachePermission; /** Records that a non-spending permission was just granted so we can skip re-prompting briefly. */ private markRecentGrant; /** Returns true if we are inside the short "cover window" immediately after granting permission. */ private isRecentlyGranted; /** Normalizes and canonicalizes originator domains (e.g., lowercase + drop default ports). */ private normalizeOriginator; private isWhitelistedCounterpartyProtocol; /** * Produces a normalized originator value along with the set of legacy * representations that should be considered when searching for existing * permission tokens (for backwards compatibility). */ private prepareOriginator; /** * Builds a unique list of originator variants that should be searched when * looking up on-chain tokens (e.g., legacy raw + normalized forms). */ private buildOriginatorLookupValues; /** * Builds a "map key" string so that identical requests (e.g. "protocol:domain:true:protoName:counterparty") * do not produce multiple user prompts. */ private buildRequestKey; private buildActiveRequestKey; } //# sourceMappingURL=WalletPermissionsManager.d.ts.map