@asseteragmbh/wallet-connector 0.1.0 → 0.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/protocol.ts","../src/provider.ts"],"names":["request","active"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The pop-up protocol between a partner page (the opener) and the Assetera Wallet (the pop-up) — ADR-0054 D3/D4.\n *\n * This file is the CONTRACT. The connector in this package speaks the opener side; AsseteraWalletFront's\n * `/connect` page speaks the pop-up side and imports these types from `@asseteragmbh/wallet-connector/protocol`.\n * Change it only in a backwards-compatible way, or bump `PROTOCOL_VERSION` and support both on the wallet side:\n * partner sites upgrade on their own schedule.\n *\n * ## The handshake\n *\n * 1. The partner opens `${walletUrl}${CONNECT_PATH}?origin=<partner origin>&v=<version>` from a user click.\n * 2. The pop-up checks the claimed origin against its allowlist (D4). If listed, it posts `ready` to\n * `window.opener` with `targetOrigin` = that origin. The browser delivers it ONLY if the opener really is\n * that origin, so a page cannot claim someone else's origin and still hear the answer.\n * 3. The opener waits for `ready` from the wallet origin, then sends `request`s with `targetOrigin` = the wallet\n * origin. The pop-up accepts a message only when `event.origin` is the allowed origin from step 2 AND\n * `event.source === window.opener`, and answers with `targetOrigin` = that origin. Nothing else is accepted.\n *\n * ## Lifetime\n *\n * The pop-up stays open while the partner uses the wallet (ADR-0054, \"the wallet tab must stay open\"). When it is\n * closed, the opener sees `disconnect` (or notices `popup.closed`) and must reconnect from a user click.\n */\n\nexport const PROTOCOL_VERSION = 1 as const;\n\n/** The pop-up route on the wallet origin. */\nexport const CONNECT_PATH = \"/connect\";\n\n/** Every message carries this prefix in `type`, so both sides can ignore unrelated `postMessage` traffic. */\nexport const MESSAGE_PREFIX = \"assetera-wallet:\" as const;\n\n/**\n * The EIP-1193 methods the pop-up answers (ADR-0054 D3). Anything else is refused with 4200. Read-only chain\n * calls (`eth_call`, `eth_getBalance`, …) do not go through the pop-up; wagmi sends them to its own transports.\n */\nexport const SUPPORTED_METHODS = [\n \"eth_requestAccounts\",\n \"eth_accounts\",\n \"eth_chainId\",\n \"wallet_switchEthereumChain\",\n \"personal_sign\",\n \"eth_signTypedData_v4\",\n \"eth_sendTransaction\",\n] as const;\n\nexport type SupportedMethod = (typeof SUPPORTED_METHODS)[number];\n\nexport function isSupportedMethod(method: string): method is SupportedMethod {\n return (SUPPORTED_METHODS as readonly string[]).includes(method);\n}\n\n/** EIP-1193 / EIP-1474 error codes the pop-up uses. */\nexport const RpcErrorCode = {\n /** The client rejected the request in the pop-up. */\n UserRejected: 4001,\n /** Not connected yet (no `eth_requestAccounts` approved in this pop-up). */\n Unauthorized: 4100,\n /** The method is not in SUPPORTED_METHODS. */\n UnsupportedMethod: 4200,\n /** The pop-up closed, or the wallet session ended. */\n Disconnected: 4900,\n /** `wallet_switchEthereumChain` to a chain the wallet does not offer. */\n UnrecognizedChain: 4902,\n /** Malformed params. */\n InvalidParams: -32602,\n /** Anything unexpected inside the wallet. */\n Internal: -32603,\n} as const;\n\nexport type RpcErrorCode = (typeof RpcErrorCode)[keyof typeof RpcErrorCode];\n\nexport interface RpcError {\n code: number;\n message: string;\n data?: unknown;\n}\n\n// --- pop-up → opener ---------------------------------------------------------------------------------\n\n/** The pop-up is loaded and accepts requests from this opener. */\nexport interface ReadyMessage {\n type: `${typeof MESSAGE_PREFIX}ready`;\n v: typeof PROTOCOL_VERSION;\n /** Shown to the partner for diagnostics only; the partner must not rely on it for anything. */\n walletVersion?: string;\n}\n\n/** The answer to one `request`, matched by `id`. Exactly one of `result` / `error`. */\nexport type ResponseMessage =\n | { type: `${typeof MESSAGE_PREFIX}response`; v: typeof PROTOCOL_VERSION; id: string; result: unknown }\n | { type: `${typeof MESSAGE_PREFIX}response`; v: typeof PROTOCOL_VERSION; id: string; error: RpcError };\n\n/** EIP-1193 provider events, forwarded to the partner. */\nexport type EventMessage =\n | {\n type: `${typeof MESSAGE_PREFIX}event`;\n v: typeof PROTOCOL_VERSION;\n event: \"accountsChanged\";\n data: `0x${string}`[];\n }\n | {\n type: `${typeof MESSAGE_PREFIX}event`;\n v: typeof PROTOCOL_VERSION;\n event: \"chainChanged\";\n data: `0x${string}`;\n }\n | {\n type: `${typeof MESSAGE_PREFIX}event`;\n v: typeof PROTOCOL_VERSION;\n event: \"disconnect\";\n data: RpcError;\n };\n\nexport type WalletToPartnerMessage = ReadyMessage | ResponseMessage | EventMessage;\n\n// --- opener → pop-up ---------------------------------------------------------------------------------\n\nexport interface RequestMessage {\n type: `${typeof MESSAGE_PREFIX}request`;\n v: typeof PROTOCOL_VERSION;\n /** Unique per request within one connection; the response carries it back. */\n id: string;\n method: string;\n params?: unknown[] | Record<string, unknown>;\n}\n\n/** The partner disconnects (for example the user clicked \"Disconnect\" in the partner page). */\nexport interface DisconnectMessage {\n type: `${typeof MESSAGE_PREFIX}disconnect`;\n v: typeof PROTOCOL_VERSION;\n}\n\nexport type PartnerToWalletMessage = RequestMessage | DisconnectMessage;\n\n// --- guards ------------------------------------------------------------------------------------------\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction hasType(value: unknown, suffix: string): value is Record<string, unknown> {\n return isRecord(value) && value.type === `${MESSAGE_PREFIX}${suffix}` && value.v === PROTOCOL_VERSION;\n}\n\nexport function isReadyMessage(value: unknown): value is ReadyMessage {\n return hasType(value, \"ready\");\n}\n\nexport function isResponseMessage(value: unknown): value is ResponseMessage {\n return (\n hasType(value, \"response\") &&\n typeof value.id === \"string\" &&\n (\"result\" in value || (isRecord(value.error) && typeof value.error.code === \"number\"))\n );\n}\n\nexport function isEventMessage(value: unknown): value is EventMessage {\n return (\n hasType(value, \"event\") &&\n (value.event === \"accountsChanged\" || value.event === \"chainChanged\" || value.event === \"disconnect\")\n );\n}\n\nexport function isRequestMessage(value: unknown): value is RequestMessage {\n return hasType(value, \"request\") && typeof value.id === \"string\" && typeof value.method === \"string\";\n}\n\nexport function isDisconnectMessage(value: unknown): value is DisconnectMessage {\n return hasType(value, \"disconnect\");\n}\n\n/** The URL the partner opens. `partnerOrigin` is `window.location.origin` of the partner page. */\nexport function connectUrl(walletUrl: string, partnerOrigin: string): string {\n const url = new URL(CONNECT_PATH, walletUrl);\n url.searchParams.set(\"origin\", partnerOrigin);\n url.searchParams.set(\"v\", String(PROTOCOL_VERSION));\n return url.toString();\n}\n","/**\n * EIP-1193 provider for the Assetera Wallet pop-up — the opener side of the ADR-0054 D3/D4 protocol.\n *\n * The provider owns a single pop-up (`window.open(connectUrl(...), \"assetera-wallet\", ...)`) and speaks the\n * wire format defined in `./protocol`. It never touches Dynamic, React, wagmi or viem, so a partner can use it\n * on its own or through the wagmi / RainbowKit adapters in this package.\n */\nimport {\n MESSAGE_PREFIX,\n PROTOCOL_VERSION,\n RpcErrorCode,\n connectUrl,\n isEventMessage,\n isReadyMessage,\n isResponseMessage,\n isSupportedMethod,\n type DisconnectMessage,\n type EventMessage,\n type RequestMessage,\n type ResponseMessage,\n} from \"./protocol\";\n\n/** Arguments accepted by `request`, mirroring EIP-1193. */\nexport interface RequestArguments {\n method: string;\n params?: unknown[] | Record<string, unknown>;\n}\n\n/** EIP-1193 provider events emitted by the pop-up. */\nexport type ProviderEvent = \"accountsChanged\" | \"chainChanged\" | \"connect\" | \"disconnect\";\n\n/**\n * Listener shape for EIP-1193 provider events. `never[]` accepts a listener with any concrete parameter list\n * (for example wagmi's `(accounts: string[]) => void`), while internal emission stays type-safe via a cast.\n */\nexport type ProviderListener = (...args: never[]) => void;\n\n/** The EIP-1193 surface returned by {@link createAsseteraWalletProvider}. */\nexport interface AsseteraWalletProvider {\n request(args: RequestArguments): Promise<unknown>;\n on(event: ProviderEvent, listener: ProviderListener): void;\n removeListener(event: ProviderEvent, listener: ProviderListener): void;\n disconnect(): void;\n}\n\n/** Options for {@link createAsseteraWalletProvider}. */\nexport interface AsseteraWalletProviderOptions {\n /** Base URL of the wallet origin, e.g. `https://wallet.playground.assetera.com`. */\n walletUrl: string;\n /** Chain id used before the wallet reports one, and as the local `eth_chainId` fallback. */\n defaultChainId: number;\n /** `window.open` feature string. Defaults to `\"popup,width=420,height=720\"`. */\n popupFeatures?: string;\n}\n\n/**\n * EIP-1193 error carrying a JSON-RPC `code` (and optional `data`). This is what every rejected `request`\n * throws, so wagmi maps the wallet's `4001` / `4100` / `4200` / `4900` correctly.\n */\nexport class ProviderRpcError extends Error {\n readonly code: number;\n readonly data?: unknown;\n\n constructor(code: number, message: string, data?: unknown) {\n super(message);\n this.name = \"ProviderRpcError\";\n this.code = code;\n this.data = data;\n }\n}\n\nconst DEFAULT_POPUP_FEATURES = \"popup,width=420,height=720\";\nconst POPUP_NAME = \"assetera-wallet\";\nconst CLOSE_POLL_MS = 500;\n\n/** Methods that show the user a signature / transaction prompt, so the pop-up should be focused first. */\nconst SIGNING_METHODS: ReadonlySet<string> = new Set([\n \"personal_sign\",\n \"eth_signTypedData_v4\",\n \"eth_sendTransaction\",\n]);\n\ninterface PendingRequest {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n}\n\ninterface Deferred<T> {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (reason: unknown) => void;\n}\n\nfunction createDeferred<T>(): Deferred<T> {\n let resolve!: (value: T) => void;\n let reject!: (reason: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n // The `ready` deferred is rejected when the pop-up closes even if no request is waiting on it; mark the\n // promise as handled so that rejection is not reported as an unhandled promise rejection.\n void promise.catch(() => {});\n return { promise, resolve, reject };\n}\n\nfunction toHexChainId(chainId: number): string {\n return `0x${chainId.toString(16)}`;\n}\n\n/**\n * Create the EIP-1193 provider that talks to the Assetera Wallet pop-up.\n *\n * Call `request` from a user gesture: `eth_requestAccounts` opens the pop-up synchronously (before any\n * `await`) so the browser treats it as part of the click and does not block it.\n */\nexport function createAsseteraWalletProvider(options: AsseteraWalletProviderOptions): AsseteraWalletProvider {\n const { defaultChainId } = options;\n const walletOrigin = new URL(options.walletUrl).origin;\n const popupFeatures = options.popupFeatures ?? DEFAULT_POPUP_FEATURES;\n\n let popup: Window | null = null;\n /** Resolves when the *current* pop-up posts `ready`. Replaced when a new pop-up is opened. */\n let ready = createDeferred<void>();\n let accounts: string[] = [];\n let chainIdHex: string | null = null;\n /** Set when the wallet itself told us the session ended (as opposed to the user merely closing the tab). */\n let walletDisconnected = false;\n const pending = new Map<string, PendingRequest>();\n const listeners = new Map<ProviderEvent, Set<(...args: unknown[]) => void>>();\n let closeTimer: ReturnType<typeof setInterval> | null = null;\n\n function currentChainId(): string {\n return chainIdHex ?? toHexChainId(defaultChainId);\n }\n\n function blockedError(): ProviderRpcError {\n return new ProviderRpcError(\n RpcErrorCode.Disconnected,\n \"The Assetera Wallet pop-up was blocked by the browser. The pop-up must be opened from a user click \" +\n \"(for example a button press) and then the request retried.\",\n );\n }\n\n function disconnectedError(message = \"The Assetera Wallet pop-up was closed.\"): ProviderRpcError {\n return new ProviderRpcError(RpcErrorCode.Disconnected, message);\n }\n\n function emit(event: ProviderEvent, ...args: unknown[]): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const listener of set) {\n try {\n listener(...args);\n } catch (error) {\n console.error(`[assetera-wallet] listener for \"${event}\" threw`, error);\n }\n }\n }\n\n function addListener(event: ProviderEvent, listener: ProviderListener): void {\n let set = listeners.get(event);\n if (!set) {\n set = new Set<(...args: unknown[]) => void>();\n listeners.set(event, set);\n }\n set.add(listener as (...args: unknown[]) => void);\n }\n\n function removeEventListener(event: ProviderEvent, listener: ProviderListener): void {\n listeners.get(event)?.delete(listener as (...args: unknown[]) => void);\n }\n\n function stopClosePolling(): void {\n if (closeTimer !== null) {\n clearInterval(closeTimer);\n closeTimer = null;\n }\n }\n\n function startClosePolling(): void {\n if (closeTimer !== null) return;\n closeTimer = setInterval(() => {\n if (popup?.closed) handlePopupClosed();\n }, CLOSE_POLL_MS);\n }\n\n function rejectAllPending(error: ProviderRpcError): void {\n for (const request of pending.values()) request.reject(error);\n pending.clear();\n }\n\n /**\n * The pop-up was closed by the user (or the wallet app).\n *\n * We deliberately KEEP `accounts` / `chainIdHex` cached: the dApp stays \"connected\" in React state and does\n * not flicker back to a disconnected UI. Because a pop-up cannot be reopened without a user gesture, the next\n * signing request reopens it from the caller's click. `disconnect` is only emitted when the close actually\n * interrupted work (a request was pending) or when the wallet itself announced the disconnect.\n */\n function handlePopupClosed(): void {\n const hadPending = pending.size > 0;\n stopClosePolling();\n const closedPopup = popup;\n popup = null;\n const closedReady = ready;\n ready = createDeferred<void>();\n const error = disconnectedError();\n if (closedPopup) closedReady.reject(error);\n rejectAllPending(error);\n const shouldEmit = hadPending || walletDisconnected;\n walletDisconnected = false;\n if (shouldEmit) emit(\"disconnect\", error);\n }\n\n /**\n * Open the pop-up, or focus and reuse it when it is still around. Must stay synchronous (it is called before\n * any `await` in `request`) so it runs inside the caller's user activation.\n */\n function openPopup(): Window | null {\n if (popup && !popup.closed) {\n popup.focus();\n return popup;\n }\n if (typeof window === \"undefined\") return null;\n const opened = window.open(\n connectUrl(options.walletUrl, window.location.origin),\n POPUP_NAME,\n popupFeatures,\n );\n if (!opened) return null;\n popup = opened;\n ready = createDeferred<void>();\n walletDisconnected = false;\n startClosePolling();\n return opened;\n }\n\n function sendRequest(method: string, params?: RequestArguments[\"params\"]): Promise<unknown> {\n const active = popup;\n if (!active || active.closed) return Promise.reject(disconnectedError());\n const id = crypto.randomUUID();\n const message: RequestMessage = {\n type: `${MESSAGE_PREFIX}request`,\n v: PROTOCOL_VERSION,\n id,\n method,\n ...(params === undefined ? {} : { params }),\n };\n return new Promise<unknown>((resolve, reject) => {\n pending.set(id, { resolve, reject });\n active.postMessage(message, walletOrigin);\n });\n }\n\n function handleResponse(message: ResponseMessage): void {\n const request = pending.get(message.id);\n if (!request) return;\n pending.delete(message.id);\n if (\"error\" in message) {\n request.reject(new ProviderRpcError(message.error.code, message.error.message, message.error.data));\n } else {\n request.resolve(message.result);\n }\n }\n\n function handleEventMessage(message: EventMessage): void {\n if (message.event === \"accountsChanged\") {\n accounts = [...message.data];\n emit(\"accountsChanged\", [...accounts]);\n return;\n }\n if (message.event === \"chainChanged\") {\n chainIdHex = message.data;\n emit(\"chainChanged\", chainIdHex);\n return;\n }\n walletDisconnected = true;\n emit(\"disconnect\", new ProviderRpcError(message.data.code, message.data.message, message.data.data));\n }\n\n function onWindowMessage(event: MessageEvent): void {\n if (event.origin !== walletOrigin) return;\n if (popup === null || (event.source as unknown) !== popup) return;\n const data: unknown = event.data;\n if (isReadyMessage(data)) {\n ready.resolve(undefined);\n return;\n }\n if (isResponseMessage(data)) {\n handleResponse(data);\n return;\n }\n if (isEventMessage(data)) handleEventMessage(data);\n }\n\n if (typeof window !== \"undefined\") window.addEventListener(\"message\", onWindowMessage);\n\n function request({ method, params }: RequestArguments): Promise<unknown> {\n if (typeof window === \"undefined\") {\n return Promise.reject(\n new ProviderRpcError(\n RpcErrorCode.Disconnected,\n \"The Assetera Wallet provider can only run in a browser.\",\n ),\n );\n }\n // Read-only chain calls go through wagmi's own transports; the pop-up refuses everything else.\n if (!isSupportedMethod(method)) {\n return Promise.reject(\n new ProviderRpcError(\n RpcErrorCode.UnsupportedMethod,\n `The Assetera Wallet pop-up does not support the method \"${method}\".`,\n ),\n );\n }\n // Answered locally, without a pop-up, so wagmi can read the connection before the user clicks.\n if (method === \"eth_accounts\") return Promise.resolve([...accounts]);\n if (method === \"eth_chainId\") return Promise.resolve(currentChainId());\n\n // Opening the pop-up MUST happen synchronously, before the first `await`, to stay in the click.\n if (method === \"eth_requestAccounts\") {\n const active = openPopup();\n if (!active) return Promise.reject(blockedError());\n return ready.promise\n .then(() => sendRequest(\"eth_requestAccounts\", params))\n .then((result) => {\n accounts = Array.isArray(result) ? (result as string[]) : [];\n emit(\"accountsChanged\", [...accounts]);\n emit(\"connect\", { chainId: currentChainId() });\n return [...accounts];\n });\n }\n\n // Every other supported method needs an approved connection.\n if (accounts.length === 0) {\n return Promise.reject(\n new ProviderRpcError(\n RpcErrorCode.Unauthorized,\n \"Connect to the Assetera Wallet first (eth_requestAccounts).\",\n ),\n );\n }\n const active = openPopup();\n if (!active) return Promise.reject(blockedError());\n if (SIGNING_METHODS.has(method)) active.focus();\n return ready.promise.then(() => sendRequest(method, params));\n }\n\n function disconnect(): void {\n const active = popup;\n if (active && !active.closed) {\n const message: DisconnectMessage = {\n type: `${MESSAGE_PREFIX}disconnect`,\n v: PROTOCOL_VERSION,\n };\n active.postMessage(message, walletOrigin);\n active.close();\n }\n stopClosePolling();\n popup = null;\n const closedReady = ready;\n ready = createDeferred<void>();\n closedReady.reject(disconnectedError(\"Disconnected from the Assetera Wallet.\"));\n rejectAllPending(disconnectedError(\"Disconnected from the Assetera Wallet.\"));\n accounts = [];\n chainIdHex = null;\n walletDisconnected = false;\n emit(\"disconnect\", disconnectedError(\"Disconnected from the Assetera Wallet.\"));\n }\n\n function on(event: ProviderEvent, listener: ProviderListener): void {\n addListener(event, listener);\n }\n\n function removeListener(event: ProviderEvent, listener: ProviderListener): void {\n removeEventListener(event, listener);\n }\n\n return { request, on, removeListener, disconnect };\n}\n"]}
1
+ {"version":3,"sources":["../src/protocol.ts","../src/provider.ts","../src/onboarding.ts"],"names":["request","active","POPUP_NAME","CLOSE_POLL_MS"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The pop-up protocol between a partner page (the opener) and the Assetera Wallet (the pop-up) — ADR-0054 D3/D4.\n *\n * This file is the CONTRACT. The connector in this package speaks the opener side; AsseteraWalletFront's\n * `/connect` page speaks the pop-up side and imports these types from `@asseteragmbh/wallet-connector/protocol`.\n * Change it only in a backwards-compatible way, or bump `PROTOCOL_VERSION` and support both on the wallet side:\n * partner sites upgrade on their own schedule.\n *\n * ## The handshake\n *\n * 1. The partner opens `${walletUrl}${CONNECT_PATH}?origin=<partner origin>&v=<version>` from a user click.\n * 2. The pop-up checks the claimed origin against its allowlist (D4). If listed, it posts `ready` to\n * `window.opener` with `targetOrigin` = that origin. The browser delivers it ONLY if the opener really is\n * that origin, so a page cannot claim someone else's origin and still hear the answer.\n * 3. The opener waits for `ready` from the wallet origin, then sends `request`s with `targetOrigin` = the wallet\n * origin. The pop-up accepts a message only when `event.origin` is the allowed origin from step 2 AND\n * `event.source === window.opener`, and answers with `targetOrigin` = that origin. Nothing else is accepted.\n *\n * ## Lifetime\n *\n * The pop-up stays open while the partner uses the wallet (ADR-0054, \"the wallet tab must stay open\"). When it is\n * closed, the opener sees `disconnect` (or notices `popup.closed`) and must reconnect from a user click.\n *\n * ## Onboarding\n *\n * Onboarding is a second, one-shot flow on the same wallet origin, for a partner that wants to create a brand\n * new client wallet rather than connect to an existing one. The partner opens\n * `${walletUrl}${ONBOARD_PATH}?origin=<partner origin>&v=<version>&chain=<CAIP-2 chain id>` from a user click.\n * The pop-up checks the claimed origin against its partner list, signs the client in through SSO, runs the\n * wizard (accept the terms, create the wallet, register it with Compliance, wait for the screening) and then\n * posts `onboarded` (or `onboard-cancelled`) to `window.opener` with `targetOrigin` = the partner origin, and\n * closes.\n *\n * The opener accepts the result only when `event.origin` is the wallet origin AND `event.source` is the pop-up\n * it opened. The wizard never returns a private key or a token, only the resulting wallet address.\n */\n\nexport const PROTOCOL_VERSION = 1 as const;\n\n/** The pop-up route on the wallet origin. */\nexport const CONNECT_PATH = \"/connect\";\n\n/** The onboarding wizard route on the wallet origin. */\nexport const ONBOARD_PATH = \"/onboard\";\n\n/** Every message carries this prefix in `type`, so both sides can ignore unrelated `postMessage` traffic. */\nexport const MESSAGE_PREFIX = \"assetera-wallet:\" as const;\n\n/**\n * The EIP-1193 methods the pop-up answers (ADR-0054 D3). Anything else is refused with 4200. Read-only chain\n * calls (`eth_call`, `eth_getBalance`, …) do not go through the pop-up; wagmi sends them to its own transports.\n */\nexport const SUPPORTED_METHODS = [\n \"eth_requestAccounts\",\n \"eth_accounts\",\n \"eth_chainId\",\n \"wallet_switchEthereumChain\",\n \"personal_sign\",\n \"eth_signTypedData_v4\",\n \"eth_sendTransaction\",\n] as const;\n\nexport type SupportedMethod = (typeof SUPPORTED_METHODS)[number];\n\nexport function isSupportedMethod(method: string): method is SupportedMethod {\n return (SUPPORTED_METHODS as readonly string[]).includes(method);\n}\n\n/** EIP-1193 / EIP-1474 error codes the pop-up uses. */\nexport const RpcErrorCode = {\n /** The client rejected the request in the pop-up. */\n UserRejected: 4001,\n /** Not connected yet (no `eth_requestAccounts` approved in this pop-up). */\n Unauthorized: 4100,\n /** The method is not in SUPPORTED_METHODS. */\n UnsupportedMethod: 4200,\n /** The pop-up closed, or the wallet session ended. */\n Disconnected: 4900,\n /** `wallet_switchEthereumChain` to a chain the wallet does not offer. */\n UnrecognizedChain: 4902,\n /** Malformed params. */\n InvalidParams: -32602,\n /** Anything unexpected inside the wallet. */\n Internal: -32603,\n} as const;\n\nexport type RpcErrorCode = (typeof RpcErrorCode)[keyof typeof RpcErrorCode];\n\nexport interface RpcError {\n code: number;\n message: string;\n data?: unknown;\n}\n\n// --- pop-up → opener ---------------------------------------------------------------------------------\n\n/** The pop-up is loaded and accepts requests from this opener. */\nexport interface ReadyMessage {\n type: `${typeof MESSAGE_PREFIX}ready`;\n v: typeof PROTOCOL_VERSION;\n /** Shown to the partner for diagnostics only; the partner must not rely on it for anything. */\n walletVersion?: string;\n}\n\n/** The answer to one `request`, matched by `id`. Exactly one of `result` / `error`. */\nexport type ResponseMessage =\n | { type: `${typeof MESSAGE_PREFIX}response`; v: typeof PROTOCOL_VERSION; id: string; result: unknown }\n | { type: `${typeof MESSAGE_PREFIX}response`; v: typeof PROTOCOL_VERSION; id: string; error: RpcError };\n\n/** EIP-1193 provider events, forwarded to the partner. */\nexport type EventMessage =\n | {\n type: `${typeof MESSAGE_PREFIX}event`;\n v: typeof PROTOCOL_VERSION;\n event: \"accountsChanged\";\n data: `0x${string}`[];\n }\n | {\n type: `${typeof MESSAGE_PREFIX}event`;\n v: typeof PROTOCOL_VERSION;\n event: \"chainChanged\";\n data: `0x${string}`;\n }\n | {\n type: `${typeof MESSAGE_PREFIX}event`;\n v: typeof PROTOCOL_VERSION;\n event: \"disconnect\";\n data: RpcError;\n };\n\n/**\n * The onboarding wizard finished and the wallet was created (or is still waiting for the Compliance screening).\n * `status: \"approved\"` means the client can transact, `\"pending\"` means the screening is still running; the\n * address is valid in both cases.\n */\nexport interface OnboardedMessage {\n type: `${typeof MESSAGE_PREFIX}onboarded`;\n v: typeof PROTOCOL_VERSION;\n address: `0x${string}`;\n chain: string;\n status: \"approved\" | \"pending\";\n}\n\n/** The onboarding wizard did not produce a wallet. `message` is optional diagnostics for the partner. */\nexport interface OnboardCancelledMessage {\n type: `${typeof MESSAGE_PREFIX}onboard-cancelled`;\n v: typeof PROTOCOL_VERSION;\n reason: \"user\" | \"refused\" | \"error\";\n message?: string;\n}\n\nexport type WalletToPartnerMessage =\n ReadyMessage | ResponseMessage | EventMessage | OnboardedMessage | OnboardCancelledMessage;\n\n// --- opener → pop-up ---------------------------------------------------------------------------------\n\nexport interface RequestMessage {\n type: `${typeof MESSAGE_PREFIX}request`;\n v: typeof PROTOCOL_VERSION;\n /** Unique per request within one connection; the response carries it back. */\n id: string;\n method: string;\n params?: unknown[] | Record<string, unknown>;\n}\n\n/** The partner disconnects (for example the user clicked \"Disconnect\" in the partner page). */\nexport interface DisconnectMessage {\n type: `${typeof MESSAGE_PREFIX}disconnect`;\n v: typeof PROTOCOL_VERSION;\n}\n\nexport type PartnerToWalletMessage = RequestMessage | DisconnectMessage;\n\n// --- guards ------------------------------------------------------------------------------------------\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction hasType(value: unknown, suffix: string): value is Record<string, unknown> {\n return isRecord(value) && value.type === `${MESSAGE_PREFIX}${suffix}` && value.v === PROTOCOL_VERSION;\n}\n\nexport function isReadyMessage(value: unknown): value is ReadyMessage {\n return hasType(value, \"ready\");\n}\n\nexport function isResponseMessage(value: unknown): value is ResponseMessage {\n return (\n hasType(value, \"response\") &&\n typeof value.id === \"string\" &&\n (\"result\" in value || (isRecord(value.error) && typeof value.error.code === \"number\"))\n );\n}\n\nexport function isEventMessage(value: unknown): value is EventMessage {\n return (\n hasType(value, \"event\") &&\n (value.event === \"accountsChanged\" || value.event === \"chainChanged\" || value.event === \"disconnect\")\n );\n}\n\nexport function isRequestMessage(value: unknown): value is RequestMessage {\n return hasType(value, \"request\") && typeof value.id === \"string\" && typeof value.method === \"string\";\n}\n\nexport function isDisconnectMessage(value: unknown): value is DisconnectMessage {\n return hasType(value, \"disconnect\");\n}\n\n/** `0x` followed by exactly 40 hexadecimal digits, the shape of an EVM address. */\nconst EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\n\nexport function isOnboardedMessage(value: unknown): value is OnboardedMessage {\n return (\n hasType(value, \"onboarded\") &&\n typeof value.address === \"string\" &&\n EVM_ADDRESS_RE.test(value.address) &&\n typeof value.chain === \"string\" &&\n (value.status === \"approved\" || value.status === \"pending\")\n );\n}\n\nexport function isOnboardCancelledMessage(value: unknown): value is OnboardCancelledMessage {\n return (\n hasType(value, \"onboard-cancelled\") &&\n (value.reason === \"user\" || value.reason === \"refused\" || value.reason === \"error\")\n );\n}\n\n/** A CAIP-2 EVM chain id, for example `eip155:80002` (Polygon Amoy) or `eip155:1` (mainnet). */\nexport function isCaip2EvmChain(value: string): boolean {\n return /^eip155:\\d{1,32}$/.test(value);\n}\n\n/** The URL the partner opens. `partnerOrigin` is `window.location.origin` of the partner page. */\nexport function connectUrl(walletUrl: string, partnerOrigin: string): string {\n const url = new URL(CONNECT_PATH, walletUrl);\n url.searchParams.set(\"origin\", partnerOrigin);\n url.searchParams.set(\"v\", String(PROTOCOL_VERSION));\n return url.toString();\n}\n\n/**\n * The URL the partner opens for the onboarding wizard. `partnerOrigin` is `window.location.origin` of the\n * partner page; `chain` is the CAIP-2 chain id the new wallet should be created on; `locale` is passed as `lang`\n * when the partner wants a specific wizard language.\n */\nexport function onboardUrl(\n walletUrl: string,\n partnerOrigin: string,\n options: { chain: string; locale?: string },\n): string {\n const url = new URL(ONBOARD_PATH, walletUrl);\n url.searchParams.set(\"origin\", partnerOrigin);\n url.searchParams.set(\"v\", String(PROTOCOL_VERSION));\n url.searchParams.set(\"chain\", options.chain);\n if (options.locale !== undefined) url.searchParams.set(\"lang\", options.locale);\n return url.toString();\n}\n","/**\n * EIP-1193 provider for the Assetera Wallet pop-up — the opener side of the ADR-0054 D3/D4 protocol.\n *\n * The provider owns a single pop-up (`window.open(connectUrl(...), \"assetera-wallet\", ...)`) and speaks the\n * wire format defined in `./protocol`. It never touches Dynamic, React, wagmi or viem, so a partner can use it\n * on its own or through the wagmi / RainbowKit adapters in this package.\n */\nimport {\n MESSAGE_PREFIX,\n PROTOCOL_VERSION,\n RpcErrorCode,\n connectUrl,\n isEventMessage,\n isReadyMessage,\n isResponseMessage,\n isSupportedMethod,\n type DisconnectMessage,\n type EventMessage,\n type RequestMessage,\n type ResponseMessage,\n} from \"./protocol\";\n\n/** Arguments accepted by `request`, mirroring EIP-1193. */\nexport interface RequestArguments {\n method: string;\n params?: unknown[] | Record<string, unknown>;\n}\n\n/** EIP-1193 provider events emitted by the pop-up. */\nexport type ProviderEvent = \"accountsChanged\" | \"chainChanged\" | \"connect\" | \"disconnect\";\n\n/**\n * Listener shape for EIP-1193 provider events. `never[]` accepts a listener with any concrete parameter list\n * (for example wagmi's `(accounts: string[]) => void`), while internal emission stays type-safe via a cast.\n */\nexport type ProviderListener = (...args: never[]) => void;\n\n/** The EIP-1193 surface returned by {@link createAsseteraWalletProvider}. */\nexport interface AsseteraWalletProvider {\n request(args: RequestArguments): Promise<unknown>;\n on(event: ProviderEvent, listener: ProviderListener): void;\n removeListener(event: ProviderEvent, listener: ProviderListener): void;\n disconnect(): void;\n}\n\n/** Options for {@link createAsseteraWalletProvider}. */\nexport interface AsseteraWalletProviderOptions {\n /** Base URL of the wallet origin, e.g. `https://wallet.playground.assetera.com`. */\n walletUrl: string;\n /** Chain id used before the wallet reports one, and as the local `eth_chainId` fallback. */\n defaultChainId: number;\n /** `window.open` feature string. Defaults to `\"popup,width=420,height=720\"`. */\n popupFeatures?: string;\n}\n\n/**\n * EIP-1193 error carrying a JSON-RPC `code` (and optional `data`). This is what every rejected `request`\n * throws, so wagmi maps the wallet's `4001` / `4100` / `4200` / `4900` correctly.\n */\nexport class ProviderRpcError extends Error {\n readonly code: number;\n readonly data?: unknown;\n\n constructor(code: number, message: string, data?: unknown) {\n super(message);\n this.name = \"ProviderRpcError\";\n this.code = code;\n this.data = data;\n }\n}\n\nconst DEFAULT_POPUP_FEATURES = \"popup,width=420,height=720\";\nconst POPUP_NAME = \"assetera-wallet\";\nconst CLOSE_POLL_MS = 500;\n\n/** Methods that show the user a signature / transaction prompt, so the pop-up should be focused first. */\nconst SIGNING_METHODS: ReadonlySet<string> = new Set([\n \"personal_sign\",\n \"eth_signTypedData_v4\",\n \"eth_sendTransaction\",\n]);\n\ninterface PendingRequest {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n}\n\ninterface Deferred<T> {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (reason: unknown) => void;\n}\n\nfunction createDeferred<T>(): Deferred<T> {\n let resolve!: (value: T) => void;\n let reject!: (reason: unknown) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n // The `ready` deferred is rejected when the pop-up closes even if no request is waiting on it; mark the\n // promise as handled so that rejection is not reported as an unhandled promise rejection.\n void promise.catch(() => {});\n return { promise, resolve, reject };\n}\n\nfunction toHexChainId(chainId: number): string {\n return `0x${chainId.toString(16)}`;\n}\n\n/**\n * Create the EIP-1193 provider that talks to the Assetera Wallet pop-up.\n *\n * Call `request` from a user gesture: `eth_requestAccounts` opens the pop-up synchronously (before any\n * `await`) so the browser treats it as part of the click and does not block it.\n */\nexport function createAsseteraWalletProvider(options: AsseteraWalletProviderOptions): AsseteraWalletProvider {\n const { defaultChainId } = options;\n const walletOrigin = new URL(options.walletUrl).origin;\n const popupFeatures = options.popupFeatures ?? DEFAULT_POPUP_FEATURES;\n\n let popup: Window | null = null;\n /** Resolves when the *current* pop-up posts `ready`. Replaced when a new pop-up is opened. */\n let ready = createDeferred<void>();\n let accounts: string[] = [];\n let chainIdHex: string | null = null;\n /** Set when the wallet itself told us the session ended (as opposed to the user merely closing the tab). */\n let walletDisconnected = false;\n const pending = new Map<string, PendingRequest>();\n const listeners = new Map<ProviderEvent, Set<(...args: unknown[]) => void>>();\n let closeTimer: ReturnType<typeof setInterval> | null = null;\n\n function currentChainId(): string {\n return chainIdHex ?? toHexChainId(defaultChainId);\n }\n\n function blockedError(): ProviderRpcError {\n return new ProviderRpcError(\n RpcErrorCode.Disconnected,\n \"The Assetera Wallet pop-up was blocked by the browser. The pop-up must be opened from a user click \" +\n \"(for example a button press) and then the request retried.\",\n );\n }\n\n function disconnectedError(message = \"The Assetera Wallet pop-up was closed.\"): ProviderRpcError {\n return new ProviderRpcError(RpcErrorCode.Disconnected, message);\n }\n\n function emit(event: ProviderEvent, ...args: unknown[]): void {\n const set = listeners.get(event);\n if (!set) return;\n for (const listener of set) {\n try {\n listener(...args);\n } catch (error) {\n console.error(`[assetera-wallet] listener for \"${event}\" threw`, error);\n }\n }\n }\n\n function addListener(event: ProviderEvent, listener: ProviderListener): void {\n let set = listeners.get(event);\n if (!set) {\n set = new Set<(...args: unknown[]) => void>();\n listeners.set(event, set);\n }\n set.add(listener as (...args: unknown[]) => void);\n }\n\n function removeEventListener(event: ProviderEvent, listener: ProviderListener): void {\n listeners.get(event)?.delete(listener as (...args: unknown[]) => void);\n }\n\n function stopClosePolling(): void {\n if (closeTimer !== null) {\n clearInterval(closeTimer);\n closeTimer = null;\n }\n }\n\n function startClosePolling(): void {\n if (closeTimer !== null) return;\n closeTimer = setInterval(() => {\n if (popup?.closed) handlePopupClosed();\n }, CLOSE_POLL_MS);\n }\n\n function rejectAllPending(error: ProviderRpcError): void {\n for (const request of pending.values()) request.reject(error);\n pending.clear();\n }\n\n /**\n * The pop-up was closed by the user (or the wallet app).\n *\n * We deliberately KEEP `accounts` / `chainIdHex` cached: the dApp stays \"connected\" in React state and does\n * not flicker back to a disconnected UI. Because a pop-up cannot be reopened without a user gesture, the next\n * signing request reopens it from the caller's click. `disconnect` is only emitted when the close actually\n * interrupted work (a request was pending) or when the wallet itself announced the disconnect.\n */\n function handlePopupClosed(): void {\n const hadPending = pending.size > 0;\n stopClosePolling();\n const closedPopup = popup;\n popup = null;\n const closedReady = ready;\n ready = createDeferred<void>();\n const error = disconnectedError();\n if (closedPopup) closedReady.reject(error);\n rejectAllPending(error);\n const shouldEmit = hadPending || walletDisconnected;\n walletDisconnected = false;\n if (shouldEmit) emit(\"disconnect\", error);\n }\n\n /**\n * Open the pop-up, or focus and reuse it when it is still around. Must stay synchronous (it is called before\n * any `await` in `request`) so it runs inside the caller's user activation.\n */\n function openPopup(): Window | null {\n if (popup && !popup.closed) {\n popup.focus();\n return popup;\n }\n if (typeof window === \"undefined\") return null;\n const opened = window.open(\n connectUrl(options.walletUrl, window.location.origin),\n POPUP_NAME,\n popupFeatures,\n );\n if (!opened) return null;\n popup = opened;\n ready = createDeferred<void>();\n walletDisconnected = false;\n startClosePolling();\n return opened;\n }\n\n function sendRequest(method: string, params?: RequestArguments[\"params\"]): Promise<unknown> {\n const active = popup;\n if (!active || active.closed) return Promise.reject(disconnectedError());\n const id = crypto.randomUUID();\n const message: RequestMessage = {\n type: `${MESSAGE_PREFIX}request`,\n v: PROTOCOL_VERSION,\n id,\n method,\n ...(params === undefined ? {} : { params }),\n };\n return new Promise<unknown>((resolve, reject) => {\n pending.set(id, { resolve, reject });\n active.postMessage(message, walletOrigin);\n });\n }\n\n function handleResponse(message: ResponseMessage): void {\n const request = pending.get(message.id);\n if (!request) return;\n pending.delete(message.id);\n if (\"error\" in message) {\n request.reject(new ProviderRpcError(message.error.code, message.error.message, message.error.data));\n } else {\n request.resolve(message.result);\n }\n }\n\n function handleEventMessage(message: EventMessage): void {\n if (message.event === \"accountsChanged\") {\n accounts = [...message.data];\n emit(\"accountsChanged\", [...accounts]);\n return;\n }\n if (message.event === \"chainChanged\") {\n chainIdHex = message.data;\n emit(\"chainChanged\", chainIdHex);\n return;\n }\n walletDisconnected = true;\n emit(\"disconnect\", new ProviderRpcError(message.data.code, message.data.message, message.data.data));\n }\n\n function onWindowMessage(event: MessageEvent): void {\n if (event.origin !== walletOrigin) return;\n if (popup === null || (event.source as unknown) !== popup) return;\n const data: unknown = event.data;\n if (isReadyMessage(data)) {\n ready.resolve(undefined);\n return;\n }\n if (isResponseMessage(data)) {\n handleResponse(data);\n return;\n }\n if (isEventMessage(data)) handleEventMessage(data);\n }\n\n if (typeof window !== \"undefined\") window.addEventListener(\"message\", onWindowMessage);\n\n function request({ method, params }: RequestArguments): Promise<unknown> {\n if (typeof window === \"undefined\") {\n return Promise.reject(\n new ProviderRpcError(\n RpcErrorCode.Disconnected,\n \"The Assetera Wallet provider can only run in a browser.\",\n ),\n );\n }\n // Read-only chain calls go through wagmi's own transports; the pop-up refuses everything else.\n if (!isSupportedMethod(method)) {\n return Promise.reject(\n new ProviderRpcError(\n RpcErrorCode.UnsupportedMethod,\n `The Assetera Wallet pop-up does not support the method \"${method}\".`,\n ),\n );\n }\n // Answered locally, without a pop-up, so wagmi can read the connection before the user clicks.\n if (method === \"eth_accounts\") return Promise.resolve([...accounts]);\n if (method === \"eth_chainId\") return Promise.resolve(currentChainId());\n\n // Opening the pop-up MUST happen synchronously, before the first `await`, to stay in the click.\n if (method === \"eth_requestAccounts\") {\n const active = openPopup();\n if (!active) return Promise.reject(blockedError());\n return ready.promise\n .then(() => sendRequest(\"eth_requestAccounts\", params))\n .then((result) => {\n accounts = Array.isArray(result) ? (result as string[]) : [];\n emit(\"accountsChanged\", [...accounts]);\n emit(\"connect\", { chainId: currentChainId() });\n return [...accounts];\n });\n }\n\n // Every other supported method needs an approved connection.\n if (accounts.length === 0) {\n return Promise.reject(\n new ProviderRpcError(\n RpcErrorCode.Unauthorized,\n \"Connect to the Assetera Wallet first (eth_requestAccounts).\",\n ),\n );\n }\n const active = openPopup();\n if (!active) return Promise.reject(blockedError());\n if (SIGNING_METHODS.has(method)) active.focus();\n return ready.promise.then(() => sendRequest(method, params));\n }\n\n function disconnect(): void {\n const active = popup;\n if (active && !active.closed) {\n const message: DisconnectMessage = {\n type: `${MESSAGE_PREFIX}disconnect`,\n v: PROTOCOL_VERSION,\n };\n active.postMessage(message, walletOrigin);\n active.close();\n }\n stopClosePolling();\n popup = null;\n const closedReady = ready;\n ready = createDeferred<void>();\n closedReady.reject(disconnectedError(\"Disconnected from the Assetera Wallet.\"));\n rejectAllPending(disconnectedError(\"Disconnected from the Assetera Wallet.\"));\n accounts = [];\n chainIdHex = null;\n walletDisconnected = false;\n emit(\"disconnect\", disconnectedError(\"Disconnected from the Assetera Wallet.\"));\n }\n\n function on(event: ProviderEvent, listener: ProviderListener): void {\n addListener(event, listener);\n }\n\n function removeListener(event: ProviderEvent, listener: ProviderListener): void {\n removeEventListener(event, listener);\n }\n\n return { request, on, removeListener, disconnect };\n}\n","/**\n * Onboarding opener for the Assetera Wallet: the partner side of the `/onboard` wizard (AO-1274).\n *\n * A tied-agent bank site shows a \"Create an Assetera wallet\" button. On the click, this module opens the wallet\n * pop-up in onboarding mode synchronously (so the browser treats it as part of the click) and waits for the\n * wizard to post the new wallet address back. While the pop-up is open the partner page shows a dimming\n * overlay; the overlay is plain DOM (no React, no CSS files) so any partner can drop this in.\n *\n * The wallet's `/onboard` page is the pop-up side and speaks the same protocol in `./protocol`, but it uses the\n * message types and the `ONBOARD_PATH` from there, so the two sides cannot drift apart.\n */\nimport {\n isCaip2EvmChain,\n isOnboardCancelledMessage,\n isOnboardedMessage,\n onboardUrl,\n type OnboardCancelledMessage,\n} from \"./protocol\";\n\n/** Why {@link openAsseteraOnboarding} rejected. */\nexport type OnboardingErrorCode =\n \"popup_blocked\" | \"closed\" | \"cancelled\" | \"refused\" | \"failed\" | \"invalid_options\";\n\n/** Error thrown (well, rejected) by {@link openAsseteraOnboarding}. `code` is stable and safe to branch on. */\nexport class OnboardingError extends Error {\n readonly code: OnboardingErrorCode;\n\n constructor(code: OnboardingErrorCode, message: string) {\n super(message);\n this.name = \"OnboardingError\";\n this.code = code;\n }\n}\n\n/** The wallet the wizard created. */\nexport interface OnboardingResult {\n address: `0x${string}`;\n chain: string;\n status: \"approved\" | \"pending\";\n}\n\n/** Text of the dimming overlay, all optional. Any key left out keeps its English default. */\nexport interface OverlayLabels {\n title?: string;\n body?: string;\n focus?: string;\n cancel?: string;\n blocked?: string;\n}\n\n/** Options for {@link openAsseteraOnboarding}. */\nexport interface OnboardingOptions {\n /** Base URL of the wallet origin, e.g. `https://wallet.playground.assetera.com`. */\n walletUrl: string;\n /** CAIP-2 chain id the new wallet should be created on, e.g. `eip155:80002`. An invalid value rejects with `invalid_options`. */\n chain: string;\n /** Wizard language passed as `lang`, e.g. `\"en\"` or `\"de\"`. */\n locale?: string;\n /** `window.open` feature string. Defaults to a centred `\"popup,width=440,height=760,left=…,top=…\"`. */\n popupFeatures?: string;\n /** `true` (default) shows the dimming overlay, `false` hides it, an object overrides its text. */\n overlay?: boolean | OverlayLabels;\n /** Only used in the overlay text, e.g. `\"Musterbank\"`. */\n partnerName?: string;\n /** Injectable `window` for tests; defaults to `globalThis.window`. */\n window?: Window;\n}\n\nconst POPUP_NAME = \"assetera-wallet-onboarding\";\nconst POPUP_WIDTH = 440;\nconst POPUP_HEIGHT = 760;\nconst CLOSE_POLL_MS = 500;\nconst OVERLAY_Z_INDEX = 2147483000;\n\nconst DEFAULT_LABELS: Required<OverlayLabels> = {\n title: \"Continue in the Assetera Wallet window\",\n body: \"A secure Assetera Wallet window is open. Follow the steps there. This page continues by itself when you are done.\",\n focus: \"Show the wallet window\",\n cancel: \"Cancel\",\n blocked: \"Your browser blocked the Assetera Wallet window. Allow pop-ups for this site and try again.\",\n};\n\ninterface OverlayHandlers {\n onFocus: () => void;\n onCancel: () => void;\n}\n\nfunction defaultPopupFeatures(win: Window): string {\n const screenX = Number.isFinite(win.screenX) ? win.screenX : 0;\n const screenY = Number.isFinite(win.screenY) ? win.screenY : 0;\n const outerWidth = Number.isFinite(win.outerWidth) ? win.outerWidth : POPUP_WIDTH;\n const outerHeight = Number.isFinite(win.outerHeight) ? win.outerHeight : POPUP_HEIGHT;\n const left = Math.max(0, Math.round(screenX + (outerWidth - POPUP_WIDTH) / 2));\n const top = Math.max(0, Math.round(screenY + (outerHeight - POPUP_HEIGHT) / 2));\n return `popup,width=${POPUP_WIDTH},height=${POPUP_HEIGHT},left=${left},top=${top}`;\n}\n\nfunction resolveLabels(options: OnboardingOptions): Required<OverlayLabels> {\n const overrides: OverlayLabels =\n typeof options.overlay === \"object\" && options.overlay !== null ? options.overlay : {};\n const partnerName = options.partnerName;\n const defaultBody = partnerName\n ? `A secure Assetera Wallet window is open for ${partnerName}. Follow the steps there. This page continues by itself when you are done.`\n : DEFAULT_LABELS.body;\n return {\n title: overrides.title ?? DEFAULT_LABELS.title,\n body: overrides.body ?? defaultBody,\n focus: overrides.focus ?? DEFAULT_LABELS.focus,\n cancel: overrides.cancel ?? DEFAULT_LABELS.cancel,\n blocked: overrides.blocked ?? DEFAULT_LABELS.blocked,\n };\n}\n\nfunction cancelCode(reason: OnboardCancelledMessage[\"reason\"]): OnboardingErrorCode {\n if (reason === \"user\") return \"cancelled\";\n if (reason === \"refused\") return \"refused\";\n return \"failed\";\n}\n\nfunction cancelMessage(reason: OnboardCancelledMessage[\"reason\"]): string {\n if (reason === \"user\") return \"The user cancelled the Assetera Wallet onboarding.\";\n if (reason === \"refused\") return \"The Assetera Wallet refused the onboarding.\";\n return \"The Assetera Wallet onboarding failed.\";\n}\n\n/**\n * Build the dimming overlay. Text is inserted with `textContent` only and every style is inline, so the\n * overlay cannot pick up partner CSS and cannot be scripted through an injected string.\n */\nfunction showOverlay(win: Window, labels: Required<OverlayLabels>, handlers: OverlayHandlers): HTMLElement {\n const doc = win.document;\n const root = doc.createElement(\"div\");\n root.setAttribute(\"role\", \"dialog\");\n root.setAttribute(\"aria-modal\", \"true\");\n root.setAttribute(\"data-assetera-onboarding-overlay\", \"\");\n root.style.cssText = [\n \"position: fixed\",\n \"inset: 0\",\n \"display: flex\",\n \"align-items: center\",\n \"justify-content: center\",\n \"padding: 24px\",\n \"box-sizing: border-box\",\n \"background: rgba(15,20,30,0.6)\",\n `z-index: ${OVERLAY_Z_INDEX}`,\n \"font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n ].join(\"; \");\n\n const card = doc.createElement(\"div\");\n card.style.cssText = [\n \"box-sizing: border-box\",\n \"width: 100%\",\n \"max-width: 420px\",\n \"border-radius: 16px\",\n \"padding: 24px\",\n \"background: #ffffff\",\n \"color: #101828\",\n \"box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35)\",\n ].join(\"; \");\n\n const title = doc.createElement(\"h2\");\n title.textContent = labels.title;\n title.style.cssText = \"margin: 0 0 10px; font-size: 18px; line-height: 1.3; font-weight: 600;\";\n\n const body = doc.createElement(\"p\");\n body.textContent = labels.body;\n body.style.cssText = \"margin: 0 0 20px; font-size: 14px; line-height: 1.5; color: #475467;\";\n\n const focus = doc.createElement(\"button\");\n focus.type = \"button\";\n focus.textContent = labels.focus;\n focus.style.cssText = [\n \"padding: 10px 16px\",\n \"border: 0\",\n \"border-radius: 10px\",\n \"background: #101828\",\n \"color: #ffffff\",\n \"font: inherit\",\n \"font-weight: 600\",\n \"cursor: pointer\",\n ].join(\"; \");\n focus.addEventListener(\"click\", handlers.onFocus);\n\n const cancel = doc.createElement(\"button\");\n cancel.type = \"button\";\n cancel.textContent = labels.cancel;\n cancel.style.cssText = [\n \"padding: 10px 16px\",\n \"border: 0\",\n \"border-radius: 10px\",\n \"background: transparent\",\n \"color: #475467\",\n \"font: inherit\",\n \"cursor: pointer\",\n ].join(\"; \");\n cancel.addEventListener(\"click\", handlers.onCancel);\n\n const actions = doc.createElement(\"div\");\n actions.style.cssText = \"display: flex; gap: 8px; align-items: center;\";\n actions.append(focus, cancel);\n\n card.append(title, body, actions);\n root.append(card);\n doc.body.append(root);\n return root;\n}\n\n/**\n * Open the Assetera Wallet onboarding wizard in a pop-up and resolve with the new wallet address.\n *\n * Call this from a user click (a button handler). `window.open` runs synchronously inside the call, before any\n * `await`, so the browser allows it; if the browser blocks the pop-up the promise rejects with\n * `OnboardingError(\"popup_blocked\")` and no overlay is shown.\n *\n * The promise rejects with `OnboardingError` and one of these codes: `invalid_options` (bad chain or wallet\n * URL), `popup_blocked`, `closed` (the pop-up was closed first), `cancelled` (the user cancelled in the wizard\n * or in the overlay), `refused` (the wallet refused the onboarding) or `failed` (anything else in the wallet).\n */\nexport function openAsseteraOnboarding(options: OnboardingOptions): Promise<OnboardingResult> {\n const requestedWindow = options.window ?? (typeof window === \"undefined\" ? undefined : window);\n if (!requestedWindow) {\n return Promise.reject(\n new OnboardingError(\"invalid_options\", \"The Assetera Wallet onboarding can only run in a browser.\"),\n );\n }\n // A non-optional alias so TypeScript keeps the narrowed type inside the callbacks below.\n const targetWindow: Window = requestedWindow;\n if (!isCaip2EvmChain(options.chain)) {\n return Promise.reject(\n new OnboardingError(\n \"invalid_options\",\n `\"${options.chain}\" is not a CAIP-2 EVM chain id (for example \"eip155:80002\").`,\n ),\n );\n }\n let walletOrigin: string;\n try {\n walletOrigin = new URL(options.walletUrl).origin;\n } catch {\n return Promise.reject(\n new OnboardingError(\"invalid_options\", `\"${options.walletUrl}\" is not a valid wallet URL.`),\n );\n }\n\n const labels = resolveLabels(options);\n const overlayEnabled = options.overlay !== false;\n\n // MUST stay synchronous, before the first await, so the pop-up runs inside the caller's user activation.\n const popup = targetWindow.open(\n onboardUrl(options.walletUrl, targetWindow.location.origin, {\n chain: options.chain,\n ...(options.locale === undefined ? {} : { locale: options.locale }),\n }),\n POPUP_NAME,\n options.popupFeatures ?? defaultPopupFeatures(targetWindow),\n );\n\n if (!popup) {\n // Nothing was opened, so there is nothing to wait for and no overlay: the partner page stays usable.\n return Promise.reject(new OnboardingError(\"popup_blocked\", labels.blocked));\n }\n // A non-optional alias so TypeScript keeps the narrowed type inside the callbacks below.\n const activePopup: Window = popup;\n\n return new Promise<OnboardingResult>((resolve, reject) => {\n let settled = false;\n let closeTimer: ReturnType<typeof setInterval> | null = null;\n let overlay: HTMLElement | null = null;\n\n function cleanup(): void {\n targetWindow.removeEventListener(\"message\", onMessage);\n if (closeTimer !== null) {\n clearInterval(closeTimer);\n closeTimer = null;\n }\n overlay?.remove();\n overlay = null;\n }\n\n function settle(action: () => void): void {\n if (settled) return;\n settled = true;\n cleanup();\n action();\n }\n\n function cancel(): void {\n activePopup.close();\n settle(() =>\n reject(new OnboardingError(\"cancelled\", \"The user cancelled the Assetera Wallet onboarding.\")),\n );\n }\n\n function onMessage(event: MessageEvent): void {\n // Trust rule: accept only the wallet origin AND the exact pop-up we opened. Ignore everything else.\n if (event.origin !== walletOrigin) return;\n if ((event.source as unknown) !== activePopup) return;\n const data: unknown = event.data;\n if (isOnboardedMessage(data)) {\n settle(() => resolve({ address: data.address, chain: data.chain, status: data.status }));\n return;\n }\n if (isOnboardCancelledMessage(data)) {\n settle(() =>\n reject(new OnboardingError(cancelCode(data.reason), data.message ?? cancelMessage(data.reason))),\n );\n }\n }\n\n targetWindow.addEventListener(\"message\", onMessage);\n closeTimer = setInterval(() => {\n if (activePopup.closed) {\n settle(() =>\n reject(\n new OnboardingError(\n \"closed\",\n \"The Assetera Wallet window was closed before onboarding finished.\",\n ),\n ),\n );\n }\n }, CLOSE_POLL_MS);\n\n if (overlayEnabled) {\n overlay = showOverlay(targetWindow, labels, {\n onFocus: () => activePopup.focus(),\n onCancel: cancel,\n });\n }\n });\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,2 +1,55 @@
1
- export { CONNECT_PATH, DisconnectMessage, EventMessage, MESSAGE_PREFIX, PROTOCOL_VERSION, PartnerToWalletMessage, ReadyMessage, RequestMessage, ResponseMessage, RpcError, RpcErrorCode, SUPPORTED_METHODS, SupportedMethod, WalletToPartnerMessage, connectUrl, isDisconnectMessage, isEventMessage, isReadyMessage, isRequestMessage, isResponseMessage, isSupportedMethod } from './protocol.cjs';
1
+ export { CONNECT_PATH, DisconnectMessage, EventMessage, MESSAGE_PREFIX, ONBOARD_PATH, OnboardCancelledMessage, OnboardedMessage, PROTOCOL_VERSION, PartnerToWalletMessage, ReadyMessage, RequestMessage, ResponseMessage, RpcError, RpcErrorCode, SUPPORTED_METHODS, SupportedMethod, WalletToPartnerMessage, connectUrl, isCaip2EvmChain, isDisconnectMessage, isEventMessage, isOnboardCancelledMessage, isOnboardedMessage, isReadyMessage, isRequestMessage, isResponseMessage, isSupportedMethod, onboardUrl } from './protocol.cjs';
2
2
  export { A as AsseteraWalletProvider, a as AsseteraWalletProviderOptions, P as ProviderEvent, b as ProviderListener, c as ProviderRpcError, R as RequestArguments, d as createAsseteraWalletProvider } from './provider-BEIsX3q_.cjs';
3
+
4
+ /** Why {@link openAsseteraOnboarding} rejected. */
5
+ type OnboardingErrorCode = "popup_blocked" | "closed" | "cancelled" | "refused" | "failed" | "invalid_options";
6
+ /** Error thrown (well, rejected) by {@link openAsseteraOnboarding}. `code` is stable and safe to branch on. */
7
+ declare class OnboardingError extends Error {
8
+ readonly code: OnboardingErrorCode;
9
+ constructor(code: OnboardingErrorCode, message: string);
10
+ }
11
+ /** The wallet the wizard created. */
12
+ interface OnboardingResult {
13
+ address: `0x${string}`;
14
+ chain: string;
15
+ status: "approved" | "pending";
16
+ }
17
+ /** Text of the dimming overlay, all optional. Any key left out keeps its English default. */
18
+ interface OverlayLabels {
19
+ title?: string;
20
+ body?: string;
21
+ focus?: string;
22
+ cancel?: string;
23
+ blocked?: string;
24
+ }
25
+ /** Options for {@link openAsseteraOnboarding}. */
26
+ interface OnboardingOptions {
27
+ /** Base URL of the wallet origin, e.g. `https://wallet.playground.assetera.com`. */
28
+ walletUrl: string;
29
+ /** CAIP-2 chain id the new wallet should be created on, e.g. `eip155:80002`. An invalid value rejects with `invalid_options`. */
30
+ chain: string;
31
+ /** Wizard language passed as `lang`, e.g. `"en"` or `"de"`. */
32
+ locale?: string;
33
+ /** `window.open` feature string. Defaults to a centred `"popup,width=440,height=760,left=…,top=…"`. */
34
+ popupFeatures?: string;
35
+ /** `true` (default) shows the dimming overlay, `false` hides it, an object overrides its text. */
36
+ overlay?: boolean | OverlayLabels;
37
+ /** Only used in the overlay text, e.g. `"Musterbank"`. */
38
+ partnerName?: string;
39
+ /** Injectable `window` for tests; defaults to `globalThis.window`. */
40
+ window?: Window;
41
+ }
42
+ /**
43
+ * Open the Assetera Wallet onboarding wizard in a pop-up and resolve with the new wallet address.
44
+ *
45
+ * Call this from a user click (a button handler). `window.open` runs synchronously inside the call, before any
46
+ * `await`, so the browser allows it; if the browser blocks the pop-up the promise rejects with
47
+ * `OnboardingError("popup_blocked")` and no overlay is shown.
48
+ *
49
+ * The promise rejects with `OnboardingError` and one of these codes: `invalid_options` (bad chain or wallet
50
+ * URL), `popup_blocked`, `closed` (the pop-up was closed first), `cancelled` (the user cancelled in the wizard
51
+ * or in the overlay), `refused` (the wallet refused the onboarding) or `failed` (anything else in the wallet).
52
+ */
53
+ declare function openAsseteraOnboarding(options: OnboardingOptions): Promise<OnboardingResult>;
54
+
55
+ export { OnboardingError, type OnboardingErrorCode, type OnboardingOptions, type OnboardingResult, type OverlayLabels, openAsseteraOnboarding };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,55 @@
1
- export { CONNECT_PATH, DisconnectMessage, EventMessage, MESSAGE_PREFIX, PROTOCOL_VERSION, PartnerToWalletMessage, ReadyMessage, RequestMessage, ResponseMessage, RpcError, RpcErrorCode, SUPPORTED_METHODS, SupportedMethod, WalletToPartnerMessage, connectUrl, isDisconnectMessage, isEventMessage, isReadyMessage, isRequestMessage, isResponseMessage, isSupportedMethod } from './protocol.js';
1
+ export { CONNECT_PATH, DisconnectMessage, EventMessage, MESSAGE_PREFIX, ONBOARD_PATH, OnboardCancelledMessage, OnboardedMessage, PROTOCOL_VERSION, PartnerToWalletMessage, ReadyMessage, RequestMessage, ResponseMessage, RpcError, RpcErrorCode, SUPPORTED_METHODS, SupportedMethod, WalletToPartnerMessage, connectUrl, isCaip2EvmChain, isDisconnectMessage, isEventMessage, isOnboardCancelledMessage, isOnboardedMessage, isReadyMessage, isRequestMessage, isResponseMessage, isSupportedMethod, onboardUrl } from './protocol.js';
2
2
  export { A as AsseteraWalletProvider, a as AsseteraWalletProviderOptions, P as ProviderEvent, b as ProviderListener, c as ProviderRpcError, R as RequestArguments, d as createAsseteraWalletProvider } from './provider-BEIsX3q_.js';
3
+
4
+ /** Why {@link openAsseteraOnboarding} rejected. */
5
+ type OnboardingErrorCode = "popup_blocked" | "closed" | "cancelled" | "refused" | "failed" | "invalid_options";
6
+ /** Error thrown (well, rejected) by {@link openAsseteraOnboarding}. `code` is stable and safe to branch on. */
7
+ declare class OnboardingError extends Error {
8
+ readonly code: OnboardingErrorCode;
9
+ constructor(code: OnboardingErrorCode, message: string);
10
+ }
11
+ /** The wallet the wizard created. */
12
+ interface OnboardingResult {
13
+ address: `0x${string}`;
14
+ chain: string;
15
+ status: "approved" | "pending";
16
+ }
17
+ /** Text of the dimming overlay, all optional. Any key left out keeps its English default. */
18
+ interface OverlayLabels {
19
+ title?: string;
20
+ body?: string;
21
+ focus?: string;
22
+ cancel?: string;
23
+ blocked?: string;
24
+ }
25
+ /** Options for {@link openAsseteraOnboarding}. */
26
+ interface OnboardingOptions {
27
+ /** Base URL of the wallet origin, e.g. `https://wallet.playground.assetera.com`. */
28
+ walletUrl: string;
29
+ /** CAIP-2 chain id the new wallet should be created on, e.g. `eip155:80002`. An invalid value rejects with `invalid_options`. */
30
+ chain: string;
31
+ /** Wizard language passed as `lang`, e.g. `"en"` or `"de"`. */
32
+ locale?: string;
33
+ /** `window.open` feature string. Defaults to a centred `"popup,width=440,height=760,left=…,top=…"`. */
34
+ popupFeatures?: string;
35
+ /** `true` (default) shows the dimming overlay, `false` hides it, an object overrides its text. */
36
+ overlay?: boolean | OverlayLabels;
37
+ /** Only used in the overlay text, e.g. `"Musterbank"`. */
38
+ partnerName?: string;
39
+ /** Injectable `window` for tests; defaults to `globalThis.window`. */
40
+ window?: Window;
41
+ }
42
+ /**
43
+ * Open the Assetera Wallet onboarding wizard in a pop-up and resolve with the new wallet address.
44
+ *
45
+ * Call this from a user click (a button handler). `window.open` runs synchronously inside the call, before any
46
+ * `await`, so the browser allows it; if the browser blocks the pop-up the promise rejects with
47
+ * `OnboardingError("popup_blocked")` and no overlay is shown.
48
+ *
49
+ * The promise rejects with `OnboardingError` and one of these codes: `invalid_options` (bad chain or wallet
50
+ * URL), `popup_blocked`, `closed` (the pop-up was closed first), `cancelled` (the user cancelled in the wizard
51
+ * or in the overlay), `refused` (the wallet refused the onboarding) or `failed` (anything else in the wallet).
52
+ */
53
+ declare function openAsseteraOnboarding(options: OnboardingOptions): Promise<OnboardingResult>;
54
+
55
+ export { OnboardingError, type OnboardingErrorCode, type OnboardingOptions, type OnboardingResult, type OverlayLabels, openAsseteraOnboarding };
package/dist/index.js CHANGED
@@ -1,4 +1,228 @@
1
- export { ProviderRpcError, createAsseteraWalletProvider } from './chunk-QPNIGEP4.js';
2
- export { CONNECT_PATH, MESSAGE_PREFIX, PROTOCOL_VERSION, RpcErrorCode, SUPPORTED_METHODS, connectUrl, isDisconnectMessage, isEventMessage, isReadyMessage, isRequestMessage, isResponseMessage, isSupportedMethod } from './chunk-N6D53D3G.js';
1
+ export { ProviderRpcError, createAsseteraWalletProvider } from './chunk-RWUB6EIS.js';
2
+ import { isCaip2EvmChain, onboardUrl, isOnboardedMessage, isOnboardCancelledMessage } from './chunk-FRKTOKLC.js';
3
+ export { CONNECT_PATH, MESSAGE_PREFIX, ONBOARD_PATH, PROTOCOL_VERSION, RpcErrorCode, SUPPORTED_METHODS, connectUrl, isCaip2EvmChain, isDisconnectMessage, isEventMessage, isOnboardCancelledMessage, isOnboardedMessage, isReadyMessage, isRequestMessage, isResponseMessage, isSupportedMethod, onboardUrl } from './chunk-FRKTOKLC.js';
4
+
5
+ // src/onboarding.ts
6
+ var OnboardingError = class extends Error {
7
+ code;
8
+ constructor(code, message) {
9
+ super(message);
10
+ this.name = "OnboardingError";
11
+ this.code = code;
12
+ }
13
+ };
14
+ var POPUP_NAME = "assetera-wallet-onboarding";
15
+ var POPUP_WIDTH = 440;
16
+ var POPUP_HEIGHT = 760;
17
+ var CLOSE_POLL_MS = 500;
18
+ var OVERLAY_Z_INDEX = 2147483e3;
19
+ var DEFAULT_LABELS = {
20
+ title: "Continue in the Assetera Wallet window",
21
+ body: "A secure Assetera Wallet window is open. Follow the steps there. This page continues by itself when you are done.",
22
+ focus: "Show the wallet window",
23
+ cancel: "Cancel",
24
+ blocked: "Your browser blocked the Assetera Wallet window. Allow pop-ups for this site and try again."
25
+ };
26
+ function defaultPopupFeatures(win) {
27
+ const screenX = Number.isFinite(win.screenX) ? win.screenX : 0;
28
+ const screenY = Number.isFinite(win.screenY) ? win.screenY : 0;
29
+ const outerWidth = Number.isFinite(win.outerWidth) ? win.outerWidth : POPUP_WIDTH;
30
+ const outerHeight = Number.isFinite(win.outerHeight) ? win.outerHeight : POPUP_HEIGHT;
31
+ const left = Math.max(0, Math.round(screenX + (outerWidth - POPUP_WIDTH) / 2));
32
+ const top = Math.max(0, Math.round(screenY + (outerHeight - POPUP_HEIGHT) / 2));
33
+ return `popup,width=${POPUP_WIDTH},height=${POPUP_HEIGHT},left=${left},top=${top}`;
34
+ }
35
+ function resolveLabels(options) {
36
+ const overrides = typeof options.overlay === "object" && options.overlay !== null ? options.overlay : {};
37
+ const partnerName = options.partnerName;
38
+ const defaultBody = partnerName ? `A secure Assetera Wallet window is open for ${partnerName}. Follow the steps there. This page continues by itself when you are done.` : DEFAULT_LABELS.body;
39
+ return {
40
+ title: overrides.title ?? DEFAULT_LABELS.title,
41
+ body: overrides.body ?? defaultBody,
42
+ focus: overrides.focus ?? DEFAULT_LABELS.focus,
43
+ cancel: overrides.cancel ?? DEFAULT_LABELS.cancel,
44
+ blocked: overrides.blocked ?? DEFAULT_LABELS.blocked
45
+ };
46
+ }
47
+ function cancelCode(reason) {
48
+ if (reason === "user") return "cancelled";
49
+ if (reason === "refused") return "refused";
50
+ return "failed";
51
+ }
52
+ function cancelMessage(reason) {
53
+ if (reason === "user") return "The user cancelled the Assetera Wallet onboarding.";
54
+ if (reason === "refused") return "The Assetera Wallet refused the onboarding.";
55
+ return "The Assetera Wallet onboarding failed.";
56
+ }
57
+ function showOverlay(win, labels, handlers) {
58
+ const doc = win.document;
59
+ const root = doc.createElement("div");
60
+ root.setAttribute("role", "dialog");
61
+ root.setAttribute("aria-modal", "true");
62
+ root.setAttribute("data-assetera-onboarding-overlay", "");
63
+ root.style.cssText = [
64
+ "position: fixed",
65
+ "inset: 0",
66
+ "display: flex",
67
+ "align-items: center",
68
+ "justify-content: center",
69
+ "padding: 24px",
70
+ "box-sizing: border-box",
71
+ "background: rgba(15,20,30,0.6)",
72
+ `z-index: ${OVERLAY_Z_INDEX}`,
73
+ "font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif"
74
+ ].join("; ");
75
+ const card = doc.createElement("div");
76
+ card.style.cssText = [
77
+ "box-sizing: border-box",
78
+ "width: 100%",
79
+ "max-width: 420px",
80
+ "border-radius: 16px",
81
+ "padding: 24px",
82
+ "background: #ffffff",
83
+ "color: #101828",
84
+ "box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35)"
85
+ ].join("; ");
86
+ const title = doc.createElement("h2");
87
+ title.textContent = labels.title;
88
+ title.style.cssText = "margin: 0 0 10px; font-size: 18px; line-height: 1.3; font-weight: 600;";
89
+ const body = doc.createElement("p");
90
+ body.textContent = labels.body;
91
+ body.style.cssText = "margin: 0 0 20px; font-size: 14px; line-height: 1.5; color: #475467;";
92
+ const focus = doc.createElement("button");
93
+ focus.type = "button";
94
+ focus.textContent = labels.focus;
95
+ focus.style.cssText = [
96
+ "padding: 10px 16px",
97
+ "border: 0",
98
+ "border-radius: 10px",
99
+ "background: #101828",
100
+ "color: #ffffff",
101
+ "font: inherit",
102
+ "font-weight: 600",
103
+ "cursor: pointer"
104
+ ].join("; ");
105
+ focus.addEventListener("click", handlers.onFocus);
106
+ const cancel = doc.createElement("button");
107
+ cancel.type = "button";
108
+ cancel.textContent = labels.cancel;
109
+ cancel.style.cssText = [
110
+ "padding: 10px 16px",
111
+ "border: 0",
112
+ "border-radius: 10px",
113
+ "background: transparent",
114
+ "color: #475467",
115
+ "font: inherit",
116
+ "cursor: pointer"
117
+ ].join("; ");
118
+ cancel.addEventListener("click", handlers.onCancel);
119
+ const actions = doc.createElement("div");
120
+ actions.style.cssText = "display: flex; gap: 8px; align-items: center;";
121
+ actions.append(focus, cancel);
122
+ card.append(title, body, actions);
123
+ root.append(card);
124
+ doc.body.append(root);
125
+ return root;
126
+ }
127
+ function openAsseteraOnboarding(options) {
128
+ const requestedWindow = options.window ?? (typeof window === "undefined" ? void 0 : window);
129
+ if (!requestedWindow) {
130
+ return Promise.reject(
131
+ new OnboardingError("invalid_options", "The Assetera Wallet onboarding can only run in a browser.")
132
+ );
133
+ }
134
+ const targetWindow = requestedWindow;
135
+ if (!isCaip2EvmChain(options.chain)) {
136
+ return Promise.reject(
137
+ new OnboardingError(
138
+ "invalid_options",
139
+ `"${options.chain}" is not a CAIP-2 EVM chain id (for example "eip155:80002").`
140
+ )
141
+ );
142
+ }
143
+ let walletOrigin;
144
+ try {
145
+ walletOrigin = new URL(options.walletUrl).origin;
146
+ } catch {
147
+ return Promise.reject(
148
+ new OnboardingError("invalid_options", `"${options.walletUrl}" is not a valid wallet URL.`)
149
+ );
150
+ }
151
+ const labels = resolveLabels(options);
152
+ const overlayEnabled = options.overlay !== false;
153
+ const popup = targetWindow.open(
154
+ onboardUrl(options.walletUrl, targetWindow.location.origin, {
155
+ chain: options.chain,
156
+ ...options.locale === void 0 ? {} : { locale: options.locale }
157
+ }),
158
+ POPUP_NAME,
159
+ options.popupFeatures ?? defaultPopupFeatures(targetWindow)
160
+ );
161
+ if (!popup) {
162
+ return Promise.reject(new OnboardingError("popup_blocked", labels.blocked));
163
+ }
164
+ const activePopup = popup;
165
+ return new Promise((resolve, reject) => {
166
+ let settled = false;
167
+ let closeTimer = null;
168
+ let overlay = null;
169
+ function cleanup() {
170
+ targetWindow.removeEventListener("message", onMessage);
171
+ if (closeTimer !== null) {
172
+ clearInterval(closeTimer);
173
+ closeTimer = null;
174
+ }
175
+ overlay?.remove();
176
+ overlay = null;
177
+ }
178
+ function settle(action) {
179
+ if (settled) return;
180
+ settled = true;
181
+ cleanup();
182
+ action();
183
+ }
184
+ function cancel() {
185
+ activePopup.close();
186
+ settle(
187
+ () => reject(new OnboardingError("cancelled", "The user cancelled the Assetera Wallet onboarding."))
188
+ );
189
+ }
190
+ function onMessage(event) {
191
+ if (event.origin !== walletOrigin) return;
192
+ if (event.source !== activePopup) return;
193
+ const data = event.data;
194
+ if (isOnboardedMessage(data)) {
195
+ settle(() => resolve({ address: data.address, chain: data.chain, status: data.status }));
196
+ return;
197
+ }
198
+ if (isOnboardCancelledMessage(data)) {
199
+ settle(
200
+ () => reject(new OnboardingError(cancelCode(data.reason), data.message ?? cancelMessage(data.reason)))
201
+ );
202
+ }
203
+ }
204
+ targetWindow.addEventListener("message", onMessage);
205
+ closeTimer = setInterval(() => {
206
+ if (activePopup.closed) {
207
+ settle(
208
+ () => reject(
209
+ new OnboardingError(
210
+ "closed",
211
+ "The Assetera Wallet window was closed before onboarding finished."
212
+ )
213
+ )
214
+ );
215
+ }
216
+ }, CLOSE_POLL_MS);
217
+ if (overlayEnabled) {
218
+ overlay = showOverlay(targetWindow, labels, {
219
+ onFocus: () => activePopup.focus(),
220
+ onCancel: cancel
221
+ });
222
+ }
223
+ });
224
+ }
225
+
226
+ export { OnboardingError, openAsseteraOnboarding };
3
227
  //# sourceMappingURL=index.js.map
4
228
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
1
+ {"version":3,"sources":["../src/onboarding.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Onboarding opener for the Assetera Wallet: the partner side of the `/onboard` wizard (AO-1274).\n *\n * A tied-agent bank site shows a \"Create an Assetera wallet\" button. On the click, this module opens the wallet\n * pop-up in onboarding mode synchronously (so the browser treats it as part of the click) and waits for the\n * wizard to post the new wallet address back. While the pop-up is open the partner page shows a dimming\n * overlay; the overlay is plain DOM (no React, no CSS files) so any partner can drop this in.\n *\n * The wallet's `/onboard` page is the pop-up side and speaks the same protocol in `./protocol`, but it uses the\n * message types and the `ONBOARD_PATH` from there, so the two sides cannot drift apart.\n */\nimport {\n isCaip2EvmChain,\n isOnboardCancelledMessage,\n isOnboardedMessage,\n onboardUrl,\n type OnboardCancelledMessage,\n} from \"./protocol\";\n\n/** Why {@link openAsseteraOnboarding} rejected. */\nexport type OnboardingErrorCode =\n \"popup_blocked\" | \"closed\" | \"cancelled\" | \"refused\" | \"failed\" | \"invalid_options\";\n\n/** Error thrown (well, rejected) by {@link openAsseteraOnboarding}. `code` is stable and safe to branch on. */\nexport class OnboardingError extends Error {\n readonly code: OnboardingErrorCode;\n\n constructor(code: OnboardingErrorCode, message: string) {\n super(message);\n this.name = \"OnboardingError\";\n this.code = code;\n }\n}\n\n/** The wallet the wizard created. */\nexport interface OnboardingResult {\n address: `0x${string}`;\n chain: string;\n status: \"approved\" | \"pending\";\n}\n\n/** Text of the dimming overlay, all optional. Any key left out keeps its English default. */\nexport interface OverlayLabels {\n title?: string;\n body?: string;\n focus?: string;\n cancel?: string;\n blocked?: string;\n}\n\n/** Options for {@link openAsseteraOnboarding}. */\nexport interface OnboardingOptions {\n /** Base URL of the wallet origin, e.g. `https://wallet.playground.assetera.com`. */\n walletUrl: string;\n /** CAIP-2 chain id the new wallet should be created on, e.g. `eip155:80002`. An invalid value rejects with `invalid_options`. */\n chain: string;\n /** Wizard language passed as `lang`, e.g. `\"en\"` or `\"de\"`. */\n locale?: string;\n /** `window.open` feature string. Defaults to a centred `\"popup,width=440,height=760,left=…,top=…\"`. */\n popupFeatures?: string;\n /** `true` (default) shows the dimming overlay, `false` hides it, an object overrides its text. */\n overlay?: boolean | OverlayLabels;\n /** Only used in the overlay text, e.g. `\"Musterbank\"`. */\n partnerName?: string;\n /** Injectable `window` for tests; defaults to `globalThis.window`. */\n window?: Window;\n}\n\nconst POPUP_NAME = \"assetera-wallet-onboarding\";\nconst POPUP_WIDTH = 440;\nconst POPUP_HEIGHT = 760;\nconst CLOSE_POLL_MS = 500;\nconst OVERLAY_Z_INDEX = 2147483000;\n\nconst DEFAULT_LABELS: Required<OverlayLabels> = {\n title: \"Continue in the Assetera Wallet window\",\n body: \"A secure Assetera Wallet window is open. Follow the steps there. This page continues by itself when you are done.\",\n focus: \"Show the wallet window\",\n cancel: \"Cancel\",\n blocked: \"Your browser blocked the Assetera Wallet window. Allow pop-ups for this site and try again.\",\n};\n\ninterface OverlayHandlers {\n onFocus: () => void;\n onCancel: () => void;\n}\n\nfunction defaultPopupFeatures(win: Window): string {\n const screenX = Number.isFinite(win.screenX) ? win.screenX : 0;\n const screenY = Number.isFinite(win.screenY) ? win.screenY : 0;\n const outerWidth = Number.isFinite(win.outerWidth) ? win.outerWidth : POPUP_WIDTH;\n const outerHeight = Number.isFinite(win.outerHeight) ? win.outerHeight : POPUP_HEIGHT;\n const left = Math.max(0, Math.round(screenX + (outerWidth - POPUP_WIDTH) / 2));\n const top = Math.max(0, Math.round(screenY + (outerHeight - POPUP_HEIGHT) / 2));\n return `popup,width=${POPUP_WIDTH},height=${POPUP_HEIGHT},left=${left},top=${top}`;\n}\n\nfunction resolveLabels(options: OnboardingOptions): Required<OverlayLabels> {\n const overrides: OverlayLabels =\n typeof options.overlay === \"object\" && options.overlay !== null ? options.overlay : {};\n const partnerName = options.partnerName;\n const defaultBody = partnerName\n ? `A secure Assetera Wallet window is open for ${partnerName}. Follow the steps there. This page continues by itself when you are done.`\n : DEFAULT_LABELS.body;\n return {\n title: overrides.title ?? DEFAULT_LABELS.title,\n body: overrides.body ?? defaultBody,\n focus: overrides.focus ?? DEFAULT_LABELS.focus,\n cancel: overrides.cancel ?? DEFAULT_LABELS.cancel,\n blocked: overrides.blocked ?? DEFAULT_LABELS.blocked,\n };\n}\n\nfunction cancelCode(reason: OnboardCancelledMessage[\"reason\"]): OnboardingErrorCode {\n if (reason === \"user\") return \"cancelled\";\n if (reason === \"refused\") return \"refused\";\n return \"failed\";\n}\n\nfunction cancelMessage(reason: OnboardCancelledMessage[\"reason\"]): string {\n if (reason === \"user\") return \"The user cancelled the Assetera Wallet onboarding.\";\n if (reason === \"refused\") return \"The Assetera Wallet refused the onboarding.\";\n return \"The Assetera Wallet onboarding failed.\";\n}\n\n/**\n * Build the dimming overlay. Text is inserted with `textContent` only and every style is inline, so the\n * overlay cannot pick up partner CSS and cannot be scripted through an injected string.\n */\nfunction showOverlay(win: Window, labels: Required<OverlayLabels>, handlers: OverlayHandlers): HTMLElement {\n const doc = win.document;\n const root = doc.createElement(\"div\");\n root.setAttribute(\"role\", \"dialog\");\n root.setAttribute(\"aria-modal\", \"true\");\n root.setAttribute(\"data-assetera-onboarding-overlay\", \"\");\n root.style.cssText = [\n \"position: fixed\",\n \"inset: 0\",\n \"display: flex\",\n \"align-items: center\",\n \"justify-content: center\",\n \"padding: 24px\",\n \"box-sizing: border-box\",\n \"background: rgba(15,20,30,0.6)\",\n `z-index: ${OVERLAY_Z_INDEX}`,\n \"font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n ].join(\"; \");\n\n const card = doc.createElement(\"div\");\n card.style.cssText = [\n \"box-sizing: border-box\",\n \"width: 100%\",\n \"max-width: 420px\",\n \"border-radius: 16px\",\n \"padding: 24px\",\n \"background: #ffffff\",\n \"color: #101828\",\n \"box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35)\",\n ].join(\"; \");\n\n const title = doc.createElement(\"h2\");\n title.textContent = labels.title;\n title.style.cssText = \"margin: 0 0 10px; font-size: 18px; line-height: 1.3; font-weight: 600;\";\n\n const body = doc.createElement(\"p\");\n body.textContent = labels.body;\n body.style.cssText = \"margin: 0 0 20px; font-size: 14px; line-height: 1.5; color: #475467;\";\n\n const focus = doc.createElement(\"button\");\n focus.type = \"button\";\n focus.textContent = labels.focus;\n focus.style.cssText = [\n \"padding: 10px 16px\",\n \"border: 0\",\n \"border-radius: 10px\",\n \"background: #101828\",\n \"color: #ffffff\",\n \"font: inherit\",\n \"font-weight: 600\",\n \"cursor: pointer\",\n ].join(\"; \");\n focus.addEventListener(\"click\", handlers.onFocus);\n\n const cancel = doc.createElement(\"button\");\n cancel.type = \"button\";\n cancel.textContent = labels.cancel;\n cancel.style.cssText = [\n \"padding: 10px 16px\",\n \"border: 0\",\n \"border-radius: 10px\",\n \"background: transparent\",\n \"color: #475467\",\n \"font: inherit\",\n \"cursor: pointer\",\n ].join(\"; \");\n cancel.addEventListener(\"click\", handlers.onCancel);\n\n const actions = doc.createElement(\"div\");\n actions.style.cssText = \"display: flex; gap: 8px; align-items: center;\";\n actions.append(focus, cancel);\n\n card.append(title, body, actions);\n root.append(card);\n doc.body.append(root);\n return root;\n}\n\n/**\n * Open the Assetera Wallet onboarding wizard in a pop-up and resolve with the new wallet address.\n *\n * Call this from a user click (a button handler). `window.open` runs synchronously inside the call, before any\n * `await`, so the browser allows it; if the browser blocks the pop-up the promise rejects with\n * `OnboardingError(\"popup_blocked\")` and no overlay is shown.\n *\n * The promise rejects with `OnboardingError` and one of these codes: `invalid_options` (bad chain or wallet\n * URL), `popup_blocked`, `closed` (the pop-up was closed first), `cancelled` (the user cancelled in the wizard\n * or in the overlay), `refused` (the wallet refused the onboarding) or `failed` (anything else in the wallet).\n */\nexport function openAsseteraOnboarding(options: OnboardingOptions): Promise<OnboardingResult> {\n const requestedWindow = options.window ?? (typeof window === \"undefined\" ? undefined : window);\n if (!requestedWindow) {\n return Promise.reject(\n new OnboardingError(\"invalid_options\", \"The Assetera Wallet onboarding can only run in a browser.\"),\n );\n }\n // A non-optional alias so TypeScript keeps the narrowed type inside the callbacks below.\n const targetWindow: Window = requestedWindow;\n if (!isCaip2EvmChain(options.chain)) {\n return Promise.reject(\n new OnboardingError(\n \"invalid_options\",\n `\"${options.chain}\" is not a CAIP-2 EVM chain id (for example \"eip155:80002\").`,\n ),\n );\n }\n let walletOrigin: string;\n try {\n walletOrigin = new URL(options.walletUrl).origin;\n } catch {\n return Promise.reject(\n new OnboardingError(\"invalid_options\", `\"${options.walletUrl}\" is not a valid wallet URL.`),\n );\n }\n\n const labels = resolveLabels(options);\n const overlayEnabled = options.overlay !== false;\n\n // MUST stay synchronous, before the first await, so the pop-up runs inside the caller's user activation.\n const popup = targetWindow.open(\n onboardUrl(options.walletUrl, targetWindow.location.origin, {\n chain: options.chain,\n ...(options.locale === undefined ? {} : { locale: options.locale }),\n }),\n POPUP_NAME,\n options.popupFeatures ?? defaultPopupFeatures(targetWindow),\n );\n\n if (!popup) {\n // Nothing was opened, so there is nothing to wait for and no overlay: the partner page stays usable.\n return Promise.reject(new OnboardingError(\"popup_blocked\", labels.blocked));\n }\n // A non-optional alias so TypeScript keeps the narrowed type inside the callbacks below.\n const activePopup: Window = popup;\n\n return new Promise<OnboardingResult>((resolve, reject) => {\n let settled = false;\n let closeTimer: ReturnType<typeof setInterval> | null = null;\n let overlay: HTMLElement | null = null;\n\n function cleanup(): void {\n targetWindow.removeEventListener(\"message\", onMessage);\n if (closeTimer !== null) {\n clearInterval(closeTimer);\n closeTimer = null;\n }\n overlay?.remove();\n overlay = null;\n }\n\n function settle(action: () => void): void {\n if (settled) return;\n settled = true;\n cleanup();\n action();\n }\n\n function cancel(): void {\n activePopup.close();\n settle(() =>\n reject(new OnboardingError(\"cancelled\", \"The user cancelled the Assetera Wallet onboarding.\")),\n );\n }\n\n function onMessage(event: MessageEvent): void {\n // Trust rule: accept only the wallet origin AND the exact pop-up we opened. Ignore everything else.\n if (event.origin !== walletOrigin) return;\n if ((event.source as unknown) !== activePopup) return;\n const data: unknown = event.data;\n if (isOnboardedMessage(data)) {\n settle(() => resolve({ address: data.address, chain: data.chain, status: data.status }));\n return;\n }\n if (isOnboardCancelledMessage(data)) {\n settle(() =>\n reject(new OnboardingError(cancelCode(data.reason), data.message ?? cancelMessage(data.reason))),\n );\n }\n }\n\n targetWindow.addEventListener(\"message\", onMessage);\n closeTimer = setInterval(() => {\n if (activePopup.closed) {\n settle(() =>\n reject(\n new OnboardingError(\n \"closed\",\n \"The Assetera Wallet window was closed before onboarding finished.\",\n ),\n ),\n );\n }\n }, CLOSE_POLL_MS);\n\n if (overlayEnabled) {\n overlay = showOverlay(targetWindow, labels, {\n onFocus: () => activePopup.focus(),\n onCancel: cancel,\n });\n }\n });\n}\n"]}