@bwalletx/connect 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,148 @@
1
+ import { WalletInterface, WalletProtocol } from '@bsv/sdk';
2
+
3
+ /** Ids bWalletX announces in BRC-100 wallet discovery. */
4
+ declare const RDNS_EXTENSION = "com.bwalletx.extension";
5
+ declare const RDNS_MOBILE = "space.bwallet.mobile";
6
+ declare const BWALLETX_RDNS: readonly ["com.bwalletx.extension", "space.bwallet.mobile"];
7
+ type FoundBy = 'extension' | 'in-app';
8
+ interface FoundWallet {
9
+ wallet: WalletInterface;
10
+ /** 'extension' for the Chrome extension; 'in-app' inside the bWalletX app's own browser. */
11
+ method: FoundBy;
12
+ rdns: string | null;
13
+ }
14
+ /**
15
+ * Like findBwalletX, but also says which bWalletX answered.
16
+ * Order: a BRC-100 announcement with a bWalletX rdns; then `window.CWI` (set by the in-app
17
+ * browser, and by older builds that do not announce); otherwise null.
18
+ */
19
+ declare function discoverBwalletX(ms?: number): Promise<FoundWallet | null>;
20
+ /**
21
+ * Find bWalletX in this page: the extension on a computer, or the wallet itself when the page is
22
+ * open in bWalletX's in-app browser. Resolves null if nothing answered within `ms`.
23
+ */
24
+ declare function findBwalletX(ms?: number): Promise<WalletInterface | null>;
25
+
26
+ /** localStorage-shaped storage. Methods may be sync or async. */
27
+ interface PairStorage {
28
+ getItem(key: string): string | null | Promise<string | null>;
29
+ setItem(key: string, value: string): void | Promise<void>;
30
+ removeItem(key: string): void | Promise<void>;
31
+ }
32
+ /** The minimum of the browser WebSocket API this package uses (the `ws` package also fits). */
33
+ interface SocketLike {
34
+ readonly readyState: number;
35
+ onopen: ((ev: unknown) => void) | null;
36
+ onmessage: ((ev: {
37
+ data: unknown;
38
+ }) => void) | null;
39
+ onerror: ((ev: unknown) => void) | null;
40
+ onclose: ((ev: unknown) => void) | null;
41
+ send(data: string): void;
42
+ close(): void;
43
+ }
44
+ type SocketFactory = (url: string) => SocketLike;
45
+ interface PairConnectionOptions {
46
+ /** Where the pairing is kept so it survives a reload. Default: localStorage, else memory only. */
47
+ storage?: PairStorage | null;
48
+ /** Storage key. Default 'bwalletx.connect.pairing.v1'. */
49
+ storageKey?: string;
50
+ /** Opens a socket. Default: the global WebSocket. Pass one to run in Node or to test. */
51
+ socket?: SocketFactory;
52
+ /** Per-call timeout in ms. Default 120000. */
53
+ callTimeoutMs?: number;
54
+ }
55
+ interface PairingOptions extends PairConnectionOptions {
56
+ /** Show this link as a QR code, and as text to copy (web.bwalletx.com takes it pasted). */
57
+ onLink: (link: string) => void;
58
+ /** Show this 4-digit code. The wallet shows the same one; the user checks they match. */
59
+ onCode: (code: string) => void;
60
+ signal?: AbortSignal;
61
+ /** Relay host. Default relay.bwallet.space. */
62
+ relay?: string;
63
+ /** This page's origin, as the relay will see it. Default location.origin. */
64
+ origin?: string;
65
+ }
66
+ /** A BRC-100 wallet whose every call goes, end-to-end encrypted, to the paired phone or web wallet. */
67
+ type PairedWallet = WalletInterface & {
68
+ /** Close the relay connection. The pairing stays stored; the next call reconnects. */
69
+ close(): void;
70
+ /** Tell the wallet to unpair, close, and delete the stored pairing. */
71
+ forget(): Promise<void>;
72
+ };
73
+ /**
74
+ * Pair with bWalletX on a phone (scan the QR) or web.bwalletx.com (paste the link).
75
+ * Resolves with a wallet once the user taps Connect. The pairing is stored (see `storage`) so
76
+ * `restorePairing()` can reconnect after a reload without a new QR.
77
+ */
78
+ declare function pairBwalletX(opts: PairingOptions): Promise<PairedWallet>;
79
+ /**
80
+ * The wallet from a pairing stored by an earlier `pairBwalletX`, or null if there is none.
81
+ * It connects on the first call. The wallet must still have this site paired.
82
+ */
83
+ declare function restorePairing(opts?: PairConnectionOptions): Promise<PairedWallet | null>;
84
+ /** Delete the stored pairing without telling the wallet. */
85
+ declare function clearPairing(opts?: Pick<PairConnectionOptions, 'storage' | 'storageKey'>): Promise<void>;
86
+
87
+ /** Security level 2, a protocol name used for nothing else. */
88
+ declare const LOGIN_PROTOCOL: WalletProtocol;
89
+ /** What your server's challenge route returns (createChallenge from '@bwalletx/connect/server'). */
90
+ interface Challenge {
91
+ nonce: string;
92
+ message: string;
93
+ keyID: string;
94
+ protocolID?: WalletProtocol;
95
+ }
96
+ type SignInMethod = 'extension' | 'in-app' | 'pairing' | 'wallet';
97
+ interface SignInOptions {
98
+ /** Ask your server for a challenge for this identity key. */
99
+ challenge: (identityKey: string) => Promise<Challenge>;
100
+ /** Use this wallet instead of looking for one. `method` is then 'wallet'. */
101
+ wallet?: WalletInterface;
102
+ /** How to show the QR and code if pairing is needed. Without it, pairing is not tried. */
103
+ pairing?: PairingOptions;
104
+ /** Reuse a pairing stored by an earlier sign-in before showing a new QR. Default true. */
105
+ reusePairing?: boolean;
106
+ /** How long to wait for the extension or in-app browser to answer, in ms. Default 1200. */
107
+ discoverMs?: number;
108
+ }
109
+ interface SignInResult {
110
+ identityKey: string;
111
+ /** DER signature as number[], ready to post to verifySignIn. */
112
+ signature: number[];
113
+ nonce: string;
114
+ method: SignInMethod;
115
+ /** The wallet that signed. Keep it to make more calls. */
116
+ wallet: WalletInterface;
117
+ }
118
+ /** Find a wallet: extension or in-app browser first, then a stored pairing, then a new pairing. */
119
+ declare function connectBwalletX(opts?: Pick<SignInOptions, 'wallet' | 'pairing' | 'reusePairing' | 'discoverMs'>): Promise<{
120
+ wallet: WalletInterface;
121
+ method: SignInMethod;
122
+ }>;
123
+ /**
124
+ * Sign the server's challenge with the user's bWalletX identity key. Post the result's
125
+ * identityKey, nonce and signature to your verify route.
126
+ */
127
+ declare function signInWithBwalletX(opts: SignInOptions): Promise<SignInResult>;
128
+
129
+ declare const LOGO_URL = "https://bwalletx.com/logo.svg";
130
+ interface ButtonOptions {
131
+ /** Second line under the label. Default "also works with bWallet". false hides it. */
132
+ subtitle?: string | false;
133
+ onClick?: (button: HTMLButtonElement) => void;
134
+ }
135
+ /** Put the gold "Sign in with bWalletX" button into `el` (replacing its contents). */
136
+ declare function renderButton(el: HTMLElement | string, opts?: ButtonOptions): HTMLButtonElement;
137
+
138
+ /**
139
+ * Wrap an async frame handler so frames are handled one at a time, in arrival order.
140
+ *
141
+ * WebSocket `onmessage` does not wait for an async handler. The phone sends its plain `hello`
142
+ * and then, as soon as the user taps Connect, a sealed `ready`. If the handler for `hello` is
143
+ * still deriving the session key when `ready` arrives, a naive handler sees no key yet and drops
144
+ * `ready`, so pairing never finishes. Chaining every frame onto one promise fixes that.
145
+ */
146
+ declare function inOrder<T>(handle: (frame: T) => Promise<void> | void, onError?: (e: unknown) => void): (frame: T) => Promise<void>;
147
+
148
+ export { BWALLETX_RDNS, type ButtonOptions, type Challenge, type FoundBy, type FoundWallet, LOGIN_PROTOCOL, LOGO_URL, type PairConnectionOptions, type PairStorage, type PairedWallet, type PairingOptions, RDNS_EXTENSION, RDNS_MOBILE, type SignInMethod, type SignInOptions, type SignInResult, type SocketFactory, type SocketLike, clearPairing, connectBwalletX, discoverBwalletX, findBwalletX, inOrder, pairBwalletX, renderButton, restorePairing, signInWithBwalletX };
@@ -0,0 +1,148 @@
1
+ import { WalletInterface, WalletProtocol } from '@bsv/sdk';
2
+
3
+ /** Ids bWalletX announces in BRC-100 wallet discovery. */
4
+ declare const RDNS_EXTENSION = "com.bwalletx.extension";
5
+ declare const RDNS_MOBILE = "space.bwallet.mobile";
6
+ declare const BWALLETX_RDNS: readonly ["com.bwalletx.extension", "space.bwallet.mobile"];
7
+ type FoundBy = 'extension' | 'in-app';
8
+ interface FoundWallet {
9
+ wallet: WalletInterface;
10
+ /** 'extension' for the Chrome extension; 'in-app' inside the bWalletX app's own browser. */
11
+ method: FoundBy;
12
+ rdns: string | null;
13
+ }
14
+ /**
15
+ * Like findBwalletX, but also says which bWalletX answered.
16
+ * Order: a BRC-100 announcement with a bWalletX rdns; then `window.CWI` (set by the in-app
17
+ * browser, and by older builds that do not announce); otherwise null.
18
+ */
19
+ declare function discoverBwalletX(ms?: number): Promise<FoundWallet | null>;
20
+ /**
21
+ * Find bWalletX in this page: the extension on a computer, or the wallet itself when the page is
22
+ * open in bWalletX's in-app browser. Resolves null if nothing answered within `ms`.
23
+ */
24
+ declare function findBwalletX(ms?: number): Promise<WalletInterface | null>;
25
+
26
+ /** localStorage-shaped storage. Methods may be sync or async. */
27
+ interface PairStorage {
28
+ getItem(key: string): string | null | Promise<string | null>;
29
+ setItem(key: string, value: string): void | Promise<void>;
30
+ removeItem(key: string): void | Promise<void>;
31
+ }
32
+ /** The minimum of the browser WebSocket API this package uses (the `ws` package also fits). */
33
+ interface SocketLike {
34
+ readonly readyState: number;
35
+ onopen: ((ev: unknown) => void) | null;
36
+ onmessage: ((ev: {
37
+ data: unknown;
38
+ }) => void) | null;
39
+ onerror: ((ev: unknown) => void) | null;
40
+ onclose: ((ev: unknown) => void) | null;
41
+ send(data: string): void;
42
+ close(): void;
43
+ }
44
+ type SocketFactory = (url: string) => SocketLike;
45
+ interface PairConnectionOptions {
46
+ /** Where the pairing is kept so it survives a reload. Default: localStorage, else memory only. */
47
+ storage?: PairStorage | null;
48
+ /** Storage key. Default 'bwalletx.connect.pairing.v1'. */
49
+ storageKey?: string;
50
+ /** Opens a socket. Default: the global WebSocket. Pass one to run in Node or to test. */
51
+ socket?: SocketFactory;
52
+ /** Per-call timeout in ms. Default 120000. */
53
+ callTimeoutMs?: number;
54
+ }
55
+ interface PairingOptions extends PairConnectionOptions {
56
+ /** Show this link as a QR code, and as text to copy (web.bwalletx.com takes it pasted). */
57
+ onLink: (link: string) => void;
58
+ /** Show this 4-digit code. The wallet shows the same one; the user checks they match. */
59
+ onCode: (code: string) => void;
60
+ signal?: AbortSignal;
61
+ /** Relay host. Default relay.bwallet.space. */
62
+ relay?: string;
63
+ /** This page's origin, as the relay will see it. Default location.origin. */
64
+ origin?: string;
65
+ }
66
+ /** A BRC-100 wallet whose every call goes, end-to-end encrypted, to the paired phone or web wallet. */
67
+ type PairedWallet = WalletInterface & {
68
+ /** Close the relay connection. The pairing stays stored; the next call reconnects. */
69
+ close(): void;
70
+ /** Tell the wallet to unpair, close, and delete the stored pairing. */
71
+ forget(): Promise<void>;
72
+ };
73
+ /**
74
+ * Pair with bWalletX on a phone (scan the QR) or web.bwalletx.com (paste the link).
75
+ * Resolves with a wallet once the user taps Connect. The pairing is stored (see `storage`) so
76
+ * `restorePairing()` can reconnect after a reload without a new QR.
77
+ */
78
+ declare function pairBwalletX(opts: PairingOptions): Promise<PairedWallet>;
79
+ /**
80
+ * The wallet from a pairing stored by an earlier `pairBwalletX`, or null if there is none.
81
+ * It connects on the first call. The wallet must still have this site paired.
82
+ */
83
+ declare function restorePairing(opts?: PairConnectionOptions): Promise<PairedWallet | null>;
84
+ /** Delete the stored pairing without telling the wallet. */
85
+ declare function clearPairing(opts?: Pick<PairConnectionOptions, 'storage' | 'storageKey'>): Promise<void>;
86
+
87
+ /** Security level 2, a protocol name used for nothing else. */
88
+ declare const LOGIN_PROTOCOL: WalletProtocol;
89
+ /** What your server's challenge route returns (createChallenge from '@bwalletx/connect/server'). */
90
+ interface Challenge {
91
+ nonce: string;
92
+ message: string;
93
+ keyID: string;
94
+ protocolID?: WalletProtocol;
95
+ }
96
+ type SignInMethod = 'extension' | 'in-app' | 'pairing' | 'wallet';
97
+ interface SignInOptions {
98
+ /** Ask your server for a challenge for this identity key. */
99
+ challenge: (identityKey: string) => Promise<Challenge>;
100
+ /** Use this wallet instead of looking for one. `method` is then 'wallet'. */
101
+ wallet?: WalletInterface;
102
+ /** How to show the QR and code if pairing is needed. Without it, pairing is not tried. */
103
+ pairing?: PairingOptions;
104
+ /** Reuse a pairing stored by an earlier sign-in before showing a new QR. Default true. */
105
+ reusePairing?: boolean;
106
+ /** How long to wait for the extension or in-app browser to answer, in ms. Default 1200. */
107
+ discoverMs?: number;
108
+ }
109
+ interface SignInResult {
110
+ identityKey: string;
111
+ /** DER signature as number[], ready to post to verifySignIn. */
112
+ signature: number[];
113
+ nonce: string;
114
+ method: SignInMethod;
115
+ /** The wallet that signed. Keep it to make more calls. */
116
+ wallet: WalletInterface;
117
+ }
118
+ /** Find a wallet: extension or in-app browser first, then a stored pairing, then a new pairing. */
119
+ declare function connectBwalletX(opts?: Pick<SignInOptions, 'wallet' | 'pairing' | 'reusePairing' | 'discoverMs'>): Promise<{
120
+ wallet: WalletInterface;
121
+ method: SignInMethod;
122
+ }>;
123
+ /**
124
+ * Sign the server's challenge with the user's bWalletX identity key. Post the result's
125
+ * identityKey, nonce and signature to your verify route.
126
+ */
127
+ declare function signInWithBwalletX(opts: SignInOptions): Promise<SignInResult>;
128
+
129
+ declare const LOGO_URL = "https://bwalletx.com/logo.svg";
130
+ interface ButtonOptions {
131
+ /** Second line under the label. Default "also works with bWallet". false hides it. */
132
+ subtitle?: string | false;
133
+ onClick?: (button: HTMLButtonElement) => void;
134
+ }
135
+ /** Put the gold "Sign in with bWalletX" button into `el` (replacing its contents). */
136
+ declare function renderButton(el: HTMLElement | string, opts?: ButtonOptions): HTMLButtonElement;
137
+
138
+ /**
139
+ * Wrap an async frame handler so frames are handled one at a time, in arrival order.
140
+ *
141
+ * WebSocket `onmessage` does not wait for an async handler. The phone sends its plain `hello`
142
+ * and then, as soon as the user taps Connect, a sealed `ready`. If the handler for `hello` is
143
+ * still deriving the session key when `ready` arrives, a naive handler sees no key yet and drops
144
+ * `ready`, so pairing never finishes. Chaining every frame onto one promise fixes that.
145
+ */
146
+ declare function inOrder<T>(handle: (frame: T) => Promise<void> | void, onError?: (e: unknown) => void): (frame: T) => Promise<void>;
147
+
148
+ export { BWALLETX_RDNS, type ButtonOptions, type Challenge, type FoundBy, type FoundWallet, LOGIN_PROTOCOL, LOGO_URL, type PairConnectionOptions, type PairStorage, type PairedWallet, type PairingOptions, RDNS_EXTENSION, RDNS_MOBILE, type SignInMethod, type SignInOptions, type SignInResult, type SocketFactory, type SocketLike, clearPairing, connectBwalletX, discoverBwalletX, findBwalletX, inOrder, pairBwalletX, renderButton, restorePairing, signInWithBwalletX };