@mysten/slush-wallet
Version:
Wallet adapter for Slush web wallet
340 lines (339 loc) • 14 kB
JavaScript
"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