@getpara/solana-wallet-connectors 3.0.0-alpha.1 → 3.1.0

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.
@@ -42,7 +42,10 @@ import { jsx } from "react/jsx-runtime";
42
42
  import { createContext, useEffect, useMemo, useRef, useState } from "react";
43
43
  import { useWallet } from "@solana/wallet-adapter-react";
44
44
  import { isIosAndRedirectable, WalletReadyState } from "@solana/wallet-adapter-base";
45
- import { isAndroid } from "@getpara/web-sdk";
45
+ import {
46
+ isAndroid,
47
+ isAndroidChrome
48
+ } from "@getpara/web-sdk";
46
49
  import {
47
50
  defaultSolanaExternalWallet
48
51
  } from "@getpara/react-common";
@@ -83,6 +86,7 @@ function SolanaExternalWalletProvider({
83
86
  const solanaAddressRef = useRef(solanaAddress == null ? void 0 : solanaAddress.toString());
84
87
  const disconnectRef = useRef(disconnect);
85
88
  const walletRef = useRef(wallet);
89
+ const lastConnectedAdapterRef = useRef(void 0);
86
90
  useEffect(() => {
87
91
  walletRef.current = wallet;
88
92
  }, [wallet]);
@@ -106,6 +110,7 @@ function SolanaExternalWalletProvider({
106
110
  interface: {
107
111
  disconnect: () => __async(this, null, function* () {
108
112
  yield disconnectRef.current();
113
+ lastConnectedAdapterRef.current = void 0;
109
114
  }),
110
115
  getAddress: () => __async(this, null, function* () {
111
116
  var _a;
@@ -113,15 +118,69 @@ function SolanaExternalWalletProvider({
113
118
  }),
114
119
  signMessage: (_0) => __async(this, [_0], function* ({ message }) {
115
120
  var _a, _b, _c, _d;
116
- try {
121
+ const resolveSignFn = () => {
122
+ var _a2;
123
+ if (solanaSignMessageRef.current) return solanaSignMessageRef.current;
124
+ if (solanaSignMessage) return solanaSignMessage;
125
+ const adapter = (_a2 = walletRef.current) == null ? void 0 : _a2.adapter;
126
+ if (adapter && typeof adapter.signMessage === "function") {
127
+ return adapter.signMessage.bind(adapter);
128
+ }
129
+ const lastConnected = lastConnectedAdapterRef.current;
130
+ if (lastConnected && typeof lastConnected.signMessage === "function") {
131
+ return lastConnected.signMessage.bind(lastConnected);
132
+ }
133
+ return void 0;
134
+ };
135
+ const snapshotState = () => {
136
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k;
137
+ return {
138
+ adapterName: (_b2 = (_a2 = walletRef.current) == null ? void 0 : _a2.adapter) == null ? void 0 : _b2.name,
139
+ adapterConnected: (_d2 = (_c2 = walletRef.current) == null ? void 0 : _c2.adapter) == null ? void 0 : _d2.connected,
140
+ adapterHasPublicKey: !!((_f = (_e = walletRef.current) == null ? void 0 : _e.adapter) == null ? void 0 : _f.publicKey),
141
+ hasRefSignMessage: !!solanaSignMessageRef.current,
142
+ hasClosureSignMessage: !!solanaSignMessage,
143
+ hasAdapterSignMessage: typeof ((_h = (_g = walletRef.current) == null ? void 0 : _g.adapter) == null ? void 0 : _h.signMessage) === "function",
144
+ lastConnectedAdapterName: (_i = lastConnectedAdapterRef.current) == null ? void 0 : _i.name,
145
+ lastConnectedAdapterConnected: (_j = lastConnectedAdapterRef.current) == null ? void 0 : _j.connected,
146
+ hasLastConnectedAdapterSignMessage: typeof ((_k = lastConnectedAdapterRef.current) == null ? void 0 : _k.signMessage) === "function"
147
+ };
148
+ };
149
+ const waitForSignFn = () => __async(this, null, function* () {
117
150
  const start = Date.now();
118
- let fn = (_a = solanaSignMessageRef.current) != null ? _a : solanaSignMessage;
151
+ let fn = resolveSignFn();
119
152
  while (!fn) {
120
153
  if (Date.now() - start > SIGN_MESSAGE_REF_WAIT_MS) {
121
- throw new Error("Solana signMessage unavailable");
154
+ return void 0;
122
155
  }
123
156
  yield new Promise((resolve) => setTimeout(resolve, 100));
124
- fn = (_b = solanaSignMessageRef.current) != null ? _b : solanaSignMessage;
157
+ fn = resolveSignFn();
158
+ }
159
+ return fn;
160
+ });
161
+ try {
162
+ let fn = yield waitForSignFn();
163
+ if (!fn) {
164
+ const adapter = (_b = (_a = walletRef.current) == null ? void 0 : _a.adapter) != null ? _b : lastConnectedAdapterRef.current;
165
+ if (adapter) {
166
+ const stateBefore = snapshotState();
167
+ console.warn(
168
+ "[Solana signMessage] sign fn unavailable after wait; attempting adapter.connect() recovery",
169
+ stateBefore
170
+ );
171
+ try {
172
+ if (!adapter.connected) {
173
+ yield adapter.connect();
174
+ }
175
+ fn = yield waitForSignFn();
176
+ } catch (reconnectErr) {
177
+ console.error("[Solana signMessage] reconnect attempt failed", reconnectErr, snapshotState());
178
+ }
179
+ }
180
+ }
181
+ if (!fn) {
182
+ console.error("[Solana signMessage] sign fn unavailable after recovery", snapshotState());
183
+ throw new Error("Solana signMessage unavailable");
125
184
  }
126
185
  const encodedMessage = new TextEncoder().encode(message);
127
186
  const signature = yield fn(encodedMessage);
@@ -133,7 +192,7 @@ function SolanaExternalWalletProvider({
133
192
  if ((_c = e == null ? void 0 : e.message) == null ? void 0 : _c.includes("User rejected the request")) {
134
193
  throw new Error("Signature request rejected");
135
194
  }
136
- console.error("Solana signature error:", e == null ? void 0 : e.message);
195
+ console.error("Solana signature error:", e == null ? void 0 : e.message, snapshotState());
137
196
  throw new Error(`Solana signMessage failed: ${(_d = e == null ? void 0 : e.message) != null ? _d : "unknown"}`);
138
197
  }
139
198
  }),
@@ -259,6 +318,7 @@ function SolanaExternalWalletProvider({
259
318
  )
260
319
  ]);
261
320
  }
321
+ lastConnectedAdapterRef.current = adapter;
262
322
  return address;
263
323
  } catch (e) {
264
324
  console.error(e);
@@ -266,7 +326,7 @@ function SolanaExternalWalletProvider({
266
326
  throw e;
267
327
  }
268
328
  });
269
- const connectCallback = (adapter) => {
329
+ const connectCallback = (adapter, walletName) => {
270
330
  return () => __async(this, null, function* () {
271
331
  var _a, _b, _c, _d;
272
332
  let address;
@@ -275,7 +335,7 @@ function SolanaExternalWalletProvider({
275
335
  } catch (e) {
276
336
  throw e;
277
337
  }
278
- const providerName = adapter.name;
338
+ const providerName = walletName != null ? walletName : adapter.name;
279
339
  const providerId = (_b = (_a = getWallet(providerName != null ? providerName : "")) == null ? void 0 : _a.id) != null ? _b : "";
280
340
  solanaAddressRef.current = address;
281
341
  return {
@@ -293,13 +353,15 @@ function SolanaExternalWalletProvider({
293
353
  };
294
354
  });
295
355
  };
296
- const connect = (adapter) => __async(this, null, function* () {
356
+ const connect = (adapter, walletName) => __async(this, null, function* () {
297
357
  var _a;
298
358
  if (isIosAndRedirectable() && !isInSolanaWalletDappBrowser()) {
299
359
  return;
300
360
  }
301
361
  if (isAndroid() && (adapter == null ? void 0 : adapter.name) === "Mobile Wallet Adapter") {
302
- return;
362
+ if (!isAndroidChrome()) return;
363
+ const tappedWallet = getWallet(walletName != null ? walletName : "");
364
+ if (!(tappedWallet == null ? void 0 : tappedWallet.mwaSupported)) return;
303
365
  }
304
366
  if (adapter && (wallet == null ? void 0 : wallet.adapter) && wallet.adapter.name !== adapter.name) {
305
367
  yield disconnect();
@@ -310,7 +372,7 @@ function SolanaExternalWalletProvider({
310
372
  let error;
311
373
  let authState;
312
374
  try {
313
- authState = yield para.connectExternalWallet({ connect: connectCallback(adapter) });
375
+ authState = yield para.connectExternalWallet({ connect: connectCallback(adapter, walletName) });
314
376
  address = (_a = authState.externalWallet) == null ? void 0 : _a.address;
315
377
  } catch (err) {
316
378
  switch (err.message) {
@@ -383,23 +445,29 @@ function SolanaExternalWalletProvider({
383
445
  const createWallet = (walletFn) => {
384
446
  const metaData = walletFn();
385
447
  const adapter = getAdapter(metaData.name);
448
+ const isMwaOnAndroidChrome = !!metaData.mwaSupported && isAndroidChrome();
386
449
  return __spreadProps(__spreadValues({
387
- connect: () => connect(adapter),
388
- connectMobile: () => connect(adapter),
450
+ connect: () => connect(adapter, metaData.name),
451
+ connectMobile: () => connect(adapter, metaData.name),
389
452
  type: "SOLANA",
390
- installed: adapter && ((adapter == null ? void 0 : adapter.readyState) === WalletReadyState.Installed || (adapter == null ? void 0 : adapter.readyState) === WalletReadyState.Loadable)
453
+ installed: isMwaOnAndroidChrome || adapter && ((adapter == null ? void 0 : adapter.readyState) === WalletReadyState.Installed || (adapter == null ? void 0 : adapter.readyState) === WalletReadyState.Loadable)
391
454
  }, metaData), {
392
455
  // Using name here since that's the only common id across the networks
393
456
  id: metaData.name
394
457
  });
395
458
  };
396
- const [wallets, setWallets] = useState(() => walletFns.map(createWallet));
459
+ const [wallets, setWallets] = useState(() => {
460
+ const created = walletFns.map(createWallet);
461
+ if (isAndroidChrome()) return created;
462
+ return created.filter((w) => w.internalId !== "SEED_VAULT_WALLET");
463
+ });
397
464
  useEffect(() => {
398
465
  setWallets(
399
466
  (prev) => prev.map((wallet2) => {
400
467
  var _a;
401
468
  const adapter = getAdapter((_a = wallet2.name) != null ? _a : "");
402
- const installed = !!adapter && (adapter.readyState === WalletReadyState.Installed || adapter.readyState === WalletReadyState.Loadable);
469
+ const isMwaOnAndroidChrome = !!wallet2.mwaSupported && isAndroidChrome();
470
+ const installed = isMwaOnAndroidChrome || !!adapter && (adapter.readyState === WalletReadyState.Installed || adapter.readyState === WalletReadyState.Loadable);
403
471
  if (wallet2.installed !== installed) {
404
472
  return __spreadProps(__spreadValues({}, wallet2), { installed });
405
473
  }
@@ -4,5 +4,6 @@ import { glowWallet } from './glow/glow.js';
4
4
  import { backpackWallet } from './backpack/backpack.js';
5
5
  import { solflareWallet } from './solflare/solflare.js';
6
6
  import { metaMaskWallet } from './metaMask/metaMask.js';
7
- export { farcasterWallet, phantomWallet, glowWallet, backpackWallet, solflareWallet, metaMaskWallet };
7
+ import { seedVaultWallet } from './seedVault/seedVault.js';
8
+ export { farcasterWallet, phantomWallet, glowWallet, backpackWallet, solflareWallet, metaMaskWallet, seedVaultWallet };
8
9
  export declare const allWallets: (() => import("../../types/Wallet.js").Wallet)[];
@@ -5,7 +5,8 @@ import { glowWallet } from "./glow/glow.js";
5
5
  import { backpackWallet } from "./backpack/backpack.js";
6
6
  import { solflareWallet } from "./solflare/solflare.js";
7
7
  import { metaMaskWallet } from "./metaMask/metaMask.js";
8
- const allWallets = [phantomWallet, glowWallet, backpackWallet, solflareWallet, metaMaskWallet];
8
+ import { seedVaultWallet } from "./seedVault/seedVault.js";
9
+ const allWallets = [phantomWallet, glowWallet, backpackWallet, solflareWallet, metaMaskWallet, seedVaultWallet];
9
10
  export {
10
11
  allWallets,
11
12
  backpackWallet,
@@ -13,5 +14,6 @@ export {
13
14
  glowWallet,
14
15
  metaMaskWallet,
15
16
  phantomWallet,
17
+ seedVaultWallet,
16
18
  solflareWallet
17
19
  };
@@ -0,0 +1,2 @@
1
+ import { Wallet } from '../../../types/Wallet.js';
2
+ export declare const seedVaultWallet: () => Wallet;
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ var __async = (__this, __arguments, generator) => {
3
+ return new Promise((resolve, reject) => {
4
+ var fulfilled = (value) => {
5
+ try {
6
+ step(generator.next(value));
7
+ } catch (e) {
8
+ reject(e);
9
+ }
10
+ };
11
+ var rejected = (value) => {
12
+ try {
13
+ step(generator.throw(value));
14
+ } catch (e) {
15
+ reject(e);
16
+ }
17
+ };
18
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
19
+ step((generator = generator.apply(__this, __arguments)).next());
20
+ });
21
+ };
22
+ import { icon } from "./seedVaultIcon.js";
23
+ const seedVaultWallet = () => {
24
+ return {
25
+ id: "seed_vault_wallet",
26
+ internalId: "SEED_VAULT_WALLET",
27
+ name: "Seed Vault Wallet",
28
+ iconUrl: icon,
29
+ isExtension: false,
30
+ isMobile: true,
31
+ hasIosSafariExtension: false,
32
+ mwaSupported: true,
33
+ // No QR / universal-link path: Seed Vault Wallet has no in-app browser and
34
+ // no `window.solana` injection. MWA is the only entry point.
35
+ getQrUri: () => __async(void 0, null, function* () {
36
+ return "";
37
+ }),
38
+ downloadUrl: "https://solanamobile.com/seeker"
39
+ };
40
+ };
41
+ export {
42
+ seedVaultWallet
43
+ };
@@ -0,0 +1 @@
1
+ export declare const icon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAyNDUgMjQ1IiBmaWxsPSJub25lIj48Y2lyY2xlIGN4PSIxMjIuNSIgY3k9IjEyMi41IiByPSIxMjIuNSIgZmlsbD0iIzAwMDAwMCIvPjxwYXRoIGQ9Ik0xMjIuNSAwQzE5MC4xNTUgMCAyNDUgNTQuODQ1MSAyNDUgMTIyLjVDMjQ1IDE5MC4xNTUgMTkwLjE1NSAyNDUgMTIyLjUgMjQ1QzU1LjAxMTkgMjQ1IDAuMjcyMzYgMTkwLjQyNSAwLjAwMjkyOTY5IDEyM0gwQzAgMTIyLjkzNiAwLjAwMDcyMDUyIDEyMi44NzIgMC4wMDA5NzY1NjIgMTIyLjgwOEMwLjAwMDcyNDU4OCAxMjIuNzA1IDAgMTIyLjYwMyAwIDEyMi41QzAgNTQuODQ1MSA1NC44NDUxIDAgMTIyLjUgMFpNMTIyLjUgMjBDODQuOTY4MiAyMCA1Mi4xNDc2IDQwLjE3MTkgMzQuMjg5MSA3MC4yNjU2QzU2LjU3MTEgNTUuOTIyOCA4Ny44NTU5IDQ3IDEyMi41IDQ3QzEzNy4zNjQgNDcgMTUwLjY3IDQ5LjQ5NjEgMTY0IDU1QzE3Ny4zMyA2MC41MDM5IDE4OC43MTggNzAuOTQxIDE5NS43OTMgODQuNTkyOEMxNzcuNDEgNzQuMDIwMiAxNTEuNzAxIDY3IDEyMi41IDY3QzkxLjc5NDEgNjcgNjQuOTQ3OSA3NC43NjE4IDQ2LjQyMjkgODYuMjU0OUMzMi44MzEzIDk0LjY4NzIgMjUuMDkzNSAxMDQuMDg2IDIxLjg0MDggMTEzSDY2VjEzM0gyMC41MzEyQzI1Ljc4OTUgMTg0LjY3NyA2OS40MzU3IDIyNSAxMjIuNSAyMjVDMTU5LjQ0IDIyNSAxOTEuODE0IDIwNS40NTkgMjA5Ljg1MyAxNzYuMTVDMTg3LjYxNCAxOTAuMjQ5IDE1Ni42MDEgMTk5IDEyMi4yOTMgMTk5QzEwNy40MjkgMTk5IDk0LjEyMzQgMTk2LjUwNCA4MC43OTMgMTkxQzY3LjQ2MjUgMTg1LjQ5NiA1Ni4wNzUyIDE3NS4wNTkgNDkgMTYxLjQwN0M2Ny4zODI2IDE3MS45OCA5My4wOTIzIDE3OSAxMjIuMjkzIDE3OUMxNTIuOTk5IDE3OSAxNzkuODQ1IDE3MS4yMzggMTk4LjM3IDE1OS43NDVDMjExLjk2MiAxNTEuMzEzIDIxOS42OTkgMTQxLjkxNCAyMjIuOTUyIDEzM0gxNzlWMTEzSDIyNC41NjNDMjE5Ljc3IDYwLjg0NDYgMTc1LjkwNiAyMCAxMjIuNSAyMFpNMTIyLjUgODZDMTQyLjY1OCA4NiAxNTkgMTAyLjM0MiAxNTkgMTIyLjVDMTU5IDE0Mi42NTggMTQyLjY1OCAxNTkgMTIyLjUgMTU5QzEwMi4zNDIgMTU5IDg2IDE0Mi42NTggODYgMTIyLjVDODYgMTAyLjM0MiAxMDIuMzQyIDg2IDEyMi41IDg2Wk0xMjIuNSAxMDZDMTEzLjM4NyAxMDYgMTA2IDExMy4zODcgMTA2IDEyMi41QzEwNiAxMzEuNjEzIDExMy4zODcgMTM5IDEyMi41IDEzOUMxMzEuNjEzIDEzOSAxMzkgMTMxLjYxMyAxMzkgMTIyLjVDMTM5IDExMy4zODcgMTMxLjYxMyAxMDYgMTIyLjUgMTA2WiIgZmlsbD0iI0ZGRkZGRiIvPjwvc3ZnPgo=";
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ const icon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAyNDUgMjQ1IiBmaWxsPSJub25lIj48Y2lyY2xlIGN4PSIxMjIuNSIgY3k9IjEyMi41IiByPSIxMjIuNSIgZmlsbD0iIzAwMDAwMCIvPjxwYXRoIGQ9Ik0xMjIuNSAwQzE5MC4xNTUgMCAyNDUgNTQuODQ1MSAyNDUgMTIyLjVDMjQ1IDE5MC4xNTUgMTkwLjE1NSAyNDUgMTIyLjUgMjQ1QzU1LjAxMTkgMjQ1IDAuMjcyMzYgMTkwLjQyNSAwLjAwMjkyOTY5IDEyM0gwQzAgMTIyLjkzNiAwLjAwMDcyMDUyIDEyMi44NzIgMC4wMDA5NzY1NjIgMTIyLjgwOEMwLjAwMDcyNDU4OCAxMjIuNzA1IDAgMTIyLjYwMyAwIDEyMi41QzAgNTQuODQ1MSA1NC44NDUxIDAgMTIyLjUgMFpNMTIyLjUgMjBDODQuOTY4MiAyMCA1Mi4xNDc2IDQwLjE3MTkgMzQuMjg5MSA3MC4yNjU2QzU2LjU3MTEgNTUuOTIyOCA4Ny44NTU5IDQ3IDEyMi41IDQ3QzEzNy4zNjQgNDcgMTUwLjY3IDQ5LjQ5NjEgMTY0IDU1QzE3Ny4zMyA2MC41MDM5IDE4OC43MTggNzAuOTQxIDE5NS43OTMgODQuNTkyOEMxNzcuNDEgNzQuMDIwMiAxNTEuNzAxIDY3IDEyMi41IDY3QzkxLjc5NDEgNjcgNjQuOTQ3OSA3NC43NjE4IDQ2LjQyMjkgODYuMjU0OUMzMi44MzEzIDk0LjY4NzIgMjUuMDkzNSAxMDQuMDg2IDIxLjg0MDggMTEzSDY2VjEzM0gyMC41MzEyQzI1Ljc4OTUgMTg0LjY3NyA2OS40MzU3IDIyNSAxMjIuNSAyMjVDMTU5LjQ0IDIyNSAxOTEuODE0IDIwNS40NTkgMjA5Ljg1MyAxNzYuMTVDMTg3LjYxNCAxOTAuMjQ5IDE1Ni42MDEgMTk5IDEyMi4yOTMgMTk5QzEwNy40MjkgMTk5IDk0LjEyMzQgMTk2LjUwNCA4MC43OTMgMTkxQzY3LjQ2MjUgMTg1LjQ5NiA1Ni4wNzUyIDE3NS4wNTkgNDkgMTYxLjQwN0M2Ny4zODI2IDE3MS45OCA5My4wOTIzIDE3OSAxMjIuMjkzIDE3OUMxNTIuOTk5IDE3OSAxNzkuODQ1IDE3MS4yMzggMTk4LjM3IDE1OS43NDVDMjExLjk2MiAxNTEuMzEzIDIxOS42OTkgMTQxLjkxNCAyMjIuOTUyIDEzM0gxNzlWMTEzSDIyNC41NjNDMjE5Ljc3IDYwLjg0NDYgMTc1LjkwNiAyMCAxMjIuNSAyMFpNMTIyLjUgODZDMTQyLjY1OCA4NiAxNTkgMTAyLjM0MiAxNTkgMTIyLjVDMTU5IDE0Mi42NTggMTQyLjY1OCAxNTkgMTIyLjUgMTU5QzEwMi4zNDIgMTU5IDg2IDE0Mi42NTggODYgMTIyLjVDODYgMTAyLjM0MiAxMDIuMzQyIDg2IDEyMi41IDg2Wk0xMjIuNSAxMDZDMTEzLjM4NyAxMDYgMTA2IDExMy4zODcgMTA2IDEyMi41QzEwNiAxMzEuNjEzIDExMy4zODcgMTM5IDEyMi41IDEzOUMxMzEuNjEzIDEzOSAxMzkgMTMxLjYxMyAxMzkgMTIyLjVDMTM5IDExMy4zODcgMTMxLjYxMyAxMDYgMTIyLjUgMTA2WiIgZmlsbD0iI0ZGRkZGRiIvPjwvc3ZnPgo=";
3
+ export {
4
+ icon
5
+ };
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@getpara/solana-wallet-connectors",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.1.0",
4
4
  "dependencies": {
5
- "@getpara/react-common": "3.0.0-alpha.1",
6
- "@getpara/web-sdk": "3.0.0-alpha.1",
5
+ "@getpara/react-common": "3.1.0",
6
+ "@getpara/web-sdk": "3.1.0",
7
7
  "bs58": "^6.0.0"
8
8
  },
9
9
  "devDependencies": {
@@ -23,7 +23,7 @@
23
23
  "dist",
24
24
  "package.json"
25
25
  ],
26
- "gitHead": "839d225579de67feb5be4da225d232290b2a2a04",
26
+ "gitHead": "e73f17cd7960fdfe62ff68a972b3461e47b21eb0",
27
27
  "main": "dist/index.js",
28
28
  "peerDependencies": {
29
29
  "@farcaster/mini-app-solana": "^1.0.5",