Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions src/features/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ export const BitcoinConnect = 'bitcoin:connect';
* @group Connect
*/
export type BitcoinConnectFeature = {
/** Name of the feature. */
readonly [BitcoinConnect]: {
/** Version of the feature implemented by the Wallet. */
readonly version: BitcoinConnectVersion;
/** Method to call to use the feature. */
readonly connect: BitcoinConnectMethod;
};
/** Name of the feature. */
readonly [BitcoinConnect]: {
/** Version of the feature implemented by the Wallet. */
readonly version: BitcoinConnectVersion;
/** Method to call to use the feature. */
readonly connect: BitcoinConnectMethod;
};
};

/**
Expand All @@ -40,8 +40,8 @@ export type BitcoinConnectMethod = (input: BitcoinConnectInput) => Promise<Bitco
* @group Connect
*/
export interface BitcoinConnectInput {
/** Type of addresses the app wants to obtain authorization to use. */
readonly purposes: BitcoinAddressPurpose[];
/** Type of addresses the app wants to obtain authorization to use. */
readonly purposes: BitcoinAddressPurpose[];
}

/** Purpose that determines the type of address of the account returned by the wallet. */
Expand All @@ -53,11 +53,11 @@ export type BitcoinAddressPurpose = 'ordinals' | 'payment';
* @group Connect
*/
export interface BitcoinConnectOutput {
/**
* List of accounts in the {@link "@wallet-standard/base".Wallet} that the app has been authorized to use.
*
* The accounts will have addresses that correspond with the `purposes` in the {@link BitcoinConnectInput}, and will
* be returned in the same order.
*/
readonly accounts: readonly WalletAccount[];
/**
* List of accounts in the {@link "@wallet-standard/base".Wallet} that the app has been authorized to use.
*
* The accounts will have addresses that correspond with the `purposes` in the {@link BitcoinConnectInput}, and will
* be returned in the same order.
*/
readonly accounts: readonly WalletAccount[];
}
36 changes: 36 additions & 0 deletions src/features/disconnect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/** Name of the feature. */
export const BitcoinDisconnect = 'bitcoin:disconnect';

/**
* `standard:disconnect` is a {@link "@wallet-standard/base".Wallet.features | feature} that may be implemented by a
* {@link "@wallet-standard/base".Wallet} to allow the app to perform any cleanup work.
*
* This feature may or may not be used by the app and the Wallet should not depend on it being used.
* If this feature is used by the app, the Wallet should perform any cleanup work, but should not revoke authorization
* to use accounts previously granted through the {@link ConnectFeature}.
*
* @group Disconnect
*/
export type BitcoinDisconnectFeature = {
/** Name of the feature. */
readonly [BitcoinDisconnect]: {
/** Version of the feature implemented by the Wallet. */
readonly version: BitcoinDisconnectVersion;
/** Method to call to use the feature. */
readonly disconnect: BitcoinDisconnectMethod;
};
};

/**
* Version of the {@link StandardDisconnectFeature} implemented by a Wallet.
*
* @group Disconnect
*/
export type BitcoinDisconnectVersion = '1.0.0';

/**
* Method to call to use the {@link StandardDisconnectFeature}.
*
* @group Disconnect
*/
export type BitcoinDisconnectMethod = () => Promise<void>;
5 changes: 4 additions & 1 deletion src/features/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import type { WalletWithFeatures } from '@wallet-standard/base';

import type { BitcoinConnectFeature } from './connect';
import type { BitcoinDisconnectFeature } from './disconnect';
import type { BitcoinSatsConnectFeature } from './satsConnect';
import type { BitcoinSignAndSendTransactionFeature } from './signAndSendTransaction';
import type { BitcoinSignMessageFeature } from './signMessage';
import type { BitcoinSignTransactionFeature } from './signTransaction';
import { BitcoinSatsConnectFeature } from './satsConnect';

/** Type alias for some or all Bitcoin features. */
export type BitcoinStandardFeatures = BitcoinConnectFeature &
BitcoinDisconnectFeature &
BitcoinSignTransactionFeature &
BitcoinSignAndSendTransactionFeature &
BitcoinSignMessageFeature;
Expand All @@ -19,6 +21,7 @@ export type WalletWithBitcoinStandardFeatures = WalletWithFeatures<BitcoinStanda
export type WalletWithBitcoinSatsConnectFeature = WalletWithFeatures<BitcoinSatsConnectFeature>;

export * from './connect';
export * from './disconnect';
export * from './signTransaction';
export * from './signAndSendTransaction';
export * from './signMessage';
Expand Down
26 changes: 13 additions & 13 deletions src/features/signAndSendTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ export const BitcoinSignAndSendTransaction = 'bitcoin:signAndSendTransaction';
* @group SignAndSendTransaction
*/
export type BitcoinSignAndSendTransactionFeature = {
/** Name of the feature. */
readonly [BitcoinSignAndSendTransaction]: {
/** Version of the feature implemented by the Wallet. */
readonly version: BitcoinSignAndSendTransactionVersion;

/** Method to call to use the feature. */
readonly signAndSendTransaction: BitcoinSignAndSendTransactionMethod;
};
/** Name of the feature. */
readonly [BitcoinSignAndSendTransaction]: {
/** Version of the feature implemented by the Wallet. */
readonly version: BitcoinSignAndSendTransactionVersion;

/** Method to call to use the feature. */
readonly signAndSendTransaction: BitcoinSignAndSendTransactionMethod;
};
};

/**
Expand All @@ -37,7 +37,7 @@ export type BitcoinSignAndSendTransactionVersion = '1.0.0';
* @group SignAndSendTransaction
*/
export type BitcoinSignAndSendTransactionMethod = (
...inputs: readonly BitcoinSignAndSendTransactionInput[]
...inputs: readonly BitcoinSignAndSendTransactionInput[]
) => Promise<readonly BitcoinSignAndSendTransactionOutput[]>;

/**
Expand All @@ -46,8 +46,8 @@ export type BitcoinSignAndSendTransactionMethod = (
* @group SignAndSendTransaction
*/
export interface BitcoinSignAndSendTransactionInput extends BitcoinSignTransactionInput {
/** Chain to use. */
readonly chain: IdentifierString;
/** Chain to use. */
readonly chain: IdentifierString;
}

/**
Expand All @@ -56,6 +56,6 @@ export interface BitcoinSignAndSendTransactionInput extends BitcoinSignTransacti
* @group SignAndSendTransaction
*/
export interface BitcoinSignAndSendTransactionOutput {
/** Transaction ID (transaction hash). */
readonly txId: string;
/** Transaction ID (transaction hash). */
readonly txId: string;
}
38 changes: 19 additions & 19 deletions src/features/signMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ export const BitcoinSignMessage = 'bitcoin:signMessage';
* @group SignMessage
*/
export type BitcoinSignMessageFeature = {
/** Name of the feature. */
readonly [BitcoinSignMessage]: {
/** Version of the feature implemented by the Wallet. */
readonly version: BitcoinSignMessageVersion;
/** Name of the feature. */
readonly [BitcoinSignMessage]: {
/** Version of the feature implemented by the Wallet. */
readonly version: BitcoinSignMessageVersion;

/** Method to call to use the feature. */
readonly signMessage: BitcoinSignMessageMethod;
};
/** Method to call to use the feature. */
readonly signMessage: BitcoinSignMessageMethod;
};
};

/**
Expand All @@ -38,7 +38,7 @@ export type BitcoinSignMessageVersion = '1.0.0';
* @group SignMessage
*/
export type BitcoinSignMessageMethod = (
...inputs: readonly BitcoinSignMessageInput[]
...inputs: readonly BitcoinSignMessageInput[]
) => Promise<readonly BitcoinSignMessageOutput[]>;

/**
Expand All @@ -47,11 +47,11 @@ export type BitcoinSignMessageMethod = (
* @group SignMessage
*/
export interface BitcoinSignMessageInput {
/** Account to use. */
readonly account: WalletAccount;
/** Account to use. */
readonly account: WalletAccount;

/** Message to sign, as raw bytes. */
readonly message: Uint8Array;
/** Message to sign, as raw bytes. */
readonly message: Uint8Array;
}

/**
Expand All @@ -60,12 +60,12 @@ export interface BitcoinSignMessageInput {
* @group SignMessage
*/
export interface BitcoinSignMessageOutput {
/**
* Message bytes that were signed.
* The wallet may prefix or otherwise modify the message before signing it.
*/
readonly signedMessage: Uint8Array;
/**
* Message bytes that were signed.
* The wallet may prefix or otherwise modify the message before signing it.
*/
readonly signedMessage: Uint8Array;

/** Message signature produced. */
readonly signature: Uint8Array;
/** Message signature produced. */
readonly signature: Uint8Array;
}
56 changes: 28 additions & 28 deletions src/features/signTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ export const BitcoinSignTransaction = 'bitcoin:signTransaction';
* @group SignTransaction
*/
export type BitcoinSignTransactionFeature = {
/** Name of the feature. */
readonly [BitcoinSignTransaction]: {
/** Version of the feature implemented by the Wallet. */
readonly version: BitcoinSignTransactionVersion;
/** Name of the feature. */
readonly [BitcoinSignTransaction]: {
/** Version of the feature implemented by the Wallet. */
readonly version: BitcoinSignTransactionVersion;

/** Method to call to use the feature. */
readonly signTransaction: BitcoinSignTransactionMethod;
};
/** Method to call to use the feature. */
readonly signTransaction: BitcoinSignTransactionMethod;
};
};

/**
Expand All @@ -34,7 +34,7 @@ export type BitcoinSignTransactionVersion = '1.0.0';
* @group SignTransaction
*/
export type BitcoinSignTransactionMethod = (
...inputs: readonly BitcoinSignTransactionInput[]
...inputs: readonly BitcoinSignTransactionInput[]
) => Promise<readonly BitcoinSignTransactionOutput[]>;

/**
Expand All @@ -43,14 +43,14 @@ export type BitcoinSignTransactionMethod = (
* @group SignTransaction
*/
export interface BitcoinSignTransactionInput {
/** Partially Signed Bitcoin Transaction (PSBT), as raw bytes. */
readonly psbt: Uint8Array;
/** Partially Signed Bitcoin Transaction (PSBT), as raw bytes. */
readonly psbt: Uint8Array;

/** Transaction inputs to sign. */
readonly inputsToSign: InputToSign[];
/** Transaction inputs to sign. */
readonly inputsToSign: InputToSign[];

/** Chain to use. */
readonly chain?: IdentifierString;
/** Chain to use. */
readonly chain?: IdentifierString;
}

/**
Expand All @@ -59,14 +59,14 @@ export interface BitcoinSignTransactionInput {
* @group SignTransaction
* */
export interface InputToSign {
/** Account to use. */
readonly account: WalletAccount;
/** Account to use. */
readonly account: WalletAccount;

/** List of input indexes that should be signed by the account. */
readonly signingIndexes: number[];
/** List of input indexes that should be signed by the account. */
readonly signingIndexes: number[];

/** A SIGHASH flag. */
readonly sigHash?: BitcoinSigHashFlag;
/** A SIGHASH flag. */
readonly sigHash?: BitcoinSigHashFlag;
}

/**
Expand All @@ -75,15 +75,15 @@ export interface InputToSign {
* @group SignTransaction
*/
export interface BitcoinSignTransactionOutput {
/** Signed Partially Signed Bitcoin Transaction (PSBT), as raw bytes. */
readonly signedPsbt: Uint8Array;
/** Signed Partially Signed Bitcoin Transaction (PSBT), as raw bytes. */
readonly signedPsbt: Uint8Array;
}

/** SIGHASH flag. */
export type BitcoinSigHashFlag =
| 'ALL'
| 'NONE'
| 'SINGLE'
| 'ALL|ANYONECANPAY'
| 'NONE|ANYONECANPAY'
| 'SINGLE|ANYONECANPAY';
| 'ALL'
| 'NONE'
| 'SINGLE'
| 'ALL|ANYONECANPAY'
| 'NONE|ANYONECANPAY'
| 'SINGLE|ANYONECANPAY';
20 changes: 20 additions & 0 deletions src/satsConnectWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { StandardConnectOutput, StandardEventsListeners, StandardEventsName
import { ReadonlyWalletAccount } from '@wallet-standard/wallet';
import { decodeToken } from 'jsontokens';
import {
BitcoinDisconnect,
BitcoinSignAndSendTransaction,
type BitcoinSignAndSendTransactionInput,
type BitcoinSignAndSendTransactionOutput,
Expand Down Expand Up @@ -93,6 +94,10 @@ export class BitcoinWallet implements Wallet {
version: this.version,
connect: this.#connect,
},
[BitcoinDisconnect]: {
version: this.version,
disconnect: this.#disconnect,
},
[SatsConnectFeatureName]: {
provider: this.#getSatsConnectProvider(),
},
Expand Down Expand Up @@ -296,6 +301,21 @@ export class BitcoinWallet implements Wallet {
};
}

#disconnect = async (): Promise<void> => {
const selectedAccount = this.#account;

if (!selectedAccount) {
throw new Error('No connected account');
}

await this.client.revokeSession({ scopes: [this.scope ?? CaipScope.MAINNET] });

this.#account = undefined;
this.scope = undefined;
this.#removeAccountsChangedListener?.();
this.#removeAccountsChangedListener = undefined;
};

#tryRestoringSession = async (): Promise<void> => {
try {
const existingSession = await this.client.getSession();
Expand Down
Loading