From 6d7dc1c7928015738f95618db01f2f1b42606187 Mon Sep 17 00:00:00 2001 From: mega123-art Date: Mon, 15 Jun 2026 16:36:52 +0530 Subject: [PATCH] feat: implement QR-to-login and unified logout (#32) --- packages/core/AGENTS.md | 4 + packages/core/package.json | 2 +- packages/core/src/account/keyPolicy.ts | 7 +- packages/core/src/account/login.spec.ts | 116 ++ packages/core/src/account/login.ts | 41 +- packages/core/src/account/transport.ts | 29 + packages/core/src/account/webWallet.ts | 20 +- packages/core/src/chat/session.ts | 2 + packages/core/src/chat/ui/onboarding.ts | 22 + packages/core/src/index.ts | 3 + packages/wallet-connect/package.json | 29 + packages/wallet-connect/src/index.ts | 152 +++ packages/wallet-connect/tsconfig.json | 15 + pnpm-lock.yaml | 988 +++++++++++++++++- scripts/wc-poc.ts | 40 + .../java/com/iqlabs/agentnet/WalletBridge.kt | 51 + surfaces/cli/package.json | 4 +- surfaces/cli/src/app.tsx | 167 ++- surfaces/cli/src/bootstrap.ts | 7 +- surfaces/cli/src/index.tsx | 16 + surfaces/cli/src/views/Chat.tsx | 12 +- surfaces/localhost/package.json | 1 + surfaces/localhost/src/index.ts | 66 +- surfaces/vscode/package.json | 3 +- surfaces/vscode/src/extension.ts | 64 +- surfaces/webview/package.json | 3 + .../webview/src/onboarding/ConnectWallet.tsx | 109 +- .../webview/src/onboarding/androidWallet.ts | 46 +- surfaces/webview/src/state/store.tsx | 35 +- surfaces/webview/src/transport/protocol.ts | 2 + 30 files changed, 1972 insertions(+), 84 deletions(-) create mode 100644 packages/core/AGENTS.md create mode 100644 packages/core/src/account/login.spec.ts create mode 100644 packages/core/src/account/transport.ts create mode 100644 packages/wallet-connect/package.json create mode 100644 packages/wallet-connect/src/index.ts create mode 100644 packages/wallet-connect/tsconfig.json create mode 100644 scripts/wc-poc.ts diff --git a/packages/core/AGENTS.md b/packages/core/AGENTS.md new file mode 100644 index 0000000..3841131 --- /dev/null +++ b/packages/core/AGENTS.md @@ -0,0 +1,4 @@ + +# Shared memory (managed by AgentNet — do not edit between the markers) + + diff --git a/packages/core/package.json b/packages/core/package.json index c037ec5..54e678a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -10,7 +10,7 @@ "./*.js": "./src/*.ts" }, "scripts": { - "build": "tsup", + "build": "tsup src/index.ts", "test": "vitest run", "test:run": "tsx test/test-runtime.ts", "test:memory": "tsx test/test-memory.ts", diff --git a/packages/core/src/account/keyPolicy.ts b/packages/core/src/account/keyPolicy.ts index e71fc4c..d8cb7c3 100644 --- a/packages/core/src/account/keyPolicy.ts +++ b/packages/core/src/account/keyPolicy.ts @@ -26,7 +26,7 @@ export interface KeyPolicy { // an ephemeral key is already dropped without calling this. clear() is the explicit // path for when a surface keeps one store across logins (e.g. the persisted toggle // wiping the in-memory copy while the vault entry stays) — wired when that lands. - clear(): void; + clear(address?: string): Promise | void; } // Memory-only: derive once per process, cache, drop on clear(). Current behavior, @@ -69,8 +69,11 @@ export function persistedKey(vault: KeyVault): KeyPolicy { } return key; }, - clear() { + async clear(address?: string) { key = undefined; + if (address) { + await vault.remove(address); + } }, }; } diff --git a/packages/core/src/account/login.spec.ts b/packages/core/src/account/login.spec.ts new file mode 100644 index 0000000..73b5ffb --- /dev/null +++ b/packages/core/src/account/login.spec.ts @@ -0,0 +1,116 @@ +import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; +import { mkdtempSync, rmSync, writeFileSync, existsSync, mkdirSync } from "node:fs"; +import { join } from "node:path"; +import { tmpdir } from "node:os"; +import { logout } from "./login.js"; +import { tokenFile, configFile, sessionsDir } from "../core/paths.js"; +import { saveCodexApiKey, getCodexApiKey } from "./codexAuth.js"; +import { ephemeralKey, persistedKey, type KeyVault } from "./keyPolicy.js"; +import type { SessionKey } from "../core/crypto.js"; + +let home: string; + +beforeEach(() => { + home = mkdtempSync(join(tmpdir(), "agentnet-test-login-")); + process.env.AGENTNET_HOME = home; + // Make sure directories exist + mkdirSync(join(home, "tokens"), { recursive: true }); + mkdirSync(join(home, "sessions"), { recursive: true }); +}); + +afterEach(() => { + delete process.env.AGENTNET_HOME; + rmSync(home, { recursive: true, force: true }); +}); + +describe("unified logout logic", () => { + it("soft logout disconnects cloud but preserves session files and Codex API key", async () => { + // Setup + writeFileSync(configFile(), JSON.stringify({ kind: "gdrive", google_client_id: "client-id" })); + writeFileSync(tokenFile("google"), JSON.stringify({ access_token: "tok" })); + + const walletAddress = "5ey2ja1KstPwMQRx7EokG2dfJksAGGPA"; + const sessionWalletDir = join(sessionsDir(), walletAddress); + mkdirSync(sessionWalletDir, { recursive: true }); + writeFileSync(join(sessionWalletDir, "history.bin"), "some history data"); + + await saveCodexApiKey("fake-codex-key"); + + // Perform soft logout + await logout({ policy: "soft" }); + + // Assert cloud disconnected + expect(existsSync(tokenFile("google"))).toBe(false); + + // Config file should only retain app credentials (google_client_id) + const configData = JSON.parse(readFileSyncText(configFile())); + expect(configData.kind).toBeUndefined(); + expect(configData.google_client_id).toBe("client-id"); + + // Assert session files and Codex API key are preserved + expect(existsSync(join(sessionWalletDir, "history.bin"))).toBe(true); + expect(await getCodexApiKey()).toBe("fake-codex-key"); + }); + + it("full logout disconnects cloud, deletes address-specific session logs, and wipes Codex API key", async () => { + // Setup + writeFileSync(configFile(), JSON.stringify({ kind: "gdrive", google_client_id: "client-id" })); + writeFileSync(tokenFile("google"), JSON.stringify({ access_token: "tok" })); + + const walletAddress = "5ey2ja1KstPwMQRx7EokG2dfJksAGGPA"; + const sessionWalletDir = join(sessionsDir(), walletAddress); + mkdirSync(sessionWalletDir, { recursive: true }); + writeFileSync(join(sessionWalletDir, "history.bin"), "some history data"); + + // Another wallet's session should NOT be wiped + const otherWalletAddress = "otherAddress123"; + const otherSessionWalletDir = join(sessionsDir(), otherWalletAddress); + mkdirSync(otherSessionWalletDir, { recursive: true }); + writeFileSync(join(otherSessionWalletDir, "history.bin"), "other data"); + + await saveCodexApiKey("fake-codex-key"); + + // Perform full logout + await logout({ policy: "full", address: walletAddress }); + + // Assert cloud disconnected + expect(existsSync(tokenFile("google"))).toBe(false); + + // Assert target wallet session files are wiped + expect(existsSync(join(sessionWalletDir, "history.bin"))).toBe(false); + expect(existsSync(sessionWalletDir)).toBe(false); + + // Assert other wallet session files are preserved + expect(existsSync(join(otherSessionWalletDir, "history.bin"))).toBe(true); + + // Assert Codex API key is wiped + expect(await getCodexApiKey()).toBeNull(); + }); + + it("calls KeyPolicy clear under soft and full logout", async () => { + // Setup mock KeyVault + const mockVault: KeyVault = { + read: vi.fn(), + write: vi.fn(), + remove: vi.fn(), + }; + + const policy = persistedKey(mockVault); + const walletAddress = "5ey2ja1KstPwMQRx7EokG2dfJksAGGPA"; + + // Test soft logout + await logout({ policy: "soft", keyPolicy: policy }); + // Soft logout calls clear() without address, which clears in-memory but doesn't call vault.remove + expect(mockVault.remove).not.toHaveBeenCalled(); + + // Test full logout + await logout({ policy: "full", address: walletAddress, keyPolicy: policy }); + // Full logout should call clear(address) which invokes vault.remove(address) + expect(mockVault.remove).toHaveBeenCalledWith(walletAddress); + }); +}); + +import { readFileSync } from "node:fs"; +function readFileSyncText(path: string): string { + return readFileSync(path, "utf8"); +} diff --git a/packages/core/src/account/login.ts b/packages/core/src/account/login.ts index 67b006a..70442f9 100644 --- a/packages/core/src/account/login.ts +++ b/packages/core/src/account/login.ts @@ -10,7 +10,10 @@ // live separately (oauth.ts → tokens/google.json). Our server stores nothing. import { readFile, writeFile, rm } from "node:fs/promises"; -import { configFile, tokenFile, rootDir, ensureDir } from "../core/paths.js"; +import { join } from "node:path"; +import { configFile, tokenFile, rootDir, ensureDir, sessionsDir } from "../core/paths.js"; +import { deleteCodexApiKey } from "./codexAuth.js"; +import type { KeyPolicy, KeyVault } from "./keyPolicy.js"; import { buildStorage, type StorageConfig, type StorageKind } from "./storage/adapter.js"; import { manualStorage, migrateLocalSessions } from "./storage/manual.js"; import { mirrorStorage, type CloudStatus } from "./storage/mirror.js"; @@ -173,8 +176,40 @@ export async function disconnectCloud(): Promise { } } -/** @deprecated use disconnectCloud — kept for callers still importing logout. */ -export const logout = disconnectCloud; +/** "soft": drop in-memory state + cloud binding (default). "full": soft + wipe this wallet's local data. */ +export type LogoutPolicy = "soft" | "full"; + +/** + * Unified logout. Soft = forget cloud binding + in-memory session key. Full = soft + + * delete this wallet's local session logs and cached Codex API key. + * + * Always KEEP: keypair file, installed skills, claude/codex own home dirs, cli-map. + * Pass `address` when policy is "full" (the wallet's base58 address). + * Pass `keyPolicy` to also clear its cached session key (and vault if address is provided). + */ +export async function logout(opts: { + policy?: LogoutPolicy; + address?: string; + keyPolicy?: KeyPolicy; +} = {}): Promise { + const { policy = "soft", address, keyPolicy } = opts; + + await disconnectCloud(); + + if (policy === "full") { + if (keyPolicy) { + await keyPolicy.clear(address); + } + if (address) { + await rm(join(sessionsDir(), address), { recursive: true, force: true }); + } + await deleteCodexApiKey(); + } else { + if (keyPolicy) { + await keyPolicy.clear(); + } + } +} /** Save Google OAuth app credentials without touching the storage kind. */ export async function saveGoogleCreds(clientId: string, clientSecret: string): Promise { diff --git a/packages/core/src/account/transport.ts b/packages/core/src/account/transport.ts new file mode 100644 index 0000000..18adfba --- /dev/null +++ b/packages/core/src/account/transport.ts @@ -0,0 +1,29 @@ +import { PublicKey, type Transaction, type VersionedTransaction } from "@solana/web3.js"; +import type { Wallet } from "../runtime/contract.js"; + +export interface WalletTransport { + connect(): Promise<{ uri: string; approved: Promise<{ address: string }> }>; // uri → QR + signMessage(msg: Uint8Array): Promise; + signTransaction(tx: T): Promise; + disconnect(): Promise; +} + +export function remoteWallet(t: WalletTransport, address: string): Wallet { + return { + address, + publicKey: new PublicKey(address), + async signMessage(msg: Uint8Array): Promise { + return t.signMessage(msg); + }, + async signTransaction(tx: T): Promise { + return t.signTransaction(tx); + }, + async signAllTransactions(txs: T[]): Promise { + const results: T[] = []; + for (const tx of txs) { + results.push(await t.signTransaction(tx)); + } + return results; + }, + }; +} diff --git a/packages/core/src/account/webWallet.ts b/packages/core/src/account/webWallet.ts index 9072b9b..66cb41a 100644 --- a/packages/core/src/account/webWallet.ts +++ b/packages/core/src/account/webWallet.ts @@ -34,7 +34,12 @@ export function pubkeyToAddress(pubkey: Uint8Array): string { // address: base58 from the connected wallet (provider.publicKey.toString()). // sessionKeySig: the wallet's signature over SESSION_KEY_MESSAGE's bytes. -export function webWallet(address: string, sessionKeySig: Uint8Array): Wallet { +export function webWallet( + address: string, + sessionKeySig: Uint8Array, + signTransaction?: (tx: T) => Promise, + signAllTransactions?: (txs: T[]) => Promise, +): Wallet { const expected = new TextEncoder().encode(SESSION_KEY_MESSAGE); const sameBytes = (a: Uint8Array, b: Uint8Array) => a.length === b.length && a.every((v, i) => v === b[i]); @@ -50,10 +55,19 @@ export function webWallet(address: string, sessionKeySig: Uint8Array): Wallet { } return sessionKeySig; }, - async signTransaction(_tx: T): Promise { + async signTransaction(tx: T): Promise { + if (signTransaction) return signTransaction(tx); throw new Error("on-chain signing not wired through the web wallet yet (Track 2)."); }, - async signAllTransactions(_txs: T[]): Promise { + async signAllTransactions(txs: T[]): Promise { + if (signAllTransactions) return signAllTransactions(txs); + if (signTransaction) { + const results: T[] = []; + for (const tx of txs) { + results.push(await signTransaction(tx)); + } + return results; + } throw new Error("on-chain signing not wired through the web wallet yet (Track 2)."); }, }; diff --git a/packages/core/src/chat/session.ts b/packages/core/src/chat/session.ts index 513e9ca..0c8a6ce 100644 --- a/packages/core/src/chat/session.ts +++ b/packages/core/src/chat/session.ts @@ -38,6 +38,7 @@ export interface ChatEnv { connectCloud?(cfg: { kind: string; location?: string; authHeader?: string }): Promise; disconnectCloud?(): Promise; disconnectWallet?(): Promise; + logoutFull?(): Promise; openCloud?(kind: string, location?: string): Promise; walletAddress(): string | null; // for the "My Wallet" view storageInfo(): Promise<{ info: unknown; options: unknown }>; // header storage pill @@ -291,6 +292,7 @@ export function createChatSession( case "connectCloud": await env.connectCloud?.({ kind: m.kind, location: m.location, authHeader: m.authHeader }); await pushStorage(); await pushSessions(); break; case "disconnectCloud": await env.disconnectCloud?.(); await pushStorage(); await pushSessions(); break; case "disconnectWallet": await env.disconnectWallet?.(); break; + case "logoutFull": await env.logoutFull?.(); break; case "openCloud": await env.openCloud?.(m.kind, m.location); break; case "wallet": transport.send({ type: "wallet", address: env.walletAddress() }); break; // ── marketplace: search → buy → install (delegated to the host) ── diff --git a/packages/core/src/chat/ui/onboarding.ts b/packages/core/src/chat/ui/onboarding.ts index e4e813e..6dd8a30 100644 --- a/packages/core/src/chat/ui/onboarding.ts +++ b/packages/core/src/chat/ui/onboarding.ts @@ -85,6 +85,18 @@ export function onboardingHtml(): string {
If no keypair exists here, a new one is created at this path.
+ +
+
+ +
+ + +
This keypair is your wallet. The same wallet = the same key that decrypts your sessions on any device. @@ -265,6 +277,9 @@ export function onboardingHtml(): string { vscode.postMessage({ type: 'connectWallet', path: p }); }); if (!WEB) $('walletPath').addEventListener('input', () => $('walletPath').classList.remove('bad')); + if (!WEB) $('qrLoginBtn').addEventListener('click', () => { + vscode.postMessage({ type: 'startQrLogin' }); + }); function pickOption(el, kind) { chosenKind = kind; @@ -303,6 +318,13 @@ export function onboardingHtml(): string { if (m.type === 'init') { if (m.defaultPath) $('walletPath').value = m.defaultPath; cloudPreselect = m.cloudKind || null; // e.g. "gdrive" if already connected + } else if (m.type === 'showQr') { + $('walletPath').style.display = 'none'; + $('connectBtn').style.display = 'none'; + $('walletHint').style.display = 'none'; + $('qrLoginBtn').style.display = 'none'; + $('qrContainer').style.display = 'flex'; + $('qrCodeImg').src = m.qrImage; } else if (m.type === 'walletConnected') { // Browser/mobile: the wallet is the whole onboarding — local save is always on // and a cloud can be added later from chat, so go straight to chat (this socket diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index ad05326..2743142 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -84,6 +84,8 @@ export type { WalletFileState, LoadResult } from "./account/localWallet.js"; // front-end's signature over the fixed session-key message — wallet-agnostic, the // front-end picks the provider. Local surfaces use localWallet; web uses this. export { webWallet, SESSION_KEY_MESSAGE } from "./account/webWallet.js"; +export { remoteWallet } from "./account/transport.js"; +export type { WalletTransport } from "./account/transport.js"; export { startClaudeLogin, isClaudeLoggedIn, @@ -116,6 +118,7 @@ export { saveGoogleCreds, hasGoogleCreds, } from "./account/login.js"; +export type { LogoutPolicy } from "./account/login.js"; export { STORAGE_OPTIONS } from "./account/storage/adapter.js"; export type { StorageConfig, StorageKind } from "./account/storage/adapter.js"; export { manualStorage } from "./account/storage/manual.js"; diff --git a/packages/wallet-connect/package.json b/packages/wallet-connect/package.json new file mode 100644 index 0000000..585589c --- /dev/null +++ b/packages/wallet-connect/package.json @@ -0,0 +1,29 @@ +{ + "name": "@iqlabs-official/wallet-connect", + "version": "0.0.1", + "type": "module", + "private": true, + "main": "./src/index.ts", + "exports": { + ".": "./src/index.ts", + "./*": "./src/*.ts", + "./*.js": "./src/*.ts" + }, + "scripts": { + "build": "tsup src/index.ts" + }, + "dependencies": { + "@walletconnect/sign-client": "^2.13.0", + "@walletconnect/utils": "^2.13.0", + "qrcode": "^1.5.3", + "bs58": "^4.0.1" + }, + "devDependencies": { + "@iqlabs-official/agent-sdk": "workspace:*", + "@solana/web3.js": "^1.98.0", + "@types/node": "^20.0.0", + "@types/qrcode": "^1.5.5", + "tsup": "^8.0.0", + "typescript": "^5.6.0" + } +} diff --git a/packages/wallet-connect/src/index.ts b/packages/wallet-connect/src/index.ts new file mode 100644 index 0000000..f43504a --- /dev/null +++ b/packages/wallet-connect/src/index.ts @@ -0,0 +1,152 @@ +import SignClient from "@walletconnect/sign-client"; +import type { WalletTransport } from "@iqlabs-official/agent-sdk"; +import bs58 from "bs58"; +import qrcode from "qrcode"; + +export function wcTransport(opts: { + projectId: string; + chain?: string; +}): WalletTransport { + const chainId = opts.chain === "solana:mainnet" || !opts.chain + ? "solana:5ey2ja1KstPwMQRx7EokG2dfJksAGGPA" + : opts.chain; + + let client: SignClient | null = null; + let session: any = null; + + async function getClient() { + if (client) return client; + client = await SignClient.init({ + projectId: opts.projectId, + metadata: { + name: "AgentNet", + description: "AgentNet Wallet Connection", + url: "https://agentnet.dev", + icons: ["https://agentnet.dev/icon.png"], + }, + }); + return client; + } + + return { + async connect() { + const c = await getClient(); + + const { uri, approval } = await c.connect({ + requiredNamespaces: { + solana: { + chains: [chainId], + methods: ["solana_signMessage", "solana_signTransaction"], + events: [], + }, + }, + }); + + const approvedPromise = (async () => { + const sess = await approval(); + session = sess; + const accounts = sess.namespaces.solana.accounts; + const address = accounts[0].split(":")[2]; + return { address }; + })(); + + return { + uri: uri || "", + approved: approvedPromise, + }; + }, + + async signMessage(msg: Uint8Array): Promise { + if (!session) throw new Error("No active session. Call connect() first."); + const c = await getClient(); + const address = session.namespaces.solana.accounts[0].split(":")[2]; + + const response = await c.request({ + topic: session.topic, + chainId, + request: { + method: "solana_signMessage", + params: { + message: bs58.encode(Buffer.from(msg)), + pubkey: address, + }, + }, + }); + + if (typeof response === "string") { + return bs58.decode(response); + } else if (response && typeof response === "object" && "signature" in response) { + return bs58.decode(response.signature); + } + throw new Error("Invalid signMessage response from wallet"); + }, + + async signTransaction(tx: T): Promise { + if (!session) throw new Error("No active session. Call connect() first."); + const c = await getClient(); + const address = session.namespaces.solana.accounts[0].split(":")[2]; + + const serialized = (tx as any).serialize({ requireAllSignatures: false, verifySignatures: false }); + const txBase58 = bs58.encode(Buffer.from(serialized)); + + const response = await c.request({ + topic: session.topic, + chainId, + request: { + method: "solana_signTransaction", + params: { + transaction: txBase58, + pubkey: address, + }, + }, + }); + + let signedBytes: Uint8Array; + if (typeof response === "string") { + const decoded = bs58.decode(response); + if (decoded.length > 64) { + signedBytes = decoded; + } else { + (tx as any).addSignature(new (await import("@solana/web3.js")).PublicKey(address), decoded); + return tx; + } + } else if (response && typeof response === "object") { + if ("transaction" in response && typeof response.transaction === "string") { + signedBytes = bs58.decode(response.transaction); + } else if ("signature" in response && typeof response.signature === "string") { + const decoded = bs58.decode(response.signature); + (tx as any).addSignature(new (await import("@solana/web3.js")).PublicKey(address), decoded); + return tx; + } else { + throw new Error("Invalid signTransaction response format"); + } + } else { + throw new Error("Invalid signTransaction response format"); + } + + const isVersioned = "version" in (tx as any); + if (isVersioned) { + const { VersionedTransaction } = await import("@solana/web3.js"); + return VersionedTransaction.deserialize(signedBytes) as unknown as T; + } else { + const { Transaction } = await import("@solana/web3.js"); + return Transaction.from(signedBytes) as unknown as T; + } + }, + + async disconnect() { + if (session) { + const c = await getClient(); + await c.disconnect({ + topic: session.topic, + reason: { code: 6000, message: "User disconnected" }, + }).catch(() => {}); + session = null; + } + }, + }; +} + +export async function generateQrDataUri(uri: string): Promise { + return qrcode.toDataURL(uri); +} diff --git a/packages/wallet-connect/tsconfig.json b/packages/wallet-connect/tsconfig.json new file mode 100644 index 0000000..81c3711 --- /dev/null +++ b/packages/wallet-connect/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "declaration": true, + "outDir": "dist", + "types": ["node"] + }, + "include": ["src"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d1f3bdb..ae8e9d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,6 +63,40 @@ importers: specifier: ^4.1.8 version: 4.1.8(@types/node@20.19.42)(vite@7.3.5(@types/node@20.19.42)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)) + packages/wallet-connect: + dependencies: + '@walletconnect/sign-client': + specifier: ^2.13.0 + version: 2.23.9(bufferutil@4.1.0)(typescript@5.9.3)(zod@4.4.3) + '@walletconnect/utils': + specifier: ^2.13.0 + version: 2.23.9(typescript@5.9.3)(zod@4.4.3) + bs58: + specifier: ^4.0.1 + version: 4.0.1 + qrcode: + specifier: ^1.5.3 + version: 1.5.4 + devDependencies: + '@iqlabs-official/agent-sdk': + specifier: workspace:* + version: link:../core + '@solana/web3.js': + specifier: ^1.98.0 + version: 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@types/node': + specifier: ^20.0.0 + version: 20.19.42 + '@types/qrcode': + specifier: ^1.5.5 + version: 1.5.6 + tsup: + specifier: ^8.0.0 + version: 8.5.1(jiti@2.7.0)(postcss@8.5.15)(tsx@4.22.4)(typescript@5.9.3) + typescript: + specifier: ^5.6.0 + version: 5.9.3 + surfaces/cli: dependencies: '@anthropic-ai/claude-agent-sdk': @@ -74,6 +108,9 @@ importers: '@iqlabs-official/agent-sdk': specifier: workspace:* version: link:../../packages/core + '@iqlabs-official/wallet-connect': + specifier: workspace:* + version: link:../../packages/wallet-connect '@openai/codex-sdk': specifier: ^0.139.0 version: 0.139.0 @@ -95,6 +132,9 @@ importers: open: specifier: ^10.1.0 version: 10.2.0 + qrcode-terminal: + specifier: ^0.12.0 + version: 0.12.0 react: specifier: ^18.3.1 version: 18.3.1 @@ -120,6 +160,9 @@ importers: '@iqlabs-official/agent-sdk': specifier: workspace:* version: link:../../packages/core + '@solana/web3.js': + specifier: ^1.98.0 + version: 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) ws: specifier: ^8.18.0 version: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -145,6 +188,9 @@ importers: '@iqlabs-official/agent-sdk': specifier: workspace:* version: link:../../packages/core + '@iqlabs-official/wallet-connect': + specifier: workspace:* + version: link:../../packages/wallet-connect devDependencies: '@types/node': specifier: ^20.0.0 @@ -164,6 +210,15 @@ importers: '@iqlabs-official/agent-sdk': specifier: workspace:* version: link:../../packages/core + '@solana/web3.js': + specifier: ^1.98.0 + version: 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@walletconnect/sign-client': + specifier: ^2.13.0 + version: 2.23.9(bufferutil@4.1.0)(typescript@5.9.3)(zod@4.4.3) + bs58: + specifier: ^4.0.1 + version: 4.0.1 react: specifier: ^19.2.0 version: 19.2.7 @@ -195,6 +250,9 @@ importers: packages: + '@adraffy/ens-normalize@1.11.1': + resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} + '@alcalzone/ansi-tokenize@0.1.3': resolution: {integrity: sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==} engines: {node: '>=14.13.1'} @@ -213,21 +271,25 @@ packages: resolution: {integrity: sha512-SRYfQcsXlOq+CD/FqkQBTSHbaD++w73GnnO+NUV9adLYrca3kfetRwWT1iguY1cNS0l34dCR3rlzCPq78vg1Jg==} cpu: [arm64] os: [linux] + libc: [musl] '@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.170': resolution: {integrity: sha512-gLbaFqcGppFJQd4DLNV4IXoeahejT/p2/M8bSSvRDbla9GOsBr1AxV5XLRyBn1e7xFGozZIAIQr3+1chp7NJgQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.170': resolution: {integrity: sha512-m4+I0qBEk7cxRKS+pL+eoWXbXTFOAo83fQ0tQvap4z/mDMm06IWJtEPoYTaMBwsp32GJWLkHWKbZSBCHZnp2DQ==} cpu: [x64] os: [linux] + libc: [musl] '@anthropic-ai/claude-agent-sdk-linux-x64@0.3.170': resolution: {integrity: sha512-Xl/m7TaSC3T5IDBdHrZQ9fCQYyDmPELN34CL+MoyPIf7uSmuZnjE9fUOqDh2Rv26JxWssi1M6X+BBvVuKd6Cpg==} cpu: [x64] os: [linux] + libc: [glibc] '@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.170': resolution: {integrity: sha512-IG+8isJNNJKbnnhO7m+PGhfVCg+XoQ/MDxGde5eigFI0WsEfitjuWSWwx82bT9ghxI1aa6qNvI+UPgPcZuo5Fg==} @@ -710,6 +772,22 @@ packages: '@cfworker/json-schema': optional: true + '@msgpack/msgpack@3.1.3': + resolution: {integrity: sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA==} + engines: {node: '>= 18'} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.9.7': resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} engines: {node: ^14.21.3 || >=16} @@ -718,6 +796,10 @@ packages: resolution: {integrity: sha512-T/BoHgFXirb0ENSPBquzX0rcjXeM6Lo892a2jlYJkqk83LqZx0l1Of7DzlKJ6jkpvMrkHSnAcgb5JegL8SeIkQ==} engines: {node: '>= 20.19.0'} + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} + '@noble/hashes@1.8.0': resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} @@ -808,66 +890,79 @@ packages: resolution: {integrity: sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.61.1': resolution: {integrity: sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.61.1': resolution: {integrity: sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.61.1': resolution: {integrity: sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.61.1': resolution: {integrity: sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.61.1': resolution: {integrity: sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.61.1': resolution: {integrity: sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.61.1': resolution: {integrity: sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.61.1': resolution: {integrity: sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.61.1': resolution: {integrity: sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.61.1': resolution: {integrity: sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.61.1': resolution: {integrity: sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.61.1': resolution: {integrity: sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.61.1': resolution: {integrity: sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==} @@ -899,6 +994,15 @@ packages: cpu: [x64] os: [win32] + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + '@solana/buffer-layout-utils@0.2.0': resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} engines: {node: '>= 10'} @@ -1031,24 +1135,28 @@ packages: engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.3.0': resolution: {integrity: sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.3.0': resolution: {integrity: sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.3.0': resolution: {integrity: sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.3.0': resolution: {integrity: sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==} @@ -1119,6 +1227,9 @@ packages: '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + '@types/qrcode@1.5.6': + resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==} + '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -1183,6 +1294,80 @@ packages: '@vitest/utils@4.1.8': resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} + '@walletconnect/core@2.23.9': + resolution: {integrity: sha512-ws4WG8LeagUo2ERRo02HryXRcpwIRmCQ3pHLW5gWbVReLXXIpgk6ZAfID3fEGHevIwwnHSGww+nNhNpdXyiq0g==} + engines: {node: '>=18.20.8'} + + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + + '@walletconnect/heartbeat@1.2.2': + resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==} + + '@walletconnect/jsonrpc-provider@1.0.14': + resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==} + + '@walletconnect/jsonrpc-types@1.0.4': + resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + + '@walletconnect/jsonrpc-utils@1.0.8': + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + + '@walletconnect/jsonrpc-ws-connection@1.0.16': + resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@3.0.2': + resolution: {integrity: sha512-7wR3wAwJTOmX4gbcUZcFMov8fjftY05+5cO/d4cpDD8wDzJ+cIlKdYOXaXfxHLSYeDazMXIsxMYjHYVDfkx+nA==} + + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/sign-client@2.23.9': + resolution: {integrity: sha512-Xj+hw4E6mGRyhCdVOT/RMgnG+up/Y3v0ho5PlkVozvXWeVSqHNh9DmjLuU97a7OACoGd/oHBF6g3NVqD7MgCMQ==} + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.23.9': + resolution: {integrity: sha512-IUl1PpD/Dig8IE2OZ9XtjbPohEyOZJ73xs92EDUzoIyzRtfm36g2D340pY3iu3AAdLv1yFiaZafB8Hf8RFze8A==} + + '@walletconnect/utils@2.23.9': + resolution: {integrity: sha512-C5TltCs8UPypNiteYnKSv8+ZDK2EjVDyXCxN6kA9bkA+j6KGsNIV7l9MUA8WBAvE5Gi5EcBdhD3R9Hpo/1HHqQ==} + + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + + abitype@1.2.4: + resolution: {integrity: sha512-dpKH+N27vRjarMVTFFkeY445VTKftzGWpL0FiT7xmVmzQRKazZexzC5uHG0f6XKsVLAuUlndnbGau6lRejClxg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} @@ -1230,10 +1415,18 @@ packages: any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + auto-bind@5.0.1: resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1259,6 +1452,9 @@ packages: bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + blakejs@1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + bn.js@5.2.3: resolution: {integrity: sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==} @@ -1314,6 +1510,10 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} @@ -1342,6 +1542,10 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + cli-boxes@3.0.0: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} @@ -1363,6 +1567,9 @@ packages: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -1418,6 +1625,9 @@ packages: resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} @@ -1437,6 +1647,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -1449,6 +1662,10 @@ packages: supports-color: optional: true + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -1469,6 +1686,9 @@ packages: resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} engines: {node: '>=0.10.0'} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + delay@5.0.0: resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} engines: {node: '>=10'} @@ -1477,10 +1697,19 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + dompurify@3.4.9: resolution: {integrity: sha512-4dPSRMRDqHvs0V4YDFCsaIZo4if5u0xM+llyxiM2fwuZFdKArUBAF3VtI2+n8NKg9P870WMdYk0UhqQNoWXbfQ==} @@ -1527,6 +1756,9 @@ packages: resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} engines: {node: '>= 0.4'} + es-toolkit@1.44.0: + resolution: {integrity: sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==} + es-toolkit@1.47.0: resolution: {integrity: sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==} @@ -1567,9 +1799,16 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + eventsource-parser@3.1.0: resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==} engines: {node: '>=18.0.0'} @@ -1631,6 +1870,10 @@ packages: resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} engines: {node: '>= 18.0.0'} + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + fix-dts-default-cjs-exports@1.0.1: resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} @@ -1681,6 +1924,9 @@ packages: resolution: {integrity: sha512-rEDCuqUQ4tbD78TpzsMtt5OIf0cBCSDWSJtUDaF6JsAh+k0v9r++NzxNEG87oDZx9ZwGhD8DaezR2L/yrw0Jdw==} engines: {node: '>=10'} + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1711,6 +1957,9 @@ packages: resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} engines: {node: '>=0.10.0'} + idb-keyval@6.2.5: + resolution: {integrity: sha512-eKQkTnS0relYsSOYomx8ozIbmdsQCKUdhyuIaQ2DZgKuaxtyQQMkyD/wlnQN32pO3yutN1b1L8uqwcDKaJd7/Q==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -1755,6 +2004,9 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + is-accessor-descriptor@1.0.2: resolution: {integrity: sha512-AIbwAcazqP3R65dGvqk1V+a+vE5Fg1yu/ZKMOiBWSUIXXiwQkYmXQcVa2O0nh0tSDKDFKxG2mY7dB1Sr4hEP1g==} engines: {node: '>= 0.4'} @@ -1862,6 +2114,9 @@ packages: engines: {node: '>=6'} hasBin: true + keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + kind-of@3.2.2: resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} engines: {node: '>=0.10.0'} @@ -1901,24 +2156,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.32.0: resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} @@ -1947,10 +2206,18 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lru-cache@11.5.1: + resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -1992,6 +2259,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -2004,6 +2274,9 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -2017,10 +2290,17 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + node-releases@2.0.47: resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} engines: {node: '>=18'} + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2033,6 +2313,13 @@ packages: resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} engines: {node: '>=12.20.0'} + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -2048,6 +2335,26 @@ packages: resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} engines: {node: '>=18'} + ox@0.9.3: + resolution: {integrity: sha512-KzyJP+fPV4uhuuqrTZyok4DC7vFzi7HLUFiUNEmpbyh59htKWkOC98IONC1zgXJPbHAhQgqs6B0Z6StCGhmQvg==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + pako@2.1.0: resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} @@ -2068,6 +2375,10 @@ packages: resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -2081,10 +2392,24 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + picomatch@4.0.4: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-std-serializers@7.1.0: + resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} + + pino@10.0.0: + resolution: {integrity: sha512-eI9pKwWEix40kfvSzqEP6ldqOoBIN7dwD/o91TY5z8vQI12sAffpR/pOqAD1IVVwIVHDpHjkq0joBPdJD0rafA==} + hasBin: true + pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -2096,6 +2421,10 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + postcss-load-config@6.0.1: resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} engines: {node: '>= 18'} @@ -2118,6 +2447,9 @@ packages: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -2125,10 +2457,25 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + qrcode-terminal@0.12.0: + resolution: {integrity: sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==} + hasBin: true + + qrcode@1.5.4: + resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} + engines: {node: '>=10.13.0'} + hasBin: true + qs@6.15.2: resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} engines: {node: '>=0.6'} + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -2167,6 +2514,14 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -2175,6 +2530,9 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} @@ -2202,6 +2560,10 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -2223,6 +2585,9 @@ packages: resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} engines: {node: '>= 18'} + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -2264,6 +2629,12 @@ packages: resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} engines: {node: '>=18'} + slow-redact@0.3.2: + resolution: {integrity: sha512-MseHyi2+E/hBRqdOi5COy6wZ7j7DxXRz9NkseavNYSvvWC06D8a5cidVZX3tcG5eCW3NIyVU4zT63hw0Q486jw==} + + sonic-boom@4.2.1: + resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2272,6 +2643,10 @@ packages: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -2348,6 +2723,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + thread-stream@3.2.0: + resolution: {integrity: sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -2392,6 +2770,9 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -2438,6 +2819,12 @@ packages: ufo@1.6.4: resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + uint8arrays@3.1.1: + resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -2445,6 +2832,68 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -2555,6 +3004,9 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -2574,6 +3026,10 @@ packages: engines: {node: '>= 0.10.0'} hasBin: true + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -2613,6 +3069,9 @@ packages: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} engines: {node: '>=18'} + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -2620,10 +3079,18 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + yargs@16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} @@ -2641,6 +3108,8 @@ packages: snapshots: + '@adraffy/ens-normalize@1.11.1': {} + '@alcalzone/ansi-tokenize@0.1.3': dependencies: ansi-styles: 6.2.3 @@ -3056,6 +3525,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@msgpack/msgpack@3.1.3': {} + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + '@noble/curves@1.9.7': dependencies: '@noble/hashes': 1.8.0 @@ -3064,6 +3545,8 @@ snapshots: dependencies: '@noble/hashes': 2.2.0 + '@noble/hashes@1.7.0': {} + '@noble/hashes@1.8.0': {} '@noble/hashes@2.2.0': {} @@ -3176,6 +3659,19 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.61.1': optional: true + '@scure/base@1.2.6': {} + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@solana/buffer-layout-utils@0.2.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': dependencies: '@solana/buffer-layout': 4.0.1 @@ -3439,6 +3935,10 @@ snapshots: '@types/prop-types@15.7.15': {} + '@types/qrcode@1.5.6': + dependencies: + '@types/node': 20.19.42 + '@types/react-dom@19.2.3(@types/react@19.2.17)': dependencies: '@types/react': 19.2.17 @@ -3522,6 +4022,265 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.0 + '@walletconnect/core@2.23.9(bufferutil@4.1.0)(typescript@5.9.3)(zod@4.4.3)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.1.0) + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 3.0.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.23.9 + '@walletconnect/utils': 2.23.9(typescript@5.9.3)(zod@4.4.3) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.44.0 + events: 3.3.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-provider@1.0.14': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-types@1.0.4': + dependencies: + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 + + '@walletconnect/jsonrpc-utils@1.0.8': + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.1.0)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.11(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@walletconnect/keyvaluestorage@1.1.1': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.5 + unstorage: 1.17.5(idb-keyval@6.2.5) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/logger@3.0.2': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 10.0.0 + + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.4 + + '@walletconnect/relay-auth@1.1.0': + dependencies: + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + uint8arrays: 3.1.1 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/sign-client@2.23.9(bufferutil@4.1.0)(typescript@5.9.3)(zod@4.4.3)': + dependencies: + '@walletconnect/core': 2.23.9(bufferutil@4.1.0)(typescript@5.9.3)(zod@4.4.3) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 3.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.23.9 + '@walletconnect/utils': 2.23.9(typescript@5.9.3)(zod@4.4.3) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/types@2.23.9': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 3.0.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/utils@2.23.9(typescript@5.9.3)(zod@4.4.3)': + dependencies: + '@msgpack/msgpack': 3.1.3 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 3.0.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.23.9 + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + blakejs: 1.2.1 + detect-browser: 5.3.0 + ox: 0.9.3(typescript@5.9.3)(zod@4.4.3) + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - typescript + - uploadthing + - zod + + '@walletconnect/window-getters@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/window-metadata@1.0.1': + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + + abitype@1.2.4(typescript@5.9.3)(zod@4.4.3): + optionalDependencies: + typescript: 5.9.3 + zod: 4.4.3 + accepts@2.0.0: dependencies: mime-types: 3.0.2 @@ -3560,8 +4319,15 @@ snapshots: any-promise@1.3.0: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + assertion-error@2.0.1: {} + atomic-sleep@1.0.0: {} + auto-bind@5.0.1: {} base-x@3.0.11: @@ -3582,6 +4348,8 @@ snapshots: dependencies: file-uri-to-path: 1.0.0 + blakejs@1.2.1: {} + bn.js@5.2.3: {} body-parser@2.2.2: @@ -3651,6 +4419,8 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 + camelcase@5.3.1: {} + camelcase@6.3.0: {} caniuse-lite@1.0.30001799: {} @@ -3673,6 +4443,10 @@ snapshots: dependencies: readdirp: 4.1.2 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + cli-boxes@3.0.0: {} cli-cursor@4.0.0: @@ -3695,6 +4469,12 @@ snapshots: slice-ansi: 5.0.0 string-width: 7.2.0 + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -3733,6 +4513,8 @@ snapshots: convert-to-spaces@2.0.1: {} + cookie-es@1.2.3: {} + cookie-signature@1.2.2: {} cookie@0.7.2: {} @@ -3754,12 +4536,18 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + csstype@3.2.3: {} debug@4.4.3: dependencies: ms: 2.1.3 + decamelize@1.2.0: {} + deepmerge@4.3.1: {} default-browser-id@5.0.1: {} @@ -3775,12 +4563,20 @@ snapshots: dependencies: is-descriptor: 1.0.4 + defu@6.1.7: {} + delay@5.0.0: {} depd@2.0.0: {} + destr@2.0.5: {} + + detect-browser@5.3.0: {} + detect-libc@2.1.2: {} + dijkstrajs@1.0.3: {} + dompurify@3.4.9: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -3818,6 +4614,8 @@ snapshots: dependencies: es-errors: 1.3.0 + es-toolkit@1.44.0: {} + es-toolkit@1.47.0: {} es6-promise@4.2.8: {} @@ -3898,8 +4696,12 @@ snapshots: eventemitter3@4.0.7: {} + eventemitter3@5.0.1: {} + eventemitter3@5.0.4: {} + events@3.3.0: {} + eventsource-parser@3.1.0: {} eventsource@3.0.7: @@ -3979,6 +4781,11 @@ snapshots: transitivePeerDependencies: - supports-color + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + fix-dts-default-cjs-exports@1.0.1: dependencies: magic-string: 0.30.21 @@ -4027,6 +4834,18 @@ snapshots: chalk: 4.1.2 tinygradient: 1.1.5 + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.4 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + has-flag@4.0.0: {} has-symbols@1.1.0: {} @@ -4055,6 +4874,8 @@ snapshots: dependencies: safer-buffer: 2.1.2 + idb-keyval@6.2.5: {} + ieee754@1.2.1: {} indent-string@5.0.0: {} @@ -4113,6 +4934,8 @@ snapshots: ipaddr.js@1.9.1: {} + iron-webcrypto@1.2.1: {} + is-accessor-descriptor@1.0.2: dependencies: hasown: 2.0.4 @@ -4158,7 +4981,7 @@ snapshots: isexe@2.0.0: {} - isomorphic-ws@4.0.1(ws@7.5.11(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + isomorphic-ws@4.0.1(ws@7.5.11(bufferutil@4.1.0)): dependencies: ws: 7.5.11(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -4171,7 +4994,7 @@ snapshots: delay: 5.0.0 es6-promisify: 5.0.0 eyes: 0.1.8 - isomorphic-ws: 4.0.1(ws@7.5.11(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + isomorphic-ws: 4.0.1(ws@7.5.11(bufferutil@4.1.0)) json-stringify-safe: 5.0.1 stream-json: 1.9.1 uuid: 8.3.2 @@ -4203,6 +5026,8 @@ snapshots: json5@2.2.3: {} + keyvaluestorage-interface@1.0.0: {} + kind-of@3.2.2: dependencies: is-buffer: 1.1.6 @@ -4262,10 +5087,16 @@ snapshots: load-tsconfig@0.2.5: {} + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 + lru-cache@11.5.1: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -4299,6 +5130,8 @@ snapshots: ms@2.1.3: {} + multiformats@9.9.0: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -4309,6 +5142,8 @@ snapshots: negotiator@1.0.0: {} + node-fetch-native@1.6.7: {} + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 @@ -4316,14 +5151,26 @@ snapshots: node-gyp-build@4.8.4: optional: true + node-mock-http@1.0.4: {} + node-releases@2.0.47: {} + normalize-path@3.0.0: {} + object-assign@4.1.1: {} object-inspect@1.13.4: {} obug@2.1.3: {} + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + on-exit-leak-free@2.1.2: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -4343,6 +5190,31 @@ snapshots: is-inside-container: 1.0.0 wsl-utils: 0.1.0 + ox@0.9.3(typescript@5.9.3)(zod@4.4.3): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.4(typescript@5.9.3)(zod@4.4.3) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-try@2.2.0: {} + pako@2.1.0: {} parse5-htmlparser2-tree-adapter@6.0.1: @@ -4357,6 +5229,8 @@ snapshots: patch-console@2.0.0: {} + path-exists@4.0.0: {} + path-key@3.1.1: {} path-to-regexp@8.4.2: {} @@ -4365,8 +5239,30 @@ snapshots: picocolors@1.1.1: {} + picomatch@2.3.2: {} + picomatch@4.0.4: {} + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-std-serializers@7.1.0: {} + + pino@10.0.0: + dependencies: + atomic-sleep: 1.0.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.1.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + slow-redact: 0.3.2 + sonic-boom: 4.2.1 + thread-stream: 3.2.0 + pirates@4.0.7: {} pkce-challenge@5.0.1: {} @@ -4377,6 +5273,8 @@ snapshots: mlly: 1.8.2 pathe: 2.0.3 + pngjs@5.0.0: {} + postcss-load-config@6.0.1(jiti@2.7.0)(postcss@8.5.15)(tsx@4.22.4): dependencies: lilconfig: 3.1.3 @@ -4391,6 +5289,8 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + process-warning@5.0.0: {} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -4402,10 +5302,22 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + qrcode-terminal@0.12.0: {} + + qrcode@1.5.4: + dependencies: + dijkstrajs: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + qs@6.15.2: dependencies: side-channel: 1.1.1 + quick-format-unescaped@4.0.4: {} + + radix3@1.1.2: {} + range-parser@1.2.1: {} raw-body@3.0.2: @@ -4438,10 +5350,16 @@ snapshots: readdirp@4.1.2: {} + readdirp@5.0.0: {} + + real-require@0.2.0: {} + require-directory@2.1.1: {} require-from-string@2.0.2: {} + require-main-filename@2.0.0: {} + resolve-from@5.0.0: {} restore-cursor@4.0.0: @@ -4507,6 +5425,8 @@ snapshots: safe-buffer@5.2.1: {} + safe-stable-stringify@2.5.0: {} + safer-buffer@2.1.2: {} scheduler@0.23.2: @@ -4542,6 +5462,8 @@ snapshots: transitivePeerDependencies: - supports-color + set-blocking@2.0.0: {} + setprototypeof@1.2.0: {} shebang-command@2.0.0: @@ -4592,10 +5514,18 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 + slow-redact@0.3.2: {} + + sonic-boom@4.2.1: + dependencies: + atomic-sleep: 1.0.0 + source-map-js@1.2.1: {} source-map@0.7.6: {} + split2@4.2.0: {} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -4673,6 +5603,10 @@ snapshots: dependencies: any-promise: 1.3.0 + thread-stream@3.2.0: + dependencies: + real-require: 0.2.0 + tinybench@2.9.0: {} tinycolor2@1.6.0: {} @@ -4705,6 +5639,8 @@ snapshots: ts-interface-checker@0.1.13: {} + tslib@1.14.1: {} + tslib@2.8.1: {} tsup@8.5.1(jiti@2.7.0)(postcss@8.5.15)(tsx@4.22.4)(typescript@5.9.3): @@ -4755,10 +5691,29 @@ snapshots: ufo@1.6.4: {} + uint8arrays@3.1.1: + dependencies: + multiformats: 9.9.0 + + uncrypto@0.1.3: {} + undici-types@6.21.0: {} unpipe@1.0.0: {} + unstorage@1.17.5(idb-keyval@6.2.5): + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.5.1 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + optionalDependencies: + idb-keyval: 6.2.5 + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: browserslist: 4.28.2 @@ -4825,6 +5780,8 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 + which-module@2.0.1: {} + which@2.0.2: dependencies: isexe: 2.0.0 @@ -4843,6 +5800,12 @@ snapshots: define-property: 1.0.0 is-number: 3.0.0 + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -4871,12 +5834,33 @@ snapshots: dependencies: is-wsl: 3.1.1 + y18n@4.0.3: {} + y18n@5.0.8: {} yallist@3.1.1: {} + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + yargs-parser@20.2.9: {} + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + yargs@16.2.0: dependencies: cliui: 7.0.4 diff --git a/scripts/wc-poc.ts b/scripts/wc-poc.ts new file mode 100644 index 0000000..f72f994 --- /dev/null +++ b/scripts/wc-poc.ts @@ -0,0 +1,40 @@ +import { wcTransport } from "../packages/wallet-connect/src/index.js"; +import { webWallet, SESSION_KEY_MESSAGE } from "../packages/core/src/account/webWallet.js"; +import { deriveSessionKey } from "../packages/core/src/core/crypto.js"; +import qrcode from "qrcode-terminal"; + +async function main() { + const projectId = process.env.REOWN_PROJECT_ID; + if (!projectId) { + console.error("Please set REOWN_PROJECT_ID env var."); + process.exit(1); + } + + console.log("Initializing WalletConnect..."); + const transport = wcTransport({ projectId }); + + console.log("Connecting..."); + const { uri, approved } = await transport.connect(); + + console.log("Scan this QR code with Phantom or Solflare on your phone:\n"); + qrcode.generate(uri, { small: true }); + + console.log("Waiting for approval..."); + const { address } = await approved; + console.log(`Approved! Connected address: ${address}`); + + console.log(`Signing message: "${SESSION_KEY_MESSAGE}"...`); + const msgBytes = new TextEncoder().encode(SESSION_KEY_MESSAGE); + const signature = await transport.signMessage(msgBytes); + console.log("Signature obtained:", Buffer.from(signature).toString("hex")); + + console.log("Validating with webWallet + deriveSessionKey..."); + const wallet = webWallet(address, signature); + const sessionKey = await deriveSessionKey(wallet); + console.log("Derived Session Key (PubHex):", sessionKey.pubHex); + + console.log("\nSuccess! POC verified."); + await transport.disconnect(); +} + +main().catch(console.error); diff --git a/surfaces/android/app/src/main/java/com/iqlabs/agentnet/WalletBridge.kt b/surfaces/android/app/src/main/java/com/iqlabs/agentnet/WalletBridge.kt index 7b7d24b..650fa99 100644 --- a/surfaces/android/app/src/main/java/com/iqlabs/agentnet/WalletBridge.kt +++ b/surfaces/android/app/src/main/java/com/iqlabs/agentnet/WalletBridge.kt @@ -124,6 +124,57 @@ class WalletBridge( } } + @JavascriptInterface + fun signTransaction(requestJson: String) { + val req = runCatching { JSONObject(requestJson) }.getOrNull() + val id = req?.optString("id").orEmpty() + val txJson = req?.optJSONArray("transaction") + if (id.isEmpty() || txJson == null) { + Log.e(TAG, "signTransaction: malformed request") + if (id.isNotEmpty()) pushError(id, "Malformed signTransaction request.", "Failure") + return + } + val txBytes = ByteArray(txJson.length()) + for (i in 0 until txBytes.size) { + txBytes[i] = txJson.getInt(i).toByte() + } + activity.lifecycleScope.launch { + try { + runSignTransaction(id, txBytes) + } catch (e: Exception) { + Log.e(TAG, "signTransaction threw", e) + pushError(id, e.message ?: "Wallet transaction signing failed.", "Failure") + } + } + } + + private suspend fun runSignTransaction(id: String, txBytes: ByteArray) { + val result = walletAdapter.transact(sender) { + val signResult = signTransactions( + transactions = arrayOf(txBytes) + ) + signResult.transactions.first() + } + when (result) { + is TransactionResult.Success -> { + val signedTx = result.payload + pushTxSuccess(id, signedTx) + } + is TransactionResult.NoWalletFound -> + pushError(id, "No compatible wallet app is installed.", "NoWalletFound") + is TransactionResult.Failure -> + pushError(id, result.e.message ?: "Wallet request failed.", "Failure") + } + } + + private fun pushTxSuccess(id: String, signedTx: ByteArray) { + val json = JSONObject() + .put("id", id) + .put("ok", true) + .put("transaction", bytesToJson(signedTx)) + dispatch(json.toString()) + } + private fun bytesToJson(bytes: ByteArray): JSONArray { val arr = JSONArray() for (b in bytes) arr.put(b.toInt() and 0xFF) diff --git a/surfaces/cli/package.json b/surfaces/cli/package.json index 64cc081..4136eaa 100644 --- a/surfaces/cli/package.json +++ b/surfaces/cli/package.json @@ -20,6 +20,7 @@ }, "dependencies": { "@iqlabs-official/agent-sdk": "workspace:*", + "@iqlabs-official/wallet-connect": "workspace:*", "@anthropic-ai/claude-agent-sdk": "^0.3.170", "@openai/codex-sdk": "^0.139.0", "@inkjs/ui": "^2.0.0", @@ -29,6 +30,7 @@ "ink-big-text": "^2.0.0", "ink-gradient": "^3.0.0", "open": "^10.1.0", - "react": "^18.3.1" + "react": "^18.3.1", + "qrcode-terminal": "^0.12.0" } } diff --git a/surfaces/cli/src/app.tsx b/surfaces/cli/src/app.tsx index c35acf8..976c55e 100644 --- a/surfaces/cli/src/app.tsx +++ b/surfaces/cli/src/app.tsx @@ -1,7 +1,10 @@ import React, { useEffect, useState } from "react"; import { Box, Text } from "ink"; import type { AgentRuntime } from "@iqlabs-official/agent-sdk/runtime/contract"; -import { autoApprove, type StorageConfig, type CliReport } from "@iqlabs-official/agent-sdk"; +import { autoApprove, type StorageConfig, type CliReport, remoteWallet } from "@iqlabs-official/agent-sdk"; +import { Select } from "@inkjs/ui"; +import qrcodeTerminal from "qrcode-terminal"; +import { wcTransport } from "@iqlabs-official/wallet-connect"; import { InkApprovalChannel } from "./InkApprovalChannel.js"; import { Banner } from "./components/Banner.js"; import { BootChecklist, type BootStep } from "./components/BootChecklist.js"; @@ -17,7 +20,7 @@ import { } from "./bootstrap.js"; import { readPrefs, savePrefs, type Prefs } from "./prefs.js"; -type Phase = "boot" | "onboard" | "chat" | "error"; +type Phase = "boot" | "walletMenu" | "qrLogin" | "onboard" | "chat" | "error"; export interface AppOptions { cli?: "claude" | "codex"; @@ -30,8 +33,6 @@ export interface AppOptions { yolo?: boolean; // auto-approve all tool use (no prompts) } -// Root router. Sequences the same boot the vscode surface does (wallet → detect → connect) -// but renders it as a live checklist, then lands on onboarding (first run) or chat. export function App({ options }: { options: AppOptions }) { const [phase, setPhase] = useState("boot"); const [steps, setSteps] = useState([ @@ -43,63 +44,124 @@ export function App({ options }: { options: AppOptions }) { const [address, setAddress] = useState(""); const [report, setReport] = useState({ claude: "missing", codex: "missing" }); const [runtime, setRuntime] = useState(null); - // the connected wallet, kept so the chat view can build the skill-market env from it. - const [wallet, setWallet] = useState>["wallet"] | null>(null); + const [wallet, setWallet] = useState(null); const [errMsg, setErrMsg] = useState(""); const [prefs, setPrefs] = useState({}); - // tool-approval seam: --yolo skips the UI (auto-allow); otherwise prompts route here. + const [qrCodeString, setQrCodeString] = useState(""); + const [qrStatus, setQrStatus] = useState("Initializing WalletConnect..."); const approval = React.useRef(options.yolo ? null : new InkApprovalChannel()); const set = (i: number, patch: Partial) => setSteps((s) => s.map((step, j) => (j === i ? { ...step, ...patch } : step))); - // connect wallet → runtime, then enter chat. Reused after onboarding too. - async function go(addr: string, w: Awaited>["wallet"]) { + async function go(addr: string, w: any) { set(3, { status: "pending", label: "connecting storage" }); const rt = await buildRuntime(w, approval.current ?? autoApprove()); setRuntime(rt); setWallet(w); set(3, { status: "ok", label: "storage ready" }); - // wipe the boot banner/checklist from the scrollback so the welcome panel lands on a - // clean screen (Ink leaves prior static output in the terminal history otherwise). process.stdout.write("\x1b[2J\x1b[3J\x1b[H"); setPhase("chat"); } + async function runBootChecks(w: any, addr: string, savedPrefs: Prefs) { + try { + setAddress(addr); + setWallet(w); + set(0, { status: "ok", label: "wallet", detail: `${addr.slice(0, 6)}…${addr.slice(-4)}` }); + + const rep = await detectCli(); + setReport(rep); + set(1, { status: rep.claude === "ok" ? "ok" : "fail", label: `claude ${rep.claude}` }); + set(2, { status: rep.codex === "ok" ? "ok" : "fail", label: `codex ${rep.codex}` }); + + if (savedPrefs.onboarded || (await isInitialized())) { + await go(addr, w); + } else { + set(3, { status: "ok", label: "storage: pick on next screen" }); + setPhase("onboard"); + onboardFinish.current = async (engine: "claude" | "codex", cfg?: StorageConfig) => { + if (cfg) await chooseStorage(cfg); + await savePrefs({ onboarded: true, lastCli: engine }); + await go(addr, w); + }; + } + } catch (e) { + setErrMsg(e instanceof Error ? e.message : String(e)); + setPhase("error"); + } + } + + async function handleWalletSourceSelect(value: string) { + if (value === "local") { + setPhase("boot"); + setSteps([ + { label: "loading wallet", status: "pending" }, + { label: "checking claude", status: "pending" }, + { label: "checking codex", status: "pending" }, + { label: "restoring storage", status: "pending" }, + ]); + try { + const { wallet: w, address: addr } = await loadWallet(options.keypair); + await runBootChecks(w, addr, prefs); + } catch (e) { + setErrMsg(e instanceof Error ? e.message : String(e)); + setPhase("error"); + } + } else if (value === "qr") { + setPhase("qrLogin"); + setQrStatus("Initializing WalletConnect..."); + setQrCodeString(""); + + try { + const projectId = process.env.REOWN_PROJECT_ID || "3fcc6b14d1b7473db311d1bfab721c0b"; + const transport = wcTransport({ projectId }); + const { uri, approved } = await transport.connect(); + + qrcodeTerminal.generate(uri, { small: true }, (code) => { + setQrCodeString(code); + setQrStatus("Scan the QR code below with your Phantom or Solflare wallet app on your phone:"); + }); + + const { address: addr } = await approved; + setQrStatus("Connection approved! Signing session key message on your phone..."); + + const SESSION_KEY_MESSAGE = "iq-sdk-derive-encryption-key-v1"; + const msgBytes = new TextEncoder().encode(SESSION_KEY_MESSAGE); + + const w = remoteWallet(transport, addr); + await w.signMessage(msgBytes); + + setPhase("boot"); + setSteps([ + { label: "wallet connected", status: "ok", detail: `${addr.slice(0, 6)}…${addr.slice(-4)}` }, + { label: "checking claude", status: "pending" }, + { label: "checking codex", status: "pending" }, + { label: "restoring storage", status: "pending" }, + ]); + + await runBootChecks(w, addr, prefs); + } catch (e) { + setErrMsg(e instanceof Error ? e.message : String(e)); + setPhase("error"); + } + } + } + useEffect(() => { let alive = true; (async () => { try { - const [{ wallet, address: addr }, savedPrefs] = await Promise.all([ - loadWallet(options.keypair), - readPrefs(), - ]); + const savedPrefs = await readPrefs(); if (!alive) return; - setAddress(addr); setPrefs(savedPrefs); - set(0, { status: "ok", label: "wallet", detail: `${addr.slice(0, 6)}…${addr.slice(-4)}` }); - const rep = await detectCli(); - if (!alive) return; - setReport(rep); - set(1, { status: rep.claude === "ok" ? "ok" : "fail", label: `claude ${rep.claude}` }); - set(2, { status: rep.codex === "ok" ? "ok" : "fail", label: `codex ${rep.codex}` }); - - // onboard only on a TRUE first run: neither a finished-setup marker nor a - // configured cloud. (Local-only writes no storage config, so the marker is what - // stops the every-launch onboarding loop.) - if (savedPrefs.onboarded || (await isInitialized())) { + if (options.keypair || !process.stdin.isTTY) { + const { wallet: w, address: addr } = await loadWallet(options.keypair); if (!alive) return; - await go(addr, wallet); + await runBootChecks(w, addr, savedPrefs); } else { - if (!alive) return; - set(3, { status: "ok", label: "storage: pick on next screen" }); - setPhase("onboard"); - onboardFinish.current = async (engine: "claude" | "codex", cfg?: StorageConfig) => { - if (cfg) await chooseStorage(cfg); - await savePrefs({ onboarded: true, lastCli: engine }); - await go(addr, wallet); - }; + setPhase("walletMenu"); } } catch (e) { if (!alive) return; @@ -113,7 +175,6 @@ export function App({ options }: { options: AppOptions }) { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - // set by the boot effect so Onboarding can finish with the live wallet in scope. const onboardFinish = React.useRef<(engine: "claude" | "codex", cfg?: StorageConfig) => void>(() => {}); if (phase === "error") { @@ -124,6 +185,36 @@ export function App({ options }: { options: AppOptions }) { ); } + if (phase === "walletMenu") { + return ( + + + Select Solana wallet source: +