diff --git a/app-kit-bridge-evm/package.json b/app-kit-bridge-evm/package.json index c068cbe..abd824b 100644 --- a/app-kit-bridge-evm/package.json +++ b/app-kit-bridge-evm/package.json @@ -5,11 +5,13 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", + "test": "vitest run", "preview": "vite preview" }, "devDependencies": { "typescript": "~7.0.2", - "vite": "^8.2.1" + "vite": "^8.2.1", + "vitest": "^4.1.9" }, "dependencies": { "@circle-fin/app-kit": "^1.12.0", diff --git a/app-kit-bridge-evm/src/connect.test.ts b/app-kit-bridge-evm/src/connect.test.ts new file mode 100644 index 0000000..9d41fd6 --- /dev/null +++ b/app-kit-bridge-evm/src/connect.test.ts @@ -0,0 +1,62 @@ +/** + * Copyright 2026 Circle Internet Group, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { describe, expect, it, vi } from "vitest"; +import { connectEvmProvider } from "./connect.ts"; +import type { BrowserWalletProvider } from "./connect.ts"; + +describe("connectEvmProvider", () => { + it("returns the provider only after permission returns an account", async () => { + const provider = { + request: vi + .fn() + .mockResolvedValueOnce(["0x3333333333333333333333333333333333333333"]), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).resolves.toEqual({ + provider, + account: "0x3333333333333333333333333333333333333333", + }); + expect(provider.request).toHaveBeenNthCalledWith(1, { + method: "eth_requestAccounts", + params: undefined, + }); + expect(provider.request).toHaveBeenCalledTimes(1); + }); + + it("does not return a connected provider when permission is rejected", async () => { + const rejection = new Error("User rejected the request"); + const provider = { + request: vi.fn().mockRejectedValue(rejection), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).rejects.toBe(rejection); + expect(provider.request).toHaveBeenCalledTimes(1); + }); + + it("does not return a connected provider when permission returns no account", async () => { + const provider = { + request: vi.fn().mockResolvedValue([]), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).rejects.toThrow( + "No account returned after wallet permission", + ); + expect(provider.request).toHaveBeenCalledTimes(1); + }); +}); diff --git a/app-kit-bridge-evm/src/connect.ts b/app-kit-bridge-evm/src/connect.ts new file mode 100644 index 0000000..1e1f7f9 --- /dev/null +++ b/app-kit-bridge-evm/src/connect.ts @@ -0,0 +1,35 @@ +/** + * Copyright 2026 Circle Internet Group, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import type { CreateViemAdapterFromProviderParams } from "@circle-fin/adapter-viem-v2"; + +export type BrowserWalletProvider = + CreateViemAdapterFromProviderParams["provider"]; + +export async function connectEvmProvider(provider: BrowserWalletProvider) { + const accounts = (await provider.request({ + method: "eth_requestAccounts", + params: undefined, + })) as string[]; + const account = accounts[0]; + if (!account) { + throw new Error("No account returned after wallet permission"); + } + + return { provider, account }; +} diff --git a/app-kit-bridge-evm/src/main.ts b/app-kit-bridge-evm/src/main.ts index d5b2fa8..e493142 100644 --- a/app-kit-bridge-evm/src/main.ts +++ b/app-kit-bridge-evm/src/main.ts @@ -18,9 +18,8 @@ import { AppKit } from "@circle-fin/app-kit"; import { createViemAdapterFromProvider } from "@circle-fin/adapter-viem-v2"; -import type { CreateViemAdapterFromProviderParams } from "@circle-fin/adapter-viem-v2"; - -type BrowserWalletProvider = CreateViemAdapterFromProviderParams["provider"]; +import { connectEvmProvider } from "./connect.ts"; +import type { BrowserWalletProvider } from "./connect.ts"; type EIP6963ProviderDetail = { info: { @@ -71,19 +70,14 @@ async function handleEvmConnect() { try { connectEvmButton.disabled = true; - evmProvider = await getProvider(); - await evmProvider.request({ - method: "eth_requestAccounts", - params: undefined, - }); - const accounts = (await evmProvider.request({ - method: "eth_accounts", - params: undefined, - })) as string[]; + const connection = await connectEvmProvider(await getProvider()); + evmProvider = connection.provider; - walletInfo.textContent = accounts[0] ?? "Connected"; - bridgeButton.disabled = !evmProvider; + walletInfo.textContent = connection.account ?? "Connected"; + bridgeButton.disabled = false; } catch (error) { + evmProvider = null; + bridgeButton.disabled = true; render({ error: error instanceof Error ? error.message : "Unknown error" }); } finally { connectEvmButton.disabled = Boolean(evmProvider); diff --git a/app-kit-bridge-solana/package.json b/app-kit-bridge-solana/package.json index 617ae3c..e3122bc 100644 --- a/app-kit-bridge-solana/package.json +++ b/app-kit-bridge-solana/package.json @@ -5,11 +5,13 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", + "test": "vitest run", "preview": "vite preview" }, "devDependencies": { "typescript": "~7.0.2", - "vite": "^8.2.1" + "vite": "^8.2.1", + "vitest": "^4.1.9" }, "dependencies": { "@circle-fin/adapter-solana": "^1.6.5", diff --git a/app-kit-bridge-solana/src/connect.test.ts b/app-kit-bridge-solana/src/connect.test.ts new file mode 100644 index 0000000..8867e8f --- /dev/null +++ b/app-kit-bridge-solana/src/connect.test.ts @@ -0,0 +1,100 @@ +/** + * Copyright 2026 Circle Internet Group, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { describe, expect, it, vi } from "vitest"; +import { + connectEvmProvider, + connectSolanaProvider, +} from "./connect.ts"; +import type { + BrowserWalletProvider, + SolanaWalletProvider, +} from "./connect.ts"; + +describe("wallet connection", () => { + it("returns the EVM provider only after account lookup succeeds", async () => { + const account = "0x4444444444444444444444444444444444444444"; + const provider = { + request: vi + .fn() + .mockResolvedValueOnce([account]), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).resolves.toEqual({ + provider, + account, + }); + expect(provider.request).toHaveBeenCalledTimes(1); + }); + + it("does not return an EVM provider when permission is rejected", async () => { + const rejection = new Error("User rejected the request"); + const provider = { + request: vi.fn().mockRejectedValue(rejection), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).rejects.toBe(rejection); + expect(provider.request).toHaveBeenCalledTimes(1); + }); + + it("does not return an EVM provider when permission returns no account", async () => { + const provider = { + request: vi.fn().mockResolvedValue([]), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).rejects.toThrow( + "No account returned after wallet permission", + ); + expect(provider.request).toHaveBeenCalledTimes(1); + }); + + it("does not return a Solana provider when connection is rejected", async () => { + const rejection = new Error("User rejected the request"); + const provider = { + connect: vi.fn().mockRejectedValue(rejection), + } as unknown as SolanaWalletProvider; + + await expect(connectSolanaProvider(provider)).rejects.toBe(rejection); + expect(provider.connect).toHaveBeenCalledTimes(1); + }); + + it("returns the Solana provider only after connection succeeds", async () => { + const publicKey = { toString: () => "solana-address" }; + const provider = { + connect: vi.fn().mockResolvedValue({ publicKey }), + publicKey: null, + } as unknown as SolanaWalletProvider; + + await expect(connectSolanaProvider(provider)).resolves.toEqual({ + provider, + address: "solana-address", + }); + }); + + it("does not return a Solana provider when connection returns no address", async () => { + const provider = { + connect: vi.fn().mockResolvedValue({}), + publicKey: null, + } as unknown as SolanaWalletProvider; + + await expect(connectSolanaProvider(provider)).rejects.toThrow( + "No address returned after wallet connection", + ); + expect(provider.connect).toHaveBeenCalledTimes(1); + }); +}); diff --git a/app-kit-bridge-solana/src/connect.ts b/app-kit-bridge-solana/src/connect.ts new file mode 100644 index 0000000..ede0e4e --- /dev/null +++ b/app-kit-bridge-solana/src/connect.ts @@ -0,0 +1,49 @@ +/** + * Copyright 2026 Circle Internet Group, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import type { CreateSolanaAdapterFromProviderParams } from "@circle-fin/adapter-solana"; +import type { CreateViemAdapterFromProviderParams } from "@circle-fin/adapter-viem-v2"; + +export type BrowserWalletProvider = + CreateViemAdapterFromProviderParams["provider"]; +export type SolanaWalletProvider = + CreateSolanaAdapterFromProviderParams["provider"]; + +export async function connectEvmProvider(provider: BrowserWalletProvider) { + const accounts = (await provider.request({ + method: "eth_requestAccounts", + params: undefined, + })) as string[]; + const account = accounts[0]; + if (!account) { + throw new Error("No account returned after wallet permission"); + } + + return { provider, account }; +} + +export async function connectSolanaProvider(provider: SolanaWalletProvider) { + const connection = await provider.connect(); + const address = + connection.publicKey?.toString() ?? provider.publicKey?.toString(); + if (!address) { + throw new Error("No address returned after wallet connection"); + } + + return { provider, address }; +} diff --git a/app-kit-bridge-solana/src/main.ts b/app-kit-bridge-solana/src/main.ts index 95e755b..d645796 100644 --- a/app-kit-bridge-solana/src/main.ts +++ b/app-kit-bridge-solana/src/main.ts @@ -19,10 +19,14 @@ import { AppKit } from "@circle-fin/app-kit"; import { createViemAdapterFromProvider } from "@circle-fin/adapter-viem-v2"; import { createSolanaAdapterFromProvider } from "@circle-fin/adapter-solana"; -import type { CreateViemAdapterFromProviderParams } from "@circle-fin/adapter-viem-v2"; -import type { CreateSolanaAdapterFromProviderParams } from "@circle-fin/adapter-solana"; - -type BrowserWalletProvider = CreateViemAdapterFromProviderParams["provider"]; +import { + connectEvmProvider, + connectSolanaProvider, +} from "./connect.ts"; +import type { + BrowserWalletProvider, + SolanaWalletProvider, +} from "./connect.ts"; type EIP6963ProviderDetail = { info: { @@ -34,8 +38,6 @@ type EIP6963ProviderDetail = { provider: BrowserWalletProvider; }; -type SolanaWalletProvider = CreateSolanaAdapterFromProviderParams["provider"]; - declare global { interface WindowEventMap { "eip6963:announceProvider": CustomEvent; @@ -79,19 +81,14 @@ async function handleEvmConnect() { try { connectEvmButton.disabled = true; - evmProvider = await getProvider(); - await evmProvider.request({ - method: "eth_requestAccounts", - params: undefined, - }); - const accounts = (await evmProvider.request({ - method: "eth_accounts", - params: undefined, - })) as string[]; + const connection = await connectEvmProvider(await getProvider()); + evmProvider = connection.provider; - walletInfo.textContent = accounts[0] ?? "Connected"; - bridgeButton.disabled = !evmProvider || !solanaProvider; + walletInfo.textContent = connection.account ?? "Connected"; + bridgeButton.disabled = !solanaProvider; } catch (error) { + evmProvider = null; + bridgeButton.disabled = true; render({ error: error instanceof Error ? error.message : "Unknown error" }); } finally { connectEvmButton.disabled = Boolean(evmProvider); @@ -107,14 +104,14 @@ async function handleSolanaConnect() { throw new Error("No Solana browser wallet found"); } - solanaProvider = window.solana; - const connection = await solanaProvider.connect(); + const connection = await connectSolanaProvider(window.solana); + solanaProvider = connection.provider; solanaWalletInfo.textContent = - connection.publicKey?.toString() ?? - solanaProvider.publicKey?.toString() ?? - "Connected"; - bridgeButton.disabled = !evmProvider || !solanaProvider; + connection.address ?? "Connected"; + bridgeButton.disabled = !evmProvider; } catch (error) { + solanaProvider = null; + bridgeButton.disabled = true; render({ error: error instanceof Error ? error.message : "Unknown error" }); } finally { connectSolButton.disabled = Boolean(solanaProvider); diff --git a/app-kit-send/package.json b/app-kit-send/package.json index 41226b4..e54cc1a 100644 --- a/app-kit-send/package.json +++ b/app-kit-send/package.json @@ -5,11 +5,13 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", + "test": "vitest run", "preview": "vite preview" }, "devDependencies": { "typescript": "~7.0.2", - "vite": "^8.2.1" + "vite": "^8.2.1", + "vitest": "^4.1.9" }, "dependencies": { "@circle-fin/adapter-viem-v2": "^1.15.1", diff --git a/app-kit-send/src/connect.test.ts b/app-kit-send/src/connect.test.ts new file mode 100644 index 0000000..a10692d --- /dev/null +++ b/app-kit-send/src/connect.test.ts @@ -0,0 +1,62 @@ +/** + * Copyright 2026 Circle Internet Group, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { describe, expect, it, vi } from "vitest"; +import { connectEvmProvider } from "./connect.ts"; +import type { BrowserWalletProvider } from "./connect.ts"; + +describe("connectEvmProvider", () => { + it("returns the provider only after permission returns an account", async () => { + const provider = { + request: vi + .fn() + .mockResolvedValueOnce(["0x1111111111111111111111111111111111111111"]), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).resolves.toEqual({ + provider, + account: "0x1111111111111111111111111111111111111111", + }); + expect(provider.request).toHaveBeenNthCalledWith(1, { + method: "eth_requestAccounts", + params: undefined, + }); + expect(provider.request).toHaveBeenCalledTimes(1); + }); + + it("does not return a connected provider when permission is rejected", async () => { + const rejection = new Error("User rejected the request"); + const provider = { + request: vi.fn().mockRejectedValue(rejection), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).rejects.toBe(rejection); + expect(provider.request).toHaveBeenCalledTimes(1); + }); + + it("does not return a connected provider when permission returns no account", async () => { + const provider = { + request: vi.fn().mockResolvedValue([]), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).rejects.toThrow( + "No account returned after wallet permission", + ); + expect(provider.request).toHaveBeenCalledTimes(1); + }); +}); diff --git a/app-kit-send/src/connect.ts b/app-kit-send/src/connect.ts new file mode 100644 index 0000000..1e1f7f9 --- /dev/null +++ b/app-kit-send/src/connect.ts @@ -0,0 +1,35 @@ +/** + * Copyright 2026 Circle Internet Group, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import type { CreateViemAdapterFromProviderParams } from "@circle-fin/adapter-viem-v2"; + +export type BrowserWalletProvider = + CreateViemAdapterFromProviderParams["provider"]; + +export async function connectEvmProvider(provider: BrowserWalletProvider) { + const accounts = (await provider.request({ + method: "eth_requestAccounts", + params: undefined, + })) as string[]; + const account = accounts[0]; + if (!account) { + throw new Error("No account returned after wallet permission"); + } + + return { provider, account }; +} diff --git a/app-kit-send/src/main.ts b/app-kit-send/src/main.ts index 9b71fcb..2c0f7e5 100644 --- a/app-kit-send/src/main.ts +++ b/app-kit-send/src/main.ts @@ -19,9 +19,8 @@ import { AppKit } from "@circle-fin/app-kit"; import type { SendParams } from "@circle-fin/app-kit"; import { createViemAdapterFromProvider } from "@circle-fin/adapter-viem-v2"; -import type { CreateViemAdapterFromProviderParams } from "@circle-fin/adapter-viem-v2"; - -type BrowserWalletProvider = CreateViemAdapterFromProviderParams["provider"]; +import { connectEvmProvider } from "./connect.ts"; +import type { BrowserWalletProvider } from "./connect.ts"; type EIP6963ProviderDetail = { info: { @@ -72,19 +71,14 @@ async function handleWalletConnect() { try { connectWalletButton.disabled = true; - walletProvider = await getProvider(); - await walletProvider.request({ - method: "eth_requestAccounts", - params: undefined, - }); - const accounts = (await walletProvider.request({ - method: "eth_accounts", - params: undefined, - })) as string[]; + const connection = await connectEvmProvider(await getProvider()); + walletProvider = connection.provider; - walletInfo.textContent = accounts[0] ?? "Connected"; - sendButton.disabled = !walletProvider; + walletInfo.textContent = connection.account ?? "Connected"; + sendButton.disabled = false; } catch (error) { + walletProvider = null; + sendButton.disabled = true; render({ error: error instanceof Error ? error.message : "Unknown error" }); } finally { connectWalletButton.disabled = Boolean(walletProvider); diff --git a/app-kit-swap/package.json b/app-kit-swap/package.json index 3742342..d396af1 100644 --- a/app-kit-swap/package.json +++ b/app-kit-swap/package.json @@ -5,11 +5,13 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", + "test": "vitest run", "preview": "vite preview" }, "devDependencies": { "typescript": "~7.0.2", - "vite": "^8.2.1" + "vite": "^8.2.1", + "vitest": "^4.1.9" }, "dependencies": { "@circle-fin/adapter-viem-v2": "^1.15.1", diff --git a/app-kit-swap/src/connect.test.ts b/app-kit-swap/src/connect.test.ts new file mode 100644 index 0000000..ef21597 --- /dev/null +++ b/app-kit-swap/src/connect.test.ts @@ -0,0 +1,62 @@ +/** + * Copyright 2026 Circle Internet Group, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { describe, expect, it, vi } from "vitest"; +import { connectEvmProvider } from "./connect.ts"; +import type { BrowserWalletProvider } from "./connect.ts"; + +describe("connectEvmProvider", () => { + it("returns the provider only after permission returns an account", async () => { + const provider = { + request: vi + .fn() + .mockResolvedValueOnce(["0x2222222222222222222222222222222222222222"]), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).resolves.toEqual({ + provider, + account: "0x2222222222222222222222222222222222222222", + }); + expect(provider.request).toHaveBeenNthCalledWith(1, { + method: "eth_requestAccounts", + params: undefined, + }); + expect(provider.request).toHaveBeenCalledTimes(1); + }); + + it("does not return a connected provider when permission is rejected", async () => { + const rejection = new Error("User rejected the request"); + const provider = { + request: vi.fn().mockRejectedValue(rejection), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).rejects.toBe(rejection); + expect(provider.request).toHaveBeenCalledTimes(1); + }); + + it("does not return a connected provider when permission returns no account", async () => { + const provider = { + request: vi.fn().mockResolvedValue([]), + } as unknown as BrowserWalletProvider; + + await expect(connectEvmProvider(provider)).rejects.toThrow( + "No account returned after wallet permission", + ); + expect(provider.request).toHaveBeenCalledTimes(1); + }); +}); diff --git a/app-kit-swap/src/connect.ts b/app-kit-swap/src/connect.ts new file mode 100644 index 0000000..1e1f7f9 --- /dev/null +++ b/app-kit-swap/src/connect.ts @@ -0,0 +1,35 @@ +/** + * Copyright 2026 Circle Internet Group, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import type { CreateViemAdapterFromProviderParams } from "@circle-fin/adapter-viem-v2"; + +export type BrowserWalletProvider = + CreateViemAdapterFromProviderParams["provider"]; + +export async function connectEvmProvider(provider: BrowserWalletProvider) { + const accounts = (await provider.request({ + method: "eth_requestAccounts", + params: undefined, + })) as string[]; + const account = accounts[0]; + if (!account) { + throw new Error("No account returned after wallet permission"); + } + + return { provider, account }; +} diff --git a/app-kit-swap/src/main.ts b/app-kit-swap/src/main.ts index 82f12df..327df0a 100644 --- a/app-kit-swap/src/main.ts +++ b/app-kit-swap/src/main.ts @@ -19,9 +19,8 @@ import { AppKit } from "@circle-fin/app-kit"; import type { SwapParams } from "@circle-fin/app-kit"; import { createViemAdapterFromProvider } from "@circle-fin/adapter-viem-v2"; -import type { CreateViemAdapterFromProviderParams } from "@circle-fin/adapter-viem-v2"; - -type BrowserWalletProvider = CreateViemAdapterFromProviderParams["provider"]; +import { connectEvmProvider } from "./connect.ts"; +import type { BrowserWalletProvider } from "./connect.ts"; type EIP6963ProviderDetail = { info: { @@ -72,19 +71,14 @@ async function handleWalletConnect() { try { connectWalletButton.disabled = true; - walletProvider = await getProvider(); - await walletProvider.request({ - method: "eth_requestAccounts", - params: undefined, - }); - const accounts = (await walletProvider.request({ - method: "eth_accounts", - params: undefined, - })) as string[]; + const connection = await connectEvmProvider(await getProvider()); + walletProvider = connection.provider; - walletInfo.textContent = accounts[0] ?? "Connected"; - swapButton.disabled = !walletProvider; + walletInfo.textContent = connection.account ?? "Connected"; + swapButton.disabled = false; } catch (error) { + walletProvider = null; + swapButton.disabled = true; render({ error: error instanceof Error ? error.message : "Unknown error" }); } finally { connectWalletButton.disabled = Boolean(walletProvider);