@multiplatform.one/web3 7.88.2 → 7.88.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/cjs/connectkit/adapters/SolanaAdapter.cjs +81 -6
  2. package/dist/cjs/connectkit/adapters/SolanaAdapter.native.js +94 -6
  3. package/dist/cjs/connectkit/adapters/SolanaAdapter.native.js.map +1 -1
  4. package/dist/cjs/connectkit/adapters/discover.cjs +15 -0
  5. package/dist/cjs/connectkit/adapters/discover.native.js +17 -0
  6. package/dist/cjs/connectkit/adapters/discover.native.js.map +1 -1
  7. package/dist/cjs/connectkit/connectors/getWalletConnectors.cjs +4 -1
  8. package/dist/cjs/connectkit/connectors/getWalletConnectors.native.js +4 -1
  9. package/dist/cjs/connectkit/connectors/getWalletConnectors.native.js.map +1 -1
  10. package/dist/esm/connectkit/adapters/SolanaAdapter.mjs +79 -6
  11. package/dist/esm/connectkit/adapters/SolanaAdapter.mjs.map +1 -1
  12. package/dist/esm/connectkit/adapters/SolanaAdapter.native.js +92 -6
  13. package/dist/esm/connectkit/adapters/SolanaAdapter.native.js.map +1 -1
  14. package/dist/esm/connectkit/adapters/discover.mjs +16 -1
  15. package/dist/esm/connectkit/adapters/discover.mjs.map +1 -1
  16. package/dist/esm/connectkit/adapters/discover.native.js +18 -1
  17. package/dist/esm/connectkit/adapters/discover.native.js.map +1 -1
  18. package/dist/esm/connectkit/connectors/getWalletConnectors.mjs +4 -1
  19. package/dist/esm/connectkit/connectors/getWalletConnectors.mjs.map +1 -1
  20. package/dist/esm/connectkit/connectors/getWalletConnectors.native.js +4 -1
  21. package/dist/esm/connectkit/connectors/getWalletConnectors.native.js.map +1 -1
  22. package/dist/jsx/connectkit/adapters/SolanaAdapter.mjs +79 -6
  23. package/dist/jsx/connectkit/adapters/SolanaAdapter.mjs.map +1 -1
  24. package/dist/jsx/connectkit/adapters/SolanaAdapter.native.js +94 -6
  25. package/dist/jsx/connectkit/adapters/SolanaAdapter.native.js.map +1 -1
  26. package/dist/jsx/connectkit/adapters/discover.mjs +16 -1
  27. package/dist/jsx/connectkit/adapters/discover.mjs.map +1 -1
  28. package/dist/jsx/connectkit/adapters/discover.native.js +17 -0
  29. package/dist/jsx/connectkit/adapters/discover.native.js.map +1 -1
  30. package/dist/jsx/connectkit/connectors/getWalletConnectors.mjs +4 -1
  31. package/dist/jsx/connectkit/connectors/getWalletConnectors.mjs.map +1 -1
  32. package/dist/jsx/connectkit/connectors/getWalletConnectors.native.js +4 -1
  33. package/dist/jsx/connectkit/connectors/getWalletConnectors.native.js.map +1 -1
  34. package/dist/keycloak/login.iife.js +251 -251
  35. package/package.json +7 -7
  36. package/src/connectkit/adapters/SolanaAdapter.ts +102 -6
  37. package/src/connectkit/adapters/discover.ts +19 -2
  38. package/src/connectkit/connectors/getWalletConnectors.ts +1 -0
  39. package/src/keycloak/KeycloakWalletLogin.solana.spec.tsx +158 -0
  40. package/types/connectkit/adapters/SolanaAdapter.d.ts +37 -0
  41. package/types/connectkit/adapters/SolanaAdapter.d.ts.map +1 -1
  42. package/types/connectkit/adapters/discover.d.ts +5 -1
  43. package/types/connectkit/adapters/discover.d.ts.map +1 -1
  44. package/types/connectkit/connectors/getWalletConnectors.d.ts.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/web3",
3
- "version": "7.88.2",
3
+ "version": "7.88.3",
4
4
  "description": "Web3 wallet integration for multiplatform.one ecosystem with ConnectKit and wagmi",
5
5
  "keywords": [
6
6
  "connectkit",
@@ -120,10 +120,10 @@
120
120
  "@aave/account": "^0.2.1",
121
121
  "@coinbase/wallet-sdk": "^4.4.0",
122
122
  "@metamask/connect-evm": "^2.1.1",
123
- "@multiplatform.one/connectkit": "^7.88.2",
124
- "@multiplatform.one/gpg": "^7.88.2",
125
- "@multiplatform.one/platform": "^7.88.2",
126
- "@multiplatform.one/theme": "^7.88.2",
123
+ "@multiplatform.one/connectkit": "^7.88.3",
124
+ "@multiplatform.one/gpg": "^7.88.3",
125
+ "@multiplatform.one/platform": "^7.88.3",
126
+ "@multiplatform.one/theme": "^7.88.3",
127
127
  "@noble/ciphers": "^1.3.0",
128
128
  "@noble/curves": "^1.9.7",
129
129
  "@phosphor-icons/react": "^2.1.10",
@@ -147,8 +147,8 @@
147
147
  "wagmi": "^3.7.1"
148
148
  },
149
149
  "devDependencies": {
150
- "@multiplatform.one/config": "7.88.2",
151
- "@multiplatform.one/test-utils": "7.88.2",
150
+ "@multiplatform.one/config": "7.88.3",
151
+ "@multiplatform.one/test-utils": "7.88.3",
152
152
  "@tamagui/build": "2.7.6",
153
153
  "@tanstack/react-query": "^5.104.3",
154
154
  "@testing-library/jest-dom": "^7.0.1",
@@ -11,6 +11,14 @@
11
11
  // (A future system-browser / Mobile-Wallet-Adapter path — the Solana analogue
12
12
  // of a relay — would be a separate adapter, same as the Ethereum gap.)
13
13
 
14
+ import {
15
+ SolanaSignMessage,
16
+ StandardConnect,
17
+ type SolanaSignMessageFeature,
18
+ type StandardConnectFeature,
19
+ type StandardWallet,
20
+ type StandardWalletAccount,
21
+ } from "../../clients/walletStandard";
14
22
  import { buildWalletMessage } from "../../message";
15
23
  import type { SignInMessageOptions, WalletAdapter, WalletAddress } from "./types";
16
24
 
@@ -39,7 +47,7 @@ function base58encode(bytes: Uint8Array): string {
39
47
 
40
48
  type SolanaListener = (publicKey?: { toString(): string } | null) => void;
41
49
 
42
- interface InjectedSolana {
50
+ export interface InjectedSolana {
43
51
  isPhantom?: boolean;
44
52
  publicKey?: { toString(): string } | null;
45
53
  connect(opts?: { onlyIfTrusted?: boolean }): Promise<{ publicKey: { toString(): string } }>;
@@ -64,14 +72,102 @@ function getInjectedProvider(): InjectedSolana {
64
72
  return provider;
65
73
  }
66
74
 
75
+ interface StandardEventsFeature {
76
+ on(
77
+ event: "change",
78
+ listener: (properties: { accounts?: readonly StandardWalletAccount[] }) => void,
79
+ ): () => void;
80
+ }
81
+
82
+ interface StandardDisconnectFeature {
83
+ disconnect(): Promise<void>;
84
+ }
85
+
86
+ const isSolanaAccount = (account: StandardWalletAccount) =>
87
+ account.chains.some((chain) => chain.startsWith("solana:"));
88
+
89
+ /** A Wallet Standard wallet that can connect and sign a message on a Solana chain. */
90
+ export function isStandardSolanaWallet(wallet: StandardWallet): boolean {
91
+ return (
92
+ !!wallet.features[StandardConnect] &&
93
+ !!wallet.features[SolanaSignMessage] &&
94
+ wallet.chains.some((chain) => chain.startsWith("solana:"))
95
+ );
96
+ }
97
+
98
+ /**
99
+ * A Wallet Standard Solana wallet (Solflare, Backpack, Phantom) behind the
100
+ * injected provider's shape, so `SolanaAdapter` drives it the same way. A
101
+ * silent connect the wallet answers with no account is refused as 4001, as an
102
+ * untrusting injected wallet refuses `onlyIfTrusted`.
103
+ */
104
+ export function standardSolanaProvider(wallet: StandardWallet): InjectedSolana {
105
+ const connectFeature = wallet.features[StandardConnect] as StandardConnectFeature;
106
+ const signFeature = wallet.features[SolanaSignMessage] as SolanaSignMessageFeature;
107
+ const events = wallet.features["standard:events"] as StandardEventsFeature | undefined;
108
+ const disconnectFeature = wallet.features["standard:disconnect"] as
109
+ | StandardDisconnectFeature
110
+ | undefined;
111
+ const key = (account: StandardWalletAccount) => ({ toString: () => account.address });
112
+ const pick = (accounts: readonly StandardWalletAccount[]) =>
113
+ accounts.find(isSolanaAccount) ?? null;
114
+ const unsubscribes = new Map<SolanaListener, () => void>();
115
+ let account: StandardWalletAccount | null = null;
116
+ return {
117
+ get publicKey() {
118
+ return account ? key(account) : null;
119
+ },
120
+ async connect(options) {
121
+ const { accounts } = await connectFeature.connect(
122
+ options?.onlyIfTrusted ? { silent: true } : undefined,
123
+ );
124
+ account = pick(accounts);
125
+ if (!account) {
126
+ throw Object.assign(new Error(`${wallet.name} shared no Solana account.`), { code: 4001 });
127
+ }
128
+ return { publicKey: key(account) };
129
+ },
130
+ async disconnect() {
131
+ account = null;
132
+ await disconnectFeature?.disconnect();
133
+ },
134
+ async signMessage(message) {
135
+ if (!account) throw new Error("connect a Solana wallet first");
136
+ const [signed] = await signFeature.signMessage({ account, message });
137
+ return { signature: signed.signature };
138
+ },
139
+ on(event, listener) {
140
+ if (!events) return;
141
+ const unsubscribe = events.on("change", ({ accounts }) => {
142
+ if (!accounts) return;
143
+ account = pick(accounts);
144
+ if (event === "accountChanged" && account) listener(key(account));
145
+ if (event === "disconnect" && !account) listener(null);
146
+ });
147
+ unsubscribes.set(listener, unsubscribe);
148
+ },
149
+ off(_event, listener) {
150
+ unsubscribes.get(listener)?.();
151
+ unsubscribes.delete(listener);
152
+ },
153
+ };
154
+ }
155
+
67
156
  export class SolanaAdapter implements WalletAdapter {
68
157
  readonly chain = "solana";
69
158
  address: WalletAddress | null = null;
70
159
  networkId: string | null = "mainnet-beta";
71
160
  isConnected = false;
72
161
 
162
+ /** Drives the injected wallet unless given another provider, such as `standardSolanaProvider(wallet)`. */
163
+ private readonly provider: () => InjectedSolana;
164
+
165
+ constructor(provider: () => InjectedSolana = getInjectedProvider) {
166
+ this.provider = provider;
167
+ }
168
+
73
169
  async connect(): Promise<void> {
74
- const provider = getInjectedProvider();
170
+ const provider = this.provider();
75
171
  const { publicKey } = await provider.connect();
76
172
  this.address = publicKey.toString();
77
173
  this.isConnected = true;
@@ -83,7 +179,7 @@ export class SolanaAdapter implements WalletAdapter {
83
179
  * any other failure, and when no wallet is injected yet.
84
180
  */
85
181
  async restore(): Promise<boolean> {
86
- const provider = getInjectedProvider();
182
+ const provider = this.provider();
87
183
  try {
88
184
  const { publicKey } = await provider.connect({ onlyIfTrusted: true });
89
185
  this.address = publicKey.toString();
@@ -101,7 +197,7 @@ export class SolanaAdapter implements WalletAdapter {
101
197
  * page must connect again; the adapter treats it as a disconnect.
102
198
  */
103
199
  subscribe(listener: () => void): () => void {
104
- const provider = getInjectedProvider();
200
+ const provider = this.provider();
105
201
  const onAccount: SolanaListener = (publicKey) => {
106
202
  this.address = publicKey ? publicKey.toString() : null;
107
203
  this.isConnected = this.address !== null;
@@ -123,7 +219,7 @@ export class SolanaAdapter implements WalletAdapter {
123
219
 
124
220
  async disconnect(): Promise<void> {
125
221
  try {
126
- await getInjectedProvider().disconnect();
222
+ await this.provider().disconnect();
127
223
  } catch {
128
224
  // ignore — clearing local state below is what matters
129
225
  }
@@ -142,7 +238,7 @@ export class SolanaAdapter implements WalletAdapter {
142
238
 
143
239
  /** Sign the UTF-8 message bytes; returns the base58 ed25519 signature. */
144
240
  async signMessage(message: string): Promise<string> {
145
- const provider = getInjectedProvider();
241
+ const provider = this.provider();
146
242
  const { signature } = await provider.signMessage(new TextEncoder().encode(message), "utf8");
147
243
  return base58encode(signature);
148
244
  }
@@ -1,5 +1,6 @@
1
+ import { getStandardWallets } from "../../clients/walletStandard";
1
2
  import type { WalletAdapter } from "./types";
2
- import { SolanaAdapter } from "./SolanaAdapter";
3
+ import { SolanaAdapter, isStandardSolanaWallet, standardSolanaProvider } from "./SolanaAdapter";
3
4
  import { SuiAdapter, discoverSuiWallets } from "./SuiAdapter";
4
5
  import { BitcoinAdapter } from "./BitcoinAdapter";
5
6
 
@@ -14,10 +15,14 @@ export interface WalletEntry {
14
15
  ecosystem: WalletEcosystem;
15
16
  /** Ready-to-drive wallet adapter. */
16
17
  adapter: WalletAdapter;
18
+ /** The wallet's own icon (a data URI), for a wallet no walletConfigs key names. */
19
+ icon?: string;
17
20
  }
18
21
 
19
22
  /**
20
- * Detect the non-EVM wallets present in the page (Solana / Sui / Bitcoin). EVM
23
+ * Detect the non-EVM wallets present in the page (Solana / Sui / Bitcoin). A
24
+ * Solana wallet is the injected one, else the first Wallet Standard wallet that
25
+ * signs on a Solana chain. EVM
21
26
  * wallets are intentionally NOT returned here — they are handled natively by
22
27
  * wagmi's EIP-6963 / Coinbase / MetaMask connectors. One entry per
23
28
  * (ecosystem, primary wallet); each carries a ready wallet adapter.
@@ -40,6 +45,18 @@ export function discoverWallets(): WalletEntry[] {
40
45
  ecosystem: "solana",
41
46
  adapter: new SolanaAdapter(),
42
47
  });
48
+ } else {
49
+ const standard = getStandardWallets().find(isStandardSolanaWallet);
50
+ if (standard) {
51
+ const provider = standardSolanaProvider(standard);
52
+ out.push({
53
+ id: `wallet:solana:${standard.name.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`,
54
+ name: standard.name,
55
+ ecosystem: "solana",
56
+ adapter: new SolanaAdapter(() => provider),
57
+ ...(standard.icon ? { icon: standard.icon } : {}),
58
+ });
59
+ }
43
60
  }
44
61
 
45
62
  const suiWallets = discoverSuiWallets();
@@ -18,6 +18,7 @@ export function getWalletConnectors(
18
18
  name: e.name,
19
19
  ecosystem: e.ecosystem,
20
20
  adapter: e.adapter,
21
+ ...(e.icon ? { icon: e.icon } : {}),
21
22
  }),
22
23
  );
23
24
  }
@@ -0,0 +1,158 @@
1
+ // @vitest-environment happy-dom
2
+ import { ed25519 } from "@noble/curves/ed25519";
3
+ import bs58 from "bs58";
4
+ import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
+ import type { StandardWallet, StandardWalletAccount } from "../clients/walletStandard";
7
+ import { discoverWallets } from "../connectkit/adapters/discover";
8
+ import { verifySiwsSignature } from "../siws/verify";
9
+ import { KeycloakWalletLogin } from "./KeycloakWalletLogin";
10
+
11
+ const LOGIN_ACTION =
12
+ "https://kc.example.com/realms/main/login-actions/authenticate?session_code=sc&execution=ex";
13
+
14
+ function keypair() {
15
+ const secret = ed25519.utils.randomPrivateKey();
16
+ return { secret, address: bs58.encode(ed25519.getPublicKey(secret)) };
17
+ }
18
+
19
+ /** A Wallet Standard wallet, registered the way Solflare and Backpack register. */
20
+ function registerStandardWallet(
21
+ name: string,
22
+ chains: readonly string[],
23
+ { secret, address }: ReturnType<typeof keypair>,
24
+ ) {
25
+ const account: StandardWalletAccount = {
26
+ address,
27
+ publicKey: bs58.decode(address),
28
+ chains,
29
+ features: ["solana:signMessage"],
30
+ };
31
+ const signMessage = vi.fn(async (...inputs: { message: Uint8Array }[]) =>
32
+ inputs.map(({ message }) => ({
33
+ signedMessage: message,
34
+ signature: ed25519.sign(message, secret),
35
+ })),
36
+ );
37
+ const wallet: StandardWallet = {
38
+ name,
39
+ icon: "data:image/svg+xml;base64,PHN2Zy8+",
40
+ chains,
41
+ accounts: [],
42
+ features: {
43
+ "standard:connect": { connect: async () => ({ accounts: [account] }) },
44
+ "standard:events": { on: () => () => {} },
45
+ "solana:signMessage": { signMessage },
46
+ },
47
+ };
48
+ const register = (event: Event) =>
49
+ ((event as CustomEvent).detail as { register: (w: StandardWallet) => void }).register(wallet);
50
+ window.addEventListener("wallet-standard:app-ready", register);
51
+ return {
52
+ signMessage,
53
+ unregister: () => window.removeEventListener("wallet-standard:app-ready", register),
54
+ };
55
+ }
56
+
57
+ const nonceRequests: string[] = [];
58
+ const cleanups: (() => void)[] = [];
59
+
60
+ beforeEach(() => {
61
+ nonceRequests.length = 0;
62
+ vi.stubGlobal(
63
+ "fetch",
64
+ vi.fn(async (input: RequestInfo | URL) => {
65
+ const url = String(input);
66
+ if (!url.endsWith("/nonce")) return new Response("not found", { status: 404 });
67
+ nonceRequests.push(url);
68
+ return new Response("nonce123abc");
69
+ }),
70
+ );
71
+ });
72
+
73
+ afterEach(() => {
74
+ cleanup();
75
+ for (const undo of cleanups.splice(0)) undo();
76
+ vi.unstubAllGlobals();
77
+ vi.restoreAllMocks();
78
+ Reflect.deleteProperty(window, "phantom");
79
+ document.querySelectorAll("form").forEach((form) => form.remove());
80
+ });
81
+
82
+ async function signInThrough(walletName: string) {
83
+ const submit = vi
84
+ .spyOn(HTMLFormElement.prototype, "submit")
85
+ .mockImplementation(function (this: HTMLFormElement) {});
86
+ render(
87
+ <KeycloakWalletLogin
88
+ baseUrl="https://kc.example.com"
89
+ realm="main"
90
+ resource="wallet"
91
+ target={{ action: LOGIN_ACTION }}
92
+ domain="kc.example.com"
93
+ />,
94
+ );
95
+ fireEvent.click(document.getElementById("mpo-wallet-login") as HTMLButtonElement);
96
+ fireEvent.click(await screen.findByText(walletName));
97
+ await waitFor(() => expect(submit).toHaveBeenCalledTimes(1));
98
+ const form = submit.mock.contexts[0] as HTMLFormElement;
99
+ const field = (name: string) =>
100
+ (form.querySelector(`input[name="${name}"]`) as HTMLInputElement).value;
101
+ return { form, signature: field("username"), message: atob(field("password")) };
102
+ }
103
+
104
+ describe("KeycloakWalletLogin Solana sign-in (FZ-1824)", () => {
105
+ it("lists a Wallet Standard Solana wallet and posts its signed SIWS message to the login action", async () => {
106
+ const keys = keypair();
107
+ const wallet = registerStandardWallet("Solflare", ["solana:mainnet"], keys);
108
+ cleanups.push(wallet.unregister);
109
+
110
+ const { form, signature, message } = await signInThrough("Solflare");
111
+
112
+ expect(form.action).toBe(LOGIN_ACTION);
113
+ expect(message.split("\n").slice(0, 2)).toEqual([
114
+ "kc.example.com wants you to sign in with your Solana account:",
115
+ keys.address,
116
+ ]);
117
+ expect(message).toContain("Chain ID: solana:mainnet");
118
+ expect(message).toContain("Nonce: nonce123abc");
119
+ expect(verifySiwsSignature(message, signature, keys.address)).toBe(true);
120
+ expect(wallet.signMessage).toHaveBeenCalledTimes(1);
121
+ expect(nonceRequests).toEqual(["https://kc.example.com/realms/main/wallet/nonce"]);
122
+ });
123
+
124
+ it("signs with the injected Phantom too, one nonce for the page", async () => {
125
+ const keys = keypair();
126
+ (window as unknown as Record<string, unknown>).phantom = {
127
+ solana: {
128
+ isPhantom: true,
129
+ publicKey: null,
130
+ connect: async () => ({ publicKey: { toString: () => keys.address } }),
131
+ disconnect: async () => {},
132
+ signMessage: async (bytes: Uint8Array) => ({ signature: ed25519.sign(bytes, keys.secret) }),
133
+ on() {},
134
+ off() {},
135
+ },
136
+ };
137
+
138
+ const { signature, message } = await signInThrough("Phantom");
139
+
140
+ expect(message.split("\n")[1]).toBe(keys.address);
141
+ expect(verifySiwsSignature(message, signature, keys.address)).toBe(true);
142
+ expect(nonceRequests).toEqual(["https://kc.example.com/realms/main/wallet/nonce"]);
143
+ });
144
+ });
145
+
146
+ describe("Solana wallet discovery", () => {
147
+ it("prefers the injected wallet, so a Phantom that also registers is listed once", () => {
148
+ (window as unknown as Record<string, unknown>).phantom = { solana: { isPhantom: true } };
149
+ cleanups.push(registerStandardWallet("Phantom", ["solana:mainnet"], keypair()).unregister);
150
+ const solana = discoverWallets().filter((entry) => entry.ecosystem === "solana");
151
+ expect(solana.map((entry) => entry.id)).toEqual(["wallet:solana:phantom"]);
152
+ });
153
+
154
+ it("skips a Wallet Standard wallet that signs on no Solana chain", () => {
155
+ cleanups.push(registerStandardWallet("Sui Only", ["sui:mainnet"], keypair()).unregister);
156
+ expect(discoverWallets().filter((entry) => entry.ecosystem === "solana")).toEqual([]);
157
+ });
158
+ });
@@ -1,9 +1,45 @@
1
+ import { type StandardWallet } from "../../clients/walletStandard";
1
2
  import type { SignInMessageOptions, WalletAdapter, WalletAddress } from "./types";
3
+ type SolanaListener = (publicKey?: {
4
+ toString(): string;
5
+ } | null) => void;
6
+ export interface InjectedSolana {
7
+ isPhantom?: boolean;
8
+ publicKey?: {
9
+ toString(): string;
10
+ } | null;
11
+ connect(opts?: {
12
+ onlyIfTrusted?: boolean;
13
+ }): Promise<{
14
+ publicKey: {
15
+ toString(): string;
16
+ };
17
+ }>;
18
+ disconnect(): Promise<void>;
19
+ signMessage(message: Uint8Array, display?: "utf8" | "hex"): Promise<{
20
+ signature: Uint8Array;
21
+ }>;
22
+ on?(event: "accountChanged" | "disconnect", listener: SolanaListener): void;
23
+ off?(event: "accountChanged" | "disconnect", listener: SolanaListener): void;
24
+ removeListener?(event: "accountChanged" | "disconnect", listener: SolanaListener): void;
25
+ }
26
+ /** A Wallet Standard wallet that can connect and sign a message on a Solana chain. */
27
+ export declare function isStandardSolanaWallet(wallet: StandardWallet): boolean;
28
+ /**
29
+ * A Wallet Standard Solana wallet (Solflare, Backpack, Phantom) behind the
30
+ * injected provider's shape, so `SolanaAdapter` drives it the same way. A
31
+ * silent connect the wallet answers with no account is refused as 4001, as an
32
+ * untrusting injected wallet refuses `onlyIfTrusted`.
33
+ */
34
+ export declare function standardSolanaProvider(wallet: StandardWallet): InjectedSolana;
2
35
  export declare class SolanaAdapter implements WalletAdapter {
3
36
  readonly chain = "solana";
4
37
  address: WalletAddress | null;
5
38
  networkId: string | null;
6
39
  isConnected: boolean;
40
+ /** Drives the injected wallet unless given another provider, such as `standardSolanaProvider(wallet)`. */
41
+ private readonly provider;
42
+ constructor(provider?: () => InjectedSolana);
7
43
  connect(): Promise<void>;
8
44
  /**
9
45
  * Reconnects without a prompt (`onlyIfTrusted`). Resolves false when the
@@ -23,4 +59,5 @@ export declare class SolanaAdapter implements WalletAdapter {
23
59
  /** Sign the UTF-8 message bytes; returns the base58 ed25519 signature. */
24
60
  signMessage(message: string): Promise<string>;
25
61
  }
62
+ export {};
26
63
  //# sourceMappingURL=SolanaAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaAdapter.d.ts","sourceRoot":"","sources":["../../../src/connectkit/adapters/SolanaAdapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAoDlF,qBAAa,aAAc,YAAW,aAAa;IACjD,QAAQ,CAAC,KAAK,YAAY;IAC1B,OAAO,EAAE,aAAa,GAAG,IAAI,CAAQ;IACrC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAkB;IAC1C,WAAW,UAAS;IAEd,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAajC;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAqBrC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC,4EAA4E;IACtE,YAAY,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ/D,0EAA0E;IACpE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAKpD"}
1
+ {"version":3,"file":"SolanaAdapter.d.ts","sourceRoot":"","sources":["../../../src/connectkit/adapters/SolanaAdapter.ts"],"names":[],"mappings":"AAaA,OAAO,EAKL,KAAK,cAAc,EAEpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAyBlF,KAAK,cAAc,GAAG,CAAC,SAAS,CAAC,EAAE;IAAE,QAAQ,IAAI,MAAM,CAAA;CAAE,GAAG,IAAI,KAAK,IAAI,CAAC;AAE1E,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE;QAAE,QAAQ,IAAI,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE;YAAE,QAAQ,IAAI,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IAC5F,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;IAC/F,EAAE,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5E,GAAG,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7E,cAAc,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;CACzF;AA8BD,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAMtE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAkD7E;AAED,qBAAa,aAAc,YAAW,aAAa;IACjD,QAAQ,CAAC,KAAK,YAAY;IAC1B,OAAO,EAAE,aAAa,GAAG,IAAI,CAAQ;IACrC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAkB;IAC1C,WAAW,UAAS;IAEpB,0GAA0G;IAC1G,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;gBAEpC,QAAQ,GAAE,MAAM,cAAoC;IAI1D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAajC;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAqBrC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC,4EAA4E;IACtE,YAAY,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ/D,0EAA0E;IACpE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAKpD"}
@@ -9,9 +9,13 @@ export interface WalletEntry {
9
9
  ecosystem: WalletEcosystem;
10
10
  /** Ready-to-drive wallet adapter. */
11
11
  adapter: WalletAdapter;
12
+ /** The wallet's own icon (a data URI), for a wallet no walletConfigs key names. */
13
+ icon?: string;
12
14
  }
13
15
  /**
14
- * Detect the non-EVM wallets present in the page (Solana / Sui / Bitcoin). EVM
16
+ * Detect the non-EVM wallets present in the page (Solana / Sui / Bitcoin). A
17
+ * Solana wallet is the injected one, else the first Wallet Standard wallet that
18
+ * signs on a Solana chain. EVM
15
19
  * wallets are intentionally NOT returned here — they are handled natively by
16
20
  * wagmi's EIP-6963 / Coinbase / MetaMask connectors. One entry per
17
21
  * (ecosystem, primary wallet); each carries a ready wallet adapter.
@@ -1 +1 @@
1
- {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../src/connectkit/adapters/discover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,SAAS,EAAE,eAAe,CAAC;IAC3B,qCAAqC;IACrC,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,WAAW,EAAE,CAyC/C"}
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../src/connectkit/adapters/discover.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,SAAS,EAAE,eAAe,CAAC;IAC3B,qCAAqC;IACrC,OAAO,EAAE,aAAa,CAAC;IACvB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,IAAI,WAAW,EAAE,CAqD/C"}
@@ -1 +1 @@
1
- {"version":3,"file":"getWalletConnectors.d.ts","sourceRoot":"","sources":["../../../src/connectkit/connectors/getWalletConnectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGzE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,WAAW,EAAsB,GACzC,iBAAiB,EAAE,CASrB"}
1
+ {"version":3,"file":"getWalletConnectors.d.ts","sourceRoot":"","sources":["../../../src/connectkit/connectors/getWalletConnectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGzE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,WAAW,EAAsB,GACzC,iBAAiB,EAAE,CAUrB"}