UNPKG

@mysten/slush-wallet

Version:
340 lines (339 loc) 14 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __typeError = (msg) => { throw TypeError(msg); }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); 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); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); var wallet_exports = {}; __export(wallet_exports, { SLUSH_WALLET_NAME: () => SLUSH_WALLET_NAME, SlushWallet: () => SlushWallet, registerSlushWallet: () => registerSlushWallet }); module.exports = __toCommonJS(wallet_exports); var import_utils = require("@mysten/sui/utils"); var import_wallet_standard = require("@mysten/wallet-standard"); var import_mitt = __toESM(require("mitt")); var import_valibot = require("valibot"); var import_window_wallet_core = require("@mysten/window-wallet-core"); var _id, _events, _accounts, _origin, _walletName, _icon, _name, _signTransactionBlock, _signTransaction, _signAndExecuteTransaction, _signPersonalMessage, _on, _SlushWallet_instances, setAccounts_fn, _connect, getPreviouslyAuthorizedAccounts_fn, _disconnect, getNewPopupChannel_fn; const DEFAULT_SLUSH_ORIGIN = "https://my.slush.app"; const SLUSH_SESSION_KEY = "slush:session"; const SLUSH_WALLET_NAME = "Slush"; const SUI_WALLET_EXTENSION_ID = "com.mystenlabs.suiwallet"; const METADATA_API_URL = "https://api.slush.app/api/wallet/metadata"; const FALLBACK_METADATA = { id: "com.mystenlabs.suiwallet.web", walletName: "Slush", description: "Trade and earn on Sui.", icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIHZpZXdCb3g9IjAgMCA1MCA1MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjUwIiBoZWlnaHQ9IjUwIiBmaWxsPSIjNENBMkZGIi8+CjxwYXRoIGQ9Ik0xMi4zNDczIDM0LjcyNTRDMTMuNTU1MyAzOS4yMzM2IDE4LjA2NzMgNDMuMzE0OCAyNy40MDI1IDQwLjgxMzRDMzYuMzA5NyAzOC40MjY3IDQxLjg5MjEgMzEuMDk5MyA0MC40NDQ2IDI1LjY5NzJDMzkuOTQ0NyAyMy44MzE3IDM4LjQzOTEgMjIuNTY4OSAzNi4xMTc4IDIyLjc3NDRMMTUuMzYxNSAyNC41MDM4QzE0LjA1NDQgMjQuNjA0MSAxMy40NTUgMjQuMzg5OCAxMy4xMDkyIDIzLjU2NjFDMTIuNzczOCAyMi43ODEyIDEyLjk2NDkgMjEuOTM4NSAxNC41NDM3IDIxLjE0MDZMMzAuMzM5NiAxMy4wMzQyQzMxLjU1MDMgMTIuNDE4MiAzMi4zNTY3IDEyLjE2MDUgMzMuMDkzNiAxMi40MjEzQzMzLjU1NTUgMTIuNTg5MSAzMy44NTk2IDEzLjI1NzQgMzMuNTgwMyAxNC4wODJMMzIuNTU2MSAxNy4xMDU2QzMxLjI5OTIgMjAuODE2NCAzMy45ODk5IDIxLjY3ODQgMzUuNTA2OCAyMS4yNzE5QzM3LjgwMTcgMjAuNjU3IDM4LjM0MTYgMTguNDcxMiAzNy42MDIzIDE1LjcxMTlDMzUuNzI3OCA4LjcxNjI5IDI4LjMwNTkgNy42MjI1NCAyMS41NzY4IDkuNDI1NTlDMTQuNzMxMSAxMS4yNTk5IDguNzk2ODEgMTYuODA3MiAxMC42MDg4IDIzLjU2OTZDMTEuMDM1OCAyNS4xNjMgMTIuNTAyNSAyNi40MzYyIDE0LjIwMTQgMjYuMzk3NUwxNi43OTUgMjYuMzkxMkMxNy4zMjg0IDI2LjM3ODggMTcuMTM2MyAyNi40MjI3IDE4LjE2NTMgMjYuMzM3NEMxOS4xOTQ0IDI2LjI1MjIgMjEuOTQyNSAyNS45MTQgMjEuOTQyNSAyNS45MTRMMzUuNDI3NSAyNC4zODhMMzUuNzc1IDI0LjMzNzVDMzYuNTYzNyAyNC4yMDMgMzcuMTU5NyAyNC40MDc5IDM3LjY2MzYgMjUuMjc2QzM4LjQxNzcgMjYuNTc1IDM3LjI2NzIgMjcuNTU0NiAzNS44ODk5IDI4LjcyNzJDMzUuODUzIDI4Ljc1ODYgMzUuODE2IDI4Ljc5MDEgMzUuNzc4OSAyOC44MjE4TDIzLjkyNSAzOS4wMzc3QzIxLjg5MzMgNDAuNzkwMSAyMC40NjYgNDAuMTMxMSAxOS45NjYyIDM4LjI2NTZMMTguMTk1OCAzMS42NTg3QzE3Ljc1ODUgMzAuMDI2NCAxNi4xNjQ2IDI4Ljc0NTYgMTQuMjk3NiAyOS4yNDU5QzExLjk2MzggMjkuODcxMiAxMS43NzQ2IDMyLjU4NzggMTIuMzQ3MyAzNC43MjU0WiIgZmlsbD0iIzA2MEQxNCIvPgo8L3N2Zz4K", enabled: true }; const WalletMetadataSchema = (0, import_valibot.object)({ id: (0, import_valibot.string)("Wallet ID is required"), walletName: (0, import_valibot.string)("Wallet name is required"), icon: (0, import_valibot.string)("Icon must be a valid wallet icon format"), enabled: (0, import_valibot.boolean)("Enabled is required") }); function setSessionToStorage(session) { localStorage.setItem(SLUSH_SESSION_KEY, session); } function getSessionFromStorage() { const session = localStorage.getItem(SLUSH_SESSION_KEY); if (!session) { throw new Error("No session found"); } return session; } const walletAccountFeatures = [ "sui:signTransaction", "sui:signAndExecuteTransaction", "sui:signPersonalMessage", "sui:signTransactionBlock", "sui:signAndExecuteTransactionBlock" ]; function getAccountsFromSession(session) { const { payload } = (0, import_window_wallet_core.decodeJwtSession)(session); return payload.accounts.map((account) => { return new import_wallet_standard.ReadonlyWalletAccount({ address: account.address, chains: import_wallet_standard.SUI_CHAINS, features: walletAccountFeatures, publicKey: (0, import_utils.fromBase64)(account.publicKey) }); }); } class SlushWallet { constructor({ name, origin, metadata }) { __privateAdd(this, _SlushWallet_instances); __privateAdd(this, _id); __privateAdd(this, _events); __privateAdd(this, _accounts); __privateAdd(this, _origin); __privateAdd(this, _walletName); __privateAdd(this, _icon); __privateAdd(this, _name); __privateAdd(this, _signTransactionBlock, async ({ transactionBlock, account, chain }) => { const data = await transactionBlock.toJSON(); const popup = __privateMethod(this, _SlushWallet_instances, getNewPopupChannel_fn).call(this); const response = await popup.send({ type: "sign-transaction", transaction: data, address: account.address, chain, session: getSessionFromStorage() }); return { transactionBlockBytes: response.bytes, signature: response.signature }; }); __privateAdd(this, _signTransaction, async ({ transaction, account, chain }) => { const popup = __privateMethod(this, _SlushWallet_instances, getNewPopupChannel_fn).call(this); const tx = await transaction.toJSON(); const response = await popup.send({ type: "sign-transaction", transaction: tx, address: account.address, chain, session: getSessionFromStorage() }); return { bytes: response.bytes, signature: response.signature }; }); __privateAdd(this, _signAndExecuteTransaction, async ({ transaction, account, chain }) => { const popup = __privateMethod(this, _SlushWallet_instances, getNewPopupChannel_fn).call(this); const data = await transaction.toJSON(); const response = await popup.send({ type: "sign-and-execute-transaction", transaction: data, address: account.address, chain, session: getSessionFromStorage() }); return { bytes: response.bytes, signature: response.signature, digest: response.digest, effects: response.effects }; }); __privateAdd(this, _signPersonalMessage, async ({ message, account, chain }) => { const popup = __privateMethod(this, _SlushWallet_instances, getNewPopupChannel_fn).call(this); const response = await popup.send({ type: "sign-personal-message", message: (0, import_utils.toBase64)(message), address: account.address, chain: chain ?? account.chains[0], session: getSessionFromStorage() }); return { bytes: response.bytes, signature: response.signature }; }); __privateAdd(this, _on, (event, listener) => { __privateGet(this, _events).on(event, listener); return () => __privateGet(this, _events).off(event, listener); }); __privateAdd(this, _connect, async (input) => { if (input?.silent) { return { accounts: this.accounts }; } const popup = __privateMethod(this, _SlushWallet_instances, getNewPopupChannel_fn).call(this); const response = await popup.send({ type: "connect" }); setSessionToStorage(response.session); __privateMethod(this, _SlushWallet_instances, setAccounts_fn).call(this, getAccountsFromSession(response.session)); return { accounts: this.accounts }; }); __privateAdd(this, _disconnect, async () => { localStorage.removeItem(SLUSH_SESSION_KEY); __privateMethod(this, _SlushWallet_instances, setAccounts_fn).call(this, []); }); __privateSet(this, _id, metadata.id); __privateSet(this, _accounts, __privateMethod(this, _SlushWallet_instances, getPreviouslyAuthorizedAccounts_fn).call(this)); __privateSet(this, _events, (0, import_mitt.default)()); __privateSet(this, _origin, origin || DEFAULT_SLUSH_ORIGIN); __privateSet(this, _name, name); __privateSet(this, _walletName, metadata.walletName); __privateSet(this, _icon, metadata.icon); } get name() { return __privateGet(this, _walletName); } get id() { return __privateGet(this, _id); } get icon() { return __privateGet(this, _icon); } get version() { return "1.0.0"; } get chains() { return import_wallet_standard.SUI_CHAINS; } get accounts() { return __privateGet(this, _accounts); } get features() { return { "standard:connect": { version: "1.0.0", connect: __privateGet(this, _connect) }, "standard:disconnect": { version: "1.0.0", disconnect: __privateGet(this, _disconnect) }, "standard:events": { version: "1.0.0", on: __privateGet(this, _on) }, "sui:signTransactionBlock": { version: "1.0.0", signTransactionBlock: __privateGet(this, _signTransactionBlock) }, "sui:signTransaction": { version: "2.0.0", signTransaction: __privateGet(this, _signTransaction) }, "sui:signPersonalMessage": { version: "1.1.0", signPersonalMessage: __privateGet(this, _signPersonalMessage) }, "sui:signAndExecuteTransaction": { version: "2.0.0", signAndExecuteTransaction: __privateGet(this, _signAndExecuteTransaction) } }; } updateMetadata(metadata) { __privateSet(this, _id, metadata.id); __privateSet(this, _walletName, metadata.walletName); __privateSet(this, _icon, metadata.icon); } } _id = new WeakMap(); _events = new WeakMap(); _accounts = new WeakMap(); _origin = new WeakMap(); _walletName = new WeakMap(); _icon = new WeakMap(); _name = new WeakMap(); _signTransactionBlock = new WeakMap(); _signTransaction = new WeakMap(); _signAndExecuteTransaction = new WeakMap(); _signPersonalMessage = new WeakMap(); _on = new WeakMap(); _SlushWallet_instances = new WeakSet(); setAccounts_fn = function(accounts) { __privateSet(this, _accounts, accounts); __privateGet(this, _events).emit("change", { accounts: this.accounts }); }; _connect = new WeakMap(); getPreviouslyAuthorizedAccounts_fn = function() { try { return getAccountsFromSession(getSessionFromStorage()); } catch (error) { return []; } }; _disconnect = new WeakMap(); getNewPopupChannel_fn = function() { return new import_window_wallet_core.DappPostMessageChannel({ appName: __privateGet(this, _name), hostOrigin: __privateGet(this, _origin) }); }; async function fetchMetadata(metadataApiUrl) { const response = await fetch(metadataApiUrl); if (!response.ok) { throw new Error("Failed to fetch wallet metadata"); } const data = await response.json(); return (0, import_valibot.parse)(WalletMetadataSchema, data); } function registerSlushWallet(name, { origin, metadataApiUrl = METADATA_API_URL } = {}) { const wallets = (0, import_wallet_standard.getWallets)(); let unregister = null; wallets.on("register", (wallet) => { if (wallet.id === SUI_WALLET_EXTENSION_ID) { unregister?.(); } }); const extension = wallets.get().find((wallet) => wallet.id === SUI_WALLET_EXTENSION_ID); if (extension) { return; } const slushWalletInstance = new SlushWallet({ name, origin, metadata: FALLBACK_METADATA }); unregister = wallets.register(slushWalletInstance); fetchMetadata(metadataApiUrl).then((metadata) => { if (!metadata.enabled) { console.log("Slush wallet is not currently enabled."); unregister?.(); return; } slushWalletInstance.updateMetadata(metadata); }).catch((error) => { console.error("Error fetching metadata", error); }); return { wallet: slushWalletInstance, unregister }; } //# sourceMappingURL=index.js.map