@naculus/connect-native 0.4.0 → 0.6.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.
- package/README.md +25 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -12,7 +12,6 @@ import "@walletconnect/react-native-compat";
|
|
|
12
12
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
13
13
|
import * as SecureStore from "expo-secure-store";
|
|
14
14
|
import { Linking, Platform } from "react-native";
|
|
15
|
-
import { transact } from "@solana-mobile/mobile-wallet-adapter-protocol-kit";
|
|
16
15
|
import { EIP1193Provider, Wallets } from "@mobile-wallet-protocol/client";
|
|
17
16
|
import { Web3ConnectProvider } from "@naculus/connect-appkit-react";
|
|
18
17
|
import {
|
|
@@ -32,13 +31,18 @@ const config = {
|
|
|
32
31
|
sessionStorage: asyncStorageSessionStorage(AsyncStorage),
|
|
33
32
|
walletConnect: nativeWalletConnect(Linking),
|
|
34
33
|
enableSolana: true,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
// Mobile Wallet Adapter is Android-only: importing it on iOS throws at
|
|
35
|
+
// startup, so require it only on Android.
|
|
36
|
+
solanaWallets:
|
|
37
|
+
Platform.OS === "android"
|
|
38
|
+
? [
|
|
39
|
+
createMobileWalletAdapterWallet({
|
|
40
|
+
transact: require("@solana-mobile/mobile-wallet-adapter-protocol-kit").transact,
|
|
41
|
+
identity: { name: "My App", uri: "https://myapp.example" },
|
|
42
|
+
chain: "solana:mainnet",
|
|
43
|
+
}),
|
|
44
|
+
]
|
|
45
|
+
: [],
|
|
42
46
|
injectedProviders: [
|
|
43
47
|
coinbaseMobileWallet(
|
|
44
48
|
new EIP1193Provider({ metadata: { name: "My App" }, wallet: Wallets.CoinbaseSmartWallet }),
|
|
@@ -65,12 +69,25 @@ install only what you use.
|
|
|
65
69
|
| `coinbaseMobileWallet(provider)` | `@mobile-wallet-protocol/client` | Coinbase Wallet over Mobile Wallet Protocol, connected with `connectInjected("coinbase-mwp")` |
|
|
66
70
|
| `keystoreWalletStorage` | `expo-secure-store` | Embedded wallet record sealed by wallet-engine (AES-256-GCM) under a Keychain / Keystore key (this device, when unlocked) |
|
|
67
71
|
|
|
72
|
+
**Mobile Wallet Adapter is Android-only.** Its native module does not exist
|
|
73
|
+
on iOS, and `@solana-mobile/mobile-wallet-adapter-protocol-kit` throws as
|
|
74
|
+
soon as it is imported there (`TurboModuleRegistry.getEnforcing(...):
|
|
75
|
+
'SolanaMobileWalletAdapter' could not be found`), before any UI renders.
|
|
76
|
+
Never import it at the top of a file that also runs on iOS: `require` it
|
|
77
|
+
behind `Platform.OS === "android"` as above, or keep it in a `.android.ts`
|
|
78
|
+
file.
|
|
79
|
+
|
|
68
80
|
**Keep `config` stable** (module scope or `useMemo`): `Web3ConnectProvider`
|
|
69
81
|
rebuilds its client when these objects change identity.
|
|
70
82
|
|
|
71
83
|
**Randomness:** `crypto.getRandomValues` must exist —
|
|
72
84
|
`@walletconnect/react-native-compat` installs `react-native-get-random-values`;
|
|
73
85
|
import it first. The embedded wallet's key generation fails closed without it.
|
|
86
|
+
Coinbase MWP (`@mobile-wallet-protocol/client`) also calls
|
|
87
|
+
`crypto.randomUUID`, which Hermes does not provide; without it connecting the
|
|
88
|
+
Smart Wallet fails with "undefined is not a function". Install a v4 UUID
|
|
89
|
+
polyfill built on `crypto.getRandomValues` before the app loads (the Expo
|
|
90
|
+
example's `crypto-random-uuid.ts` is one).
|
|
74
91
|
|
|
75
92
|
**Clusters:** the MWA wallet's `chain` must match `solanaDefaultChain`; a
|
|
76
93
|
mismatch fails on send rather than paying on another cluster.
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/codec.ts","../src/coinbase.ts","../src/keystore.ts","../src/mwa.ts","../src/platform.ts","../src/storage.ts","../src/walletconnect.ts"],"sourcesContent":["export { base58Encode } from \"./codec\";\nexport { coinbaseMobileWallet } from \"./coinbase\";\nexport {\n type KeystoreWalletStorageOptions,\n keystoreWalletStorage,\n} from \"./keystore\";\nexport {\n createMobileWalletAdapterWallet,\n kitTransactionFromWire,\n type MobileWalletAdapterOptions,\n type MwaAppIdentity,\n type MwaTransact,\n type MwaWalletLike,\n wireFromKitTransaction,\n} from \"./mwa\";\nexport { setupNaculusNative } from \"./platform\";\nexport { asyncStorageAdapter, asyncStorageSessionStorage } from \"./storage\";\nexport type { AsyncStorageLike, LinkingLike, SecureStoreLike } from \"./types\";\nexport {\n installedWallets,\n nativeWalletConnect,\n type WalletLinkTarget,\n} from \"./walletconnect\";\n","const B58 = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\n/** base58 (Bitcoin alphabet), as Solana addresses and signatures use. */\nexport function base58Encode(bytes: Uint8Array): string {\n let zeros = 0;\n while (zeros < bytes.length && bytes[zeros] === 0) zeros++;\n let value = 0n;\n for (const byte of bytes) value = value * 256n + BigInt(byte);\n let out = \"\";\n while (value > 0n) {\n out = B58[Number(value % 58n)] + out;\n value /= 58n;\n }\n return \"1\".repeat(zeros) + out;\n}\n\nexport function base64Encode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\nexport function base64Decode(value: string): Uint8Array {\n return Uint8Array.from(atob(value), (c) => c.charCodeAt(0));\n}\n","import type { InjectedProviderRegistration } from \"@naculus/connect-appkit-react\";\n\n/**\n * Coinbase Wallet on React Native through Mobile Wallet Protocol. The app\n * builds the provider — `new EIP1193Provider({ metadata, wallet:\n * Wallets.CoinbaseSmartWallet })` from `@mobile-wallet-protocol/client` —\n * and this registers it as an injected wallet (pass in\n * `config.injectedProviders`); connect with `connectInjected(\"coinbase-mwp\")`.\n */\nexport function coinbaseMobileWallet(\n provider: unknown,\n info: Partial<InjectedProviderRegistration[\"info\"]> = {},\n): InjectedProviderRegistration {\n return {\n info: {\n uuid: info.uuid ?? \"coinbase-mwp\",\n name: info.name ?? \"Coinbase Wallet\",\n icon: info.icon ?? \"data:image/svg+xml;base64,\",\n rdns: info.rdns ?? \"com.coinbase.wallet\",\n },\n provider,\n };\n}\n","import {\n KeyStoreStorageAdapter,\n type StorageAdapter,\n} from \"@naculus/wallet-engine\";\nimport type { AsyncStorageLike, SecureStoreLike } from \"./types\";\n\n/**\n * The embedded wallet's storage on a phone: wallet-engine's\n * `KeyStoreStorageAdapter` with its key in iOS Keychain / Android Keystore\n * (`expo-secure-store`, this device only, when unlocked) and the sealed record\n * in AsyncStorage. Sealing happens inside wallet-engine; this only moves two\n * opaque strings. Pass as `embeddedConfig.storage`.\n *\n * Isolation is weaker than the web's worker: React Native has no Web Worker,\n * so signing runs on the JS thread. The Keystore makes the sealed record\n * useless off the device and keeps the key out of AsyncStorage. Needs\n * `crypto.getRandomValues` (`react-native-get-random-values`, which\n * `@walletconnect/react-native-compat` installs).\n */\nexport interface KeystoreWalletStorageOptions {\n secureStore: SecureStoreLike;\n asyncStorage: AsyncStorageLike;\n /** Names both the Keystore entry and the AsyncStorage record. */\n name?: string;\n}\n\nexport function keystoreWalletStorage(\n options: KeystoreWalletStorageOptions,\n): StorageAdapter {\n const { secureStore, asyncStorage } = options;\n const name = options.name ?? \"naculus_wallet\";\n const keyName = `${name}.key`;\n const recordName = `${name}.sealed`;\n const access =\n secureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY !== undefined\n ? { keychainAccessible: secureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY }\n : undefined;\n return new KeyStoreStorageAdapter({\n slot: name,\n keyStore: {\n load: () => secureStore.getItemAsync(keyName, access),\n save: (value) => secureStore.setItemAsync(keyName, value, access),\n delete: () => secureStore.deleteItemAsync(keyName),\n },\n blobStore: {\n read: () => asyncStorage.getItem(recordName),\n write: (value) => asyncStorage.setItem(recordName, value),\n remove: () => asyncStorage.removeItem(recordName),\n },\n });\n}\n","import { parseSolanaTransaction, WalletError } from \"@naculus/connect-core\";\nimport { base58Encode, base64Decode } from \"./codec\";\n\n/**\n * Solana Mobile Wallet Adapter as a Wallet Standard wallet, for\n * connector-solana's `registerWallet` (pass it in `config.solanaWallets`).\n *\n * Each operation opens one MWA session with `transact` (from\n * `@solana-mobile/mobile-wallet-adapter-protocol-kit`, passed in by the app),\n * re-authorizes with the stored auth token and asks the wallet app. Wire\n * transactions become the Kit `{ messageBytes, signatures }` objects that\n * package expects and back; the signer order is taken from the message.\n */\n\n/** MWA's app identity, shown by the wallet. */\nexport interface MwaAppIdentity {\n name?: string;\n uri?: string;\n icon?: string;\n}\n\ntype KitTransaction = {\n messageBytes: Uint8Array;\n signatures: Record<string, Uint8Array | null>;\n};\n\n/** The members of the Kit `KitMobileWallet` used here. */\nexport interface MwaWalletLike {\n authorize(params: {\n identity: MwaAppIdentity;\n chain?: string;\n auth_token?: string;\n }): Promise<{\n accounts: readonly { address: string; label?: string }[];\n auth_token: string;\n }>;\n deauthorize(params: { auth_token: string }): Promise<unknown>;\n signMessages(params: {\n addresses: string[];\n payloads: Uint8Array[];\n }): Promise<Uint8Array[]>;\n signTransactions(params: {\n transactions: KitTransaction[];\n }): Promise<KitTransaction[]>;\n signAndSendTransactions(params: {\n transactions: KitTransaction[];\n }): Promise<Uint8Array[]>;\n}\n\nexport type MwaTransact = <T>(\n callback: (wallet: MwaWalletLike) => Promise<T>,\n) => Promise<T>;\n\nexport interface MobileWalletAdapterOptions {\n transact: MwaTransact;\n identity: MwaAppIdentity;\n /** MWA 2.0 chain id: `solana:mainnet`, `solana:devnet` or `solana:testnet`. */\n chain: \"solana:mainnet\" | \"solana:devnet\" | \"solana:testnet\";\n name?: string;\n icon?: string;\n}\n\nconst SIGNATURE_LENGTH = 64;\n\n/** Wire transaction → Kit transaction (signatures keyed by signer address). */\nexport function kitTransactionFromWire(wire: Uint8Array): KitTransaction {\n const tx = parseSolanaTransaction(wire);\n const signatures: Record<string, Uint8Array | null> = {};\n for (let i = 0; i < tx.numRequiredSignatures; i++) {\n const signature = tx.signatures[i] as Uint8Array;\n signatures[tx.accountKeys[i] as string] = signature.some((b) => b !== 0)\n ? signature\n : null;\n }\n return { messageBytes: tx.message, signatures };\n}\n\n/** Kit transaction → wire, in the message's signer order. */\nexport function wireFromKitTransaction(tx: KitTransaction): Uint8Array {\n const count = Object.keys(tx.signatures).length;\n if (count === 0 || count > 127) {\n throw new WalletError(\"invalid_input\", \"Unexpected signature count.\");\n }\n const unsigned = new Uint8Array(1 + 64 * count + tx.messageBytes.length);\n unsigned[0] = count;\n unsigned.set(tx.messageBytes, 1 + 64 * count);\n const parsed = parseSolanaTransaction(unsigned);\n const out = unsigned.slice();\n parsed.accountKeys.slice(0, parsed.numRequiredSignatures).forEach((k, i) => {\n const signature = tx.signatures[k];\n if (!signature) return;\n if (signature.length !== 64) {\n throw new WalletError(\n \"signature_rejected\",\n \"The wallet returned a malformed signature.\",\n );\n }\n out.set(signature, 1 + 64 * i);\n });\n return out;\n}\n\nexport function createMobileWalletAdapterWallet(\n options: MobileWalletAdapterOptions,\n) {\n const { transact, identity, chain } = options;\n let authToken: string | undefined;\n let account: {\n address: string;\n base64: string;\n publicKey: Uint8Array;\n } | null = null;\n const listeners = new Set<(change: unknown) => void>();\n\n const authorize = async (wallet: MwaWalletLike) => {\n const result = await wallet.authorize({\n identity,\n chain,\n ...(authToken ? { auth_token: authToken } : {}),\n });\n authToken = result.auth_token;\n const first = result.accounts[0];\n if (!first) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"The wallet returned no account.\",\n );\n }\n const publicKey = base64Decode(first.address);\n if (publicKey.length !== 32) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"The wallet returned a malformed account.\",\n );\n }\n const previous = account?.address;\n account = {\n address: base58Encode(publicKey),\n base64: first.address,\n publicKey,\n };\n // The user may pick another account when the wallet re-authorizes: tell\n // the connector, so the session never shows one account while another\n // signs (as the official wallet-standard-mobile adapter does).\n if (previous !== undefined && previous !== account.address) {\n for (const listener of listeners) {\n listener({ accounts: [standardAccount()] });\n }\n }\n return account;\n };\n\n const standardAccount = () => {\n if (!account) {\n throw new WalletError(\"session_expired\", \"Connect the wallet first.\");\n }\n return {\n address: account.address,\n publicKey: account.publicKey,\n chains: [chain],\n features: [\n \"solana:signMessage\",\n \"solana:signTransaction\",\n \"solana:signAndSendTransaction\",\n ],\n };\n };\n\n return {\n version: \"1.0.0\" as const,\n name: options.name ?? \"Mobile Wallet Adapter\",\n icon: options.icon ?? \"data:image/svg+xml;base64,\",\n chains: [chain],\n get accounts() {\n return account ? [standardAccount()] : [];\n },\n features: {\n \"standard:connect\": {\n version: \"1.0.0\",\n connect: async () => {\n await transact((wallet) => authorize(wallet));\n for (const listener of listeners)\n listener({ accounts: [standardAccount()] });\n return { accounts: [standardAccount()] };\n },\n },\n \"standard:disconnect\": {\n version: \"1.0.0\",\n disconnect: async () => {\n const token = authToken;\n authToken = undefined;\n account = null;\n for (const listener of listeners) listener({ accounts: [] });\n if (token) {\n await transact((wallet) =>\n wallet.deauthorize({ auth_token: token }),\n ).catch(() => {});\n }\n },\n },\n \"standard:events\": {\n version: \"1.0.0\",\n on: (_event: string, listener: (change: unknown) => void) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n },\n \"solana:signMessage\": {\n version: \"1.0.0\",\n signMessage: async (message: Uint8Array) =>\n transact(async (wallet) => {\n const { base64 } = await authorize(wallet);\n const [signed] = await wallet.signMessages({\n addresses: [base64],\n payloads: [message],\n });\n if (!signed || signed.length < SIGNATURE_LENGTH) {\n throw new WalletError(\n \"signature_rejected\",\n \"No signature returned.\",\n );\n }\n // MWA returns the message with the signature appended.\n return { signature: signed.slice(-SIGNATURE_LENGTH) };\n }),\n },\n \"solana:signTransaction\": {\n version: \"1.0.0\",\n signTransaction: async (transaction: Uint8Array) =>\n transact(async (wallet) => {\n await authorize(wallet);\n const [signed] = await wallet.signTransactions({\n transactions: [kitTransactionFromWire(transaction)],\n });\n if (!signed) {\n throw new WalletError(\n \"signature_rejected\",\n \"No transaction returned.\",\n );\n }\n return { signedTransaction: wireFromKitTransaction(signed) };\n }),\n },\n \"solana:signAndSendTransaction\": {\n version: \"1.0.0\",\n signAndSendTransaction: async (transaction: Uint8Array) =>\n transact(async (wallet) => {\n await authorize(wallet);\n const [signature] = await wallet.signAndSendTransactions({\n transactions: [kitTransactionFromWire(transaction)],\n });\n if (!signature) {\n throw new WalletError(\"tx_failed\", \"No signature returned.\");\n }\n return { signature: base58Encode(signature) };\n }),\n },\n },\n };\n}\n","import { setPlatformOverride } from \"@naculus/connect-core\";\n\n/**\n * Tell connect-core it runs in a native app (`Platform.OS` from\n * react-native). React Native cannot be told apart from a browser by\n * `navigator`; without this, connectors record sessions as `desktop-web` and\n * the connector manager does not prefer mobile-capable connectors.\n */\nexport function setupNaculusNative(os: string): void {\n if (os === \"ios\") setPlatformOverride(\"native-ios\");\n else if (os === \"android\") setPlatformOverride(\"native-android\");\n else setPlatformOverride(null);\n}\n","import type {\n SessionStorage,\n StorageAdapter,\n UniversalWalletSession,\n} from \"@naculus/connect-core\";\nimport type { AsyncStorageLike } from \"./types\";\n\n/** connect-core `StorageAdapter` over AsyncStorage, under a key prefix. */\nexport function asyncStorageAdapter(\n storage: AsyncStorageLike,\n prefix = \"naculus:\",\n): StorageAdapter {\n const k = (key: string) => `${prefix}${key}`;\n return {\n async get<T>(key: string): Promise<T | null> {\n const raw = await storage.getItem(k(key));\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return null;\n }\n },\n async set<T>(key: string, value: T): Promise<void> {\n await storage.setItem(k(key), JSON.stringify(value));\n },\n async remove(key: string): Promise<void> {\n await storage.removeItem(k(key));\n },\n async clear(): Promise<void> {\n const keys = (await storage.getAllKeys()).filter((key) =>\n key.startsWith(prefix),\n );\n if (keys.length > 0) await storage.multiRemove(keys);\n },\n async has(key: string): Promise<boolean> {\n return (await storage.getItem(k(key))) !== null;\n },\n isAvailable(): boolean {\n return true;\n },\n };\n}\n\n/**\n * Where `Web3ConnectProvider` persists the connected session on React\n * Native (pass as `config.sessionStorage`); the web default is localStorage.\n */\nexport function asyncStorageSessionStorage(\n storage: AsyncStorageLike,\n key = \"naculus_web3_session\",\n): SessionStorage {\n return {\n async load(): Promise<UniversalWalletSession | null> {\n const raw = await storage.getItem(key);\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as UniversalWalletSession;\n } catch {\n // An unreadable record is no session, not a crash at startup.\n await storage.removeItem(key);\n return null;\n }\n },\n async save(session: UniversalWalletSession): Promise<void> {\n await storage.setItem(key, JSON.stringify(session));\n },\n async clear(): Promise<void> {\n await storage.removeItem(key);\n },\n };\n}\n","import type { NativeWalletConnectOptions } from \"@naculus/connect-appkit-react\";\nimport type { LinkingLike } from \"./types\";\n\n/**\n * WalletConnect on React Native: deep links open through `Linking`. The\n * SignClient builds itself; with `@walletconnect/react-native-compat`\n * imported first in the app's entry file, its storage is AsyncStorage.\n */\nexport function nativeWalletConnect(\n linking: LinkingLike,\n): NativeWalletConnectOptions {\n return {\n openUrl: async (url) => {\n await linking.openURL(url);\n },\n };\n}\n\nexport interface WalletLinkTarget {\n id: string;\n name: string;\n /** Deep-link base the WalletConnect URI is appended to, e.g. `metamask://wc`. */\n deepLink: string;\n}\n\n/**\n * The wallets whose apps are installed. iOS answers only for schemes listed\n * under `LSApplicationQueriesSchemes` in Info.plist, Android only for those in\n * the manifest's `<queries>`; anything else reads as not installed.\n */\nexport async function installedWallets(\n linking: LinkingLike,\n wallets: readonly WalletLinkTarget[],\n): Promise<WalletLinkTarget[]> {\n const checks = await Promise.all(\n wallets.map(async (wallet) => {\n try {\n return await linking.canOpenURL(wallet.deepLink);\n } catch {\n return false;\n }\n }),\n );\n return wallets.filter((_, i) => checks[i]);\n}\n"],"mappings":"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","names":["import_connect_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/codec.ts","../src/coinbase.ts","../src/keystore.ts","../src/mwa.ts","../src/platform.ts","../src/storage.ts","../src/walletconnect.ts"],"sourcesContent":["export { base58Encode } from \"./codec\";\nexport { coinbaseMobileWallet } from \"./coinbase\";\nexport {\n type KeystoreWalletStorageOptions,\n keystoreWalletStorage,\n} from \"./keystore\";\nexport {\n createMobileWalletAdapterWallet,\n kitTransactionFromWire,\n type MobileWalletAdapterOptions,\n type MwaAppIdentity,\n type MwaTransact,\n type MwaWalletLike,\n wireFromKitTransaction,\n} from \"./mwa\";\nexport { setupNaculusNative } from \"./platform\";\nexport { asyncStorageAdapter, asyncStorageSessionStorage } from \"./storage\";\nexport type { AsyncStorageLike, LinkingLike, SecureStoreLike } from \"./types\";\nexport {\n installedWallets,\n nativeWalletConnect,\n type WalletLinkTarget,\n} from \"./walletconnect\";\n","const B58 = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\n/** base58 (Bitcoin alphabet), as Solana addresses and signatures use. */\nexport function base58Encode(bytes: Uint8Array): string {\n let zeros = 0;\n while (zeros < bytes.length && bytes[zeros] === 0) zeros++;\n let value = 0n;\n for (const byte of bytes) value = value * 256n + BigInt(byte);\n let out = \"\";\n while (value > 0n) {\n out = B58[Number(value % 58n)] + out;\n value /= 58n;\n }\n return \"1\".repeat(zeros) + out;\n}\n\nexport function base64Decode(value: string): Uint8Array {\n return Uint8Array.from(atob(value), (c) => c.charCodeAt(0));\n}\n","import type { InjectedProviderRegistration } from \"@naculus/connect-appkit-react\";\n\n/**\n * Coinbase Wallet on React Native through Mobile Wallet Protocol. The app\n * builds the provider — `new EIP1193Provider({ metadata, wallet:\n * Wallets.CoinbaseSmartWallet })` from `@mobile-wallet-protocol/client` —\n * and this registers it as an injected wallet (pass in\n * `config.injectedProviders`); connect with `connectInjected(\"coinbase-mwp\")`.\n */\nexport function coinbaseMobileWallet(\n provider: unknown,\n info: Partial<InjectedProviderRegistration[\"info\"]> = {},\n): InjectedProviderRegistration {\n return {\n info: {\n uuid: info.uuid ?? \"coinbase-mwp\",\n name: info.name ?? \"Coinbase Wallet\",\n icon: info.icon ?? \"data:image/svg+xml;base64,\",\n rdns: info.rdns ?? \"com.coinbase.wallet\",\n },\n provider,\n };\n}\n","import {\n KeyStoreStorageAdapter,\n type StorageAdapter,\n} from \"@naculus/wallet-engine\";\nimport type { AsyncStorageLike, SecureStoreLike } from \"./types\";\n\n/**\n * The embedded wallet's storage on a phone: wallet-engine's\n * `KeyStoreStorageAdapter` with its key in iOS Keychain / Android Keystore\n * (`expo-secure-store`, this device only, when unlocked) and the sealed record\n * in AsyncStorage. Sealing happens inside wallet-engine; this only moves two\n * opaque strings. Pass as `embeddedConfig.storage`.\n *\n * Isolation is weaker than the web's worker: React Native has no Web Worker,\n * so signing runs on the JS thread. The Keystore makes the sealed record\n * useless off the device and keeps the key out of AsyncStorage. Needs\n * `crypto.getRandomValues` (`react-native-get-random-values`, which\n * `@walletconnect/react-native-compat` installs).\n */\nexport interface KeystoreWalletStorageOptions {\n secureStore: SecureStoreLike;\n asyncStorage: AsyncStorageLike;\n /** Names both the Keystore entry and the AsyncStorage record. */\n name?: string;\n}\n\nexport function keystoreWalletStorage(\n options: KeystoreWalletStorageOptions,\n): StorageAdapter {\n const { secureStore, asyncStorage } = options;\n const name = options.name ?? \"naculus_wallet\";\n const keyName = `${name}.key`;\n const recordName = `${name}.sealed`;\n const access =\n secureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY !== undefined\n ? { keychainAccessible: secureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY }\n : undefined;\n return new KeyStoreStorageAdapter({\n slot: name,\n keyStore: {\n load: () => secureStore.getItemAsync(keyName, access),\n save: (value) => secureStore.setItemAsync(keyName, value, access),\n delete: () => secureStore.deleteItemAsync(keyName),\n },\n blobStore: {\n read: () => asyncStorage.getItem(recordName),\n write: (value) => asyncStorage.setItem(recordName, value),\n remove: () => asyncStorage.removeItem(recordName),\n },\n });\n}\n","import { parseSolanaTransaction, WalletError } from \"@naculus/connect-core\";\nimport { base58Encode, base64Decode } from \"./codec\";\n\n/**\n * Solana Mobile Wallet Adapter as a Wallet Standard wallet, for\n * connector-solana's `registerWallet` (pass it in `config.solanaWallets`).\n *\n * Each operation opens one MWA session with `transact` (from\n * `@solana-mobile/mobile-wallet-adapter-protocol-kit`, passed in by the app),\n * re-authorizes with the stored auth token and asks the wallet app. Wire\n * transactions become the Kit `{ messageBytes, signatures }` objects that\n * package expects and back; the signer order is taken from the message.\n */\n\n/** MWA's app identity, shown by the wallet. */\nexport interface MwaAppIdentity {\n name?: string;\n uri?: string;\n icon?: string;\n}\n\ntype KitTransaction = {\n messageBytes: Uint8Array;\n signatures: Record<string, Uint8Array | null>;\n};\n\n/** The members of the Kit `KitMobileWallet` used here. */\nexport interface MwaWalletLike {\n authorize(params: {\n identity: MwaAppIdentity;\n chain?: string;\n auth_token?: string;\n }): Promise<{\n accounts: readonly { address: string; label?: string }[];\n auth_token: string;\n }>;\n deauthorize(params: { auth_token: string }): Promise<unknown>;\n signMessages(params: {\n addresses: string[];\n payloads: Uint8Array[];\n }): Promise<Uint8Array[]>;\n signTransactions(params: {\n transactions: KitTransaction[];\n }): Promise<KitTransaction[]>;\n signAndSendTransactions(params: {\n transactions: KitTransaction[];\n }): Promise<Uint8Array[]>;\n}\n\nexport type MwaTransact = <T>(\n callback: (wallet: MwaWalletLike) => Promise<T>,\n) => Promise<T>;\n\nexport interface MobileWalletAdapterOptions {\n transact: MwaTransact;\n identity: MwaAppIdentity;\n /** MWA 2.0 chain id: `solana:mainnet`, `solana:devnet` or `solana:testnet`. */\n chain: \"solana:mainnet\" | \"solana:devnet\" | \"solana:testnet\";\n name?: string;\n icon?: string;\n}\n\nconst SIGNATURE_LENGTH = 64;\n\n/** Wire transaction → Kit transaction (signatures keyed by signer address). */\nexport function kitTransactionFromWire(wire: Uint8Array): KitTransaction {\n const tx = parseSolanaTransaction(wire);\n const signatures: Record<string, Uint8Array | null> = {};\n for (let i = 0; i < tx.numRequiredSignatures; i++) {\n const signature = tx.signatures[i] as Uint8Array;\n signatures[tx.accountKeys[i] as string] = signature.some((b) => b !== 0)\n ? signature\n : null;\n }\n return { messageBytes: tx.message, signatures };\n}\n\n/** Kit transaction → wire, in the message's signer order. */\nexport function wireFromKitTransaction(tx: KitTransaction): Uint8Array {\n const count = Object.keys(tx.signatures).length;\n if (count === 0 || count > 127) {\n throw new WalletError(\"invalid_input\", \"Unexpected signature count.\");\n }\n const unsigned = new Uint8Array(1 + 64 * count + tx.messageBytes.length);\n unsigned[0] = count;\n unsigned.set(tx.messageBytes, 1 + 64 * count);\n const parsed = parseSolanaTransaction(unsigned);\n const out = unsigned.slice();\n parsed.accountKeys.slice(0, parsed.numRequiredSignatures).forEach((k, i) => {\n const signature = tx.signatures[k];\n if (!signature) return;\n if (signature.length !== 64) {\n throw new WalletError(\n \"signature_rejected\",\n \"The wallet returned a malformed signature.\",\n );\n }\n out.set(signature, 1 + 64 * i);\n });\n return out;\n}\n\nexport function createMobileWalletAdapterWallet(\n options: MobileWalletAdapterOptions,\n) {\n const { transact, identity, chain } = options;\n let authToken: string | undefined;\n let account: {\n address: string;\n base64: string;\n publicKey: Uint8Array;\n } | null = null;\n const listeners = new Set<(change: unknown) => void>();\n\n const authorize = async (wallet: MwaWalletLike) => {\n const result = await wallet.authorize({\n identity,\n chain,\n ...(authToken ? { auth_token: authToken } : {}),\n });\n authToken = result.auth_token;\n const first = result.accounts[0];\n if (!first) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"The wallet returned no account.\",\n );\n }\n const publicKey = base64Decode(first.address);\n if (publicKey.length !== 32) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"The wallet returned a malformed account.\",\n );\n }\n const previous = account?.address;\n account = {\n address: base58Encode(publicKey),\n base64: first.address,\n publicKey,\n };\n // The user may pick another account when the wallet re-authorizes: tell\n // the connector, so the session never shows one account while another\n // signs (as the official wallet-standard-mobile adapter does).\n if (previous !== undefined && previous !== account.address) {\n for (const listener of listeners) {\n listener({ accounts: [standardAccount()] });\n }\n }\n return account;\n };\n\n const standardAccount = () => {\n if (!account) {\n throw new WalletError(\"session_expired\", \"Connect the wallet first.\");\n }\n return {\n address: account.address,\n publicKey: account.publicKey,\n chains: [chain],\n features: [\n \"solana:signMessage\",\n \"solana:signTransaction\",\n \"solana:signAndSendTransaction\",\n ],\n };\n };\n\n return {\n version: \"1.0.0\" as const,\n name: options.name ?? \"Mobile Wallet Adapter\",\n icon: options.icon ?? \"data:image/svg+xml;base64,\",\n chains: [chain],\n get accounts() {\n return account ? [standardAccount()] : [];\n },\n features: {\n \"standard:connect\": {\n version: \"1.0.0\",\n connect: async () => {\n await transact((wallet) => authorize(wallet));\n for (const listener of listeners)\n listener({ accounts: [standardAccount()] });\n return { accounts: [standardAccount()] };\n },\n },\n \"standard:disconnect\": {\n version: \"1.0.0\",\n disconnect: async () => {\n const token = authToken;\n authToken = undefined;\n account = null;\n for (const listener of listeners) listener({ accounts: [] });\n if (token) {\n await transact((wallet) =>\n wallet.deauthorize({ auth_token: token }),\n ).catch(() => {});\n }\n },\n },\n \"standard:events\": {\n version: \"1.0.0\",\n on: (_event: string, listener: (change: unknown) => void) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n },\n \"solana:signMessage\": {\n version: \"1.0.0\",\n signMessage: async (message: Uint8Array) =>\n transact(async (wallet) => {\n const { base64 } = await authorize(wallet);\n const [signed] = await wallet.signMessages({\n addresses: [base64],\n payloads: [message],\n });\n if (!signed || signed.length < SIGNATURE_LENGTH) {\n throw new WalletError(\n \"signature_rejected\",\n \"No signature returned.\",\n );\n }\n // MWA returns the message with the signature appended.\n return { signature: signed.slice(-SIGNATURE_LENGTH) };\n }),\n },\n \"solana:signTransaction\": {\n version: \"1.0.0\",\n signTransaction: async (transaction: Uint8Array) =>\n transact(async (wallet) => {\n await authorize(wallet);\n const [signed] = await wallet.signTransactions({\n transactions: [kitTransactionFromWire(transaction)],\n });\n if (!signed) {\n throw new WalletError(\n \"signature_rejected\",\n \"No transaction returned.\",\n );\n }\n return { signedTransaction: wireFromKitTransaction(signed) };\n }),\n },\n \"solana:signAndSendTransaction\": {\n version: \"1.0.0\",\n signAndSendTransaction: async (transaction: Uint8Array) =>\n transact(async (wallet) => {\n await authorize(wallet);\n const [signature] = await wallet.signAndSendTransactions({\n transactions: [kitTransactionFromWire(transaction)],\n });\n if (!signature) {\n throw new WalletError(\"tx_failed\", \"No signature returned.\");\n }\n return { signature: base58Encode(signature) };\n }),\n },\n },\n };\n}\n","import { setPlatformOverride } from \"@naculus/connect-core\";\n\n/**\n * Tell connect-core it runs in a native app (`Platform.OS` from\n * react-native). React Native cannot be told apart from a browser by\n * `navigator`; without this, connectors record sessions as `desktop-web` and\n * the connector manager does not prefer mobile-capable connectors.\n */\nexport function setupNaculusNative(os: string): void {\n if (os === \"ios\") setPlatformOverride(\"native-ios\");\n else if (os === \"android\") setPlatformOverride(\"native-android\");\n else setPlatformOverride(null);\n}\n","import type {\n SessionStorage,\n StorageAdapter,\n UniversalWalletSession,\n} from \"@naculus/connect-core\";\nimport type { AsyncStorageLike } from \"./types\";\n\n/** connect-core `StorageAdapter` over AsyncStorage, under a key prefix. */\nexport function asyncStorageAdapter(\n storage: AsyncStorageLike,\n prefix = \"naculus:\",\n): StorageAdapter {\n const k = (key: string) => `${prefix}${key}`;\n return {\n async get<T>(key: string): Promise<T | null> {\n const raw = await storage.getItem(k(key));\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return null;\n }\n },\n async set<T>(key: string, value: T): Promise<void> {\n await storage.setItem(k(key), JSON.stringify(value));\n },\n async remove(key: string): Promise<void> {\n await storage.removeItem(k(key));\n },\n async clear(): Promise<void> {\n const keys = (await storage.getAllKeys()).filter((key) =>\n key.startsWith(prefix),\n );\n if (keys.length > 0) await storage.multiRemove(keys);\n },\n async has(key: string): Promise<boolean> {\n return (await storage.getItem(k(key))) !== null;\n },\n isAvailable(): boolean {\n return true;\n },\n };\n}\n\n/**\n * Where `Web3ConnectProvider` persists the connected session on React\n * Native (pass as `config.sessionStorage`); the web default is localStorage.\n */\nexport function asyncStorageSessionStorage(\n storage: AsyncStorageLike,\n key = \"naculus_web3_session\",\n): SessionStorage {\n return {\n async load(): Promise<UniversalWalletSession | null> {\n const raw = await storage.getItem(key);\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as UniversalWalletSession;\n } catch {\n // An unreadable record is no session, not a crash at startup.\n await storage.removeItem(key);\n return null;\n }\n },\n async save(session: UniversalWalletSession): Promise<void> {\n await storage.setItem(key, JSON.stringify(session));\n },\n async clear(): Promise<void> {\n await storage.removeItem(key);\n },\n };\n}\n","import type { NativeWalletConnectOptions } from \"@naculus/connect-appkit-react\";\nimport type { LinkingLike } from \"./types\";\n\n/**\n * WalletConnect on React Native: deep links open through `Linking`. The\n * SignClient builds itself; with `@walletconnect/react-native-compat`\n * imported first in the app's entry file, its storage is AsyncStorage.\n */\nexport function nativeWalletConnect(\n linking: LinkingLike,\n): NativeWalletConnectOptions {\n return {\n openUrl: async (url) => {\n await linking.openURL(url);\n },\n };\n}\n\nexport interface WalletLinkTarget {\n id: string;\n name: string;\n /** Deep-link base the WalletConnect URI is appended to, e.g. `metamask://wc`. */\n deepLink: string;\n}\n\n/**\n * The wallets whose apps are installed. iOS answers only for schemes listed\n * under `LSApplicationQueriesSchemes` in Info.plist, Android only for those in\n * the manifest's `<queries>`; anything else reads as not installed.\n */\nexport async function installedWallets(\n linking: LinkingLike,\n wallets: readonly WalletLinkTarget[],\n): Promise<WalletLinkTarget[]> {\n const checks = await Promise.all(\n wallets.map(async (wallet) => {\n try {\n return await linking.canOpenURL(wallet.deepLink);\n } catch {\n return false;\n }\n }),\n );\n return wallets.filter((_, i) => checks[i]);\n}\n"],"mappings":"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","names":["import_connect_core"]}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/codec.ts","../src/coinbase.ts","../src/keystore.ts","../src/mwa.ts","../src/platform.ts","../src/storage.ts","../src/walletconnect.ts"],"sourcesContent":["const B58 = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\n/** base58 (Bitcoin alphabet), as Solana addresses and signatures use. */\nexport function base58Encode(bytes: Uint8Array): string {\n let zeros = 0;\n while (zeros < bytes.length && bytes[zeros] === 0) zeros++;\n let value = 0n;\n for (const byte of bytes) value = value * 256n + BigInt(byte);\n let out = \"\";\n while (value > 0n) {\n out = B58[Number(value % 58n)] + out;\n value /= 58n;\n }\n return \"1\".repeat(zeros) + out;\n}\n\nexport function base64Encode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\nexport function base64Decode(value: string): Uint8Array {\n return Uint8Array.from(atob(value), (c) => c.charCodeAt(0));\n}\n","import type { InjectedProviderRegistration } from \"@naculus/connect-appkit-react\";\n\n/**\n * Coinbase Wallet on React Native through Mobile Wallet Protocol. The app\n * builds the provider — `new EIP1193Provider({ metadata, wallet:\n * Wallets.CoinbaseSmartWallet })` from `@mobile-wallet-protocol/client` —\n * and this registers it as an injected wallet (pass in\n * `config.injectedProviders`); connect with `connectInjected(\"coinbase-mwp\")`.\n */\nexport function coinbaseMobileWallet(\n provider: unknown,\n info: Partial<InjectedProviderRegistration[\"info\"]> = {},\n): InjectedProviderRegistration {\n return {\n info: {\n uuid: info.uuid ?? \"coinbase-mwp\",\n name: info.name ?? \"Coinbase Wallet\",\n icon: info.icon ?? \"data:image/svg+xml;base64,\",\n rdns: info.rdns ?? \"com.coinbase.wallet\",\n },\n provider,\n };\n}\n","import {\n KeyStoreStorageAdapter,\n type StorageAdapter,\n} from \"@naculus/wallet-engine\";\nimport type { AsyncStorageLike, SecureStoreLike } from \"./types\";\n\n/**\n * The embedded wallet's storage on a phone: wallet-engine's\n * `KeyStoreStorageAdapter` with its key in iOS Keychain / Android Keystore\n * (`expo-secure-store`, this device only, when unlocked) and the sealed record\n * in AsyncStorage. Sealing happens inside wallet-engine; this only moves two\n * opaque strings. Pass as `embeddedConfig.storage`.\n *\n * Isolation is weaker than the web's worker: React Native has no Web Worker,\n * so signing runs on the JS thread. The Keystore makes the sealed record\n * useless off the device and keeps the key out of AsyncStorage. Needs\n * `crypto.getRandomValues` (`react-native-get-random-values`, which\n * `@walletconnect/react-native-compat` installs).\n */\nexport interface KeystoreWalletStorageOptions {\n secureStore: SecureStoreLike;\n asyncStorage: AsyncStorageLike;\n /** Names both the Keystore entry and the AsyncStorage record. */\n name?: string;\n}\n\nexport function keystoreWalletStorage(\n options: KeystoreWalletStorageOptions,\n): StorageAdapter {\n const { secureStore, asyncStorage } = options;\n const name = options.name ?? \"naculus_wallet\";\n const keyName = `${name}.key`;\n const recordName = `${name}.sealed`;\n const access =\n secureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY !== undefined\n ? { keychainAccessible: secureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY }\n : undefined;\n return new KeyStoreStorageAdapter({\n slot: name,\n keyStore: {\n load: () => secureStore.getItemAsync(keyName, access),\n save: (value) => secureStore.setItemAsync(keyName, value, access),\n delete: () => secureStore.deleteItemAsync(keyName),\n },\n blobStore: {\n read: () => asyncStorage.getItem(recordName),\n write: (value) => asyncStorage.setItem(recordName, value),\n remove: () => asyncStorage.removeItem(recordName),\n },\n });\n}\n","import { parseSolanaTransaction, WalletError } from \"@naculus/connect-core\";\nimport { base58Encode, base64Decode } from \"./codec\";\n\n/**\n * Solana Mobile Wallet Adapter as a Wallet Standard wallet, for\n * connector-solana's `registerWallet` (pass it in `config.solanaWallets`).\n *\n * Each operation opens one MWA session with `transact` (from\n * `@solana-mobile/mobile-wallet-adapter-protocol-kit`, passed in by the app),\n * re-authorizes with the stored auth token and asks the wallet app. Wire\n * transactions become the Kit `{ messageBytes, signatures }` objects that\n * package expects and back; the signer order is taken from the message.\n */\n\n/** MWA's app identity, shown by the wallet. */\nexport interface MwaAppIdentity {\n name?: string;\n uri?: string;\n icon?: string;\n}\n\ntype KitTransaction = {\n messageBytes: Uint8Array;\n signatures: Record<string, Uint8Array | null>;\n};\n\n/** The members of the Kit `KitMobileWallet` used here. */\nexport interface MwaWalletLike {\n authorize(params: {\n identity: MwaAppIdentity;\n chain?: string;\n auth_token?: string;\n }): Promise<{\n accounts: readonly { address: string; label?: string }[];\n auth_token: string;\n }>;\n deauthorize(params: { auth_token: string }): Promise<unknown>;\n signMessages(params: {\n addresses: string[];\n payloads: Uint8Array[];\n }): Promise<Uint8Array[]>;\n signTransactions(params: {\n transactions: KitTransaction[];\n }): Promise<KitTransaction[]>;\n signAndSendTransactions(params: {\n transactions: KitTransaction[];\n }): Promise<Uint8Array[]>;\n}\n\nexport type MwaTransact = <T>(\n callback: (wallet: MwaWalletLike) => Promise<T>,\n) => Promise<T>;\n\nexport interface MobileWalletAdapterOptions {\n transact: MwaTransact;\n identity: MwaAppIdentity;\n /** MWA 2.0 chain id: `solana:mainnet`, `solana:devnet` or `solana:testnet`. */\n chain: \"solana:mainnet\" | \"solana:devnet\" | \"solana:testnet\";\n name?: string;\n icon?: string;\n}\n\nconst SIGNATURE_LENGTH = 64;\n\n/** Wire transaction → Kit transaction (signatures keyed by signer address). */\nexport function kitTransactionFromWire(wire: Uint8Array): KitTransaction {\n const tx = parseSolanaTransaction(wire);\n const signatures: Record<string, Uint8Array | null> = {};\n for (let i = 0; i < tx.numRequiredSignatures; i++) {\n const signature = tx.signatures[i] as Uint8Array;\n signatures[tx.accountKeys[i] as string] = signature.some((b) => b !== 0)\n ? signature\n : null;\n }\n return { messageBytes: tx.message, signatures };\n}\n\n/** Kit transaction → wire, in the message's signer order. */\nexport function wireFromKitTransaction(tx: KitTransaction): Uint8Array {\n const count = Object.keys(tx.signatures).length;\n if (count === 0 || count > 127) {\n throw new WalletError(\"invalid_input\", \"Unexpected signature count.\");\n }\n const unsigned = new Uint8Array(1 + 64 * count + tx.messageBytes.length);\n unsigned[0] = count;\n unsigned.set(tx.messageBytes, 1 + 64 * count);\n const parsed = parseSolanaTransaction(unsigned);\n const out = unsigned.slice();\n parsed.accountKeys.slice(0, parsed.numRequiredSignatures).forEach((k, i) => {\n const signature = tx.signatures[k];\n if (!signature) return;\n if (signature.length !== 64) {\n throw new WalletError(\n \"signature_rejected\",\n \"The wallet returned a malformed signature.\",\n );\n }\n out.set(signature, 1 + 64 * i);\n });\n return out;\n}\n\nexport function createMobileWalletAdapterWallet(\n options: MobileWalletAdapterOptions,\n) {\n const { transact, identity, chain } = options;\n let authToken: string | undefined;\n let account: {\n address: string;\n base64: string;\n publicKey: Uint8Array;\n } | null = null;\n const listeners = new Set<(change: unknown) => void>();\n\n const authorize = async (wallet: MwaWalletLike) => {\n const result = await wallet.authorize({\n identity,\n chain,\n ...(authToken ? { auth_token: authToken } : {}),\n });\n authToken = result.auth_token;\n const first = result.accounts[0];\n if (!first) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"The wallet returned no account.\",\n );\n }\n const publicKey = base64Decode(first.address);\n if (publicKey.length !== 32) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"The wallet returned a malformed account.\",\n );\n }\n const previous = account?.address;\n account = {\n address: base58Encode(publicKey),\n base64: first.address,\n publicKey,\n };\n // The user may pick another account when the wallet re-authorizes: tell\n // the connector, so the session never shows one account while another\n // signs (as the official wallet-standard-mobile adapter does).\n if (previous !== undefined && previous !== account.address) {\n for (const listener of listeners) {\n listener({ accounts: [standardAccount()] });\n }\n }\n return account;\n };\n\n const standardAccount = () => {\n if (!account) {\n throw new WalletError(\"session_expired\", \"Connect the wallet first.\");\n }\n return {\n address: account.address,\n publicKey: account.publicKey,\n chains: [chain],\n features: [\n \"solana:signMessage\",\n \"solana:signTransaction\",\n \"solana:signAndSendTransaction\",\n ],\n };\n };\n\n return {\n version: \"1.0.0\" as const,\n name: options.name ?? \"Mobile Wallet Adapter\",\n icon: options.icon ?? \"data:image/svg+xml;base64,\",\n chains: [chain],\n get accounts() {\n return account ? [standardAccount()] : [];\n },\n features: {\n \"standard:connect\": {\n version: \"1.0.0\",\n connect: async () => {\n await transact((wallet) => authorize(wallet));\n for (const listener of listeners)\n listener({ accounts: [standardAccount()] });\n return { accounts: [standardAccount()] };\n },\n },\n \"standard:disconnect\": {\n version: \"1.0.0\",\n disconnect: async () => {\n const token = authToken;\n authToken = undefined;\n account = null;\n for (const listener of listeners) listener({ accounts: [] });\n if (token) {\n await transact((wallet) =>\n wallet.deauthorize({ auth_token: token }),\n ).catch(() => {});\n }\n },\n },\n \"standard:events\": {\n version: \"1.0.0\",\n on: (_event: string, listener: (change: unknown) => void) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n },\n \"solana:signMessage\": {\n version: \"1.0.0\",\n signMessage: async (message: Uint8Array) =>\n transact(async (wallet) => {\n const { base64 } = await authorize(wallet);\n const [signed] = await wallet.signMessages({\n addresses: [base64],\n payloads: [message],\n });\n if (!signed || signed.length < SIGNATURE_LENGTH) {\n throw new WalletError(\n \"signature_rejected\",\n \"No signature returned.\",\n );\n }\n // MWA returns the message with the signature appended.\n return { signature: signed.slice(-SIGNATURE_LENGTH) };\n }),\n },\n \"solana:signTransaction\": {\n version: \"1.0.0\",\n signTransaction: async (transaction: Uint8Array) =>\n transact(async (wallet) => {\n await authorize(wallet);\n const [signed] = await wallet.signTransactions({\n transactions: [kitTransactionFromWire(transaction)],\n });\n if (!signed) {\n throw new WalletError(\n \"signature_rejected\",\n \"No transaction returned.\",\n );\n }\n return { signedTransaction: wireFromKitTransaction(signed) };\n }),\n },\n \"solana:signAndSendTransaction\": {\n version: \"1.0.0\",\n signAndSendTransaction: async (transaction: Uint8Array) =>\n transact(async (wallet) => {\n await authorize(wallet);\n const [signature] = await wallet.signAndSendTransactions({\n transactions: [kitTransactionFromWire(transaction)],\n });\n if (!signature) {\n throw new WalletError(\"tx_failed\", \"No signature returned.\");\n }\n return { signature: base58Encode(signature) };\n }),\n },\n },\n };\n}\n","import { setPlatformOverride } from \"@naculus/connect-core\";\n\n/**\n * Tell connect-core it runs in a native app (`Platform.OS` from\n * react-native). React Native cannot be told apart from a browser by\n * `navigator`; without this, connectors record sessions as `desktop-web` and\n * the connector manager does not prefer mobile-capable connectors.\n */\nexport function setupNaculusNative(os: string): void {\n if (os === \"ios\") setPlatformOverride(\"native-ios\");\n else if (os === \"android\") setPlatformOverride(\"native-android\");\n else setPlatformOverride(null);\n}\n","import type {\n SessionStorage,\n StorageAdapter,\n UniversalWalletSession,\n} from \"@naculus/connect-core\";\nimport type { AsyncStorageLike } from \"./types\";\n\n/** connect-core `StorageAdapter` over AsyncStorage, under a key prefix. */\nexport function asyncStorageAdapter(\n storage: AsyncStorageLike,\n prefix = \"naculus:\",\n): StorageAdapter {\n const k = (key: string) => `${prefix}${key}`;\n return {\n async get<T>(key: string): Promise<T | null> {\n const raw = await storage.getItem(k(key));\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return null;\n }\n },\n async set<T>(key: string, value: T): Promise<void> {\n await storage.setItem(k(key), JSON.stringify(value));\n },\n async remove(key: string): Promise<void> {\n await storage.removeItem(k(key));\n },\n async clear(): Promise<void> {\n const keys = (await storage.getAllKeys()).filter((key) =>\n key.startsWith(prefix),\n );\n if (keys.length > 0) await storage.multiRemove(keys);\n },\n async has(key: string): Promise<boolean> {\n return (await storage.getItem(k(key))) !== null;\n },\n isAvailable(): boolean {\n return true;\n },\n };\n}\n\n/**\n * Where `Web3ConnectProvider` persists the connected session on React\n * Native (pass as `config.sessionStorage`); the web default is localStorage.\n */\nexport function asyncStorageSessionStorage(\n storage: AsyncStorageLike,\n key = \"naculus_web3_session\",\n): SessionStorage {\n return {\n async load(): Promise<UniversalWalletSession | null> {\n const raw = await storage.getItem(key);\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as UniversalWalletSession;\n } catch {\n // An unreadable record is no session, not a crash at startup.\n await storage.removeItem(key);\n return null;\n }\n },\n async save(session: UniversalWalletSession): Promise<void> {\n await storage.setItem(key, JSON.stringify(session));\n },\n async clear(): Promise<void> {\n await storage.removeItem(key);\n },\n };\n}\n","import type { NativeWalletConnectOptions } from \"@naculus/connect-appkit-react\";\nimport type { LinkingLike } from \"./types\";\n\n/**\n * WalletConnect on React Native: deep links open through `Linking`. The\n * SignClient builds itself; with `@walletconnect/react-native-compat`\n * imported first in the app's entry file, its storage is AsyncStorage.\n */\nexport function nativeWalletConnect(\n linking: LinkingLike,\n): NativeWalletConnectOptions {\n return {\n openUrl: async (url) => {\n await linking.openURL(url);\n },\n };\n}\n\nexport interface WalletLinkTarget {\n id: string;\n name: string;\n /** Deep-link base the WalletConnect URI is appended to, e.g. `metamask://wc`. */\n deepLink: string;\n}\n\n/**\n * The wallets whose apps are installed. iOS answers only for schemes listed\n * under `LSApplicationQueriesSchemes` in Info.plist, Android only for those in\n * the manifest's `<queries>`; anything else reads as not installed.\n */\nexport async function installedWallets(\n linking: LinkingLike,\n wallets: readonly WalletLinkTarget[],\n): Promise<WalletLinkTarget[]> {\n const checks = await Promise.all(\n wallets.map(async (wallet) => {\n try {\n return await linking.canOpenURL(wallet.deepLink);\n } catch {\n return false;\n }\n }),\n );\n return wallets.filter((_, i) => checks[i]);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/codec.ts","../src/coinbase.ts","../src/keystore.ts","../src/mwa.ts","../src/platform.ts","../src/storage.ts","../src/walletconnect.ts"],"sourcesContent":["const B58 = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\n/** base58 (Bitcoin alphabet), as Solana addresses and signatures use. */\nexport function base58Encode(bytes: Uint8Array): string {\n let zeros = 0;\n while (zeros < bytes.length && bytes[zeros] === 0) zeros++;\n let value = 0n;\n for (const byte of bytes) value = value * 256n + BigInt(byte);\n let out = \"\";\n while (value > 0n) {\n out = B58[Number(value % 58n)] + out;\n value /= 58n;\n }\n return \"1\".repeat(zeros) + out;\n}\n\nexport function base64Decode(value: string): Uint8Array {\n return Uint8Array.from(atob(value), (c) => c.charCodeAt(0));\n}\n","import type { InjectedProviderRegistration } from \"@naculus/connect-appkit-react\";\n\n/**\n * Coinbase Wallet on React Native through Mobile Wallet Protocol. The app\n * builds the provider — `new EIP1193Provider({ metadata, wallet:\n * Wallets.CoinbaseSmartWallet })` from `@mobile-wallet-protocol/client` —\n * and this registers it as an injected wallet (pass in\n * `config.injectedProviders`); connect with `connectInjected(\"coinbase-mwp\")`.\n */\nexport function coinbaseMobileWallet(\n provider: unknown,\n info: Partial<InjectedProviderRegistration[\"info\"]> = {},\n): InjectedProviderRegistration {\n return {\n info: {\n uuid: info.uuid ?? \"coinbase-mwp\",\n name: info.name ?? \"Coinbase Wallet\",\n icon: info.icon ?? \"data:image/svg+xml;base64,\",\n rdns: info.rdns ?? \"com.coinbase.wallet\",\n },\n provider,\n };\n}\n","import {\n KeyStoreStorageAdapter,\n type StorageAdapter,\n} from \"@naculus/wallet-engine\";\nimport type { AsyncStorageLike, SecureStoreLike } from \"./types\";\n\n/**\n * The embedded wallet's storage on a phone: wallet-engine's\n * `KeyStoreStorageAdapter` with its key in iOS Keychain / Android Keystore\n * (`expo-secure-store`, this device only, when unlocked) and the sealed record\n * in AsyncStorage. Sealing happens inside wallet-engine; this only moves two\n * opaque strings. Pass as `embeddedConfig.storage`.\n *\n * Isolation is weaker than the web's worker: React Native has no Web Worker,\n * so signing runs on the JS thread. The Keystore makes the sealed record\n * useless off the device and keeps the key out of AsyncStorage. Needs\n * `crypto.getRandomValues` (`react-native-get-random-values`, which\n * `@walletconnect/react-native-compat` installs).\n */\nexport interface KeystoreWalletStorageOptions {\n secureStore: SecureStoreLike;\n asyncStorage: AsyncStorageLike;\n /** Names both the Keystore entry and the AsyncStorage record. */\n name?: string;\n}\n\nexport function keystoreWalletStorage(\n options: KeystoreWalletStorageOptions,\n): StorageAdapter {\n const { secureStore, asyncStorage } = options;\n const name = options.name ?? \"naculus_wallet\";\n const keyName = `${name}.key`;\n const recordName = `${name}.sealed`;\n const access =\n secureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY !== undefined\n ? { keychainAccessible: secureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY }\n : undefined;\n return new KeyStoreStorageAdapter({\n slot: name,\n keyStore: {\n load: () => secureStore.getItemAsync(keyName, access),\n save: (value) => secureStore.setItemAsync(keyName, value, access),\n delete: () => secureStore.deleteItemAsync(keyName),\n },\n blobStore: {\n read: () => asyncStorage.getItem(recordName),\n write: (value) => asyncStorage.setItem(recordName, value),\n remove: () => asyncStorage.removeItem(recordName),\n },\n });\n}\n","import { parseSolanaTransaction, WalletError } from \"@naculus/connect-core\";\nimport { base58Encode, base64Decode } from \"./codec\";\n\n/**\n * Solana Mobile Wallet Adapter as a Wallet Standard wallet, for\n * connector-solana's `registerWallet` (pass it in `config.solanaWallets`).\n *\n * Each operation opens one MWA session with `transact` (from\n * `@solana-mobile/mobile-wallet-adapter-protocol-kit`, passed in by the app),\n * re-authorizes with the stored auth token and asks the wallet app. Wire\n * transactions become the Kit `{ messageBytes, signatures }` objects that\n * package expects and back; the signer order is taken from the message.\n */\n\n/** MWA's app identity, shown by the wallet. */\nexport interface MwaAppIdentity {\n name?: string;\n uri?: string;\n icon?: string;\n}\n\ntype KitTransaction = {\n messageBytes: Uint8Array;\n signatures: Record<string, Uint8Array | null>;\n};\n\n/** The members of the Kit `KitMobileWallet` used here. */\nexport interface MwaWalletLike {\n authorize(params: {\n identity: MwaAppIdentity;\n chain?: string;\n auth_token?: string;\n }): Promise<{\n accounts: readonly { address: string; label?: string }[];\n auth_token: string;\n }>;\n deauthorize(params: { auth_token: string }): Promise<unknown>;\n signMessages(params: {\n addresses: string[];\n payloads: Uint8Array[];\n }): Promise<Uint8Array[]>;\n signTransactions(params: {\n transactions: KitTransaction[];\n }): Promise<KitTransaction[]>;\n signAndSendTransactions(params: {\n transactions: KitTransaction[];\n }): Promise<Uint8Array[]>;\n}\n\nexport type MwaTransact = <T>(\n callback: (wallet: MwaWalletLike) => Promise<T>,\n) => Promise<T>;\n\nexport interface MobileWalletAdapterOptions {\n transact: MwaTransact;\n identity: MwaAppIdentity;\n /** MWA 2.0 chain id: `solana:mainnet`, `solana:devnet` or `solana:testnet`. */\n chain: \"solana:mainnet\" | \"solana:devnet\" | \"solana:testnet\";\n name?: string;\n icon?: string;\n}\n\nconst SIGNATURE_LENGTH = 64;\n\n/** Wire transaction → Kit transaction (signatures keyed by signer address). */\nexport function kitTransactionFromWire(wire: Uint8Array): KitTransaction {\n const tx = parseSolanaTransaction(wire);\n const signatures: Record<string, Uint8Array | null> = {};\n for (let i = 0; i < tx.numRequiredSignatures; i++) {\n const signature = tx.signatures[i] as Uint8Array;\n signatures[tx.accountKeys[i] as string] = signature.some((b) => b !== 0)\n ? signature\n : null;\n }\n return { messageBytes: tx.message, signatures };\n}\n\n/** Kit transaction → wire, in the message's signer order. */\nexport function wireFromKitTransaction(tx: KitTransaction): Uint8Array {\n const count = Object.keys(tx.signatures).length;\n if (count === 0 || count > 127) {\n throw new WalletError(\"invalid_input\", \"Unexpected signature count.\");\n }\n const unsigned = new Uint8Array(1 + 64 * count + tx.messageBytes.length);\n unsigned[0] = count;\n unsigned.set(tx.messageBytes, 1 + 64 * count);\n const parsed = parseSolanaTransaction(unsigned);\n const out = unsigned.slice();\n parsed.accountKeys.slice(0, parsed.numRequiredSignatures).forEach((k, i) => {\n const signature = tx.signatures[k];\n if (!signature) return;\n if (signature.length !== 64) {\n throw new WalletError(\n \"signature_rejected\",\n \"The wallet returned a malformed signature.\",\n );\n }\n out.set(signature, 1 + 64 * i);\n });\n return out;\n}\n\nexport function createMobileWalletAdapterWallet(\n options: MobileWalletAdapterOptions,\n) {\n const { transact, identity, chain } = options;\n let authToken: string | undefined;\n let account: {\n address: string;\n base64: string;\n publicKey: Uint8Array;\n } | null = null;\n const listeners = new Set<(change: unknown) => void>();\n\n const authorize = async (wallet: MwaWalletLike) => {\n const result = await wallet.authorize({\n identity,\n chain,\n ...(authToken ? { auth_token: authToken } : {}),\n });\n authToken = result.auth_token;\n const first = result.accounts[0];\n if (!first) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"The wallet returned no account.\",\n );\n }\n const publicKey = base64Decode(first.address);\n if (publicKey.length !== 32) {\n throw new WalletError(\n \"wallet_unavailable\",\n \"The wallet returned a malformed account.\",\n );\n }\n const previous = account?.address;\n account = {\n address: base58Encode(publicKey),\n base64: first.address,\n publicKey,\n };\n // The user may pick another account when the wallet re-authorizes: tell\n // the connector, so the session never shows one account while another\n // signs (as the official wallet-standard-mobile adapter does).\n if (previous !== undefined && previous !== account.address) {\n for (const listener of listeners) {\n listener({ accounts: [standardAccount()] });\n }\n }\n return account;\n };\n\n const standardAccount = () => {\n if (!account) {\n throw new WalletError(\"session_expired\", \"Connect the wallet first.\");\n }\n return {\n address: account.address,\n publicKey: account.publicKey,\n chains: [chain],\n features: [\n \"solana:signMessage\",\n \"solana:signTransaction\",\n \"solana:signAndSendTransaction\",\n ],\n };\n };\n\n return {\n version: \"1.0.0\" as const,\n name: options.name ?? \"Mobile Wallet Adapter\",\n icon: options.icon ?? \"data:image/svg+xml;base64,\",\n chains: [chain],\n get accounts() {\n return account ? [standardAccount()] : [];\n },\n features: {\n \"standard:connect\": {\n version: \"1.0.0\",\n connect: async () => {\n await transact((wallet) => authorize(wallet));\n for (const listener of listeners)\n listener({ accounts: [standardAccount()] });\n return { accounts: [standardAccount()] };\n },\n },\n \"standard:disconnect\": {\n version: \"1.0.0\",\n disconnect: async () => {\n const token = authToken;\n authToken = undefined;\n account = null;\n for (const listener of listeners) listener({ accounts: [] });\n if (token) {\n await transact((wallet) =>\n wallet.deauthorize({ auth_token: token }),\n ).catch(() => {});\n }\n },\n },\n \"standard:events\": {\n version: \"1.0.0\",\n on: (_event: string, listener: (change: unknown) => void) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n },\n \"solana:signMessage\": {\n version: \"1.0.0\",\n signMessage: async (message: Uint8Array) =>\n transact(async (wallet) => {\n const { base64 } = await authorize(wallet);\n const [signed] = await wallet.signMessages({\n addresses: [base64],\n payloads: [message],\n });\n if (!signed || signed.length < SIGNATURE_LENGTH) {\n throw new WalletError(\n \"signature_rejected\",\n \"No signature returned.\",\n );\n }\n // MWA returns the message with the signature appended.\n return { signature: signed.slice(-SIGNATURE_LENGTH) };\n }),\n },\n \"solana:signTransaction\": {\n version: \"1.0.0\",\n signTransaction: async (transaction: Uint8Array) =>\n transact(async (wallet) => {\n await authorize(wallet);\n const [signed] = await wallet.signTransactions({\n transactions: [kitTransactionFromWire(transaction)],\n });\n if (!signed) {\n throw new WalletError(\n \"signature_rejected\",\n \"No transaction returned.\",\n );\n }\n return { signedTransaction: wireFromKitTransaction(signed) };\n }),\n },\n \"solana:signAndSendTransaction\": {\n version: \"1.0.0\",\n signAndSendTransaction: async (transaction: Uint8Array) =>\n transact(async (wallet) => {\n await authorize(wallet);\n const [signature] = await wallet.signAndSendTransactions({\n transactions: [kitTransactionFromWire(transaction)],\n });\n if (!signature) {\n throw new WalletError(\"tx_failed\", \"No signature returned.\");\n }\n return { signature: base58Encode(signature) };\n }),\n },\n },\n };\n}\n","import { setPlatformOverride } from \"@naculus/connect-core\";\n\n/**\n * Tell connect-core it runs in a native app (`Platform.OS` from\n * react-native). React Native cannot be told apart from a browser by\n * `navigator`; without this, connectors record sessions as `desktop-web` and\n * the connector manager does not prefer mobile-capable connectors.\n */\nexport function setupNaculusNative(os: string): void {\n if (os === \"ios\") setPlatformOverride(\"native-ios\");\n else if (os === \"android\") setPlatformOverride(\"native-android\");\n else setPlatformOverride(null);\n}\n","import type {\n SessionStorage,\n StorageAdapter,\n UniversalWalletSession,\n} from \"@naculus/connect-core\";\nimport type { AsyncStorageLike } from \"./types\";\n\n/** connect-core `StorageAdapter` over AsyncStorage, under a key prefix. */\nexport function asyncStorageAdapter(\n storage: AsyncStorageLike,\n prefix = \"naculus:\",\n): StorageAdapter {\n const k = (key: string) => `${prefix}${key}`;\n return {\n async get<T>(key: string): Promise<T | null> {\n const raw = await storage.getItem(k(key));\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return null;\n }\n },\n async set<T>(key: string, value: T): Promise<void> {\n await storage.setItem(k(key), JSON.stringify(value));\n },\n async remove(key: string): Promise<void> {\n await storage.removeItem(k(key));\n },\n async clear(): Promise<void> {\n const keys = (await storage.getAllKeys()).filter((key) =>\n key.startsWith(prefix),\n );\n if (keys.length > 0) await storage.multiRemove(keys);\n },\n async has(key: string): Promise<boolean> {\n return (await storage.getItem(k(key))) !== null;\n },\n isAvailable(): boolean {\n return true;\n },\n };\n}\n\n/**\n * Where `Web3ConnectProvider` persists the connected session on React\n * Native (pass as `config.sessionStorage`); the web default is localStorage.\n */\nexport function asyncStorageSessionStorage(\n storage: AsyncStorageLike,\n key = \"naculus_web3_session\",\n): SessionStorage {\n return {\n async load(): Promise<UniversalWalletSession | null> {\n const raw = await storage.getItem(key);\n if (raw === null) return null;\n try {\n return JSON.parse(raw) as UniversalWalletSession;\n } catch {\n // An unreadable record is no session, not a crash at startup.\n await storage.removeItem(key);\n return null;\n }\n },\n async save(session: UniversalWalletSession): Promise<void> {\n await storage.setItem(key, JSON.stringify(session));\n },\n async clear(): Promise<void> {\n await storage.removeItem(key);\n },\n };\n}\n","import type { NativeWalletConnectOptions } from \"@naculus/connect-appkit-react\";\nimport type { LinkingLike } from \"./types\";\n\n/**\n * WalletConnect on React Native: deep links open through `Linking`. The\n * SignClient builds itself; with `@walletconnect/react-native-compat`\n * imported first in the app's entry file, its storage is AsyncStorage.\n */\nexport function nativeWalletConnect(\n linking: LinkingLike,\n): NativeWalletConnectOptions {\n return {\n openUrl: async (url) => {\n await linking.openURL(url);\n },\n };\n}\n\nexport interface WalletLinkTarget {\n id: string;\n name: string;\n /** Deep-link base the WalletConnect URI is appended to, e.g. `metamask://wc`. */\n deepLink: string;\n}\n\n/**\n * The wallets whose apps are installed. iOS answers only for schemes listed\n * under `LSApplicationQueriesSchemes` in Info.plist, Android only for those in\n * the manifest's `<queries>`; anything else reads as not installed.\n */\nexport async function installedWallets(\n linking: LinkingLike,\n wallets: readonly WalletLinkTarget[],\n): Promise<WalletLinkTarget[]> {\n const checks = await Promise.all(\n wallets.map(async (wallet) => {\n try {\n return await linking.canOpenURL(wallet.deepLink);\n } catch {\n return false;\n }\n }),\n );\n return wallets.filter((_, i) => checks[i]);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naculus/connect-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"peerDependencies": {
|
|
19
|
-
"@naculus/connect-core": "^0.
|
|
20
|
-
"@naculus/connect-appkit-react": "^0.
|
|
21
|
-
"@naculus/wallet-engine": "^0.
|
|
19
|
+
"@naculus/connect-core": "^0.6.0",
|
|
20
|
+
"@naculus/connect-appkit-react": "^0.6.0",
|
|
21
|
+
"@naculus/wallet-engine": "^0.6.0",
|
|
22
22
|
"react-native": "*",
|
|
23
23
|
"@react-native-async-storage/async-storage": "*",
|
|
24
24
|
"@walletconnect/react-native-compat": "*",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"expo-secure-store": "*"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@naculus/connect-core": "^0.
|
|
31
|
-
"@naculus/wallet-engine": "^0.
|
|
30
|
+
"@naculus/connect-core": "^0.6.0",
|
|
31
|
+
"@naculus/wallet-engine": "^0.6.0",
|
|
32
32
|
"tsup": "^8.5.1",
|
|
33
|
-
"typescript": "^
|
|
34
|
-
"@naculus/connect-appkit-react": "0.
|
|
33
|
+
"typescript": "^6.0.3",
|
|
34
|
+
"@naculus/connect-appkit-react": "0.6.0"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public",
|