@enbox/browser 0.3.70 → 0.3.72
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.
- package/README.md +30 -7
- package/dist/browser.mjs +14 -14
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/blob-url-pool.js +36 -0
- package/dist/esm/blob-url-pool.js.map +1 -0
- package/dist/esm/browser-connect-handler.js +3 -1
- package/dist/esm/browser-connect-handler.js.map +1 -1
- package/dist/esm/file-envelope-url-store.js +203 -0
- package/dist/esm/file-envelope-url-store.js.map +1 -0
- package/dist/esm/index.js +12 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/object-url-reference.js +68 -0
- package/dist/esm/object-url-reference.js.map +1 -0
- package/dist/esm/relay-connect-runner.js +9 -1
- package/dist/esm/relay-connect-runner.js.map +1 -1
- package/dist/esm/ui/connect-modal.js +134 -16
- package/dist/esm/ui/connect-modal.js.map +1 -1
- package/dist/types/blob-url-pool.d.ts +16 -0
- package/dist/types/blob-url-pool.d.ts.map +1 -0
- package/dist/types/browser-connect-handler.d.ts +8 -2
- package/dist/types/browser-connect-handler.d.ts.map +1 -1
- package/dist/types/file-envelope-url-store.d.ts +30 -0
- package/dist/types/file-envelope-url-store.d.ts.map +1 -0
- package/dist/types/index.d.ts +16 -14
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/object-url-reference.d.ts +20 -0
- package/dist/types/object-url-reference.d.ts.map +1 -0
- package/dist/types/relay-connect-runner.d.ts +4 -0
- package/dist/types/relay-connect-runner.d.ts.map +1 -1
- package/dist/types/ui/connect-modal.d.ts +24 -11
- package/dist/types/ui/connect-modal.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/blob-url-pool.ts +55 -0
- package/src/browser-connect-handler.ts +13 -2
- package/src/file-envelope-url-store.ts +260 -0
- package/src/index.ts +23 -159
- package/src/object-url-reference.ts +82 -0
- package/src/relay-connect-runner.ts +17 -2
- package/src/ui/connect-modal.ts +187 -28
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH,cAAc,YAAY,CAAC;AAM3B,cAAc,qBAAqB,CAAC;AAOpC,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMtE,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACtF,YAAY,EAAE,4BAA4B,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACzG,YAAY,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACjG,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,YAAY,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EACL,6BAA6B,EAC7B,gCAAgC,EAChC,iBAAiB,EACjB,iCAAiC,EACjC,kCAAkC,GACnC,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,qBAAqB,EACrB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAC/G,YAAY,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,8BAA8B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxF,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1I,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC1G,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,8BAA8B,CAAC;AActC,OAAO,EAAE,mBAAmB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AACrF,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAK5C,YAAY,EACV,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAItB,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type ObjectUrlLease = Readonly<{
|
|
2
|
+
url: string;
|
|
3
|
+
/** Release immediately, cancelling any deferred release. Idempotent. */
|
|
4
|
+
release(): void;
|
|
5
|
+
/** Release after a grace period. The first deferred release wins. */
|
|
6
|
+
releaseAfter(delayMs: number): void;
|
|
7
|
+
}>;
|
|
8
|
+
/** Private reference-counted ownership for one object URL. */
|
|
9
|
+
export declare class ObjectUrlReference {
|
|
10
|
+
private readonly _onEmpty;
|
|
11
|
+
readonly url: string;
|
|
12
|
+
private _isRevoked;
|
|
13
|
+
private _references;
|
|
14
|
+
private readonly _releaseTimers;
|
|
15
|
+
constructor(blob: Blob, _onEmpty: (reference: ObjectUrlReference) => void);
|
|
16
|
+
get references(): number;
|
|
17
|
+
acquire(): ObjectUrlLease;
|
|
18
|
+
revoke(): void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=object-url-reference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-url-reference.d.ts","sourceRoot":"","sources":["../../src/object-url-reference.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,OAAO,IAAI,IAAI,CAAC;IAChB,qEAAqE;IACrE,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC,CAAC;AAUH,8DAA8D;AAC9D,qBAAa,kBAAkB;IAME,OAAO,CAAC,QAAQ,CAAC,QAAQ;IALxD,SAAgB,GAAG,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4C;gBAExD,IAAI,EAAE,IAAI,EAAmB,QAAQ,EAAE,CAAC,SAAS,EAAE,kBAAkB,KAAK,IAAI;IAIjG,IAAW,UAAU,IAAI,MAAM,CAE9B;IAEM,OAAO,IAAI,cAAc;IAuCzB,MAAM,IAAI,IAAI;CAWtB"}
|
|
@@ -37,6 +37,8 @@ export interface RelayConnectOptions {
|
|
|
37
37
|
appName: string;
|
|
38
38
|
/** Optional icon URL for the app, shown in the wallet consent UI. */
|
|
39
39
|
appIcon?: string;
|
|
40
|
+
/** Stable application identifier hint available to the wallet during approval. */
|
|
41
|
+
applicationId?: string;
|
|
40
42
|
/** Optional client/environment metadata for wallet session display. */
|
|
41
43
|
clientMetadata?: ConnectClientMetadata;
|
|
42
44
|
/** DWN protocols and permission scopes being requested. */
|
|
@@ -45,6 +47,8 @@ export interface RelayConnectOptions {
|
|
|
45
47
|
delegatePortableDid?: PortableDid;
|
|
46
48
|
/** User-facing request purpose. Absent means a normal connect. */
|
|
47
49
|
requestType?: ConnectRequestType;
|
|
50
|
+
/** Wallet profile DID that a refresh must renew. */
|
|
51
|
+
expectedProviderDid?: string;
|
|
48
52
|
/** Total milliseconds to poll the relay for a wallet response. */
|
|
49
53
|
timeoutMs?: number;
|
|
50
54
|
/** Milliseconds between relay polling attempts. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-connect-runner.d.ts","sourceRoot":"","sources":["../../src/relay-connect-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EAExB,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAIL,oBAAoB,EAGrB,MAAM,gBAAgB,CAAC;AAExB,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,uEAAuE;AACvE,qBAAa,0BAA2B,SAAQ,KAAK;;CAKpD;AAED,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,wDAAwD;IACxD,gBAAgB,EAAE,MAAM,CAAC;IAEzB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAElB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAEhB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,uEAAuE;IACvE,cAAc,CAAC,EAAE,qBAAqB,CAAC;IAEvC,2DAA2D;IAC3D,kBAAkB,EAAE,wBAAwB,EAAE,CAAC;IAE/C,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,WAAW,CAAC;IAElC,kEAAkE;IAClE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAEjC,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,gBAAgB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAEtD;;;;OAIG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAExE;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAEvB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE;QAC1B,gBAAgB,EAAE,MAAM,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;QACvB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,KAAK,IAAI,CAAC,oBAAoB,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,eAAe,GAAG,aAAa,CAAC,GACnG,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,CAAC,CAAC;CAC5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB9D;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"relay-connect-runner.d.ts","sourceRoot":"","sources":["../../src/relay-connect-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EAExB,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAIL,oBAAoB,EAGrB,MAAM,gBAAgB,CAAC;AAExB,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,uEAAuE;AACvE,qBAAa,0BAA2B,SAAQ,KAAK;;CAKpD;AAED,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,wDAAwD;IACxD,gBAAgB,EAAE,MAAM,CAAC;IAEzB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAElB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAEhB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,kFAAkF;IAClF,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,uEAAuE;IACvE,cAAc,CAAC,EAAE,qBAAqB,CAAC;IAEvC,2DAA2D;IAC3D,kBAAkB,EAAE,wBAAwB,EAAE,CAAC;IAE/C,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,WAAW,CAAC;IAElC,kEAAkE;IAClE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAEjC,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,gBAAgB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAEtD;;;;OAIG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAExE;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAEvB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE;QAC1B,gBAAgB,EAAE,MAAM,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;QACvB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,KAAK,IAAI,CAAC,oBAAoB,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,eAAe,GAAG,aAAa,CAAC,GACnG,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,CAAC,CAAC;CAC5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB9D;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAoGtG"}
|
|
@@ -96,8 +96,9 @@ export interface ConnectModalOptions {
|
|
|
96
96
|
/** Preferred method on open; overrides the remembered choice. */
|
|
97
97
|
preferredMethod?: ConnectMethod;
|
|
98
98
|
/**
|
|
99
|
-
* Remember the successful method + wallet in localStorage
|
|
100
|
-
* the
|
|
99
|
+
* Remember the successful method + wallet in localStorage. Refreshes reuse
|
|
100
|
+
* the route saved for their delegate DID; new connections use the latest
|
|
101
|
+
* successful route as a convenience.
|
|
101
102
|
* @default true
|
|
102
103
|
*/
|
|
103
104
|
rememberChoice?: boolean;
|
|
@@ -105,6 +106,13 @@ export interface ConnectModalOptions {
|
|
|
105
106
|
appName?: string;
|
|
106
107
|
/** Icon URL of the requesting application. */
|
|
107
108
|
appIcon?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Stable application identifier hint available to the wallet during approval.
|
|
111
|
+
* Defaults to the browser's canonical origin.
|
|
112
|
+
*/
|
|
113
|
+
applicationId?: string;
|
|
114
|
+
/** Wallet profile DID that a refresh must renew. */
|
|
115
|
+
expectedProviderDid?: string;
|
|
108
116
|
/**
|
|
109
117
|
* Relay base URL override for the phone path. When omitted, each wallet's
|
|
110
118
|
* `connectServerUrl` is discovered from its `/.well-known/enbox-connect`
|
|
@@ -134,15 +142,7 @@ export interface ConnectModalDeps {
|
|
|
134
142
|
/** Runs one relay handshake (phone path). */
|
|
135
143
|
runRelay: typeof runRelayConnect;
|
|
136
144
|
/** Runs one popup handshake (browser path); must open the popup synchronously. */
|
|
137
|
-
runPopup:
|
|
138
|
-
walletUrl: string;
|
|
139
|
-
permissionRequests: ConnectPermissionRequest[];
|
|
140
|
-
appName: string;
|
|
141
|
-
appIcon?: string;
|
|
142
|
-
timeoutMs?: number;
|
|
143
|
-
delegatePortableDid?: PortableDid;
|
|
144
|
-
requestType?: ConnectRequestType;
|
|
145
|
-
}) => Promise<ConnectResult | undefined>;
|
|
145
|
+
runPopup: typeof runPopupConnect;
|
|
146
146
|
/** Resolves a wallet origin to its relay `connectServerUrl` (or undefined). */
|
|
147
147
|
discoverConnectServerUrl: (walletOrigin: string) => Promise<string | undefined>;
|
|
148
148
|
/** Validates a pasted custom wallet URL. */
|
|
@@ -158,6 +158,18 @@ export interface ConnectModalDeps {
|
|
|
158
158
|
* same machinery the wallet selector uses for custom-URL validation).
|
|
159
159
|
*/
|
|
160
160
|
export declare function discoverWalletConnectServerUrl(walletOrigin: string): Promise<string | undefined>;
|
|
161
|
+
/** Runs one popup handshake without collapsing early-close into a denial. */
|
|
162
|
+
declare function runPopupConnect(options: {
|
|
163
|
+
walletUrl: string;
|
|
164
|
+
permissionRequests: ConnectPermissionRequest[];
|
|
165
|
+
appName: string;
|
|
166
|
+
appIcon?: string;
|
|
167
|
+
applicationId?: string;
|
|
168
|
+
timeoutMs?: number;
|
|
169
|
+
delegatePortableDid?: PortableDid;
|
|
170
|
+
requestType?: ConnectRequestType;
|
|
171
|
+
expectedProviderDid?: string;
|
|
172
|
+
}): Promise<ConnectResult | undefined>;
|
|
161
173
|
/**
|
|
162
174
|
* Opens the connect modal and resolves when the session ends.
|
|
163
175
|
*
|
|
@@ -167,4 +179,5 @@ export declare function discoverWalletConnectServerUrl(walletOrigin: string): Pr
|
|
|
167
179
|
* user dismisses the error.
|
|
168
180
|
*/
|
|
169
181
|
export declare function runConnectModal(options: ConnectModalOptions): Promise<ConnectResult | undefined>;
|
|
182
|
+
export {};
|
|
170
183
|
//# sourceMappingURL=connect-modal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect-modal.d.ts","sourceRoot":"","sources":["../../../src/ui/connect-modal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,aAAa,EAAoB,MAAM,gBAAgB,CAAC;AAYpH,OAAO,EAA8B,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAEzF,6CAA6C;AAC7C,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"connect-modal.d.ts","sourceRoot":"","sources":["../../../src/ui/connect-modal.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enbox/browser",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.72",
|
|
4
4
|
"description": "Enbox tools and features to use in the browser",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/esm/index.js",
|
|
@@ -66,15 +66,15 @@
|
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@enbox/agent": "0.8.
|
|
70
|
-
"@enbox/api": "0.6.
|
|
71
|
-
"@enbox/auth": "0.6.
|
|
69
|
+
"@enbox/agent": "0.8.41",
|
|
70
|
+
"@enbox/api": "0.6.80",
|
|
71
|
+
"@enbox/auth": "0.6.87",
|
|
72
72
|
"@enbox/common": "0.1.6",
|
|
73
|
-
"@enbox/connect": "0.1.
|
|
73
|
+
"@enbox/connect": "0.1.21",
|
|
74
74
|
"@enbox/crypto": "0.1.9",
|
|
75
75
|
"@enbox/dids": "0.1.10",
|
|
76
|
-
"@enbox/dwn-sdk-js": "0.4.
|
|
77
|
-
"@enbox/protocols": "0.2.
|
|
76
|
+
"@enbox/dwn-sdk-js": "0.4.25",
|
|
77
|
+
"@enbox/protocols": "0.2.107"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@types/qrcode": "^1.5.6",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ObjectUrlLease } from './object-url-reference.js';
|
|
2
|
+
|
|
3
|
+
import { ObjectUrlReference } from './object-url-reference.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A reference-counted lease for a browser object URL.
|
|
7
|
+
*
|
|
8
|
+
* When replacing a URL already rendered by the DOM, `releaseAfter()` provides
|
|
9
|
+
* a grace period without passing the lease through the component tree.
|
|
10
|
+
*/
|
|
11
|
+
export type BlobUrlLease = ObjectUrlLease;
|
|
12
|
+
|
|
13
|
+
/** Owns object URLs for Blob identities until their last lease is released. */
|
|
14
|
+
export interface BlobUrlPool {
|
|
15
|
+
acquire(blob: Blob): BlobUrlLease;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class DefaultBlobUrlPool implements BlobUrlPool {
|
|
20
|
+
private readonly _references = new Map<Blob, ObjectUrlReference>();
|
|
21
|
+
private _isDisposed = false;
|
|
22
|
+
|
|
23
|
+
public acquire(blob: Blob): BlobUrlLease {
|
|
24
|
+
if (this._isDisposed) {
|
|
25
|
+
throw new Error('BlobUrlPool is disposed.');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let reference = this._references.get(blob);
|
|
29
|
+
if (reference === undefined) {
|
|
30
|
+
reference = new ObjectUrlReference(blob, (released): void => {
|
|
31
|
+
this._references.delete(blob);
|
|
32
|
+
released.revoke();
|
|
33
|
+
});
|
|
34
|
+
this._references.set(blob, reference);
|
|
35
|
+
}
|
|
36
|
+
return reference.acquire();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public dispose(): void {
|
|
40
|
+
if (this._isDisposed) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this._isDisposed = true;
|
|
45
|
+
for (const reference of this._references.values()) {
|
|
46
|
+
reference.revoke();
|
|
47
|
+
}
|
|
48
|
+
this._references.clear();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Create a terminally disposable, reference-counted object URL pool. */
|
|
53
|
+
export function createBlobUrlPool(): BlobUrlPool {
|
|
54
|
+
return new DefaultBlobUrlPool();
|
|
55
|
+
}
|
|
@@ -107,6 +107,12 @@ export interface BrowserConnectHandlerOptions {
|
|
|
107
107
|
*/
|
|
108
108
|
appIcon?: string;
|
|
109
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Stable application identifier hint available to the wallet during approval.
|
|
112
|
+
* Defaults to the browser's canonical origin.
|
|
113
|
+
*/
|
|
114
|
+
applicationId?: string;
|
|
115
|
+
|
|
110
116
|
/**
|
|
111
117
|
* Preferred connect method on open: `'phone'` (QR / deep link via the
|
|
112
118
|
* relay) or `'browser'` (wallet popup on this device). Overrides the
|
|
@@ -116,8 +122,9 @@ export interface BrowserConnectHandlerOptions {
|
|
|
116
122
|
preferredMethod?: ConnectMethod;
|
|
117
123
|
|
|
118
124
|
/**
|
|
119
|
-
* Remember the successful method + wallet in localStorage
|
|
120
|
-
* the
|
|
125
|
+
* Remember the successful method + wallet in localStorage. Refreshes reuse
|
|
126
|
+
* the route saved for their delegate DID; new connections use the latest
|
|
127
|
+
* successful route as a convenience.
|
|
121
128
|
* @default true
|
|
122
129
|
*/
|
|
123
130
|
rememberChoice?: boolean;
|
|
@@ -176,6 +183,7 @@ export function BrowserConnectHandler(
|
|
|
176
183
|
timeout,
|
|
177
184
|
appName,
|
|
178
185
|
appIcon,
|
|
186
|
+
applicationId,
|
|
179
187
|
preferredMethod,
|
|
180
188
|
rememberChoice,
|
|
181
189
|
connectServerUrl,
|
|
@@ -188,6 +196,7 @@ export function BrowserConnectHandler(
|
|
|
188
196
|
permissionRequests: ConnectPermissionRequest[];
|
|
189
197
|
delegatePortableDid?: PortableDid;
|
|
190
198
|
requestType?: ConnectRequestType;
|
|
199
|
+
expectedProviderDid?: string;
|
|
191
200
|
}): Promise<ConnectResult | undefined> {
|
|
192
201
|
return runConnectModal({
|
|
193
202
|
wallets,
|
|
@@ -196,12 +205,14 @@ export function BrowserConnectHandler(
|
|
|
196
205
|
rememberChoice,
|
|
197
206
|
appName,
|
|
198
207
|
appIcon : appIcon ?? `${window.location.origin}/favicon.ico`,
|
|
208
|
+
applicationId,
|
|
199
209
|
connectServerUrl,
|
|
200
210
|
relayWalletPath,
|
|
201
211
|
timeout,
|
|
202
212
|
theme,
|
|
203
213
|
mode : params.requestType,
|
|
204
214
|
delegatePortableDid : params.delegatePortableDid,
|
|
215
|
+
expectedProviderDid : params.expectedProviderDid,
|
|
205
216
|
permissionRequests : params.permissionRequests,
|
|
206
217
|
});
|
|
207
218
|
},
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import type { FileEnvelopeData } from '@enbox/api';
|
|
2
|
+
|
|
3
|
+
import type { BlobUrlLease } from './blob-url-pool.js';
|
|
4
|
+
|
|
5
|
+
import { ObjectUrlReference } from './object-url-reference.js';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_MAX_BYTES = 128 * 1024 * 1024;
|
|
8
|
+
const DEFAULT_MAX_ENTRIES = 50;
|
|
9
|
+
|
|
10
|
+
type CacheEntry = {
|
|
11
|
+
bytes: number;
|
|
12
|
+
filename: string;
|
|
13
|
+
key: string;
|
|
14
|
+
mimeType: string;
|
|
15
|
+
url: ObjectUrlReference;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type PendingRead = {
|
|
19
|
+
controller: AbortController;
|
|
20
|
+
generation: number;
|
|
21
|
+
promise: Promise<CacheEntry | undefined>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/** A cached file envelope represented by a leased browser object URL. */
|
|
25
|
+
export type FileEnvelopeUrlLease = BlobUrlLease & Readonly<{
|
|
26
|
+
filename: string;
|
|
27
|
+
mimeType: string;
|
|
28
|
+
}>;
|
|
29
|
+
|
|
30
|
+
export type FileEnvelopeUrlStoreOptions<Request> = Readonly<{
|
|
31
|
+
/** Select the stable cache key for a read request. */
|
|
32
|
+
key(request: Request): string;
|
|
33
|
+
/** Read and decode the file. The signal aborts invalidated work. */
|
|
34
|
+
read(request: Request, signal: AbortSignal): Promise<FileEnvelopeData | undefined>;
|
|
35
|
+
/** Choose the Blob exposed by the URL, retaining MIME/render policy in the caller. */
|
|
36
|
+
blobForUrl(value: FileEnvelopeData): Blob;
|
|
37
|
+
/** Maximum cached entries (default 50). Soft while every eviction candidate is leased. */
|
|
38
|
+
maxEntries?: number;
|
|
39
|
+
/** Maximum cached Blob bytes (default 128 MiB). Soft while every eviction candidate is leased. */
|
|
40
|
+
maxBytes?: number;
|
|
41
|
+
}>;
|
|
42
|
+
|
|
43
|
+
/** A keyed, bounded object URL cache for decoded file envelopes. */
|
|
44
|
+
export interface FileEnvelopeUrlStore<Request> {
|
|
45
|
+
acquire(request: Request): Promise<FileEnvelopeUrlLease | undefined>;
|
|
46
|
+
acquireCached(request: Request): FileEnvelopeUrlLease | undefined;
|
|
47
|
+
clear(): void;
|
|
48
|
+
dispose(): void;
|
|
49
|
+
invalidate(request: Request): void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function assertLimit(value: number, name: string): void {
|
|
53
|
+
if (value !== Infinity && (!Number.isSafeInteger(value) || value < 0)) {
|
|
54
|
+
throw new TypeError(`${name} must be a non-negative safe integer or Infinity.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function throwAborted(controller: AbortController): never {
|
|
59
|
+
controller.abort();
|
|
60
|
+
throw controller.signal.reason;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
class DefaultFileEnvelopeUrlStore<Request> implements FileEnvelopeUrlStore<Request> {
|
|
64
|
+
private readonly _cache = new Map<string, CacheEntry>();
|
|
65
|
+
private readonly _entries = new Set<CacheEntry>();
|
|
66
|
+
private readonly _maxBytes: number;
|
|
67
|
+
private readonly _maxEntries: number;
|
|
68
|
+
private readonly _pending = new Map<string, PendingRead>();
|
|
69
|
+
private _bytes = 0;
|
|
70
|
+
private _generation = 0;
|
|
71
|
+
private _isDisposed = false;
|
|
72
|
+
|
|
73
|
+
public constructor(private readonly _options: FileEnvelopeUrlStoreOptions<Request>) {
|
|
74
|
+
this._maxBytes = _options.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
75
|
+
this._maxEntries = _options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
76
|
+
assertLimit(this._maxBytes, 'maxBytes');
|
|
77
|
+
assertLimit(this._maxEntries, 'maxEntries');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public async acquire(request: Request): Promise<FileEnvelopeUrlLease | undefined> {
|
|
81
|
+
this._assertActive();
|
|
82
|
+
const key = this._options.key(request);
|
|
83
|
+
const cached = this._cache.get(key);
|
|
84
|
+
if (cached !== undefined) {
|
|
85
|
+
return this._acquire(cached);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const pending = this._pending.get(key) ?? this._startRead(request, key);
|
|
89
|
+
const entry = await pending.promise;
|
|
90
|
+
if (this._isDisposed || pending.generation !== this._generation) {
|
|
91
|
+
return throwAborted(pending.controller);
|
|
92
|
+
}
|
|
93
|
+
if (entry === undefined) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
if (this._cache.get(key) !== entry) {
|
|
97
|
+
return throwAborted(pending.controller);
|
|
98
|
+
}
|
|
99
|
+
return this._acquire(entry);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public acquireCached(request: Request): FileEnvelopeUrlLease | undefined {
|
|
103
|
+
this._assertActive();
|
|
104
|
+
const entry = this._cache.get(this._options.key(request));
|
|
105
|
+
return entry === undefined ? undefined : this._acquire(entry);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public invalidate(request: Request): void {
|
|
109
|
+
this._assertActive();
|
|
110
|
+
const key = this._options.key(request);
|
|
111
|
+
const pending = this._pending.get(key);
|
|
112
|
+
pending?.controller.abort();
|
|
113
|
+
this._pending.delete(key);
|
|
114
|
+
const entry = this._cache.get(key);
|
|
115
|
+
if (entry !== undefined) {
|
|
116
|
+
this._remove(entry);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public clear(): void {
|
|
121
|
+
this._assertActive();
|
|
122
|
+
this._reset(false);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public dispose(): void {
|
|
126
|
+
if (this._isDisposed) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this._isDisposed = true;
|
|
131
|
+
this._reset(true);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private _abortReads(): void {
|
|
135
|
+
for (const pending of this._pending.values()) {
|
|
136
|
+
pending.controller.abort();
|
|
137
|
+
}
|
|
138
|
+
this._pending.clear();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private _acquire(entry: CacheEntry): FileEnvelopeUrlLease {
|
|
142
|
+
this._cache.delete(entry.key);
|
|
143
|
+
this._cache.set(entry.key, entry);
|
|
144
|
+
const lease = entry.url.acquire();
|
|
145
|
+
this._evict();
|
|
146
|
+
return Object.freeze({
|
|
147
|
+
filename : entry.filename,
|
|
148
|
+
mimeType : entry.mimeType,
|
|
149
|
+
release : lease.release,
|
|
150
|
+
releaseAfter : lease.releaseAfter,
|
|
151
|
+
url : lease.url,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private _assertActive(): void {
|
|
156
|
+
if (this._isDisposed) {
|
|
157
|
+
throw new Error('FileEnvelopeUrlStore is disposed.');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private _assertCurrent(key: string, controller: AbortController, generation: number): void {
|
|
162
|
+
if (
|
|
163
|
+
this._isDisposed
|
|
164
|
+
|| controller.signal.aborted
|
|
165
|
+
|| this._generation !== generation
|
|
166
|
+
|| this._pending.get(key)?.controller !== controller
|
|
167
|
+
) {
|
|
168
|
+
throwAborted(controller);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private _evict(): void {
|
|
173
|
+
while (this._cache.size > this._maxEntries || this._bytes > this._maxBytes) {
|
|
174
|
+
const entry = [...this._cache.values()].find((candidate): boolean => candidate.url.references === 0);
|
|
175
|
+
if (entry === undefined) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
this._remove(entry);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private async _load(request: Request, key: string, controller: AbortController, generation: number): Promise<CacheEntry | undefined> {
|
|
183
|
+
const value = await this._options.read(request, controller.signal);
|
|
184
|
+
this._assertCurrent(key, controller, generation);
|
|
185
|
+
if (value === undefined) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const blob = this._options.blobForUrl(value);
|
|
190
|
+
this._assertCurrent(key, controller, generation);
|
|
191
|
+
const url = new ObjectUrlReference(blob, (): void => this._released(entry));
|
|
192
|
+
const entry: CacheEntry = {
|
|
193
|
+
bytes : blob.size,
|
|
194
|
+
filename : value.filename,
|
|
195
|
+
key,
|
|
196
|
+
mimeType : value.mimeType,
|
|
197
|
+
url,
|
|
198
|
+
};
|
|
199
|
+
this._cache.set(key, entry);
|
|
200
|
+
this._bytes += entry.bytes;
|
|
201
|
+
this._entries.add(entry);
|
|
202
|
+
return entry;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private _released(entry: CacheEntry): void {
|
|
206
|
+
if (this._cache.get(entry.key) !== entry) {
|
|
207
|
+
this._revoke(entry);
|
|
208
|
+
} else {
|
|
209
|
+
this._evict();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
private _remove(entry: CacheEntry): void {
|
|
214
|
+
if (this._cache.get(entry.key) !== entry) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
this._cache.delete(entry.key);
|
|
218
|
+
this._bytes -= entry.bytes;
|
|
219
|
+
if (entry.url.references === 0) {
|
|
220
|
+
this._revoke(entry);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
private _reset(revokeActive: boolean): void {
|
|
225
|
+
this._generation += 1;
|
|
226
|
+
this._abortReads();
|
|
227
|
+
this._cache.clear();
|
|
228
|
+
this._bytes = 0;
|
|
229
|
+
for (const entry of this._entries) {
|
|
230
|
+
if (revokeActive || entry.url.references === 0) {
|
|
231
|
+
this._revoke(entry);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private _revoke(entry: CacheEntry): void {
|
|
237
|
+
entry.url.revoke();
|
|
238
|
+
this._entries.delete(entry);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private _startRead(request: Request, key: string): PendingRead {
|
|
242
|
+
const controller = new AbortController();
|
|
243
|
+
const generation = this._generation;
|
|
244
|
+
const promise = this._load(request, key, controller, generation).finally((): void => {
|
|
245
|
+
if (this._pending.get(key)?.controller === controller) {
|
|
246
|
+
this._pending.delete(key);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
const pending = { controller, generation, promise };
|
|
250
|
+
this._pending.set(key, pending);
|
|
251
|
+
return pending;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/** Create a bounded file-envelope URL store with deduplicated reads. */
|
|
256
|
+
export function createFileEnvelopeUrlStore<Request>(
|
|
257
|
+
options: FileEnvelopeUrlStoreOptions<Request>,
|
|
258
|
+
): FileEnvelopeUrlStore<Request> {
|
|
259
|
+
return new DefaultFileEnvelopeUrlStore(options);
|
|
260
|
+
}
|