better-near-auth
Version:
Sign in with NEAR (SIWN) plugin for Better Auth
1,594 lines (1,517 loc) • 79.2 kB
JavaScript
import { t as __commonJSMin } from "./client.js";
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/helpers/storage.js
var require_storage = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocalStorage = void 0;
var LocalStorage = class {
async get(key) {
if (typeof window === "undefined") return null;
return localStorage.getItem(key);
}
async set(key, value) {
if (typeof window === "undefined") return;
localStorage.setItem(key, value);
}
async remove(key) {
if (typeof window === "undefined") return;
localStorage.removeItem(key);
}
};
exports.LocalStorage = LocalStorage;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/helpers/base58.js
var require_base58 = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeBase58 = encodeBase58;
const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
/**
* Encodes a Uint8Array into a base58 string.
* @param {Uint8Array} bytes
* @returns {string}
*/
function encodeBase58(bytes) {
if (bytes.length === 0) return "";
let zeros = 0;
let i = 0;
while (i < bytes.length && bytes[i] === 0) {
zeros++;
i++;
}
let digits = [0];
for (; i < bytes.length; i++) {
let carry = bytes[i];
for (let j = 0; j < digits.length; ++j) {
carry += digits[j] << 8;
digits[j] = carry % 58;
carry = carry / 58 | 0;
}
while (carry > 0) {
digits.push(carry % 58);
carry = carry / 58 | 0;
}
}
while (digits.length > 0 && digits[digits.length - 1] === 0) digits.pop();
let result = "";
for (let k = 0; k < zeros; k++) result += BASE58_ALPHABET[0];
for (let q = digits.length - 1; q >= 0; --q) result += BASE58_ALPHABET[digits[q]];
return result;
}
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/actions/index.js
var require_actions = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.nearActionsToConnectorActions = void 0;
const base58_1 = require_base58();
const deserializeArgs = (args) => {
try {
return JSON.parse(new TextDecoder().decode(args));
} catch {
return args;
}
};
const nearActionsToConnectorActions = (actions) => {
return actions.map((action) => {
if ("type" in action) return action;
if (action.functionCall) return {
type: "FunctionCall",
params: {
methodName: action.functionCall.methodName,
args: deserializeArgs(action.functionCall.args),
gas: action.functionCall.gas.toString(),
deposit: action.functionCall.deposit.toString()
}
};
if (action.deployGlobalContract) return {
type: "DeployGlobalContract",
params: {
code: action.deployGlobalContract.code,
deployMode: action.deployGlobalContract.deployMode.AccountId ? "AccountId" : "CodeHash"
}
};
if (action.createAccount) return { type: "CreateAccount" };
if (action.useGlobalContract) return {
type: "UseGlobalContract",
params: { contractIdentifier: action.useGlobalContract.contractIdentifier.AccountId ? { accountId: action.useGlobalContract.contractIdentifier.AccountId } : { codeHash: (0, base58_1.encodeBase58)(action.useGlobalContract.contractIdentifier.CodeHash) } }
};
if (action.deployContract) return {
type: "DeployContract",
params: { code: action.deployContract.code }
};
if (action.deleteAccount) return {
type: "DeleteAccount",
params: { beneficiaryId: action.deleteAccount.beneficiaryId }
};
if (action.deleteKey) return {
type: "DeleteKey",
params: { publicKey: action.deleteKey.publicKey.toString() }
};
if (action.transfer) return {
type: "Transfer",
params: { deposit: action.transfer.deposit.toString() }
};
if (action.stake) return {
type: "Stake",
params: {
stake: action.stake.stake.toString(),
publicKey: action.stake.publicKey.toString()
}
};
if (action.addKey) return {
type: "AddKey",
params: {
publicKey: action.addKey.publicKey.toString(),
accessKey: {
nonce: Number(action.addKey.accessKey.nonce),
permission: action.addKey.accessKey.permission.functionCall ? {
receiverId: action.addKey.accessKey.permission.functionCall.receiverId,
allowance: action.addKey.accessKey.permission.functionCall.allowance?.toString(),
methodNames: action.addKey.accessKey.permission.functionCall.methodNames
} : "FullAccess"
}
}
};
throw new Error("Unsupported action type");
});
};
exports.nearActionsToConnectorActions = nearActionsToConnectorActions;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/helpers/uuid.js
var require_uuid = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.uuid4 = void 0;
const uuid4 = () => {
if (typeof window !== "undefined" && typeof window.crypto !== "undefined" && typeof window.crypto.randomUUID === "function") return window.crypto.randomUUID();
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
return (c === "x" ? r : r & 3 | 8).toString(16);
});
};
exports.uuid4 = uuid4;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/ParentFrameWallet.js
var require_ParentFrameWallet = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParentFrameWallet = void 0;
const actions_1 = require_actions();
const uuid_1 = require_uuid();
var ParentFrameWallet = class {
connector;
manifest;
constructor(connector, manifest) {
this.connector = connector;
this.manifest = manifest;
}
callParentFrame(method, params) {
const id = (0, uuid_1.uuid4)();
window.parent.postMessage({
type: "near-wallet-injected-request",
id,
method,
params
}, "*");
return new Promise((resolve, reject) => {
const handler = (event) => {
if (event.data.type === "near-wallet-injected-response" && event.data.id === id) {
window.removeEventListener("message", handler);
if (event.data.success) resolve(event.data.result);
else reject(event.data.error);
}
};
window.addEventListener("message", handler);
});
}
async signIn(data) {
const result = await this.callParentFrame("near:signIn", {
network: data?.network ?? this.connector.network,
addFunctionCallKey: data?.addFunctionCallKey
});
if (Array.isArray(result)) return result;
return [result];
}
async signInAndSignMessage(data) {
const result = await this.callParentFrame("near:signInAndSignMessage", {
network: data?.network ?? this.connector.network,
addFunctionCallKey: data?.addFunctionCallKey,
messageParams: data.messageParams
});
if (Array.isArray(result)) return result;
return [result];
}
async signOut(data) {
const args = {
...data,
network: data?.network ?? this.connector.network
};
await this.callParentFrame("near:signOut", args);
}
async getAccounts(data) {
const args = {
...data,
network: data?.network ?? this.connector.network
};
return this.callParentFrame("near:getAccounts", args);
}
async signAndSendTransaction(params) {
const connectorActions = (0, actions_1.nearActionsToConnectorActions)(params.actions);
const args = {
...params,
actions: connectorActions,
network: params.network ?? this.connector.network
};
return this.callParentFrame("near:signAndSendTransaction", args);
}
async signAndSendTransactions(params) {
const args = {
...params,
network: params.network ?? this.connector.network
};
args.transactions = args.transactions.map((transaction) => ({
actions: (0, actions_1.nearActionsToConnectorActions)(transaction.actions),
receiverId: transaction.receiverId
}));
return this.callParentFrame("near:signAndSendTransactions", args);
}
async signMessage(params) {
const args = {
...params,
network: params.network ?? this.connector.network
};
return this.callParentFrame("near:signMessage", args);
}
async signDelegateActions(params) {
const args = {
...params,
delegateActions: params.delegateActions.map((delegateAction) => ({
...delegateAction,
actions: (0, actions_1.nearActionsToConnectorActions)(delegateAction.actions)
})),
network: params.network || this.connector.network
};
return this.callParentFrame("near:signDelegateActions", args);
}
};
exports.ParentFrameWallet = ParentFrameWallet;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/helpers/url.js
var require_url = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseUrl = void 0;
const parseUrl = (url) => {
try {
return new URL(url);
} catch {
return null;
}
};
exports.parseUrl = parseUrl;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/helpers/events.js
var require_events = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventEmitter = void 0;
/**
* Generic event emitter class for handling typed events and their callbacks
* @template T Record type containing event names as keys and their payload types as values
*/
var EventEmitter = class {
/** Internal storage for event callbacks */
events = {};
/**
* Subscribe to an event
* @template K Event name type
* @param event Name of the event to subscribe to
* @param callback Function to be called when event is emitted
*/
on(event, callback) {
if (!this.events[event]) this.events[event] = [];
this.events[event].push(callback);
}
/**
* Emit an event with payload
* @template K Event name type
* @param event Name of the event to emit
* @param payload Data to pass to event handlers
*/
emit(event, payload) {
this.events[event]?.forEach((cb) => cb(payload));
}
/**
* Unsubscribe from an event
* @template K Event name type
* @param event Name of the event to unsubscribe from
* @param callback Function to remove from event handlers
*/
off(event, callback) {
this.events[event] = this.events[event]?.filter((cb) => cb !== callback);
}
/**
* Subscribe to an event for a single emission
* @template K Event name type
* @param event Name of the event to subscribe to
* @param callback Function to be called when event is emitted
*/
once(event, callback) {
const onceWrapper = (payload) => {
callback(payload);
this.off(event, onceWrapper);
};
this.on(event, onceWrapper);
}
/**
* Remove all event listeners
* @template K Event name type
* @param event Optional event name to remove listeners for. If not provided, removes all listeners for all events
*/
removeAllListeners(event) {
if (event) delete this.events[event];
else this.events = {};
}
};
exports.EventEmitter = EventEmitter;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/helpers/html.js
var require_html = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.escapeHtml = escapeHtml;
exports.html = html;
function escapeHtml(unsafe) {
return unsafe.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}
const htmlTag = Symbol("htmlTag");
function html(strings, ...values) {
let result = strings[0];
for (let i = 0; i < values.length; i++) {
for (const value of Array.isArray(values[i]) ? values[i] : [values[i]]) {
const escaped = value?.[htmlTag] ? value[htmlTag] : escapeHtml(String(value ?? ""));
result += escaped;
}
result += strings[i + 1];
}
return Object.freeze({
[htmlTag]: result,
get html() {
return result;
}
});
}
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/popups/styles.js
var require_styles = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.css = void 0;
const css = (id) => `
${id} * {
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
-ms-overflow-style: none;
scrollbar-width: none;
color: #fff;
}
${id} *::-webkit-scrollbar {
display: none;
}
${id} p,
${id} h1,
${id} h2,
${id} h3,
${id} h4,
${id} h5,
${id} h6 {
margin: 0;
}
${id} .modal-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100000000;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
transition: opacity 0.2s ease-in-out;
}
@media (max-width: 600px) {
${id} .modal-container {
justify-content: flex-end;
}
}
${id} .modal-content {
display: flex;
flex-direction: column;
align-items: center;
max-width: 420px;
max-height: 615px;
width: 100%;
border-radius: 24px;
background: #0d0d0d;
border: 1.5px solid rgba(255, 255, 255, 0.1);
transition: transform 0.2s ease-in-out;
}
@media (max-width: 600px) {
${id} .modal-content {
max-width: 100%;
width: 100%;
max-height: 80%;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
border: none;
border-top: 1.5px solid rgba(255, 255, 255, 0.1);
}
}
${id} .modal-header {
display: flex;
padding: 16px;
gap: 16px;
align-self: stretch;
align-items: center;
justify-content: center;
position: relative;
}
${id} .modal-header button {
position: absolute;
right: 16px;
top: 16px;
width: 32px;
height: 32px;
border-radius: 12px;
cursor: pointer;
transition: background 0.2s ease-in-out;
border: none;
background: none;
display: flex;
align-items: center;
justify-content: center;
}
${id} .modal-header button:hover {
background: rgba(255, 255, 255, 0.04);
}
${id} .modal-header p {
color: #fff;
text-align: center;
font-size: 24px;
font-style: normal;
font-weight: 600;
line-height: normal;
margin: 0;
}
${id} .modal-body {
display: flex;
padding: 16px;
flex-direction: column;
align-items: flex-start;
text-align: center;
gap: 8px;
overflow: auto;
border-radius: 24px;
background: rgba(255, 255, 255, 0.08);
width: 100%;
flex: 1;
}
${id} .modal-body textarea {
width: 100%;
padding: 12px;
border-radius: 12px;
background: #0d0d0d;
color: #fff;
border: 1px solid rgba(255, 255, 255, 0.1);
outline: none;
font-size: 16px;
transition: background 0.2s ease-in-out;
font-family: monospace;
font-size: 12px;
}
${id} .modal-body button {
width: 100%;
padding: 12px;
border-radius: 12px;
background: #fff;
color: #000;
border: none;
cursor: pointer;
font-size: 16px;
transition: background 0.2s ease-in-out;
margin-top: 16px;
}
${id} .footer {
width: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
padding: 16px 24px;
color: #fff;
gap: 12px;
}
${id} .modal-body p {
color: rgba(255, 255, 255, 0.9);
text-align: center;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: normal;
letter-spacing: -0.8px;
}
${id} .footer img {
width: 24px;
height: 24px;
border-radius: 50%;
object-fit: cover;
}
${id} .get-wallet-link {
color: rgba(255, 255, 255, 0.5);
text-align: center;
font-size: 16px;
font-style: normal;
font-weight: 500;
margin-left: auto;
text-decoration: none;
transition: color 0.2s ease-in-out;
cursor: pointer;
}
${id} .get-wallet-link:hover {
color: rgba(255, 255, 255, 1);
}
${id} .connect-item {
display: flex;
padding: 8px;
align-items: center;
gap: 12px;
align-self: stretch;
cursor: pointer;
transition: background 0.2s ease-in-out;
border-radius: 24px;
}
${id} .connect-item img {
width: 48px;
height: 48px;
border-radius: 16px;
object-fit: cover;
flex-shrink: 0;
}
${id} .connect-item-info {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 4px;
text-align: left;
flex: 1;
margin-top: -2px;
}
${id} .connect-item-info .wallet-address {
color: rgba(255, 255, 255, 0.5);
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
}
${id} .connect-item:hover {
background: rgba(255, 255, 255, 0.04);
}
${id} .connect-item img {
width: 48px;
height: 48px;
border-radius: 16px;
object-fit: cover;
}
${id} .connect-item p {
color: rgba(255, 255, 255, 0.9);
text-align: center;
font-size: 18px;
font-style: normal;
font-weight: 600;
line-height: normal;
letter-spacing: -0.36px;
margin: 0;
}
`;
exports.css = css;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/popups/Popup.js
var require_Popup = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.Popup = void 0;
const styles_1 = require_styles();
const html_1 = require_html();
const ID = `n${Math.random().toString(36).substring(2, 15)}`;
if (typeof document !== "undefined") {
const style = document.createElement("style");
style.textContent = (0, styles_1.css)(`.${ID}`);
document.head.append(style);
}
var Popup = class {
delegate;
isClosed = false;
root = document.createElement("div");
state = {};
constructor(delegate) {
this.delegate = delegate;
}
get dom() {
return (0, html_1.html)``;
}
disposables = [];
addListener(querySelector, event, callback) {
const element = typeof querySelector === "string" ? this.root.querySelector(querySelector) : querySelector;
if (!element) return;
element.addEventListener(event, callback);
this.disposables.push(() => element.removeEventListener(event, callback));
}
handlers() {
this.disposables.forEach((dispose) => dispose());
this.disposables = [];
const modalContainer = this.root.querySelector(".modal-container");
const modalContent = this.root.querySelector(".modal-content");
modalContent.onclick = (e) => e.stopPropagation();
modalContainer.onclick = () => {
this.delegate.onReject();
this.destroy();
};
}
update(state) {
this.state = {
...this.state,
...state
};
this.root.innerHTML = this.dom.html;
this.handlers();
}
create({ show = true }) {
this.root.className = `${ID} hot-connector-popup`;
this.root.innerHTML = this.dom.html;
document.body.append(this.root);
this.handlers();
const modalContainer = this.root.querySelector(".modal-container");
const modalContent = this.root.querySelector(".modal-content");
modalContent.style.transform = "translateY(50px)";
modalContainer.style.opacity = "0";
this.root.style.display = "none";
if (show) setTimeout(() => this.show(), 10);
}
show() {
const modalContainer = this.root.querySelector(".modal-container");
const modalContent = this.root.querySelector(".modal-content");
modalContent.style.transform = "translateY(50px)";
modalContainer.style.opacity = "0";
this.root.style.display = "block";
setTimeout(() => {
modalContent.style.transform = "translateY(0)";
modalContainer.style.opacity = "1";
}, 100);
}
hide() {
const modalContainer = this.root.querySelector(".modal-container");
const modalContent = this.root.querySelector(".modal-content");
modalContent.style.transform = "translateY(50px)";
modalContainer.style.opacity = "0";
setTimeout(() => {
this.root.style.display = "none";
}, 200);
}
destroy() {
if (this.isClosed) return;
this.isClosed = true;
this.hide();
setTimeout(() => {
this.root.remove();
}, 200);
}
};
exports.Popup = Popup;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/popups/IframeWalletPopup.js
var require_IframeWalletPopup = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.IframeWalletPopup = void 0;
const html_1 = require_html();
const Popup_1 = require_Popup();
var IframeWalletPopup = class extends Popup_1.Popup {
delegate;
constructor(delegate) {
super(delegate);
this.delegate = delegate;
}
handlers() {
super.handlers();
this.addListener("button", "click", () => this.delegate.onApprove());
}
create() {
super.create({ show: false });
this.root.querySelector(".modal-body").appendChild(this.delegate.iframe);
this.delegate.iframe.style.width = "100%";
this.delegate.iframe.style.height = "720px";
this.delegate.iframe.style.border = "none";
}
get footer() {
if (!this.delegate.footer) return "";
const { icon, heading } = this.delegate.footer;
return (0, html_1.html)`
<div class="footer">
${icon ? (0, html_1.html)`<img src="${icon}" alt="${heading}" />` : ""}
<p>${heading}</p>
</div>
`;
}
get dom() {
return (0, html_1.html)`<div class="modal-container">
<div class="modal-content">
<div class="modal-body" style="padding: 0; overflow: auto;"></div>
${this.footer}
</div>
</div>`;
}
};
exports.IframeWalletPopup = IframeWalletPopup;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/nearConnectStatic.js
var require_nearConnectStatic = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.NEAR_CONNECT_VERSION = void 0;
exports.NEAR_CONNECT_VERSION = "0.11.4";
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/SandboxedWallet/code.js
var require_code = /* @__PURE__ */ __commonJSMin(((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
const nearConnectStatic_1 = require_nearConnectStatic();
async function getIframeCode(args) {
const storage = await args.executor.getAllStorage();
const providers = args.executor.connector.providers;
const manifest = args.executor.manifest;
const uuid = args.id;
const code = args.code.replaceAll(".localStorage", ".sandboxedLocalStorage").replaceAll("window.top", "window.selector").replaceAll("window.open", "window.selector.open");
const nonceAttr = args.cspNonce ? ` nonce="${args.cspNonce.replace(/[^A-Za-z0-9+/=]/g, "")}"` : "";
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="root"></div>
<style>
:root {
--background-color: rgb(40, 40, 40);
--text-color: rgb(255, 255, 255);
--border-color: rgb(209, 209, 209);
}
* {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif
}
body, html {
box-sizing: border-box;
margin: 0;
padding: 0;
background-color: var(--background-color);
color: var(--text-color);
}
#root {
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
width: 100vw;
background: radial-gradient(circle at center, #2c2c2c 0%, #1a1a1a 100%);
text-align: center;
}
#root * {
box-sizing: border-box;
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
color-scheme: light dark;
color: rgb(255, 255, 255);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}
.prompt-container img {
width: 100px;
height: 100px;
object-fit: cover;
border-radius: 12px;
}
.prompt-container h1 {
margin: 0;
font-size: 24px;
font-weight: 600;
margin-top: 16px;
}
.prompt-container p {
margin: 0;
font-size: 16px;
font-weight: 500;
color: rgb(209, 209, 209);
}
.prompt-container button {
background-color: #131313;
border: none;
border-radius: 12px;
padding: 12px 24px;
cursor: pointer;
transition: border-color 0.25s;
color: #fff;
outline: none;
font-size: 14px;
font-weight: 500;
font-family: inherit;
margin-top: 16px;
}
</style>
<script${nonceAttr}>
window.sandboxedLocalStorage = (() => {
let storage = ${JSON.stringify(storage)}
return {
setItem: function(key, value) {
window.selector.storage.set(key, value)
storage[key] = value || '';
},
getItem: function(key) {
return key in storage ? storage[key] : null;
},
removeItem: function(key) {
window.selector.storage.remove(key)
delete storage[key];
},
get length() {
return Object.keys(storage).length;
},
key: function(i) {
const keys = Object.keys(storage);
return keys[i] || null;
},
};
})();
const showPrompt = async (args) => {
const root = document.getElementById("root");
root.style.display = "flex";
root.innerHTML = \`
<div class="prompt-container">
<img src="${manifest.icon}" />
<h1>${manifest.name}</h1>
<p>\${args.title}</p>
<button>\${args.button}</button>
</div>
\`;
return new Promise((resolve) => {
root.querySelector("button")?.addEventListener("click", () => {
root.innerHTML = "";
resolve(true);
});
});
}
class ProxyWindow {
constructor(url, features) {
this.closed = false;
this.windowIdPromise = window.selector.call("open", { url, features });
window.addEventListener("message", async (event) => {
if (event.data.origin !== "${uuid}") return;
if (!event.data.method?.startsWith("proxy-window:")) return;
const method = event.data.method.replace("proxy-window:", "");
if (method === "closed" && event.data.windowId === await this.id()) this.closed = true;
});
}
async id() {
return await this.windowIdPromise;
}
async focus() {
await window.selector.call("panel.focus", { windowId: await this.id() });
}
async postMessage(data) {
window.selector.call("panel.postMessage", { windowId: await this.id(), data });
}
async close() {
await window.selector.call("panel.close", { windowId: await this.id() });
}
}
window.selector = {
wallet: null,
location: "${window.location.href}",
nearConnectVersion: "${nearConnectStatic_1.NEAR_CONNECT_VERSION}",
outerHeight: ${window.outerHeight},
screenY: ${window.screenY},
outerWidth: ${window.outerWidth},
screenX: ${window.screenX},
providers: {
mainnet: ${JSON.stringify(providers.mainnet)},
testnet: ${JSON.stringify(providers.testnet)},
},
uuid() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0;
const v = c === "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
},
walletConnect: {
connect(params) {
return window.selector.call("walletConnect.connect", params);
},
disconnect(params) {
return window.selector.call("walletConnect.disconnect", params);
},
request(params) {
return window.selector.call("walletConnect.request", params);
},
getProjectId() {
return window.selector.call("walletConnect.getProjectId", {});
},
getSession() {
return window.selector.call("walletConnect.getSession", {});
},
},
async ready(wallet) {
wallet.manifest = ${JSON.stringify(manifest)};
window.parent.postMessage({ method: "wallet-ready", origin: "${uuid}" }, "*");
window.selector.wallet = wallet;
},
async call(method, params) {
const id = window.selector.uuid();
window.parent.postMessage({ method, params, id, origin: "${uuid}" }, "*");
return new Promise((resolve, reject) => {
const handler = (event) => {
if (event.data.id !== id || event.data.origin !== "${uuid}") return;
window.removeEventListener("message", handler);
if (event.data.status === "failed") reject(event.data.result);
else resolve(event.data.result);
};
window.addEventListener("message", handler);
});
},
panelClosed(windowId) {
window.parent.postMessage({
method: "panel.closed",
origin: "${uuid}",
result: { windowId }
}, "*");
},
open(url, _, params) {
return new ProxyWindow(url, params)
},
external(entity, key, ...args) {
return window.selector.call("external", { entity, key, args: args || [] });
},
openNativeApp(url) {
return window.selector.call("open.nativeApp", { url });
},
ui: {
async whenApprove(options) {
window.selector.ui.showIframe();
await showPrompt(options);
window.selector.ui.hideIframe();
},
async showIframe() {
return await window.selector.call("ui.showIframe");
},
async hideIframe() {
return await window.selector.call("ui.hideIframe");
},
},
storage: {
async set(key, value) {
await window.selector.call("storage.set", { key, value });
},
async get(key) {
return await window.selector.call("storage.get", { key });
},
async remove(key) {
await window.selector.call("storage.remove", { key });
},
async keys() {
return await window.selector.call("storage.keys", {});
},
},
};
window.addEventListener("message", async (event) => {
if (event.data.origin !== "${uuid}") return;
if (!event.data.method?.startsWith("wallet:")) return;
const wallet = window.selector.wallet;
const method = event.data.method.replace("wallet:", "");
const payload = { id: event.data.id, origin: "${uuid}", method };
if (wallet == null || typeof wallet[method] !== "function") {
const data = { ...payload, status: "failed", result: "Method not found" };
window.parent.postMessage(data, "*");
return;
}
try {
const result = await wallet[method](event.data.params);
window.parent.postMessage({ ...payload, status: "success", result }, "*");
} catch (error) {
const data = { ...payload, status: "failed", result: error };
window.parent.postMessage(data, "*");
}
});
<\/script>
<script type="module"${nonceAttr}>${code}<\/script>
</body>
</html>
`;
}
exports.default = getIframeCode;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/SandboxedWallet/iframe.js
var require_iframe = /* @__PURE__ */ __commonJSMin(((exports) => {
var __importDefault = exports && exports.__importDefault || function(mod) {
return mod && mod.__esModule ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require_events();
const uuid_1 = require_uuid();
const IframeWalletPopup_1 = require_IframeWalletPopup();
const code_1 = __importDefault(require_code());
var IframeExecutor = class {
executor;
origin;
iframe = document.createElement("iframe");
events = new events_1.EventEmitter();
popup;
handler;
readyPromiseResolve;
readyPromise = new Promise((resolve) => {
this.readyPromiseResolve = resolve;
});
constructor(executor, code, onMessage, cspNonce) {
this.executor = executor;
this.origin = (0, uuid_1.uuid4)();
this.handler = (event) => {
if (event.data.origin !== this.origin) return;
if (event.data.method === "wallet-ready") this.readyPromiseResolve();
onMessage(this, event);
};
window.addEventListener("message", this.handler);
const iframeAllowedPermissions = [];
if (this.executor.checkPermissions("usb")) iframeAllowedPermissions.push("usb *;");
if (this.executor.checkPermissions("hid")) iframeAllowedPermissions.push("hid *;");
if (this.executor.checkPermissions("clipboardRead")) iframeAllowedPermissions.push("clipboard-read;");
if (this.executor.checkPermissions("clipboardWrite")) iframeAllowedPermissions.push("clipboard-write;");
if (this.executor.checkPermissions("bluetooth")) iframeAllowedPermissions.push("bluetooth *;");
this.iframe.allow = iframeAllowedPermissions.join(" ");
this.iframe.setAttribute("sandbox", "allow-scripts");
(0, code_1.default)({
id: this.origin,
executor: this.executor,
code,
cspNonce
}).then((code) => {
this.executor.connector.logger?.log(`Iframe code injected`);
this.iframe.srcdoc = code;
});
this.popup = new IframeWalletPopup_1.IframeWalletPopup({
footer: this.executor.connector.footerBranding,
iframe: this.iframe,
onApprove: () => {},
onReject: () => {
window.removeEventListener("message", this.handler);
this.events.emit("close", {});
this.popup.destroy();
}
});
this.popup.create();
}
on(event, callback) {
this.events.on(event, callback);
}
show() {
this.popup.show();
}
hide() {
this.popup.hide();
}
postMessage(data) {
if (!this.iframe.contentWindow) throw new Error("Iframe not loaded");
this.iframe.contentWindow.postMessage({
...data,
origin: this.origin
}, "*");
}
dispose() {
window.removeEventListener("message", this.handler);
this.popup.destroy();
}
};
exports.default = IframeExecutor;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/SandboxedWallet/executor.js
var require_executor = /* @__PURE__ */ __commonJSMin(((exports) => {
var __importDefault = exports && exports.__importDefault || function(mod) {
return mod && mod.__esModule ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const url_1 = require_url();
const uuid_1 = require_uuid();
const iframe_1 = __importDefault(require_iframe());
const cacheId = (0, uuid_1.uuid4)();
var SandboxExecutor = class {
connector;
manifest;
activePanels = {};
storageSpace;
constructor(connector, manifest) {
this.connector = connector;
this.manifest = manifest;
this.storageSpace = manifest.id;
}
checkPermissions(action, params) {
if (action === "walletConnect") return !!this.manifest.permissions.walletConnect;
if (action === "external") {
const external = this.manifest.permissions.external;
if (!external || !params?.entity) return false;
return external.includes(params.entity);
}
if (action === "allowsOpen") {
const openUrl = (0, url_1.parseUrl)(params?.url || "");
const allowsOpen = this.manifest.permissions.allowsOpen;
if (!openUrl || !allowsOpen || !Array.isArray(allowsOpen) || allowsOpen.length === 0) return false;
return allowsOpen.some((path) => {
const url = (0, url_1.parseUrl)(path);
if (!url) return false;
if (openUrl.protocol !== url.protocol) return false;
if (!!url.hostname && openUrl.hostname !== url.hostname) return false;
if (!!url.pathname && url.pathname !== "/" && openUrl.pathname !== url.pathname) return false;
return true;
});
}
return this.manifest.permissions[action];
}
assertPermissions(iframe, action, event) {
if (!this.checkPermissions(action, event.data.params)) {
iframe.postMessage({
...event.data,
status: "failed",
result: "Permission denied"
});
throw new Error("Permission denied");
}
}
_onMessage = async (iframe, event) => {
const success = (result) => {
iframe.postMessage({
...event.data,
status: "success",
result
});
};
const failed = (error) => {
iframe.postMessage({
...event.data,
status: "failed",
result: error
});
};
if (event.data.method === "ui.showIframe") {
iframe.show();
success(null);
return;
}
if (event.data.method === "ui.hideIframe") {
iframe.hide();
success(null);
return;
}
if (event.data.method === "storage.set") {
this.assertPermissions(iframe, "storage", event);
localStorage.setItem(`${this.storageSpace}:${event.data.params.key}`, event.data.params.value);
success(null);
return;
}
if (event.data.method === "storage.get") {
this.assertPermissions(iframe, "storage", event);
success(localStorage.getItem(`${this.storageSpace}:${event.data.params.key}`));
return;
}
if (event.data.method === "storage.keys") {
this.assertPermissions(iframe, "storage", event);
success(Object.keys(localStorage).filter((key) => key.startsWith(`${this.storageSpace}:`)));
return;
}
if (event.data.method === "storage.remove") {
this.assertPermissions(iframe, "storage", event);
localStorage.removeItem(`${this.storageSpace}:${event.data.params.key}`);
success(null);
return;
}
if (event.data.method === "panel.focus") {
const panel = this.activePanels[event.data.params.windowId];
if (panel) panel.focus();
success(null);
return;
}
if (event.data.method === "panel.postMessage") {
const panel = this.activePanels[event.data.params.windowId];
if (panel) panel.postMessage(event.data.params.data, "*");
success(null);
return;
}
if (event.data.method === "panel.close") {
const panel = this.activePanels[event.data.params.windowId];
if (panel) panel.close();
delete this.activePanels[event.data.params.windowId];
success(null);
return;
}
if (event.data.method === "walletConnect.connect") {
this.assertPermissions(iframe, "walletConnect", event);
try {
if (!this.connector.walletConnect) throw new Error("WalletConnect is not configured");
const result = await (await this.connector.walletConnect).connect(event.data.params);
result.approval();
success({ uri: result.uri });
} catch (e) {
failed(e);
}
return;
}
if (event.data.method === "walletConnect.getProjectId") {
if (!this.connector.walletConnect) throw new Error("WalletConnect is not configured");
this.assertPermissions(iframe, "walletConnect", event);
success((await this.connector.walletConnect).core.projectId);
return;
}
if (event.data.method === "walletConnect.disconnect") {
this.assertPermissions(iframe, "walletConnect", event);
try {
if (!this.connector.walletConnect) throw new Error("WalletConnect is not configured");
success(await (await this.connector.walletConnect).disconnect(event.data.params));
} catch (e) {
failed(e);
}
return;
}
if (event.data.method === "walletConnect.getSession") {
this.assertPermissions(iframe, "walletConnect", event);
try {
if (!this.connector.walletConnect) throw new Error("WalletConnect is not configured");
const client = await this.connector.walletConnect;
const key = client.session.keys[client.session.keys.length - 1];
const session = key ? client.session.get(key) : null;
success(session ? {
topic: session.topic,
namespaces: session.namespaces
} : null);
} catch (e) {
failed(e);
}
return;
}
if (event.data.method === "walletConnect.request") {
this.assertPermissions(iframe, "walletConnect", event);
try {
if (!this.connector.walletConnect) throw new Error("WalletConnect is not configured");
success(await (await this.connector.walletConnect).request(event.data.params));
} catch (e) {
failed(e);
}
return;
}
if (event.data.method === "external") {
this.assertPermissions(iframe, "external", event);
try {
const { entity, key, args } = event.data.params;
const obj = entity.split(".").reduce((acc, key) => acc[key], window);
if (entity === "nightly.near" && key === "signTransaction") args[0].encode = () => args[0];
success(typeof obj[key] === "function" ? await obj[key](...args || []) : obj[key]);
} catch (e) {
failed(e);
}
return;
}
if (event.data.method === "open") {
this.assertPermissions(iframe, "allowsOpen", event);
const tgapp = typeof window !== "undefined" ? window?.Telegram?.WebApp : null;
if (tgapp && event.data.params.url.startsWith("https://t.me")) {
tgapp.openTelegramLink(event.data.params.url);
return;
}
const panel = window.open(event.data.params.url, "_blank", event.data.params.features);
const panelId = panel ? (0, uuid_1.uuid4)() : null;
const handler = (ev) => {
const url = (0, url_1.parseUrl)(event.data.params.url);
if (url && url.origin === ev.origin) iframe.postMessage(ev.data);
};
success(panelId);
window.addEventListener("message", handler);
if (panel && panelId) {
this.activePanels[panelId] = panel;
const interval = setInterval(() => {
if (!panel?.closed) return;
window.removeEventListener("message", handler);
const args = {
method: "proxy-window:closed",
windowId: panelId
};
delete this.activePanels[panelId];
clearInterval(interval);
try {
iframe.postMessage(args);
} catch {}
}, 500);
}
return;
}
if (event.data.method === "open.nativeApp") {
this.assertPermissions(iframe, "allowsOpen", event);
const url = (0, url_1.parseUrl)(event.data.params.url);
if (!url || [
"https",
"http",
"javascript:",
"file:",
"data:",
"blob:",
"about:"
].includes(url.protocol)) {
failed("Invalid URL");
throw new Error("[open.nativeApp] Invalid URL");
}
const linkIframe = document.createElement("iframe");
linkIframe.src = event.data.params.url;
linkIframe.style.display = "none";
document.body.appendChild(linkIframe);
iframe.postMessage({
...event.data,
status: "success",
result: null
});
return;
}
};
actualCode = null;
async checkNewVersion(executor, currentVersion) {
if (this.actualCode) {
this.connector.logger?.log(`New version of code already checked`);
return this.actualCode;
}
let url = (0, url_1.parseUrl)(executor.manifest.executor);
if (!url) url = (0, url_1.parseUrl)(location.origin + executor.manifest.executor);
if (!url) throw new Error("Invalid executor URL");
url.searchParams.set("nonce", cacheId);
const newVersion = await fetch(url.toString()).then((res) => res.text());
this.connector.logger?.log(`New version of code fetched`);
this.actualCode = newVersion;
if (newVersion === currentVersion) {
this.connector.logger?.log(`New version of code is the same as the current version`);
return this.actualCode;
}
await this.connector.db.setItem(`${this.manifest.id}:${this.manifest.version}`, newVersion);
this.connector.logger?.log(`New version of code saved to cache`);
return newVersion;
}
async loadCode() {
const cachedCode = await this.connector.db.getItem(`${this.manifest.id}:${this.manifest.version}`).catch(() => null);
this.connector.logger?.log(`Code loaded from cache`, cachedCode !== null);
const task = this.checkNewVersion(this, cachedCode);
if (cachedCode) return cachedCode;
return await task;
}
async call(method, params) {
this.connector.logger?.log(`Add to queue`, method, params);
this.connector.logger?.log(`Calling method`, method, params);
const code = await this.loadCode();
this.connector.logger?.log(`Code loaded, preparing`);
const iframe = new iframe_1.default(this, code, this._onMessage, this.connector.cspNonce);
this.connector.logger?.log(`Code loaded, iframe initialized`);
await iframe.readyPromise;
this.connector.logger?.log(`Iframe ready`);
const id = (0, uuid_1.uuid4)();
return new Promise((resolve, reject) => {
try {
const handler = (event) => {
if (event.data.id !== id || event.data.origin !== iframe.origin) return;
iframe.dispose();
window.removeEventListener("message", handler);
this.connector.logger?.log("postMessage", {
result: event.data,
request: {
method,
params
}
});
if (event.data.status === "failed") reject(event.data.result);
else resolve(event.data.result);
};
window.addEventListener("message", handler);
iframe.postMessage({
method,
params,
id
});
iframe.on("close", () => reject(/* @__PURE__ */ new Error("Wallet closed")));
} catch (e) {
this.connector.logger?.log(`Iframe error`, e);
reject(e);
}
});
}
async getAllStorage() {
const keys = Object.keys(localStorage).filter((key) => key.startsWith(`${this.storageSpace}:`));
const storage = {};
for (const key of keys) storage[key.replace(`${this.storageSpace}:`, "")] = localStorage.getItem(key);
return storage;
}
async clearStorage() {
const keys = Object.keys(localStorage).filter((key) => key.startsWith(`${this.storageSpace}:`));
for (const key of keys) localStorage.removeItem(key);
}
};
exports.default = SandboxExecutor;
}));
//#endregion
//#region node_modules/.pnpm/@hot-labs+near-connect@0.11.4/node_modules/@hot-labs/near-connect/build/SandboxedWallet/index.js
var require_SandboxedWallet = /* @__PURE__ */ __commonJSMin(((exports) => {
var __importDefault = exports && exports.__importDefault || function(mod) {
return mod && mod.__esModule ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SandboxWallet = void 0;
const actions_1 = require_actions();
const executor_1 = __importDefault(require_executor());
var SandboxWallet = class {
connector;
manifest;
executor;
constructor(connector, manifest) {
this.connector = connector;
this.manifest = manifest;
this.executor = new executor_1.default(connector, manifest);
}
async signIn(data) {
return this.executor.call("wallet:signIn", {
network: data?.network ?? this.connector.network,
addFunctionCallKey: data?.addFunctionCallKey
});
}
async signInAndSignMessage(data) {
return this.executor.call("wallet:signInAndSignMessage", {
network: data?.network ?? this.connector.network,
addFunctionCallKey: data?.addFunctionCallKey,
messageParams: data.messageParams
});
}
async signOut(data) {
const args = {
...data,
network: data?.network ?? this.connector.network
};
await this.executor.call("wallet:signOut", args);
await this.executor.clearStorage();
}
async getAccounts(data) {
const args = {
...data,
network: data?.network ?? this.connector.network
};
return this.executor.call("wallet:getAccounts", args);
}
async signAndSendTransaction(params) {
const actions = (0, actions_1.nearActionsToConnectorActions)(params.actions);
const args = {
...params,
actions,
network: params.network ?? this.connector.network
};
return this.executor.call("wallet:signAndSendTransaction", args);
}
async signAndSendTransactions(params) {
const transactions = params.transactions.map((transaction) => ({
actions: (0, actions_1.nearActionsToConnectorActions)(transaction.actions),
receiverId: transaction.receiverId
}));
const args = {
...params,
transactions,
network: params.network ?? this.connector.network
};
return this.executor.call("wallet:signAndSendTransactions", args);
}
async signMessage(params) {
const args = {
...params,
network: params.network ?? this.connector.network
};
return this.executor.call("wallet:signMessage", args);
}
async signDelegateActions(params) {
const args = {
...params,
delegateActions: params.delegateActions.map((delegateAction) => ({
...delegateAction,
actions: (0, actions_1.nearActionsToConnectorActions)(delegateAction.actions)
})),
network: params.network ?? this.connector.network
};
return this.executor.call("wallet:signDel