@mysten/enoki-connect 0.0.26 → 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.
- package/CHANGELOG.md +19 -0
- package/dist/cjs/components/base-modal.d.ts +43 -0
- package/dist/cjs/components/base-modal.js +197 -0
- package/dist/cjs/components/base-modal.js.map +7 -0
- package/dist/cjs/components/modal.d.ts +24 -0
- package/dist/cjs/components/modal.js +269 -0
- package/dist/cjs/components/modal.js.map +7 -0
- package/dist/cjs/package.json +1 -2
- package/dist/cjs/wallet/index.d.ts +1 -0
- package/dist/cjs/wallet/index.js +46 -7
- package/dist/cjs/wallet/index.js.map +3 -3
- package/dist/esm/components/base-modal.d.ts +43 -0
- package/dist/esm/components/base-modal.js +179 -0
- package/dist/esm/components/base-modal.js.map +7 -0
- package/dist/esm/components/modal.d.ts +24 -0
- package/dist/esm/components/modal.js +251 -0
- package/dist/esm/components/modal.js.map +7 -0
- package/dist/esm/package.json +1 -2
- package/dist/esm/wallet/index.d.ts +1 -0
- package/dist/esm/wallet/index.js +46 -7
- package/dist/esm/wallet/index.js.map +2 -2
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -6
package/dist/cjs/wallet/index.js
CHANGED
|
@@ -44,6 +44,8 @@ var import_utils = require("@mysten/sui/utils");
|
|
|
44
44
|
var import_wallet_standard = require("@mysten/wallet-standard");
|
|
45
45
|
var import_mitt = __toESM(require("mitt"));
|
|
46
46
|
var import_window_wallet_core = require("@mysten/window-wallet-core");
|
|
47
|
+
var import_utils2 = require("@mysten/utils");
|
|
48
|
+
var import_modal = require("../components/modal.js");
|
|
47
49
|
var _events, _accounts, _hostOrigin, _walletName, _dappName, _icon, _defaultChain, _publicAppSlug, _signTransactionBlock, _signTransaction, _signAndExecuteTransaction, _signPersonalMessage, _on, _EnokiConnectWallet_instances, setAccounts_fn, _connect, _disconnect, getSessionKey_fn, getStoredSession_fn, getNewPopupChannel_fn, getAccountsFromSession_fn;
|
|
48
50
|
const SUPPORTED_CHAINS = [import_wallet_standard.SUI_MAINNET_CHAIN, import_wallet_standard.SUI_TESTNET_CHAIN, import_wallet_standard.SUI_DEVNET_CHAIN];
|
|
49
51
|
const ACCOUNT_FEATURES = [
|
|
@@ -76,7 +78,7 @@ class EnokiConnectWallet {
|
|
|
76
78
|
account,
|
|
77
79
|
chain
|
|
78
80
|
}) => {
|
|
79
|
-
const popup = __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
81
|
+
const popup = await __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
80
82
|
const response = await popup.send({
|
|
81
83
|
type: "sign-transaction",
|
|
82
84
|
chain,
|
|
@@ -90,7 +92,7 @@ class EnokiConnectWallet {
|
|
|
90
92
|
};
|
|
91
93
|
});
|
|
92
94
|
__privateAdd(this, _signTransaction, async ({ transaction, account, chain }) => {
|
|
93
|
-
const popup = __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
95
|
+
const popup = await __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
94
96
|
const response = await popup.send({
|
|
95
97
|
type: "sign-transaction",
|
|
96
98
|
chain,
|
|
@@ -108,7 +110,7 @@ class EnokiConnectWallet {
|
|
|
108
110
|
account,
|
|
109
111
|
chain
|
|
110
112
|
}) => {
|
|
111
|
-
const popup = __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
113
|
+
const popup = await __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
112
114
|
const response = await popup.send({
|
|
113
115
|
type: "sign-and-execute-transaction",
|
|
114
116
|
transaction: await transaction.toJSON(),
|
|
@@ -124,7 +126,7 @@ class EnokiConnectWallet {
|
|
|
124
126
|
};
|
|
125
127
|
});
|
|
126
128
|
__privateAdd(this, _signPersonalMessage, async ({ message, account, chain }) => {
|
|
127
|
-
const popup = __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
129
|
+
const popup = await __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
128
130
|
const response = await popup.send({
|
|
129
131
|
type: "sign-personal-message",
|
|
130
132
|
chain: chain ?? __privateGet(this, _defaultChain),
|
|
@@ -152,7 +154,7 @@ class EnokiConnectWallet {
|
|
|
152
154
|
}
|
|
153
155
|
return { accounts: this.accounts };
|
|
154
156
|
}
|
|
155
|
-
const popup = __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
157
|
+
const popup = await __privateMethod(this, _EnokiConnectWallet_instances, getNewPopupChannel_fn).call(this);
|
|
156
158
|
const response = await popup.send({
|
|
157
159
|
type: "connect"
|
|
158
160
|
});
|
|
@@ -256,13 +258,21 @@ getStoredSession_fn = function() {
|
|
|
256
258
|
}
|
|
257
259
|
return session;
|
|
258
260
|
};
|
|
259
|
-
getNewPopupChannel_fn = function() {
|
|
261
|
+
getNewPopupChannel_fn = async function() {
|
|
262
|
+
let popupWindow = window.open("about:blank", "_blank");
|
|
263
|
+
if (!popupWindow) {
|
|
264
|
+
popupWindow = await addClickToOpenPopupWindow({
|
|
265
|
+
walletName: __privateGet(this, _walletName),
|
|
266
|
+
dappName: __privateGet(this, _dappName)
|
|
267
|
+
});
|
|
268
|
+
}
|
|
260
269
|
return new import_window_wallet_core.DappPostMessageChannel({
|
|
261
270
|
appName: __privateGet(this, _dappName),
|
|
262
271
|
hostOrigin: __privateGet(this, _hostOrigin),
|
|
263
272
|
extraRequestOptions: {
|
|
264
273
|
publicAppSlug: __privateGet(this, _publicAppSlug)
|
|
265
|
-
}
|
|
274
|
+
},
|
|
275
|
+
popupWindow
|
|
266
276
|
});
|
|
267
277
|
};
|
|
268
278
|
getAccountsFromSession_fn = function(session) {
|
|
@@ -282,6 +292,35 @@ getAccountsFromSession_fn = function(session) {
|
|
|
282
292
|
return [];
|
|
283
293
|
}
|
|
284
294
|
};
|
|
295
|
+
function addClickToOpenPopupWindow({
|
|
296
|
+
walletName,
|
|
297
|
+
dappName
|
|
298
|
+
}) {
|
|
299
|
+
const { promise, resolve, reject } = (0, import_utils2.promiseWithResolvers)();
|
|
300
|
+
const modal = document.createElement("enoki-connect-modal");
|
|
301
|
+
modal.walletName = walletName;
|
|
302
|
+
modal.dappName = dappName;
|
|
303
|
+
modal.open = true;
|
|
304
|
+
modal.addEventListener("cancel", () => {
|
|
305
|
+
reject(new Error("Popup was blocked from browser and user rejected click to review request"));
|
|
306
|
+
modal.open = false;
|
|
307
|
+
});
|
|
308
|
+
modal.addEventListener("approved", () => {
|
|
309
|
+
modal.disabled = true;
|
|
310
|
+
modal.open = false;
|
|
311
|
+
const popup = window.open("about:blank", "_blank");
|
|
312
|
+
if (popup) {
|
|
313
|
+
resolve(popup);
|
|
314
|
+
} else {
|
|
315
|
+
reject(new Error("Failed to open popup"));
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
modal.addEventListener("closed", () => {
|
|
319
|
+
modal.remove();
|
|
320
|
+
});
|
|
321
|
+
document.body.appendChild(modal);
|
|
322
|
+
return promise;
|
|
323
|
+
}
|
|
285
324
|
async function getEnokiConnectMetadata(publicAppSlugs, enokiApiUrl) {
|
|
286
325
|
const sortedPublicAppSlugs = [...publicAppSlugs].sort();
|
|
287
326
|
const queryParams = new URLSearchParams();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/wallet/index.ts"],
|
|
4
|
-
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase64, toBase64 } from '@mysten/sui/utils';\nimport type {\n\tIdentifierString,\n\tStandardConnectFeature,\n\tStandardConnectMethod,\n\tStandardDisconnectFeature,\n\tStandardDisconnectMethod,\n\tStandardEventsFeature,\n\tStandardEventsListeners,\n\tStandardEventsOnMethod,\n\tSuiSignAndExecuteTransactionFeature,\n\tSuiSignAndExecuteTransactionMethod,\n\tSuiSignPersonalMessageFeature,\n\tSuiSignPersonalMessageMethod,\n\tSuiSignTransactionBlockFeature,\n\tSuiSignTransactionBlockMethod,\n\tSuiSignTransactionFeature,\n\tSuiSignTransactionMethod,\n\tWallet,\n\tWalletIcon,\n} from '@mysten/wallet-standard';\nimport {\n\tgetWallets,\n\tReadonlyWalletAccount,\n\tSUI_DEVNET_CHAIN,\n\tSUI_MAINNET_CHAIN,\n\tSUI_TESTNET_CHAIN,\n} from '@mysten/wallet-standard';\nimport type { Emitter } from 'mitt';\nimport mitt from 'mitt';\nimport { DappPostMessageChannel, decodeJwtSession } from '@mysten/window-wallet-core';\n\nexport type SupportedNetwork = 'mainnet' | 'testnet' | 'devnet';\n\ntype WalletEventsMap = {\n\t[E in keyof StandardEventsListeners]: Parameters<StandardEventsListeners[E]>[0];\n};\n\nconst SUPPORTED_CHAINS = [SUI_MAINNET_CHAIN, SUI_TESTNET_CHAIN, SUI_DEVNET_CHAIN] as const;\nconst ACCOUNT_FEATURES = [\n\t'sui:signTransaction',\n\t'sui:signAndExecuteTransaction',\n\t'sui:signPersonalMessage',\n\t'sui:signTransactionBlock',\n\t'sui:signAndExecuteTransactionBlock',\n] as const;\n\nexport class EnokiConnectWallet implements Wallet {\n\treadonly id: string;\n\t#events: Emitter<WalletEventsMap>;\n\t#accounts: ReadonlyWalletAccount[];\n\t#hostOrigin: string;\n\t#walletName: string;\n\t#dappName: string;\n\t#icon: WalletIcon;\n\t#defaultChain: IdentifierString;\n\t#publicAppSlug: string;\n\n\tget name() {\n\t\treturn this.#walletName;\n\t}\n\n\tget icon() {\n\t\treturn this.#icon;\n\t}\n\n\tget version() {\n\t\treturn '1.0.0' as const;\n\t}\n\n\tget chains() {\n\t\treturn SUPPORTED_CHAINS;\n\t}\n\n\tget accounts() {\n\t\treturn this.#accounts;\n\t}\n\n\tget features(): StandardConnectFeature &\n\t\tStandardDisconnectFeature &\n\t\tStandardEventsFeature &\n\t\tSuiSignTransactionBlockFeature &\n\t\tSuiSignTransactionFeature &\n\t\tSuiSignPersonalMessageFeature &\n\t\tSuiSignAndExecuteTransactionFeature {\n\t\treturn {\n\t\t\t'standard:connect': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tconnect: this.#connect,\n\t\t\t},\n\t\t\t'standard:disconnect': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tdisconnect: this.#disconnect,\n\t\t\t},\n\t\t\t'standard:events': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\ton: this.#on,\n\t\t\t},\n\t\t\t'sui:signTransactionBlock': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tsignTransactionBlock: this.#signTransactionBlock,\n\t\t\t},\n\t\t\t'sui:signTransaction': {\n\t\t\t\tversion: '2.0.0',\n\t\t\t\tsignTransaction: this.#signTransaction,\n\t\t\t},\n\t\t\t'sui:signPersonalMessage': {\n\t\t\t\tversion: '1.1.0',\n\t\t\t\tsignPersonalMessage: this.#signPersonalMessage,\n\t\t\t},\n\t\t\t'sui:signAndExecuteTransaction': {\n\t\t\t\tversion: '2.0.0',\n\t\t\t\tsignAndExecuteTransaction: this.#signAndExecuteTransaction,\n\t\t\t},\n\t\t};\n\t}\n\n\tconstructor({\n\t\tpublicAppSlug,\n\t\twalletName,\n\t\tdappName,\n\t\thostOrigin,\n\t\ticon,\n\t\tnetwork,\n\t}: {\n\t\tpublicAppSlug: string;\n\t\twalletName: string;\n\t\tdappName: string;\n\t\tnetwork: SupportedNetwork;\n\t\thostOrigin: string;\n\t\ticon: WalletIcon;\n\t}) {\n\t\tthis.#accounts = [];\n\t\tthis.#events = mitt();\n\t\tthis.#hostOrigin = hostOrigin;\n\t\tthis.#walletName = walletName;\n\t\tthis.#dappName = dappName;\n\t\tthis.#icon = icon;\n\t\tthis.#defaultChain = `sui:${network}`;\n\t\tthis.#publicAppSlug = publicAppSlug;\n\t\tthis.id = `enoki-connect-${publicAppSlug}`;\n\t}\n\n\t#signTransactionBlock: SuiSignTransactionBlockMethod = async ({\n\t\ttransactionBlock,\n\t\taccount,\n\t\tchain,\n\t}) => {\n\t\tconst popup = this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'sign-transaction',\n\t\t\tchain,\n\t\t\ttransaction: await transactionBlock.toJSON(),\n\t\t\taddress: account.address,\n\t\t\tsession: this.#getStoredSession(),\n\t\t});\n\n\t\treturn {\n\t\t\ttransactionBlockBytes: response.bytes,\n\t\t\tsignature: response.signature,\n\t\t};\n\t};\n\n\t#signTransaction: SuiSignTransactionMethod = async ({ transaction, account, chain }) => {\n\t\tconst popup = this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'sign-transaction',\n\t\t\tchain,\n\t\t\ttransaction: await transaction.toJSON(),\n\t\t\taddress: account.address,\n\t\t\tsession: this.#getStoredSession(),\n\t\t});\n\n\t\treturn {\n\t\t\tbytes: response.bytes,\n\t\t\tsignature: response.signature,\n\t\t};\n\t};\n\n\t#signAndExecuteTransaction: SuiSignAndExecuteTransactionMethod = async ({\n\t\ttransaction,\n\t\taccount,\n\t\tchain,\n\t}) => {\n\t\tconst popup = this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'sign-and-execute-transaction',\n\t\t\ttransaction: await transaction.toJSON(),\n\t\t\taddress: account.address,\n\t\t\tchain,\n\t\t\tsession: this.#getStoredSession(),\n\t\t});\n\n\t\treturn {\n\t\t\tbytes: response.bytes,\n\t\t\tsignature: response.signature,\n\t\t\tdigest: response.digest,\n\t\t\teffects: response.effects,\n\t\t};\n\t};\n\n\t#signPersonalMessage: SuiSignPersonalMessageMethod = async ({ message, account, chain }) => {\n\t\tconst popup = this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'sign-personal-message',\n\t\t\tchain: chain ?? this.#defaultChain,\n\t\t\tmessage: toBase64(message),\n\t\t\taddress: account.address,\n\t\t\tsession: this.#getStoredSession(),\n\t\t});\n\n\t\treturn {\n\t\t\tbytes: response.bytes,\n\t\t\tsignature: response.signature,\n\t\t};\n\t};\n\n\t#on: StandardEventsOnMethod = (event, listener) => {\n\t\tthis.#events.on(event, listener);\n\n\t\treturn () => this.#events.off(event, listener);\n\t};\n\n\t#setAccounts(session?: string) {\n\t\tif (session) {\n\t\t\tthis.#accounts = this.#getAccountsFromSession(session);\n\t\t\tlocalStorage.setItem(this.#getSessionKey(), session);\n\t\t} else {\n\t\t\tthis.#accounts = [];\n\t\t}\n\n\t\tthis.#events.emit('change', { accounts: this.accounts });\n\t}\n\n\t#connect: StandardConnectMethod = async (input) => {\n\t\tif (input?.silent) {\n\t\t\ttry {\n\t\t\t\tconst session = this.#getStoredSession();\n\n\t\t\t\tif (session) {\n\t\t\t\t\tthis.#setAccounts(session);\n\t\t\t\t}\n\t\t\t} catch (_e) {\n\t\t\t\t// ignore\n\t\t\t}\n\n\t\t\treturn { accounts: this.accounts };\n\t\t}\n\n\t\tconst popup = this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'connect',\n\t\t});\n\n\t\tthis.#setAccounts(response.session);\n\n\t\treturn { accounts: this.accounts };\n\t};\n\n\t#disconnect: StandardDisconnectMethod = async () => {\n\t\tlocalStorage.removeItem(this.#getSessionKey());\n\t\tthis.#setAccounts();\n\t};\n\n\t#getSessionKey() {\n\t\treturn `enoki-connect-${this.#publicAppSlug}:session`;\n\t}\n\n\t#getStoredSession() {\n\t\tconst session = localStorage.getItem(this.#getSessionKey());\n\n\t\tif (!session) {\n\t\t\tthrow new Error('No session found');\n\t\t}\n\n\t\treturn session;\n\t}\n\n\t#getNewPopupChannel() {\n\t\treturn new DappPostMessageChannel({\n\t\t\tappName: this.#dappName,\n\t\t\thostOrigin: this.#hostOrigin,\n\t\t\textraRequestOptions: {\n\t\t\t\tpublicAppSlug: this.#publicAppSlug,\n\t\t\t},\n\t\t});\n\t}\n\n\t#getAccountsFromSession(session: string) {\n\t\ttry {\n\t\t\tconst {\n\t\t\t\tpayload: { accounts },\n\t\t\t} = decodeJwtSession(session);\n\n\t\t\treturn accounts.map(\n\t\t\t\t(anAccount) =>\n\t\t\t\t\tnew ReadonlyWalletAccount({\n\t\t\t\t\t\taddress: anAccount.address,\n\t\t\t\t\t\tchains: SUPPORTED_CHAINS,\n\t\t\t\t\t\tfeatures: ACCOUNT_FEATURES,\n\t\t\t\t\t\tpublicKey: fromBase64(anAccount.publicKey),\n\t\t\t\t\t}),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\treturn [];\n\t\t}\n\t}\n}\n\ntype EnokiConnectMetadata = {\n\tpublicAppSlug: string;\n\tname: string;\n\tlogoUrl: WalletIcon;\n\tappUrl: string;\n};\n\nasync function getEnokiConnectMetadata(publicAppSlugs: string[], enokiApiUrl: string) {\n\tconst sortedPublicAppSlugs = [...publicAppSlugs].sort();\n\tconst queryParams = new URLSearchParams();\n\n\tfor (const publicAppSlug of sortedPublicAppSlugs) {\n\t\tqueryParams.append('slugs', publicAppSlug);\n\t}\n\n\tqueryParams.sort();\n\n\tconst res = await fetch(new URL(`/v1/connect/metadata?${queryParams.toString()}`, enokiApiUrl));\n\n\tif (!res.ok) {\n\t\tthrow new Error('Failed to fetch enoki connect metadata');\n\t}\n\n\tconst { data } = await res.json();\n\n\treturn data as EnokiConnectMetadata[];\n}\n\n/**\n * Registers Enoki Connect wallets for your dApp.\n *\n * This function fetches wallet metadata for the provided public app slugs and registers\n * them with the wallet standard. It returns the registered wallet instances and an\n * `unregister` function to remove them if needed.\n *\n * @param publicAppSlugs - An array of public app slugs to register. You can obtain these slugs from the wallet developer.\n * @param dappName - The display name of your dApp. This will be shown to users in wallet UIs.\n * @param network - (Optional) The default Sui network to use for wallet operations (when chain is not specified in the wallet method). Accepts 'mainnet', 'testnet', or 'devnet'. Defaults to 'mainnet' if not specified.\n * @param enokiApiUrl - (Optional) The Enoki API endpoint to use for fetching wallet metadata. Defaults to the public Enoki API at 'https://api.enoki.mystenlabs.com'. (Override this if you are running a local or custom Enoki API instance.)\n *\n * @returns An object containing:\n * - `wallets`: The array of registered EnokiConnectWallet instances.\n * - `unregister`: A function to unregister all registered wallets.\n *\n * @example\n * ```ts\n * const { wallets, unregister } = await registerEnokiConnectWallets({\n * publicAppSlugs: ['an-app-slug'],\n * dappName: 'My Dapp',\n * });\n * ```\n */\nexport async function registerEnokiConnectWallets({\n\tpublicAppSlugs,\n\tdappName,\n\tnetwork = 'mainnet',\n\tenokiApiUrl = 'https://api.enoki.mystenlabs.com',\n}: {\n\tpublicAppSlugs: string[];\n\tdappName: string;\n\tnetwork?: SupportedNetwork;\n\tenokiApiUrl?: string;\n}) {\n\tconst wallets = getWallets();\n\tconst data = await getEnokiConnectMetadata(publicAppSlugs, enokiApiUrl);\n\tconst unregisterCallbacks: (() => void)[] = [];\n\tconst registeredWallets: EnokiConnectWallet[] = [];\n\n\tfor (const aWalletMetadata of data) {\n\t\tconst wallet = new EnokiConnectWallet({\n\t\t\twalletName: aWalletMetadata.name,\n\t\t\tdappName,\n\t\t\thostOrigin: aWalletMetadata.appUrl,\n\t\t\ticon: aWalletMetadata.logoUrl,\n\t\t\tnetwork,\n\t\t\tpublicAppSlug: aWalletMetadata.publicAppSlug,\n\t\t});\n\t\tconst unregister = wallets.register(wallet);\n\n\t\tunregisterCallbacks.push(unregister);\n\t\tregisteredWallets.push(wallet);\n\t}\n\n\treturn {\n\t\twallets: registeredWallets,\n\t\tunregister: () => {\n\t\t\tfor (const unregister of unregisterCallbacks) {\n\t\t\t\tunregister();\n\t\t\t}\n\t\t},\n\t};\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAAqC;AAqBrC,6BAMO;AAEP,kBAAiB;AACjB,gCAAyD;
|
|
6
|
-
"names": ["mitt"]
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase64, toBase64 } from '@mysten/sui/utils';\nimport type {\n\tIdentifierString,\n\tStandardConnectFeature,\n\tStandardConnectMethod,\n\tStandardDisconnectFeature,\n\tStandardDisconnectMethod,\n\tStandardEventsFeature,\n\tStandardEventsListeners,\n\tStandardEventsOnMethod,\n\tSuiSignAndExecuteTransactionFeature,\n\tSuiSignAndExecuteTransactionMethod,\n\tSuiSignPersonalMessageFeature,\n\tSuiSignPersonalMessageMethod,\n\tSuiSignTransactionBlockFeature,\n\tSuiSignTransactionBlockMethod,\n\tSuiSignTransactionFeature,\n\tSuiSignTransactionMethod,\n\tWallet,\n\tWalletIcon,\n} from '@mysten/wallet-standard';\nimport {\n\tgetWallets,\n\tReadonlyWalletAccount,\n\tSUI_DEVNET_CHAIN,\n\tSUI_MAINNET_CHAIN,\n\tSUI_TESTNET_CHAIN,\n} from '@mysten/wallet-standard';\nimport type { Emitter } from 'mitt';\nimport mitt from 'mitt';\nimport { DappPostMessageChannel, decodeJwtSession } from '@mysten/window-wallet-core';\nimport { promiseWithResolvers } from '@mysten/utils';\n\nimport '../components/modal.js';\n\nexport type SupportedNetwork = 'mainnet' | 'testnet' | 'devnet';\n\ntype WalletEventsMap = {\n\t[E in keyof StandardEventsListeners]: Parameters<StandardEventsListeners[E]>[0];\n};\n\nconst SUPPORTED_CHAINS = [SUI_MAINNET_CHAIN, SUI_TESTNET_CHAIN, SUI_DEVNET_CHAIN] as const;\nconst ACCOUNT_FEATURES = [\n\t'sui:signTransaction',\n\t'sui:signAndExecuteTransaction',\n\t'sui:signPersonalMessage',\n\t'sui:signTransactionBlock',\n\t'sui:signAndExecuteTransactionBlock',\n] as const;\n\nexport class EnokiConnectWallet implements Wallet {\n\treadonly id: string;\n\t#events: Emitter<WalletEventsMap>;\n\t#accounts: ReadonlyWalletAccount[];\n\t#hostOrigin: string;\n\t#walletName: string;\n\t#dappName: string;\n\t#icon: WalletIcon;\n\t#defaultChain: IdentifierString;\n\t#publicAppSlug: string;\n\n\tget name() {\n\t\treturn this.#walletName;\n\t}\n\n\tget icon() {\n\t\treturn this.#icon;\n\t}\n\n\tget version() {\n\t\treturn '1.0.0' as const;\n\t}\n\n\tget chains() {\n\t\treturn SUPPORTED_CHAINS;\n\t}\n\n\tget accounts() {\n\t\treturn this.#accounts;\n\t}\n\n\tget features(): StandardConnectFeature &\n\t\tStandardDisconnectFeature &\n\t\tStandardEventsFeature &\n\t\tSuiSignTransactionBlockFeature &\n\t\tSuiSignTransactionFeature &\n\t\tSuiSignPersonalMessageFeature &\n\t\tSuiSignAndExecuteTransactionFeature {\n\t\treturn {\n\t\t\t'standard:connect': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tconnect: this.#connect,\n\t\t\t},\n\t\t\t'standard:disconnect': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tdisconnect: this.#disconnect,\n\t\t\t},\n\t\t\t'standard:events': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\ton: this.#on,\n\t\t\t},\n\t\t\t'sui:signTransactionBlock': {\n\t\t\t\tversion: '1.0.0',\n\t\t\t\tsignTransactionBlock: this.#signTransactionBlock,\n\t\t\t},\n\t\t\t'sui:signTransaction': {\n\t\t\t\tversion: '2.0.0',\n\t\t\t\tsignTransaction: this.#signTransaction,\n\t\t\t},\n\t\t\t'sui:signPersonalMessage': {\n\t\t\t\tversion: '1.1.0',\n\t\t\t\tsignPersonalMessage: this.#signPersonalMessage,\n\t\t\t},\n\t\t\t'sui:signAndExecuteTransaction': {\n\t\t\t\tversion: '2.0.0',\n\t\t\t\tsignAndExecuteTransaction: this.#signAndExecuteTransaction,\n\t\t\t},\n\t\t};\n\t}\n\n\tconstructor({\n\t\tpublicAppSlug,\n\t\twalletName,\n\t\tdappName,\n\t\thostOrigin,\n\t\ticon,\n\t\tnetwork,\n\t}: {\n\t\tpublicAppSlug: string;\n\t\twalletName: string;\n\t\tdappName: string;\n\t\tnetwork: SupportedNetwork;\n\t\thostOrigin: string;\n\t\ticon: WalletIcon;\n\t}) {\n\t\tthis.#accounts = [];\n\t\tthis.#events = mitt();\n\t\tthis.#hostOrigin = hostOrigin;\n\t\tthis.#walletName = walletName;\n\t\tthis.#dappName = dappName;\n\t\tthis.#icon = icon;\n\t\tthis.#defaultChain = `sui:${network}`;\n\t\tthis.#publicAppSlug = publicAppSlug;\n\t\tthis.id = `enoki-connect-${publicAppSlug}`;\n\t}\n\n\t#signTransactionBlock: SuiSignTransactionBlockMethod = async ({\n\t\ttransactionBlock,\n\t\taccount,\n\t\tchain,\n\t}) => {\n\t\tconst popup = await this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'sign-transaction',\n\t\t\tchain,\n\t\t\ttransaction: await transactionBlock.toJSON(),\n\t\t\taddress: account.address,\n\t\t\tsession: this.#getStoredSession(),\n\t\t});\n\n\t\treturn {\n\t\t\ttransactionBlockBytes: response.bytes,\n\t\t\tsignature: response.signature,\n\t\t};\n\t};\n\n\t#signTransaction: SuiSignTransactionMethod = async ({ transaction, account, chain }) => {\n\t\tconst popup = await this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'sign-transaction',\n\t\t\tchain,\n\t\t\ttransaction: await transaction.toJSON(),\n\t\t\taddress: account.address,\n\t\t\tsession: this.#getStoredSession(),\n\t\t});\n\n\t\treturn {\n\t\t\tbytes: response.bytes,\n\t\t\tsignature: response.signature,\n\t\t};\n\t};\n\n\t#signAndExecuteTransaction: SuiSignAndExecuteTransactionMethod = async ({\n\t\ttransaction,\n\t\taccount,\n\t\tchain,\n\t}) => {\n\t\tconst popup = await this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'sign-and-execute-transaction',\n\t\t\ttransaction: await transaction.toJSON(),\n\t\t\taddress: account.address,\n\t\t\tchain,\n\t\t\tsession: this.#getStoredSession(),\n\t\t});\n\n\t\treturn {\n\t\t\tbytes: response.bytes,\n\t\t\tsignature: response.signature,\n\t\t\tdigest: response.digest,\n\t\t\teffects: response.effects,\n\t\t};\n\t};\n\n\t#signPersonalMessage: SuiSignPersonalMessageMethod = async ({ message, account, chain }) => {\n\t\tconst popup = await this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'sign-personal-message',\n\t\t\tchain: chain ?? this.#defaultChain,\n\t\t\tmessage: toBase64(message),\n\t\t\taddress: account.address,\n\t\t\tsession: this.#getStoredSession(),\n\t\t});\n\n\t\treturn {\n\t\t\tbytes: response.bytes,\n\t\t\tsignature: response.signature,\n\t\t};\n\t};\n\n\t#on: StandardEventsOnMethod = (event, listener) => {\n\t\tthis.#events.on(event, listener);\n\n\t\treturn () => this.#events.off(event, listener);\n\t};\n\n\t#setAccounts(session?: string) {\n\t\tif (session) {\n\t\t\tthis.#accounts = this.#getAccountsFromSession(session);\n\t\t\tlocalStorage.setItem(this.#getSessionKey(), session);\n\t\t} else {\n\t\t\tthis.#accounts = [];\n\t\t}\n\n\t\tthis.#events.emit('change', { accounts: this.accounts });\n\t}\n\n\t#connect: StandardConnectMethod = async (input) => {\n\t\tif (input?.silent) {\n\t\t\ttry {\n\t\t\t\tconst session = this.#getStoredSession();\n\n\t\t\t\tif (session) {\n\t\t\t\t\tthis.#setAccounts(session);\n\t\t\t\t}\n\t\t\t} catch (_e) {\n\t\t\t\t// ignore\n\t\t\t}\n\n\t\t\treturn { accounts: this.accounts };\n\t\t}\n\n\t\tconst popup = await this.#getNewPopupChannel();\n\t\tconst response = await popup.send({\n\t\t\ttype: 'connect',\n\t\t});\n\n\t\tthis.#setAccounts(response.session);\n\n\t\treturn { accounts: this.accounts };\n\t};\n\n\t#disconnect: StandardDisconnectMethod = async () => {\n\t\tlocalStorage.removeItem(this.#getSessionKey());\n\t\tthis.#setAccounts();\n\t};\n\n\t#getSessionKey() {\n\t\treturn `enoki-connect-${this.#publicAppSlug}:session`;\n\t}\n\n\t#getStoredSession() {\n\t\tconst session = localStorage.getItem(this.#getSessionKey());\n\n\t\tif (!session) {\n\t\t\tthrow new Error('No session found');\n\t\t}\n\n\t\treturn session;\n\t}\n\n\tasync #getNewPopupChannel() {\n\t\tlet popupWindow: Window | undefined | null = window.open('about:blank', '_blank');\n\n\t\tif (!popupWindow) {\n\t\t\tpopupWindow = await addClickToOpenPopupWindow({\n\t\t\t\twalletName: this.#walletName,\n\t\t\t\tdappName: this.#dappName,\n\t\t\t});\n\t\t}\n\n\t\treturn new DappPostMessageChannel({\n\t\t\tappName: this.#dappName,\n\t\t\thostOrigin: this.#hostOrigin,\n\t\t\textraRequestOptions: {\n\t\t\t\tpublicAppSlug: this.#publicAppSlug,\n\t\t\t},\n\t\t\tpopupWindow,\n\t\t});\n\t}\n\n\t#getAccountsFromSession(session: string) {\n\t\ttry {\n\t\t\tconst {\n\t\t\t\tpayload: { accounts },\n\t\t\t} = decodeJwtSession(session);\n\n\t\t\treturn accounts.map(\n\t\t\t\t(anAccount) =>\n\t\t\t\t\tnew ReadonlyWalletAccount({\n\t\t\t\t\t\taddress: anAccount.address,\n\t\t\t\t\t\tchains: SUPPORTED_CHAINS,\n\t\t\t\t\t\tfeatures: ACCOUNT_FEATURES,\n\t\t\t\t\t\tpublicKey: fromBase64(anAccount.publicKey),\n\t\t\t\t\t}),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\treturn [];\n\t\t}\n\t}\n}\n\nfunction addClickToOpenPopupWindow({\n\twalletName,\n\tdappName,\n}: {\n\twalletName: string;\n\tdappName: string;\n}) {\n\tconst { promise, resolve, reject } = promiseWithResolvers<Window>();\n\tconst modal = document.createElement('enoki-connect-modal');\n\n\tmodal.walletName = walletName;\n\tmodal.dappName = dappName;\n\tmodal.open = true;\n\n\tmodal.addEventListener('cancel', () => {\n\t\treject(new Error('Popup was blocked from browser and user rejected click to review request'));\n\t\tmodal.open = false;\n\t});\n\n\tmodal.addEventListener('approved', () => {\n\t\tmodal.disabled = true;\n\t\tmodal.open = false;\n\n\t\tconst popup = window.open('about:blank', '_blank');\n\n\t\tif (popup) {\n\t\t\tresolve(popup);\n\t\t} else {\n\t\t\treject(new Error('Failed to open popup'));\n\t\t}\n\t});\n\n\tmodal.addEventListener('closed', () => {\n\t\tmodal.remove();\n\t});\n\n\tdocument.body.appendChild(modal);\n\n\treturn promise;\n}\n\ntype EnokiConnectMetadata = {\n\tpublicAppSlug: string;\n\tname: string;\n\tlogoUrl: WalletIcon;\n\tappUrl: string;\n};\n\nasync function getEnokiConnectMetadata(publicAppSlugs: string[], enokiApiUrl: string) {\n\tconst sortedPublicAppSlugs = [...publicAppSlugs].sort();\n\tconst queryParams = new URLSearchParams();\n\n\tfor (const publicAppSlug of sortedPublicAppSlugs) {\n\t\tqueryParams.append('slugs', publicAppSlug);\n\t}\n\n\tqueryParams.sort();\n\n\tconst res = await fetch(new URL(`/v1/connect/metadata?${queryParams.toString()}`, enokiApiUrl));\n\n\tif (!res.ok) {\n\t\tthrow new Error('Failed to fetch enoki connect metadata');\n\t}\n\n\tconst { data } = await res.json();\n\n\treturn data as EnokiConnectMetadata[];\n}\n\n/**\n * Registers Enoki Connect wallets for your dApp.\n *\n * This function fetches wallet metadata for the provided public app slugs and registers\n * them with the wallet standard. It returns the registered wallet instances and an\n * `unregister` function to remove them if needed.\n *\n * @param publicAppSlugs - An array of public app slugs to register. You can obtain these slugs from the wallet developer.\n * @param dappName - The display name of your dApp. This will be shown to users in wallet UIs.\n * @param network - (Optional) The default Sui network to use for wallet operations (when chain is not specified in the wallet method). Accepts 'mainnet', 'testnet', or 'devnet'. Defaults to 'mainnet' if not specified.\n * @param enokiApiUrl - (Optional) The Enoki API endpoint to use for fetching wallet metadata. Defaults to the public Enoki API at 'https://api.enoki.mystenlabs.com'. (Override this if you are running a local or custom Enoki API instance.)\n *\n * @returns An object containing:\n * - `wallets`: The array of registered EnokiConnectWallet instances.\n * - `unregister`: A function to unregister all registered wallets.\n *\n * @example\n * ```ts\n * const { wallets, unregister } = await registerEnokiConnectWallets({\n * publicAppSlugs: ['an-app-slug'],\n * dappName: 'My Dapp',\n * });\n * ```\n */\nexport async function registerEnokiConnectWallets({\n\tpublicAppSlugs,\n\tdappName,\n\tnetwork = 'mainnet',\n\tenokiApiUrl = 'https://api.enoki.mystenlabs.com',\n}: {\n\tpublicAppSlugs: string[];\n\tdappName: string;\n\tnetwork?: SupportedNetwork;\n\tenokiApiUrl?: string;\n}) {\n\tconst wallets = getWallets();\n\tconst data = await getEnokiConnectMetadata(publicAppSlugs, enokiApiUrl);\n\tconst unregisterCallbacks: (() => void)[] = [];\n\tconst registeredWallets: EnokiConnectWallet[] = [];\n\n\tfor (const aWalletMetadata of data) {\n\t\tconst wallet = new EnokiConnectWallet({\n\t\t\twalletName: aWalletMetadata.name,\n\t\t\tdappName,\n\t\t\thostOrigin: aWalletMetadata.appUrl,\n\t\t\ticon: aWalletMetadata.logoUrl,\n\t\t\tnetwork,\n\t\t\tpublicAppSlug: aWalletMetadata.publicAppSlug,\n\t\t});\n\t\tconst unregister = wallets.register(wallet);\n\n\t\tunregisterCallbacks.push(unregister);\n\t\tregisteredWallets.push(wallet);\n\t}\n\n\treturn {\n\t\twallets: registeredWallets,\n\t\tunregister: () => {\n\t\t\tfor (const unregister of unregisterCallbacks) {\n\t\t\t\tunregister();\n\t\t\t}\n\t\t},\n\t};\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_utils", "mitt"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import type { PropertyValues } from 'lit';
|
|
3
|
+
import type { PromiseWithResolvers } from '@mysten/utils';
|
|
4
|
+
export declare class BaseModal extends LitElement {
|
|
5
|
+
#private;
|
|
6
|
+
static shadowRootOptions: {
|
|
7
|
+
delegatesFocus: boolean;
|
|
8
|
+
clonable?: boolean;
|
|
9
|
+
customElementRegistry?: CustomElementRegistry;
|
|
10
|
+
mode: ShadowRootMode;
|
|
11
|
+
serializable?: boolean;
|
|
12
|
+
slotAssignment?: SlotAssignmentMode;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Opens the dialog when set to `true` and closes it when set to `false`.
|
|
16
|
+
*/
|
|
17
|
+
get open(): boolean;
|
|
18
|
+
set open(open: boolean);
|
|
19
|
+
disabled: boolean;
|
|
20
|
+
private readonly _dialog;
|
|
21
|
+
protected _closingResolvers?: PromiseWithResolvers<void>;
|
|
22
|
+
protected get _isClosing(): boolean;
|
|
23
|
+
firstUpdated(changedProperties: PropertyValues): void;
|
|
24
|
+
/**
|
|
25
|
+
* Opens the dialog and fires a cancelable `open` event. An `opened` event
|
|
26
|
+
* is fired after the dialog opens.
|
|
27
|
+
*
|
|
28
|
+
* @return A `Promise` that resolves after the `opened` event was fired.
|
|
29
|
+
*/
|
|
30
|
+
show(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Closes the dialog and fires a cancelable `close` event. After a dialog's
|
|
33
|
+
* animation, a `closed` event is fired.
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
close(): Promise<void>;
|
|
37
|
+
protected handleAnimationEnd(e: AnimationEvent): void;
|
|
38
|
+
connectedCallback(): void;
|
|
39
|
+
disconnectedCallback(): void;
|
|
40
|
+
protected handleContentClick(): void;
|
|
41
|
+
protected handleDialogClick(): void;
|
|
42
|
+
protected handleCancel(e?: Event): void;
|
|
43
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __typeError = (msg) => {
|
|
4
|
+
throw TypeError(msg);
|
|
5
|
+
};
|
|
6
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
7
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
8
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
9
|
+
if (decorator = decorators[i])
|
|
10
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
11
|
+
if (kind && result) __defProp(target, key, result);
|
|
12
|
+
return result;
|
|
13
|
+
};
|
|
14
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
15
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
16
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
17
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
18
|
+
var _isOpen, _isOpening, _isConnected, _nextClickIsFromContent, _keyDownHandler;
|
|
19
|
+
import { LitElement } from "lit";
|
|
20
|
+
import { property, query, state } from "lit/decorators.js";
|
|
21
|
+
import { promiseWithResolvers } from "@mysten/utils";
|
|
22
|
+
class BaseModal extends LitElement {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
__privateAdd(this, _isOpen, false);
|
|
26
|
+
__privateAdd(this, _isOpening, false);
|
|
27
|
+
__privateAdd(this, _isConnected, promiseWithResolvers());
|
|
28
|
+
__privateAdd(this, _nextClickIsFromContent, false);
|
|
29
|
+
this.disabled = false;
|
|
30
|
+
__privateAdd(this, _keyDownHandler, (e) => {
|
|
31
|
+
if (e.key === "Escape" && this.open) {
|
|
32
|
+
this.handleCancel(e);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
get open() {
|
|
37
|
+
return __privateGet(this, _isOpen);
|
|
38
|
+
}
|
|
39
|
+
set open(open) {
|
|
40
|
+
if (open === __privateGet(this, _isOpen)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
__privateSet(this, _isOpen, open);
|
|
44
|
+
if (__privateGet(this, _isOpen)) {
|
|
45
|
+
this.setAttribute("open", "");
|
|
46
|
+
this.show();
|
|
47
|
+
} else {
|
|
48
|
+
this.removeAttribute("open");
|
|
49
|
+
this.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
get _isClosing() {
|
|
53
|
+
return !!this._closingResolvers;
|
|
54
|
+
}
|
|
55
|
+
firstUpdated(changedProperties) {
|
|
56
|
+
super.firstUpdated(changedProperties);
|
|
57
|
+
this._dialog.addEventListener("keydown", __privateGet(this, _keyDownHandler), { capture: true });
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Opens the dialog and fires a cancelable `open` event. An `opened` event
|
|
61
|
+
* is fired after the dialog opens.
|
|
62
|
+
*
|
|
63
|
+
* @return A `Promise` that resolves after the `opened` event was fired.
|
|
64
|
+
*/
|
|
65
|
+
async show() {
|
|
66
|
+
this._closingResolvers?.resolve();
|
|
67
|
+
this._closingResolvers = void 0;
|
|
68
|
+
__privateSet(this, _isOpening, true);
|
|
69
|
+
await __privateGet(this, _isConnected).promise;
|
|
70
|
+
await this.updateComplete;
|
|
71
|
+
if (this._dialog.open || !__privateGet(this, _isOpening)) {
|
|
72
|
+
__privateSet(this, _isOpening, false);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const wasDispatched = this.dispatchEvent(new Event("open", { cancelable: true }));
|
|
76
|
+
if (!wasDispatched) {
|
|
77
|
+
this.open = false;
|
|
78
|
+
__privateSet(this, _isOpening, false);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this._dialog.showModal();
|
|
82
|
+
this.open = true;
|
|
83
|
+
this.dispatchEvent(new Event("opened"));
|
|
84
|
+
__privateSet(this, _isOpening, false);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Closes the dialog and fires a cancelable `close` event. After a dialog's
|
|
88
|
+
* animation, a `closed` event is fired.
|
|
89
|
+
*
|
|
90
|
+
*/
|
|
91
|
+
async close() {
|
|
92
|
+
if (this._closingResolvers) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
__privateSet(this, _isOpening, false);
|
|
96
|
+
if (!this.isConnected) {
|
|
97
|
+
this.open = false;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
await this.updateComplete;
|
|
101
|
+
if (!this._dialog.open || __privateGet(this, _isOpening)) {
|
|
102
|
+
this.open = false;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const wasDispatched = this.dispatchEvent(new Event("close", { cancelable: true }));
|
|
106
|
+
if (!wasDispatched) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
this._closingResolvers = promiseWithResolvers();
|
|
110
|
+
this.open = false;
|
|
111
|
+
return this._closingResolvers.promise;
|
|
112
|
+
}
|
|
113
|
+
handleAnimationEnd(e) {
|
|
114
|
+
if (e.animationName === "fadeOut" && !this.open && this._dialog.open && this._closingResolvers) {
|
|
115
|
+
this._closingResolvers.resolve();
|
|
116
|
+
this._closingResolvers = void 0;
|
|
117
|
+
this._dialog.close();
|
|
118
|
+
this.dispatchEvent(new Event("closed"));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
connectedCallback() {
|
|
122
|
+
super.connectedCallback();
|
|
123
|
+
__privateGet(this, _isConnected).resolve();
|
|
124
|
+
}
|
|
125
|
+
disconnectedCallback() {
|
|
126
|
+
super.disconnectedCallback();
|
|
127
|
+
__privateSet(this, _isConnected, Promise.withResolvers());
|
|
128
|
+
this._dialog.removeEventListener("keydown", __privateGet(this, _keyDownHandler), { capture: true });
|
|
129
|
+
}
|
|
130
|
+
handleContentClick() {
|
|
131
|
+
__privateSet(this, _nextClickIsFromContent, true);
|
|
132
|
+
}
|
|
133
|
+
handleDialogClick() {
|
|
134
|
+
if (__privateGet(this, _nextClickIsFromContent)) {
|
|
135
|
+
__privateSet(this, _nextClickIsFromContent, false);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
this.handleCancel();
|
|
139
|
+
}
|
|
140
|
+
handleCancel(e) {
|
|
141
|
+
if (this.disabled || this._closingResolvers) {
|
|
142
|
+
e?.preventDefault();
|
|
143
|
+
e?.stopPropagation();
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const wasDispatched = this.dispatchEvent(new Event("cancel", { cancelable: true }));
|
|
147
|
+
if (!wasDispatched) {
|
|
148
|
+
e?.preventDefault();
|
|
149
|
+
e?.stopPropagation();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
this.close();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
_isOpen = new WeakMap();
|
|
156
|
+
_isOpening = new WeakMap();
|
|
157
|
+
_isConnected = new WeakMap();
|
|
158
|
+
_nextClickIsFromContent = new WeakMap();
|
|
159
|
+
_keyDownHandler = new WeakMap();
|
|
160
|
+
BaseModal.shadowRootOptions = {
|
|
161
|
+
...LitElement.shadowRootOptions,
|
|
162
|
+
delegatesFocus: true
|
|
163
|
+
};
|
|
164
|
+
__decorateClass([
|
|
165
|
+
property({ type: Boolean })
|
|
166
|
+
], BaseModal.prototype, "open", 1);
|
|
167
|
+
__decorateClass([
|
|
168
|
+
property()
|
|
169
|
+
], BaseModal.prototype, "disabled", 2);
|
|
170
|
+
__decorateClass([
|
|
171
|
+
query("dialog")
|
|
172
|
+
], BaseModal.prototype, "_dialog", 2);
|
|
173
|
+
__decorateClass([
|
|
174
|
+
state()
|
|
175
|
+
], BaseModal.prototype, "_closingResolvers", 2);
|
|
176
|
+
export {
|
|
177
|
+
BaseModal
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=base-modal.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/components/base-modal.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { LitElement } from 'lit';\nimport type { PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { promiseWithResolvers } from '@mysten/utils';\nimport type { PromiseWithResolvers } from '@mysten/utils';\n\nexport class BaseModal extends LitElement {\n\t#isOpen = false;\n\t#isOpening = false;\n\t#isConnected = promiseWithResolvers<void>();\n\t#nextClickIsFromContent = false;\n\n\tstatic override shadowRootOptions = {\n\t\t...LitElement.shadowRootOptions,\n\t\tdelegatesFocus: true,\n\t};\n\n\t/**\n\t * Opens the dialog when set to `true` and closes it when set to `false`.\n\t */\n\t@property({ type: Boolean })\n\tget open() {\n\t\treturn this.#isOpen;\n\t}\n\n\tset open(open: boolean) {\n\t\tif (open === this.#isOpen) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#isOpen = open;\n\t\tif (this.#isOpen) {\n\t\t\tthis.setAttribute('open', '');\n\t\t\tthis.show();\n\t\t} else {\n\t\t\tthis.removeAttribute('open');\n\t\t\tthis.close();\n\t\t}\n\t}\n\t@property()\n\tdisabled: boolean = false;\n\n\t@query('dialog')\n\tprivate readonly _dialog!: HTMLDialogElement;\n\n\t@state()\n\tprotected _closingResolvers?: PromiseWithResolvers<void>;\n\n\t#keyDownHandler = (e: KeyboardEvent) => {\n\t\tif (e.key === 'Escape' && this.open) {\n\t\t\tthis.handleCancel(e);\n\t\t}\n\t};\n\n\tprotected get _isClosing() {\n\t\treturn !!this._closingResolvers;\n\t}\n\n\toverride firstUpdated(changedProperties: PropertyValues) {\n\t\tsuper.firstUpdated(changedProperties);\n\t\t// NOTE: there is a bug in Chrome where even after canceling the dialog cancel event still closes the dialog. (The second time the user clicks escape)\n\t\t// Using this handler to mitigate this issue.\n\t\tthis._dialog.addEventListener('keydown', this.#keyDownHandler, { capture: true });\n\t}\n\n\t/**\n\t * Opens the dialog and fires a cancelable `open` event. An `opened` event\n\t * is fired after the dialog opens.\n\t *\n\t * @return A `Promise` that resolves after the `opened` event was fired.\n\t */\n\tasync show() {\n\t\tthis._closingResolvers?.resolve();\n\t\tthis._closingResolvers = undefined;\n\t\tthis.#isOpening = true;\n\n\t\t// Dialogs can be opened before being attached to the DOM, so we need to\n\t\t// wait until we're connected before calling `showModal()`.\n\t\tawait this.#isConnected.promise;\n\t\tawait this.updateComplete;\n\n\t\t// Check if already opened or if `dialog.close()` was called while awaiting.\n\t\tif (this._dialog.open || !this.#isOpening) {\n\t\t\tthis.#isOpening = false;\n\t\t\treturn;\n\t\t}\n\n\t\tconst wasDispatched = this.dispatchEvent(new Event('open', { cancelable: true }));\n\t\tif (!wasDispatched) {\n\t\t\tthis.open = false;\n\t\t\tthis.#isOpening = false;\n\t\t\treturn;\n\t\t}\n\n\t\tthis._dialog.showModal();\n\t\tthis.open = true;\n\n\t\tthis.dispatchEvent(new Event('opened'));\n\t\tthis.#isOpening = false;\n\t}\n\n\t/**\n\t * Closes the dialog and fires a cancelable `close` event. After a dialog's\n\t * animation, a `closed` event is fired.\n\t *\n\t */\n\tasync close() {\n\t\tif (this._closingResolvers) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#isOpening = false;\n\n\t\tif (!this.isConnected) {\n\t\t\t// Disconnected dialogs do not fire close events or animate.\n\t\t\tthis.open = false;\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.updateComplete;\n\n\t\t// Check if already closed or if `dialog.show()` was called while awaiting.\n\t\tif (!this._dialog.open || this.#isOpening) {\n\t\t\tthis.open = false;\n\t\t\treturn;\n\t\t}\n\n\t\tconst wasDispatched = this.dispatchEvent(new Event('close', { cancelable: true }));\n\t\tif (!wasDispatched) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._closingResolvers = promiseWithResolvers<void>();\n\t\tthis.open = false;\n\n\t\treturn this._closingResolvers.promise;\n\t}\n\n\tprotected handleAnimationEnd(e: AnimationEvent) {\n\t\tif (\n\t\t\te.animationName === 'fadeOut' &&\n\t\t\t!this.open &&\n\t\t\tthis._dialog.open &&\n\t\t\tthis._closingResolvers\n\t\t) {\n\t\t\tthis._closingResolvers.resolve();\n\t\t\tthis._closingResolvers = undefined;\n\t\t\tthis._dialog.close();\n\t\t\tthis.dispatchEvent(new Event('closed'));\n\t\t}\n\t}\n\n\toverride connectedCallback() {\n\t\tsuper.connectedCallback();\n\t\tthis.#isConnected.resolve();\n\t}\n\n\toverride disconnectedCallback() {\n\t\tsuper.disconnectedCallback();\n\t\tthis.#isConnected = Promise.withResolvers<void>();\n\t\tthis._dialog.removeEventListener('keydown', this.#keyDownHandler, { capture: true });\n\t}\n\n\tprotected handleContentClick() {\n\t\tthis.#nextClickIsFromContent = true;\n\t}\n\n\tprotected handleDialogClick() {\n\t\tif (this.#nextClickIsFromContent) {\n\t\t\t// This trick uses event bubbling to determine whether or not the click originated\n\t\t\t// from the dialog content or dialog backdrop psuedo-element. If you click the dialog\n\t\t\t// content, then `nextClickIsFromContent` will be set to true and we'll early exit.\n\t\t\tthis.#nextClickIsFromContent = false;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.handleCancel();\n\t}\n\n\tprotected handleCancel(e?: Event) {\n\t\tif (this.disabled || this._closingResolvers) {\n\t\t\te?.preventDefault();\n\t\t\te?.stopPropagation();\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst wasDispatched = this.dispatchEvent(new Event('cancel', { cancelable: true }));\n\n\t\tif (!wasDispatched) {\n\t\t\te?.preventDefault();\n\t\t\te?.stopPropagation();\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.close();\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseModal } from './base-modal.js';
|
|
2
|
+
/**
|
|
3
|
+
* A modal component for displaying wallet operation request fallback UI.
|
|
4
|
+
*
|
|
5
|
+
* @element enoki-connect-modal
|
|
6
|
+
*
|
|
7
|
+
* @prop {string} walletName - The name of the wallet.
|
|
8
|
+
* @prop {string} dappName - The name of the dapp.
|
|
9
|
+
* @prop {boolean} disabled - Whether the modal is disabled.
|
|
10
|
+
* @prop {boolean} open - Whether the modal is open.
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
export declare class EnokiConnectModal extends BaseModal {
|
|
14
|
+
#private;
|
|
15
|
+
static styles: import("lit").CSSResult;
|
|
16
|
+
walletName: string;
|
|
17
|
+
dappName: string;
|
|
18
|
+
render(): import("lit").TemplateResult<1>;
|
|
19
|
+
}
|
|
20
|
+
declare global {
|
|
21
|
+
interface HTMLElementTagNameMap {
|
|
22
|
+
'enoki-connect-modal': EnokiConnectModal;
|
|
23
|
+
}
|
|
24
|
+
}
|