{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["/**\n * @typedef {Object} WalletState\n * @property {string} [accountId] - NEAR account ID if signed in\n * @property {string} [publicKey] - Public key if available\n * @property {string} [privateKey] - Private key if available\n * @property {string} [lastWalletId] - ID of last used wallet\n * @property {string} [networkId] - ID of last used network\n */\n\n/**\n * @typedef {Object} SignInConfig\n * @property {string} networkId - NEAR network ID ('mainnet' or 'testnet')\n * @property {string} contractId - Contract ID to request access for\n * @property {string} [walletId] - Preferred wallet to use. E.g. 'near', 'here', 'meteor'\n * @property {string} [callbackUrl] - URL to redirect back to after wallet interaction\n */\n\n/**\n * @typedef {Object} SignInResult\n * @property {string} [url] - URL to redirect to if needed\n * @property {string} [accountId] - Account ID if immediately available\n * @property {string} [error] - Error message if sign in failed\n */\nexport interface SignInResult {\n  url?: string;\n  accountId?: string;\n  error?: string;\n}\n\n/**\n * @typedef {Object} Transaction\n * @property {string} [signerId] - Transaction signer account ID\n * @property {string} receiverId - Transaction receiver account ID\n * @property {Object[]} actions - Transaction actions to perform\n */\n\n/**\n * @typedef {Object} TransactionConfig\n * @property {Transaction} transactions - Transaction actions to perform\n * @property {string} [callbackUrl] - URL to redirect back to after wallet interaction\n */\n\n/**\n * @typedef {Object} TransactionResult\n * @property {string} [url] - URL to redirect to if needed\n * @property {string} [hash] - Transaction hash if immediately available\n * @property {string} [error] - Error message if transaction failed\n * Represents the result of attempting to send or execute a transaction.\n */\nexport interface TransactionResult {\n  /** URL to redirect to if needed. */\n  url?: string;\n\n  /** Transaction hash if immediately available. */\n  hash?: string;\n\n  /** Error message if the transaction failed. */\n  error?: string;\n}\n\nexport interface WalletAdapterConstructor {\n  widgetUrl?: string;\n  targetOrigin?: string;\n  onStateUpdate?: (state: any) => void;\n  lastState?: any;\n  callbackUrl?: string;\n}\n\n/**\n * @typedef {Object} WalletAdapterConfig\n * @property {string} [widgetUrl] - URL of the wallet widget (defaults to official hosted version)\n * @property {string} [targetOrigin] - Target origin for postMessage (defaults to '*')\n * @property {string} [lastState] - The last state that was given by WalletAdapter before the redirect or reload.\n * @property {(state: WalletState) => void} [onStateUpdate] - Called when wallet state changes\n * @property {string} [callbackUrl] - Default callback URL for wallet interactions (defaults to current page URL)\n */\n\n/**\n * Interface for interacting with NEAR wallets\n */\nexport class WalletAdapter {\n  /** @type {HTMLIFrameElement} */\n  #iframe: HTMLIFrameElement | null = null;\n\n  /** @type {string} */\n  #targetOrigin;\n\n  /** @type {string} */\n  #widgetUrl;\n\n  /** @type {Map<string, Function>} */\n  #pending = new Map();\n\n  /** @type {WalletState} */\n  #state;\n\n  /** @type {Function} */\n  #onStateUpdate;\n\n  /** @type {string} */\n  #callbackUrl;\n\n  /** @type {string} */\n  static defaultWidgetUrl = \"https://wallet-adapter.fastnear.com\";\n\n  /**\n   * @param {WalletAdapterConfig} [config]\n   */\n  constructor({\n    widgetUrl = WalletAdapter.defaultWidgetUrl,\n    targetOrigin = \"*\",\n    onStateUpdate,\n    lastState,\n    callbackUrl = window.location.href,\n  }: WalletAdapterConstructor = {}) {\n    this.#targetOrigin = targetOrigin;\n    this.#widgetUrl = widgetUrl;\n    this.#onStateUpdate = onStateUpdate;\n    this.#callbackUrl = callbackUrl;\n    this.#state = lastState || {};\n    window.addEventListener(\"message\", this.#handleMessage.bind(this));\n  }\n\n  /**\n   * Creates an iframe for wallet interaction\n   * @param {string} path - Path to load in iframe\n   * @returns {HTMLIFrameElement}\n   */\n  #createIframe(path) {\n    // Remove existing iframe if any\n    if (this.#iframe) {\n      this.#iframe.remove();\n    }\n\n    // Create URL\n    const url = new URL(path, this.#widgetUrl);\n\n    // Create and configure iframe\n    const iframe = document.createElement(\"iframe\");\n    iframe.src = url.toString();\n    iframe.allow = \"usb\";\n    iframe.style.border = \"none\";\n    iframe.style.zIndex = \"10000\";\n    iframe.style.position = \"fixed\";\n    iframe.style.display = \"block\";\n    iframe.style.top = \"0\";\n    iframe.style.left = \"0\";\n    iframe.style.width = \"100%\";\n    iframe.style.height = \"100%\";\n    document.body.appendChild(iframe);\n\n    this.#iframe = iframe;\n    return iframe;\n  }\n\n  /**\n   * Handles messages from the wallet widget\n   * @param {MessageEvent} event\n   */\n  #handleMessage(event) {\n    // Check origin if specified\n    if (this.#targetOrigin !== \"*\" && event.origin !== this.#targetOrigin) {\n      return;\n    }\n\n    const { id, type, action, payload } = event.data;\n    if (type !== \"wallet-adapter\") return;\n\n    // Handle close action\n    if (action === \"close\") {\n      this.#iframe?.remove();\n      this.#iframe = null;\n      return;\n    }\n\n    // Update state if provided\n    if (payload?.state) {\n      this.#state = { ...this.#state, ...payload.state };\n      this.#onStateUpdate?.(this.#state);\n    }\n\n    // Resolve pending promise if any\n    const resolve = this.#pending.get(id) as ((value: SignInResult) => void);\n    if (resolve) {\n      this.#pending.delete(id);\n      this.#iframe?.remove();\n      this.#iframe = null;\n      resolve(payload as SignInResult);\n    }\n  }\n\n  /**\n   * Sends a message to the wallet widget\n   * @param {string} path - Path to load in iframe\n   * @param {string} method - Method to call\n   * @param {Object} params - Parameters to pass\n   * @returns {Promise<any>}\n   */\n  async #sendMessage(path, method, params): Promise<TransactionResult> {\n    return new Promise((resolve) => {\n      const id = Math.random().toString(36).slice(2);\n      this.#pending.set(id, resolve);\n\n      const iframe = this.#createIframe(path);\n\n      iframe.onload = () => {\n        iframe.contentWindow?.postMessage(\n          {\n            type: \"wallet-adapter\",\n            method,\n            params: {\n              id,\n              ...params,\n              state: this.#state,\n              callbackUrl: params.callbackUrl || this.#callbackUrl,\n            },\n          },\n          this.#targetOrigin\n        );\n      };\n    });\n  }\n\n  /**\n   * Get current wallet state\n   * @returns {WalletState}\n   */\n  getState() {\n    return { ...this.#state };\n  }\n\n  /**\n   * Set current wallet state\n   * @param state\n   */\n  setState(state) {\n    this.#state = state;\n  }\n\n  /**\n   * Sign in with a NEAR wallet\n   * @param {SignInConfig} config\n   * @returns {Promise<any>}\n   *\n   * Should be returning SignInResult\n   */\n  async signIn(config): Promise<any> {\n    return this.#sendMessage(\"/login.html\", \"signIn\", config);\n  }\n\n  /**\n   * Send a transaction using connected wallet\n   * @param {TransactionConfig} config\n   * @returns {Promise<TransactionResult>}\n   */\n  async sendTransactions(config): Promise<TransactionResult> {\n    return this.#sendMessage(\"/send.html\", \"sendTransactions\", config);\n  }\n\n  /**\n   * Clean up adapter resources\n   */\n  destroy() {\n    window.removeEventListener(\"message\", this.#handleMessage);\n    this.#iframe?.remove();\n    this.#iframe = null;\n  }\n}\n"],"mappings":"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","names":[]}