@bsv/wallet-toolbox-client
Version:
Client only Wallet Storage
668 lines • 31 kB
TypeScript
import { WalletInterface, WalletProtocol, Base64String, PubKeyHex } from '@bsv/sdk';
/**
* 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<void>;
/**
* 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;
privileged?: boolean;
protocolID?: WalletProtocol;
counterparty?: string;
basket?: string;
certificate?: {
verifier: string;
certType: string;
fields: string[];
};
spending?: {
satoshis: number;
lineItems?: Array<{
type: 'input' | 'output' | 'fee';
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<void>;
/**
* 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 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?: 0 | 1 | 2;
/** 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[];
}
/**
* 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 {
/**
* 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;
}
/**
* @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 underlying;
/** The "admin" domain or FQDN that is implicitly allowed to do everything. */
private 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 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 activeRequests;
/** Cache recently confirmed permissions to avoid repeated lookups. */
private permissionCache;
/** How long a cached permission remains valid (5 minutes). */
private static readonly CACHE_TTL_MS;
/**
* Configuration that determines whether to skip or apply various checks and encryption.
*/
private 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);
/**
* 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): 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<void>;
/**
* 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<void>;
/**
* 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<GroupedPermissions>;
expiry?: number;
}): Promise<void>;
/**
* Denies a previously requested grouped permission.
* @param requestID The ID of the request being denied.
*/
denyGroupedPermission(requestID: string): Promise<void>;
/**
* 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<boolean>;
/**
* 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<boolean>;
/**
* 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<boolean>;
/**
* 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: 'input' | 'output' | 'fee';
description: string;
satoshis: number;
}>;
reason?: string;
seekPermission?: boolean;
}): Promise<boolean>;
/**
* 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<boolean>;
/**
* 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;
/**
* 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;
/** Looks for a DPACP permission token matching origin/domain, privileged, protocol, cpty. */
private findProtocolToken;
/** 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<number>;
/**
* 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;
/**
* 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<PermissionToken[]>;
/**
* 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<boolean>;
/**
* 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<PermissionToken[]>;
/**
* Returns `true` if the originator already holds a valid unexpired basket permission for `basket`.
*/
hasBasketAccess(params: {
originator: string;
basket: string;
}): Promise<boolean>;
/**
* Lists spending authorization tokens (DSAP) for a given originator (or all).
*/
listSpendingAuthorizations(params: {
originator?: string;
}): Promise<PermissionToken[]>;
/**
* 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<boolean>;
/**
* 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<PermissionToken[]>;
/**
* 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<boolean>;
/**
* 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<void>;
createAction(args: Parameters<WalletInterface['createAction']>[0], originator?: string): ReturnType<WalletInterface['createAction']>;
signAction(...args: Parameters<WalletInterface['signAction']>): ReturnType<WalletInterface['signAction']>;
abortAction(...args: Parameters<WalletInterface['abortAction']>): ReturnType<WalletInterface['abortAction']>;
listActions(...args: Parameters<WalletInterface['listActions']>): ReturnType<WalletInterface['listActions']>;
internalizeAction(...args: Parameters<WalletInterface['internalizeAction']>): ReturnType<WalletInterface['internalizeAction']>;
listOutputs(...args: Parameters<WalletInterface['listOutputs']>): ReturnType<WalletInterface['listOutputs']>;
relinquishOutput(...args: Parameters<WalletInterface['relinquishOutput']>): ReturnType<WalletInterface['relinquishOutput']>;
getPublicKey(...args: Parameters<WalletInterface['getPublicKey']>): ReturnType<WalletInterface['getPublicKey']>;
revealCounterpartyKeyLinkage(...args: Parameters<WalletInterface['revealCounterpartyKeyLinkage']>): ReturnType<WalletInterface['revealCounterpartyKeyLinkage']>;
revealSpecificKeyLinkage(...args: Parameters<WalletInterface['revealSpecificKeyLinkage']>): ReturnType<WalletInterface['revealSpecificKeyLinkage']>;
encrypt(...args: Parameters<WalletInterface['encrypt']>): ReturnType<WalletInterface['encrypt']>;
decrypt(...args: Parameters<WalletInterface['decrypt']>): ReturnType<WalletInterface['decrypt']>;
createHmac(...args: Parameters<WalletInterface['createHmac']>): ReturnType<WalletInterface['createHmac']>;
verifyHmac(...args: Parameters<WalletInterface['verifyHmac']>): ReturnType<WalletInterface['verifyHmac']>;
createSignature(...args: Parameters<WalletInterface['createSignature']>): ReturnType<WalletInterface['createSignature']>;
verifySignature(...args: Parameters<WalletInterface['verifySignature']>): ReturnType<WalletInterface['verifySignature']>;
acquireCertificate(...args: Parameters<WalletInterface['acquireCertificate']>): ReturnType<WalletInterface['acquireCertificate']>;
listCertificates(...args: Parameters<WalletInterface['listCertificates']>): ReturnType<WalletInterface['listCertificates']>;
proveCertificate(...args: Parameters<WalletInterface['proveCertificate']>): ReturnType<WalletInterface['proveCertificate']>;
relinquishCertificate(...args: Parameters<WalletInterface['relinquishCertificate']>): ReturnType<WalletInterface['relinquishCertificate']>;
discoverByIdentityKey(...args: Parameters<WalletInterface['discoverByIdentityKey']>): ReturnType<WalletInterface['discoverByIdentityKey']>;
discoverByAttributes(...args: Parameters<WalletInterface['discoverByAttributes']>): ReturnType<WalletInterface['discoverByAttributes']>;
isAuthenticated(...args: Parameters<WalletInterface['isAuthenticated']>): ReturnType<WalletInterface['isAuthenticated']>;
waitForAuthentication(...args: Parameters<WalletInterface['waitForAuthentication']>): ReturnType<WalletInterface['waitForAuthentication']>;
getHeight(...args: Parameters<WalletInterface['getHeight']>): ReturnType<WalletInterface['getHeight']>;
getHeaderForHeight(...args: Parameters<WalletInterface['getHeaderForHeight']>): ReturnType<WalletInterface['getHeaderForHeight']>;
getNetwork(...args: Parameters<WalletInterface['getNetwork']>): ReturnType<WalletInterface['getNetwork']>;
getVersion(...args: Parameters<WalletInterface['getVersion']>): ReturnType<WalletInterface['getVersion']>;
/** 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)
*
* 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;
/**
* Builds a "map key" string so that identical requests (e.g. "protocol:domain:true:protoName:counterparty")
* do not produce multiple user prompts.
*/
private buildRequestKey;
}
//# sourceMappingURL=WalletPermissionsManager.d.ts.map