@wallet-ui/react-native-web3js 2.2.0-canary-20251120223258
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/LICENSE +20 -0
- package/README.md +17 -0
- package/dist/index.browser.cjs +275 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.mjs +246 -0
- package/dist/index.browser.mjs.map +1 -0
- package/dist/index.native.mjs +246 -0
- package/dist/index.native.mjs.map +1 -0
- package/dist/index.node.cjs +275 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.mjs +246 -0
- package/dist/index.node.mjs.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/mobile-wallet-adapter-provider.d.ts +18 -0
- package/dist/types/mobile-wallet-adapter-provider.d.ts.map +1 -0
- package/dist/types/use-authorization.d.ts +53 -0
- package/dist/types/use-authorization.d.ts.map +1 -0
- package/dist/types/use-mobile-wallet-adapter.d.ts +19 -0
- package/dist/types/use-mobile-wallet-adapter.d.ts.map +1 -0
- package/dist/types/use-mobile-wallet.d.ts +16 -0
- package/dist/types/use-mobile-wallet.d.ts.map +1 -0
- package/package.json +95 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2024 Bram Borggreve (https://github.com/beeman)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[![npm][npm-image]][npm-url]
|
|
2
|
+
[![npm-downloads][npm-downloads-image]][npm-url]
|
|
3
|
+
<br />
|
|
4
|
+
[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]
|
|
5
|
+
|
|
6
|
+
[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square
|
|
7
|
+
[code-style-prettier-url]: https://github.com/prettier/prettier
|
|
8
|
+
[npm-downloads-image]: https://img.shields.io/npm/dm/@wallet-ui/react-native-web3js/latest.svg?style=flat
|
|
9
|
+
[npm-image]: https://img.shields.io/npm/v/@wallet-ui/react-native-web3js/latest.svg?style=flat
|
|
10
|
+
[npm-url]: https://www.npmjs.com/package/@wallet-ui/react-native-web3js/v/latest
|
|
11
|
+
|
|
12
|
+
# @wallet-ui/react-native-web3js
|
|
13
|
+
|
|
14
|
+
This package provides the official React Native components and hooks for [Wallet UI](https://wallet-ui.dev), a modern,
|
|
15
|
+
headless UI component library for Solana apps.
|
|
16
|
+
|
|
17
|
+
# TBD
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var web3_js = require('@solana/web3.js');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var AsyncStorage = require('@react-native-async-storage/async-storage');
|
|
6
|
+
var reactQuery = require('@tanstack/react-query');
|
|
7
|
+
var jsBase64 = require('js-base64');
|
|
8
|
+
var mobileWalletAdapterProtocolWeb3js = require('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
|
|
9
|
+
var core = require('@wallet-ui/core');
|
|
10
|
+
|
|
11
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
|
|
13
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
14
|
+
var AsyncStorage__default = /*#__PURE__*/_interopDefault(AsyncStorage);
|
|
15
|
+
|
|
16
|
+
// src/mobile-wallet-adapter-provider.tsx
|
|
17
|
+
var MobileWalletAdapterProviderContext = React.createContext(
|
|
18
|
+
{}
|
|
19
|
+
);
|
|
20
|
+
function MobileWalletAdapterProvider({
|
|
21
|
+
children,
|
|
22
|
+
clusterId,
|
|
23
|
+
endpoint,
|
|
24
|
+
identity
|
|
25
|
+
}) {
|
|
26
|
+
const connection = React.useMemo(() => new web3_js.Connection(endpoint, { commitment: "confirmed" }), [endpoint]);
|
|
27
|
+
const value = React.useMemo(() => ({ clusterId, connection, identity }), [connection, identity, clusterId]);
|
|
28
|
+
return /* @__PURE__ */ React__default.default.createElement(MobileWalletAdapterProviderContext.Provider, { value }, children);
|
|
29
|
+
}
|
|
30
|
+
function ellipsify(str = "", len = 4, delimiter = "..") {
|
|
31
|
+
const limit = len * 2 + delimiter.length;
|
|
32
|
+
return str.length > limit ? str.slice(0, len) + delimiter + str.slice(-len) : str;
|
|
33
|
+
}
|
|
34
|
+
function getPublicKeyFromAddress(address) {
|
|
35
|
+
const publicKeyByteArray = jsBase64.toUint8Array(address);
|
|
36
|
+
return new web3_js.PublicKey(publicKeyByteArray);
|
|
37
|
+
}
|
|
38
|
+
function getAccountFromAuthorizedAccount(account) {
|
|
39
|
+
const publicKey = getPublicKeyFromAddress(account.address);
|
|
40
|
+
return {
|
|
41
|
+
address: account.address,
|
|
42
|
+
// TODO: Fix upstream?
|
|
43
|
+
displayAddress: account.display_address,
|
|
44
|
+
icon: account.icon,
|
|
45
|
+
label: account.label ?? ellipsify(publicKey.toString(), 8),
|
|
46
|
+
publicKey
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function getAuthorizationFromAuthorizationResult(authorizationResult, previouslySelectedAccount) {
|
|
50
|
+
let selectedAccount;
|
|
51
|
+
if (
|
|
52
|
+
// We have yet to select an account.
|
|
53
|
+
previouslySelectedAccount == null || // The previously selected account is no longer in the set of authorized addresses.
|
|
54
|
+
!authorizationResult.accounts.some(({ address }) => address === previouslySelectedAccount.address)
|
|
55
|
+
) {
|
|
56
|
+
const firstAccount = authorizationResult.accounts[0];
|
|
57
|
+
selectedAccount = getAccountFromAuthorizedAccount(firstAccount);
|
|
58
|
+
} else {
|
|
59
|
+
selectedAccount = previouslySelectedAccount;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
accounts: authorizationResult.accounts.map(getAccountFromAuthorizedAccount),
|
|
63
|
+
authToken: authorizationResult.auth_token,
|
|
64
|
+
selectedAccount
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
var AUTHORIZATION_STORAGE_KEY = "authorization-cache";
|
|
68
|
+
var queryKey = ["wallet-authorization"];
|
|
69
|
+
function cacheReviver(key, value) {
|
|
70
|
+
if (key === "publicKey") {
|
|
71
|
+
return new web3_js.PublicKey(value);
|
|
72
|
+
} else {
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function usePersistAuthorization() {
|
|
77
|
+
const queryClient = reactQuery.useQueryClient();
|
|
78
|
+
return reactQuery.useMutation({
|
|
79
|
+
mutationFn: async (auth) => {
|
|
80
|
+
await AsyncStorage__default.default.setItem(AUTHORIZATION_STORAGE_KEY, JSON.stringify(auth));
|
|
81
|
+
},
|
|
82
|
+
onSuccess: async () => {
|
|
83
|
+
await queryClient.invalidateQueries({ queryKey });
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
function useFetchAuthorization() {
|
|
88
|
+
return reactQuery.useQuery({
|
|
89
|
+
queryFn: async () => {
|
|
90
|
+
const cacheFetchResult = await AsyncStorage__default.default.getItem(AUTHORIZATION_STORAGE_KEY);
|
|
91
|
+
return cacheFetchResult ? JSON.parse(cacheFetchResult, cacheReviver) : null;
|
|
92
|
+
},
|
|
93
|
+
queryKey
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function useInvalidateAuthorizations() {
|
|
97
|
+
const client = reactQuery.useQueryClient();
|
|
98
|
+
return () => client.invalidateQueries({ queryKey });
|
|
99
|
+
}
|
|
100
|
+
function useAuthorization({ clusterId, identity }) {
|
|
101
|
+
const fetchQuery = useFetchAuthorization();
|
|
102
|
+
const invalidateAuthorizations = useInvalidateAuthorizations();
|
|
103
|
+
const persistMutation = usePersistAuthorization();
|
|
104
|
+
const handleAuthorizationResult = React.useCallback(
|
|
105
|
+
async (authorizationResult) => {
|
|
106
|
+
const nextAuthorization = getAuthorizationFromAuthorizationResult(
|
|
107
|
+
authorizationResult,
|
|
108
|
+
fetchQuery.data?.selectedAccount
|
|
109
|
+
);
|
|
110
|
+
await persistMutation.mutateAsync(nextAuthorization);
|
|
111
|
+
return nextAuthorization;
|
|
112
|
+
},
|
|
113
|
+
[fetchQuery.data?.selectedAccount, persistMutation]
|
|
114
|
+
);
|
|
115
|
+
const authorizeSession = React.useCallback(
|
|
116
|
+
async (wallet) => {
|
|
117
|
+
const authorizationResult = await wallet.authorize({
|
|
118
|
+
auth_token: fetchQuery.data?.authToken,
|
|
119
|
+
chain: clusterId,
|
|
120
|
+
identity
|
|
121
|
+
});
|
|
122
|
+
return (await handleAuthorizationResult(authorizationResult)).selectedAccount;
|
|
123
|
+
},
|
|
124
|
+
[fetchQuery.data?.authToken, clusterId, identity, handleAuthorizationResult]
|
|
125
|
+
);
|
|
126
|
+
const authorizeSessionWithSignIn = React.useCallback(
|
|
127
|
+
async (wallet, signInPayload) => {
|
|
128
|
+
const authorizationResult = await wallet.authorize({
|
|
129
|
+
auth_token: fetchQuery.data?.authToken,
|
|
130
|
+
chain: clusterId,
|
|
131
|
+
identity,
|
|
132
|
+
sign_in_payload: signInPayload
|
|
133
|
+
});
|
|
134
|
+
return (await handleAuthorizationResult(authorizationResult)).selectedAccount;
|
|
135
|
+
},
|
|
136
|
+
[fetchQuery.data?.authToken, clusterId, identity, handleAuthorizationResult]
|
|
137
|
+
);
|
|
138
|
+
const deauthorizeSession = React.useCallback(
|
|
139
|
+
async (wallet) => {
|
|
140
|
+
if (fetchQuery.data?.authToken == null) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
await wallet.deauthorize({ auth_token: fetchQuery.data.authToken });
|
|
144
|
+
await persistMutation.mutateAsync(null);
|
|
145
|
+
},
|
|
146
|
+
[fetchQuery.data?.authToken, persistMutation]
|
|
147
|
+
);
|
|
148
|
+
const deauthorizeSessions = React.useCallback(async () => {
|
|
149
|
+
await invalidateAuthorizations();
|
|
150
|
+
await persistMutation.mutateAsync(null);
|
|
151
|
+
}, [invalidateAuthorizations, persistMutation]);
|
|
152
|
+
return React.useMemo(
|
|
153
|
+
() => ({
|
|
154
|
+
accounts: fetchQuery.data?.accounts ?? null,
|
|
155
|
+
authorizeSession,
|
|
156
|
+
authorizeSessionWithSignIn,
|
|
157
|
+
deauthorizeSession,
|
|
158
|
+
deauthorizeSessions,
|
|
159
|
+
isLoading: fetchQuery.isLoading,
|
|
160
|
+
selectedAccount: fetchQuery.data?.selectedAccount ?? null
|
|
161
|
+
}),
|
|
162
|
+
[
|
|
163
|
+
authorizeSession,
|
|
164
|
+
authorizeSessionWithSignIn,
|
|
165
|
+
deauthorizeSession,
|
|
166
|
+
deauthorizeSessions,
|
|
167
|
+
fetchQuery.data?.accounts,
|
|
168
|
+
fetchQuery.data?.selectedAccount,
|
|
169
|
+
fetchQuery.isLoading
|
|
170
|
+
]
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
function useMobileWallet({ clusterId, identity }) {
|
|
174
|
+
const { authorizeSessionWithSignIn, authorizeSession, deauthorizeSessions } = useAuthorization({
|
|
175
|
+
clusterId,
|
|
176
|
+
identity
|
|
177
|
+
});
|
|
178
|
+
const connect = React.useCallback(
|
|
179
|
+
async () => await mobileWalletAdapterProtocolWeb3js.transact(async (wallet) => await authorizeSession(wallet)),
|
|
180
|
+
[authorizeSession]
|
|
181
|
+
);
|
|
182
|
+
const connectAnd = React.useCallback(
|
|
183
|
+
async (cb) => {
|
|
184
|
+
return await mobileWalletAdapterProtocolWeb3js.transact(async (wallet) => await cb(wallet));
|
|
185
|
+
},
|
|
186
|
+
[]
|
|
187
|
+
);
|
|
188
|
+
const signIn = React.useCallback(
|
|
189
|
+
async (signInPayload) => await mobileWalletAdapterProtocolWeb3js.transact(async (wallet) => await authorizeSessionWithSignIn(wallet, signInPayload)),
|
|
190
|
+
[authorizeSessionWithSignIn]
|
|
191
|
+
);
|
|
192
|
+
const disconnect = React.useCallback(async () => {
|
|
193
|
+
await deauthorizeSessions();
|
|
194
|
+
}, [deauthorizeSessions]);
|
|
195
|
+
const signAndSendTransaction = React.useCallback(
|
|
196
|
+
async (transaction, minContextSlot) => {
|
|
197
|
+
return await mobileWalletAdapterProtocolWeb3js.transact(async (wallet) => {
|
|
198
|
+
await authorizeSession(wallet);
|
|
199
|
+
const signatures = await wallet.signAndSendTransactions({
|
|
200
|
+
minContextSlot,
|
|
201
|
+
transactions: [transaction]
|
|
202
|
+
});
|
|
203
|
+
return signatures[0];
|
|
204
|
+
});
|
|
205
|
+
},
|
|
206
|
+
[authorizeSession]
|
|
207
|
+
);
|
|
208
|
+
const signMessage = React.useCallback(
|
|
209
|
+
async (message) => {
|
|
210
|
+
return await mobileWalletAdapterProtocolWeb3js.transact(async (wallet) => {
|
|
211
|
+
const authResult = await authorizeSession(wallet);
|
|
212
|
+
const signedMessages = await wallet.signMessages({
|
|
213
|
+
addresses: [authResult.address],
|
|
214
|
+
payloads: [message]
|
|
215
|
+
});
|
|
216
|
+
return signedMessages[0];
|
|
217
|
+
});
|
|
218
|
+
},
|
|
219
|
+
[authorizeSession]
|
|
220
|
+
);
|
|
221
|
+
return React.useMemo(
|
|
222
|
+
() => ({
|
|
223
|
+
connect,
|
|
224
|
+
connectAnd,
|
|
225
|
+
disconnect,
|
|
226
|
+
signAndSendTransaction,
|
|
227
|
+
signIn,
|
|
228
|
+
signMessage
|
|
229
|
+
}),
|
|
230
|
+
[connect, connectAnd, disconnect, signAndSendTransaction, signIn, signMessage]
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
function useMobileWalletAdapter() {
|
|
234
|
+
const ctx = React.useContext(MobileWalletAdapterProviderContext);
|
|
235
|
+
const { connect, connectAnd, signAndSendTransaction, signMessage, signIn } = useMobileWallet(ctx);
|
|
236
|
+
const { selectedAccount, deauthorizeSessions } = useAuthorization(ctx);
|
|
237
|
+
return {
|
|
238
|
+
...ctx,
|
|
239
|
+
account: selectedAccount,
|
|
240
|
+
connect,
|
|
241
|
+
connectAnd,
|
|
242
|
+
disconnect: deauthorizeSessions,
|
|
243
|
+
signAndSendTransaction,
|
|
244
|
+
signIn,
|
|
245
|
+
signMessage
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
Object.defineProperty(exports, "fromUint8Array", {
|
|
250
|
+
enumerable: true,
|
|
251
|
+
get: function () { return jsBase64.fromUint8Array; }
|
|
252
|
+
});
|
|
253
|
+
Object.defineProperty(exports, "toUint8Array", {
|
|
254
|
+
enumerable: true,
|
|
255
|
+
get: function () { return jsBase64.toUint8Array; }
|
|
256
|
+
});
|
|
257
|
+
exports.MobileWalletAdapterProvider = MobileWalletAdapterProvider;
|
|
258
|
+
exports.MobileWalletAdapterProviderContext = MobileWalletAdapterProviderContext;
|
|
259
|
+
exports.useAuthorization = useAuthorization;
|
|
260
|
+
exports.useMobileWallet = useMobileWallet;
|
|
261
|
+
exports.useMobileWalletAdapter = useMobileWalletAdapter;
|
|
262
|
+
Object.keys(mobileWalletAdapterProtocolWeb3js).forEach(function (k) {
|
|
263
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
264
|
+
enumerable: true,
|
|
265
|
+
get: function () { return mobileWalletAdapterProtocolWeb3js[k]; }
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
Object.keys(core).forEach(function (k) {
|
|
269
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
270
|
+
enumerable: true,
|
|
271
|
+
get: function () { return core[k]; }
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
//# sourceMappingURL=index.browser.cjs.map
|
|
275
|
+
//# sourceMappingURL=index.browser.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mobile-wallet-adapter-provider.tsx","../src/use-authorization.ts","../src/use-mobile-wallet.ts","../src/use-mobile-wallet-adapter.ts"],"names":["createContext","useMemo","Connection","React","toUint8Array","PublicKey","useQueryClient","useMutation","AsyncStorage","useQuery","useCallback","transact","useContext"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["import { Connection } from '@solana/web3.js';\nimport { AppIdentity } from '@solana-mobile/mobile-wallet-adapter-protocol';\nimport { SolanaClusterId } from '@wallet-ui/core/src';\nimport React, { createContext, type ReactNode, useMemo } from 'react';\n\nexport interface MobileWalletAdapterProviderProps {\n children: ReactNode;\n clusterId: SolanaClusterId;\n endpoint: string;\n identity: AppIdentity;\n}\nexport interface MobileWalletAdapterProviderState {\n clusterId: SolanaClusterId;\n connection: Connection;\n identity: AppIdentity;\n}\n\nexport const MobileWalletAdapterProviderContext = createContext<MobileWalletAdapterProviderState>(\n {} as MobileWalletAdapterProviderState,\n);\nexport function MobileWalletAdapterProvider({\n children,\n clusterId,\n endpoint,\n identity,\n}: MobileWalletAdapterProviderProps) {\n const connection = useMemo(() => new Connection(endpoint, { commitment: 'confirmed' }), [endpoint]);\n const value = useMemo(() => ({ clusterId, connection, identity }), [connection, identity, clusterId]);\n\n return (\n <MobileWalletAdapterProviderContext.Provider value={value}>\n {children}\n </MobileWalletAdapterProviderContext.Provider>\n );\n}\n","import AsyncStorage from '@react-native-async-storage/async-storage';\nimport { PublicKey, PublicKeyInitData } from '@solana/web3.js';\nimport {\n Account as AuthorizedAccount,\n AppIdentity,\n AuthorizationResult,\n AuthorizeAPI,\n AuthToken,\n Base64EncodedAddress,\n DeauthorizeAPI,\n SignInPayload,\n} from '@solana-mobile/mobile-wallet-adapter-protocol';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { WalletIcon } from '@wallet-standard/core';\nimport { SolanaClusterId } from '@wallet-ui/core';\nimport { toUint8Array } from 'js-base64';\nimport { useCallback, useMemo } from 'react';\n\nfunction ellipsify(str = '', len = 4, delimiter = '..') {\n const limit = len * 2 + delimiter.length;\n\n return str.length > limit ? str.slice(0, len) + delimiter + str.slice(-len) : str;\n}\n\nexport type Account = Readonly<{\n address: Base64EncodedAddress;\n displayAddress?: string;\n icon?: WalletIcon;\n label?: string;\n publicKey: PublicKey;\n}>;\n\nexport type WalletAuthorization = Readonly<{\n accounts: Account[];\n authToken: AuthToken;\n selectedAccount: Account;\n}>;\n\nfunction getPublicKeyFromAddress(address: Base64EncodedAddress): PublicKey {\n const publicKeyByteArray = toUint8Array(address);\n return new PublicKey(publicKeyByteArray);\n}\n\nfunction getAccountFromAuthorizedAccount(account: AuthorizedAccount): Account {\n const publicKey = getPublicKeyFromAddress(account.address);\n return {\n address: account.address,\n // TODO: Fix upstream?\n displayAddress: (account as unknown as { display_address: string }).display_address,\n icon: account.icon,\n label: account.label ?? ellipsify(publicKey.toString(), 8),\n publicKey,\n };\n}\n\nfunction getAuthorizationFromAuthorizationResult(\n authorizationResult: AuthorizationResult,\n previouslySelectedAccount?: Account,\n): WalletAuthorization {\n let selectedAccount: Account;\n if (\n // We have yet to select an account.\n previouslySelectedAccount == null ||\n // The previously selected account is no longer in the set of authorized addresses.\n !authorizationResult.accounts.some(({ address }) => address === previouslySelectedAccount.address)\n ) {\n const firstAccount = authorizationResult.accounts[0];\n selectedAccount = getAccountFromAuthorizedAccount(firstAccount);\n } else {\n selectedAccount = previouslySelectedAccount;\n }\n return {\n accounts: authorizationResult.accounts.map(getAccountFromAuthorizedAccount),\n authToken: authorizationResult.auth_token,\n selectedAccount,\n };\n}\n\nconst AUTHORIZATION_STORAGE_KEY = 'authorization-cache';\n\nconst queryKey = ['wallet-authorization'];\n\nfunction cacheReviver(key: string, value: unknown) {\n if (key === 'publicKey') {\n return new PublicKey(value as PublicKeyInitData); // the PublicKeyInitData should match the actual data structure stored in AsyncStorage\n } else {\n return value;\n }\n}\nfunction usePersistAuthorization() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (auth: WalletAuthorization | null): Promise<void> => {\n await AsyncStorage.setItem(AUTHORIZATION_STORAGE_KEY, JSON.stringify(auth));\n },\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey });\n },\n });\n}\n\nfunction useFetchAuthorization() {\n return useQuery({\n queryFn: async (): Promise<WalletAuthorization | null> => {\n const cacheFetchResult = await AsyncStorage.getItem(AUTHORIZATION_STORAGE_KEY);\n\n // Return prior authorization, if found.\n return cacheFetchResult ? JSON.parse(cacheFetchResult, cacheReviver) : null;\n },\n queryKey,\n });\n}\n\nfunction useInvalidateAuthorizations() {\n const client = useQueryClient();\n return () => client.invalidateQueries({ queryKey });\n}\n\nexport function useAuthorization({ clusterId, identity }: { clusterId: SolanaClusterId; identity: AppIdentity }) {\n const fetchQuery = useFetchAuthorization();\n const invalidateAuthorizations = useInvalidateAuthorizations();\n const persistMutation = usePersistAuthorization();\n\n const handleAuthorizationResult = useCallback(\n async (authorizationResult: AuthorizationResult): Promise<WalletAuthorization> => {\n const nextAuthorization = getAuthorizationFromAuthorizationResult(\n authorizationResult,\n fetchQuery.data?.selectedAccount,\n );\n await persistMutation.mutateAsync(nextAuthorization);\n return nextAuthorization;\n },\n [fetchQuery.data?.selectedAccount, persistMutation],\n );\n\n const authorizeSession = useCallback(\n async (wallet: AuthorizeAPI) => {\n const authorizationResult = await wallet.authorize({\n auth_token: fetchQuery.data?.authToken,\n chain: clusterId,\n identity,\n });\n return (await handleAuthorizationResult(authorizationResult)).selectedAccount;\n },\n [fetchQuery.data?.authToken, clusterId, identity, handleAuthorizationResult],\n );\n\n const authorizeSessionWithSignIn = useCallback(\n async (wallet: AuthorizeAPI, signInPayload: SignInPayload) => {\n const authorizationResult = await wallet.authorize({\n auth_token: fetchQuery.data?.authToken,\n chain: clusterId,\n identity,\n sign_in_payload: signInPayload,\n });\n return (await handleAuthorizationResult(authorizationResult)).selectedAccount;\n },\n [fetchQuery.data?.authToken, clusterId, identity, handleAuthorizationResult],\n );\n\n const deauthorizeSession = useCallback(\n async (wallet: DeauthorizeAPI) => {\n if (fetchQuery.data?.authToken == null) {\n return;\n }\n await wallet.deauthorize({ auth_token: fetchQuery.data.authToken });\n await persistMutation.mutateAsync(null);\n },\n [fetchQuery.data?.authToken, persistMutation],\n );\n\n const deauthorizeSessions = useCallback(async () => {\n await invalidateAuthorizations();\n await persistMutation.mutateAsync(null);\n }, [invalidateAuthorizations, persistMutation]);\n\n return useMemo(\n () => ({\n accounts: fetchQuery.data?.accounts ?? null,\n authorizeSession,\n authorizeSessionWithSignIn,\n deauthorizeSession,\n deauthorizeSessions,\n isLoading: fetchQuery.isLoading,\n selectedAccount: fetchQuery.data?.selectedAccount ?? null,\n }),\n [\n authorizeSession,\n authorizeSessionWithSignIn,\n deauthorizeSession,\n deauthorizeSessions,\n fetchQuery.data?.accounts,\n fetchQuery.data?.selectedAccount,\n fetchQuery.isLoading,\n ],\n );\n}\n","import { Transaction, TransactionSignature, VersionedTransaction } from '@solana/web3.js';\nimport { AppIdentity, AuthorizeAPI, SignInPayload } from '@solana-mobile/mobile-wallet-adapter-protocol';\nimport { transact } from '@solana-mobile/mobile-wallet-adapter-protocol-web3js';\nimport { SolanaClusterId } from '@wallet-ui/core';\nimport { useCallback, useMemo } from 'react';\n\nimport { Account, useAuthorization } from './use-authorization';\n\nexport function useMobileWallet({ clusterId, identity }: { clusterId: SolanaClusterId; identity: AppIdentity }) {\n const { authorizeSessionWithSignIn, authorizeSession, deauthorizeSessions } = useAuthorization({\n clusterId,\n identity,\n });\n\n const connect = useCallback(\n async (): Promise<Account> => await transact(async wallet => await authorizeSession(wallet)),\n [authorizeSession],\n );\n\n const connectAnd = useCallback(\n async (cb: (wallet: AuthorizeAPI) => Promise<Account | void>): Promise<Account | void> => {\n return await transact(async wallet => await cb(wallet));\n },\n [],\n );\n\n const signIn = useCallback(\n async (signInPayload: SignInPayload): Promise<Account> =>\n await transact(async wallet => await authorizeSessionWithSignIn(wallet, signInPayload)),\n [authorizeSessionWithSignIn],\n );\n\n const disconnect = useCallback(async (): Promise<void> => {\n await deauthorizeSessions();\n }, [deauthorizeSessions]);\n\n const signAndSendTransaction = useCallback(\n async (\n transaction: Transaction | VersionedTransaction,\n minContextSlot: number,\n ): Promise<TransactionSignature> => {\n return await transact(async wallet => {\n await authorizeSession(wallet);\n const signatures = await wallet.signAndSendTransactions({\n minContextSlot,\n transactions: [transaction],\n });\n return signatures[0];\n });\n },\n [authorizeSession],\n );\n\n const signMessage = useCallback(\n async (message: Uint8Array): Promise<Uint8Array> => {\n return await transact(async wallet => {\n const authResult = await authorizeSession(wallet);\n const signedMessages = await wallet.signMessages({\n addresses: [authResult.address],\n payloads: [message],\n });\n return signedMessages[0];\n });\n },\n [authorizeSession],\n );\n\n return useMemo(\n () => ({\n connect,\n connectAnd,\n disconnect,\n signAndSendTransaction,\n signIn,\n signMessage,\n }),\n [connect, connectAnd, disconnect, signAndSendTransaction, signIn, signMessage],\n );\n}\n","import { useContext } from 'react';\n\nimport { MobileWalletAdapterProviderContext } from './mobile-wallet-adapter-provider';\nimport { useAuthorization } from './use-authorization';\nimport { useMobileWallet } from './use-mobile-wallet';\n\nexport function useMobileWalletAdapter() {\n const ctx = useContext(MobileWalletAdapterProviderContext);\n const { connect, connectAnd, signAndSendTransaction, signMessage, signIn } = useMobileWallet(ctx);\n const { selectedAccount, deauthorizeSessions } = useAuthorization(ctx);\n\n return {\n ...ctx,\n account: selectedAccount,\n connect,\n connectAnd,\n disconnect: deauthorizeSessions,\n signAndSendTransaction,\n signIn,\n signMessage,\n };\n}\n"]}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
2
|
+
import React, { createContext, useMemo, useCallback, useContext } from 'react';
|
|
3
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
4
|
+
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
|
|
5
|
+
import { toUint8Array } from 'js-base64';
|
|
6
|
+
export { fromUint8Array, toUint8Array } from 'js-base64';
|
|
7
|
+
import { transact } from '@solana-mobile/mobile-wallet-adapter-protocol-web3js';
|
|
8
|
+
export * from '@solana-mobile/mobile-wallet-adapter-protocol-web3js';
|
|
9
|
+
export * from '@wallet-ui/core';
|
|
10
|
+
|
|
11
|
+
// src/mobile-wallet-adapter-provider.tsx
|
|
12
|
+
var MobileWalletAdapterProviderContext = createContext(
|
|
13
|
+
{}
|
|
14
|
+
);
|
|
15
|
+
function MobileWalletAdapterProvider({
|
|
16
|
+
children,
|
|
17
|
+
clusterId,
|
|
18
|
+
endpoint,
|
|
19
|
+
identity
|
|
20
|
+
}) {
|
|
21
|
+
const connection = useMemo(() => new Connection(endpoint, { commitment: "confirmed" }), [endpoint]);
|
|
22
|
+
const value = useMemo(() => ({ clusterId, connection, identity }), [connection, identity, clusterId]);
|
|
23
|
+
return /* @__PURE__ */ React.createElement(MobileWalletAdapterProviderContext.Provider, { value }, children);
|
|
24
|
+
}
|
|
25
|
+
function ellipsify(str = "", len = 4, delimiter = "..") {
|
|
26
|
+
const limit = len * 2 + delimiter.length;
|
|
27
|
+
return str.length > limit ? str.slice(0, len) + delimiter + str.slice(-len) : str;
|
|
28
|
+
}
|
|
29
|
+
function getPublicKeyFromAddress(address) {
|
|
30
|
+
const publicKeyByteArray = toUint8Array(address);
|
|
31
|
+
return new PublicKey(publicKeyByteArray);
|
|
32
|
+
}
|
|
33
|
+
function getAccountFromAuthorizedAccount(account) {
|
|
34
|
+
const publicKey = getPublicKeyFromAddress(account.address);
|
|
35
|
+
return {
|
|
36
|
+
address: account.address,
|
|
37
|
+
// TODO: Fix upstream?
|
|
38
|
+
displayAddress: account.display_address,
|
|
39
|
+
icon: account.icon,
|
|
40
|
+
label: account.label ?? ellipsify(publicKey.toString(), 8),
|
|
41
|
+
publicKey
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function getAuthorizationFromAuthorizationResult(authorizationResult, previouslySelectedAccount) {
|
|
45
|
+
let selectedAccount;
|
|
46
|
+
if (
|
|
47
|
+
// We have yet to select an account.
|
|
48
|
+
previouslySelectedAccount == null || // The previously selected account is no longer in the set of authorized addresses.
|
|
49
|
+
!authorizationResult.accounts.some(({ address }) => address === previouslySelectedAccount.address)
|
|
50
|
+
) {
|
|
51
|
+
const firstAccount = authorizationResult.accounts[0];
|
|
52
|
+
selectedAccount = getAccountFromAuthorizedAccount(firstAccount);
|
|
53
|
+
} else {
|
|
54
|
+
selectedAccount = previouslySelectedAccount;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
accounts: authorizationResult.accounts.map(getAccountFromAuthorizedAccount),
|
|
58
|
+
authToken: authorizationResult.auth_token,
|
|
59
|
+
selectedAccount
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
var AUTHORIZATION_STORAGE_KEY = "authorization-cache";
|
|
63
|
+
var queryKey = ["wallet-authorization"];
|
|
64
|
+
function cacheReviver(key, value) {
|
|
65
|
+
if (key === "publicKey") {
|
|
66
|
+
return new PublicKey(value);
|
|
67
|
+
} else {
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function usePersistAuthorization() {
|
|
72
|
+
const queryClient = useQueryClient();
|
|
73
|
+
return useMutation({
|
|
74
|
+
mutationFn: async (auth) => {
|
|
75
|
+
await AsyncStorage.setItem(AUTHORIZATION_STORAGE_KEY, JSON.stringify(auth));
|
|
76
|
+
},
|
|
77
|
+
onSuccess: async () => {
|
|
78
|
+
await queryClient.invalidateQueries({ queryKey });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function useFetchAuthorization() {
|
|
83
|
+
return useQuery({
|
|
84
|
+
queryFn: async () => {
|
|
85
|
+
const cacheFetchResult = await AsyncStorage.getItem(AUTHORIZATION_STORAGE_KEY);
|
|
86
|
+
return cacheFetchResult ? JSON.parse(cacheFetchResult, cacheReviver) : null;
|
|
87
|
+
},
|
|
88
|
+
queryKey
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function useInvalidateAuthorizations() {
|
|
92
|
+
const client = useQueryClient();
|
|
93
|
+
return () => client.invalidateQueries({ queryKey });
|
|
94
|
+
}
|
|
95
|
+
function useAuthorization({ clusterId, identity }) {
|
|
96
|
+
const fetchQuery = useFetchAuthorization();
|
|
97
|
+
const invalidateAuthorizations = useInvalidateAuthorizations();
|
|
98
|
+
const persistMutation = usePersistAuthorization();
|
|
99
|
+
const handleAuthorizationResult = useCallback(
|
|
100
|
+
async (authorizationResult) => {
|
|
101
|
+
const nextAuthorization = getAuthorizationFromAuthorizationResult(
|
|
102
|
+
authorizationResult,
|
|
103
|
+
fetchQuery.data?.selectedAccount
|
|
104
|
+
);
|
|
105
|
+
await persistMutation.mutateAsync(nextAuthorization);
|
|
106
|
+
return nextAuthorization;
|
|
107
|
+
},
|
|
108
|
+
[fetchQuery.data?.selectedAccount, persistMutation]
|
|
109
|
+
);
|
|
110
|
+
const authorizeSession = useCallback(
|
|
111
|
+
async (wallet) => {
|
|
112
|
+
const authorizationResult = await wallet.authorize({
|
|
113
|
+
auth_token: fetchQuery.data?.authToken,
|
|
114
|
+
chain: clusterId,
|
|
115
|
+
identity
|
|
116
|
+
});
|
|
117
|
+
return (await handleAuthorizationResult(authorizationResult)).selectedAccount;
|
|
118
|
+
},
|
|
119
|
+
[fetchQuery.data?.authToken, clusterId, identity, handleAuthorizationResult]
|
|
120
|
+
);
|
|
121
|
+
const authorizeSessionWithSignIn = useCallback(
|
|
122
|
+
async (wallet, signInPayload) => {
|
|
123
|
+
const authorizationResult = await wallet.authorize({
|
|
124
|
+
auth_token: fetchQuery.data?.authToken,
|
|
125
|
+
chain: clusterId,
|
|
126
|
+
identity,
|
|
127
|
+
sign_in_payload: signInPayload
|
|
128
|
+
});
|
|
129
|
+
return (await handleAuthorizationResult(authorizationResult)).selectedAccount;
|
|
130
|
+
},
|
|
131
|
+
[fetchQuery.data?.authToken, clusterId, identity, handleAuthorizationResult]
|
|
132
|
+
);
|
|
133
|
+
const deauthorizeSession = useCallback(
|
|
134
|
+
async (wallet) => {
|
|
135
|
+
if (fetchQuery.data?.authToken == null) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
await wallet.deauthorize({ auth_token: fetchQuery.data.authToken });
|
|
139
|
+
await persistMutation.mutateAsync(null);
|
|
140
|
+
},
|
|
141
|
+
[fetchQuery.data?.authToken, persistMutation]
|
|
142
|
+
);
|
|
143
|
+
const deauthorizeSessions = useCallback(async () => {
|
|
144
|
+
await invalidateAuthorizations();
|
|
145
|
+
await persistMutation.mutateAsync(null);
|
|
146
|
+
}, [invalidateAuthorizations, persistMutation]);
|
|
147
|
+
return useMemo(
|
|
148
|
+
() => ({
|
|
149
|
+
accounts: fetchQuery.data?.accounts ?? null,
|
|
150
|
+
authorizeSession,
|
|
151
|
+
authorizeSessionWithSignIn,
|
|
152
|
+
deauthorizeSession,
|
|
153
|
+
deauthorizeSessions,
|
|
154
|
+
isLoading: fetchQuery.isLoading,
|
|
155
|
+
selectedAccount: fetchQuery.data?.selectedAccount ?? null
|
|
156
|
+
}),
|
|
157
|
+
[
|
|
158
|
+
authorizeSession,
|
|
159
|
+
authorizeSessionWithSignIn,
|
|
160
|
+
deauthorizeSession,
|
|
161
|
+
deauthorizeSessions,
|
|
162
|
+
fetchQuery.data?.accounts,
|
|
163
|
+
fetchQuery.data?.selectedAccount,
|
|
164
|
+
fetchQuery.isLoading
|
|
165
|
+
]
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
function useMobileWallet({ clusterId, identity }) {
|
|
169
|
+
const { authorizeSessionWithSignIn, authorizeSession, deauthorizeSessions } = useAuthorization({
|
|
170
|
+
clusterId,
|
|
171
|
+
identity
|
|
172
|
+
});
|
|
173
|
+
const connect = useCallback(
|
|
174
|
+
async () => await transact(async (wallet) => await authorizeSession(wallet)),
|
|
175
|
+
[authorizeSession]
|
|
176
|
+
);
|
|
177
|
+
const connectAnd = useCallback(
|
|
178
|
+
async (cb) => {
|
|
179
|
+
return await transact(async (wallet) => await cb(wallet));
|
|
180
|
+
},
|
|
181
|
+
[]
|
|
182
|
+
);
|
|
183
|
+
const signIn = useCallback(
|
|
184
|
+
async (signInPayload) => await transact(async (wallet) => await authorizeSessionWithSignIn(wallet, signInPayload)),
|
|
185
|
+
[authorizeSessionWithSignIn]
|
|
186
|
+
);
|
|
187
|
+
const disconnect = useCallback(async () => {
|
|
188
|
+
await deauthorizeSessions();
|
|
189
|
+
}, [deauthorizeSessions]);
|
|
190
|
+
const signAndSendTransaction = useCallback(
|
|
191
|
+
async (transaction, minContextSlot) => {
|
|
192
|
+
return await transact(async (wallet) => {
|
|
193
|
+
await authorizeSession(wallet);
|
|
194
|
+
const signatures = await wallet.signAndSendTransactions({
|
|
195
|
+
minContextSlot,
|
|
196
|
+
transactions: [transaction]
|
|
197
|
+
});
|
|
198
|
+
return signatures[0];
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
[authorizeSession]
|
|
202
|
+
);
|
|
203
|
+
const signMessage = useCallback(
|
|
204
|
+
async (message) => {
|
|
205
|
+
return await transact(async (wallet) => {
|
|
206
|
+
const authResult = await authorizeSession(wallet);
|
|
207
|
+
const signedMessages = await wallet.signMessages({
|
|
208
|
+
addresses: [authResult.address],
|
|
209
|
+
payloads: [message]
|
|
210
|
+
});
|
|
211
|
+
return signedMessages[0];
|
|
212
|
+
});
|
|
213
|
+
},
|
|
214
|
+
[authorizeSession]
|
|
215
|
+
);
|
|
216
|
+
return useMemo(
|
|
217
|
+
() => ({
|
|
218
|
+
connect,
|
|
219
|
+
connectAnd,
|
|
220
|
+
disconnect,
|
|
221
|
+
signAndSendTransaction,
|
|
222
|
+
signIn,
|
|
223
|
+
signMessage
|
|
224
|
+
}),
|
|
225
|
+
[connect, connectAnd, disconnect, signAndSendTransaction, signIn, signMessage]
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
function useMobileWalletAdapter() {
|
|
229
|
+
const ctx = useContext(MobileWalletAdapterProviderContext);
|
|
230
|
+
const { connect, connectAnd, signAndSendTransaction, signMessage, signIn } = useMobileWallet(ctx);
|
|
231
|
+
const { selectedAccount, deauthorizeSessions } = useAuthorization(ctx);
|
|
232
|
+
return {
|
|
233
|
+
...ctx,
|
|
234
|
+
account: selectedAccount,
|
|
235
|
+
connect,
|
|
236
|
+
connectAnd,
|
|
237
|
+
disconnect: deauthorizeSessions,
|
|
238
|
+
signAndSendTransaction,
|
|
239
|
+
signIn,
|
|
240
|
+
signMessage
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export { MobileWalletAdapterProvider, MobileWalletAdapterProviderContext, useAuthorization, useMobileWallet, useMobileWalletAdapter };
|
|
245
|
+
//# sourceMappingURL=index.browser.mjs.map
|
|
246
|
+
//# sourceMappingURL=index.browser.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mobile-wallet-adapter-provider.tsx","../src/use-authorization.ts","../src/use-mobile-wallet.ts","../src/use-mobile-wallet-adapter.ts"],"names":["useMemo","useCallback"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["import { Connection } from '@solana/web3.js';\nimport { AppIdentity } from '@solana-mobile/mobile-wallet-adapter-protocol';\nimport { SolanaClusterId } from '@wallet-ui/core/src';\nimport React, { createContext, type ReactNode, useMemo } from 'react';\n\nexport interface MobileWalletAdapterProviderProps {\n children: ReactNode;\n clusterId: SolanaClusterId;\n endpoint: string;\n identity: AppIdentity;\n}\nexport interface MobileWalletAdapterProviderState {\n clusterId: SolanaClusterId;\n connection: Connection;\n identity: AppIdentity;\n}\n\nexport const MobileWalletAdapterProviderContext = createContext<MobileWalletAdapterProviderState>(\n {} as MobileWalletAdapterProviderState,\n);\nexport function MobileWalletAdapterProvider({\n children,\n clusterId,\n endpoint,\n identity,\n}: MobileWalletAdapterProviderProps) {\n const connection = useMemo(() => new Connection(endpoint, { commitment: 'confirmed' }), [endpoint]);\n const value = useMemo(() => ({ clusterId, connection, identity }), [connection, identity, clusterId]);\n\n return (\n <MobileWalletAdapterProviderContext.Provider value={value}>\n {children}\n </MobileWalletAdapterProviderContext.Provider>\n );\n}\n","import AsyncStorage from '@react-native-async-storage/async-storage';\nimport { PublicKey, PublicKeyInitData } from '@solana/web3.js';\nimport {\n Account as AuthorizedAccount,\n AppIdentity,\n AuthorizationResult,\n AuthorizeAPI,\n AuthToken,\n Base64EncodedAddress,\n DeauthorizeAPI,\n SignInPayload,\n} from '@solana-mobile/mobile-wallet-adapter-protocol';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { WalletIcon } from '@wallet-standard/core';\nimport { SolanaClusterId } from '@wallet-ui/core';\nimport { toUint8Array } from 'js-base64';\nimport { useCallback, useMemo } from 'react';\n\nfunction ellipsify(str = '', len = 4, delimiter = '..') {\n const limit = len * 2 + delimiter.length;\n\n return str.length > limit ? str.slice(0, len) + delimiter + str.slice(-len) : str;\n}\n\nexport type Account = Readonly<{\n address: Base64EncodedAddress;\n displayAddress?: string;\n icon?: WalletIcon;\n label?: string;\n publicKey: PublicKey;\n}>;\n\nexport type WalletAuthorization = Readonly<{\n accounts: Account[];\n authToken: AuthToken;\n selectedAccount: Account;\n}>;\n\nfunction getPublicKeyFromAddress(address: Base64EncodedAddress): PublicKey {\n const publicKeyByteArray = toUint8Array(address);\n return new PublicKey(publicKeyByteArray);\n}\n\nfunction getAccountFromAuthorizedAccount(account: AuthorizedAccount): Account {\n const publicKey = getPublicKeyFromAddress(account.address);\n return {\n address: account.address,\n // TODO: Fix upstream?\n displayAddress: (account as unknown as { display_address: string }).display_address,\n icon: account.icon,\n label: account.label ?? ellipsify(publicKey.toString(), 8),\n publicKey,\n };\n}\n\nfunction getAuthorizationFromAuthorizationResult(\n authorizationResult: AuthorizationResult,\n previouslySelectedAccount?: Account,\n): WalletAuthorization {\n let selectedAccount: Account;\n if (\n // We have yet to select an account.\n previouslySelectedAccount == null ||\n // The previously selected account is no longer in the set of authorized addresses.\n !authorizationResult.accounts.some(({ address }) => address === previouslySelectedAccount.address)\n ) {\n const firstAccount = authorizationResult.accounts[0];\n selectedAccount = getAccountFromAuthorizedAccount(firstAccount);\n } else {\n selectedAccount = previouslySelectedAccount;\n }\n return {\n accounts: authorizationResult.accounts.map(getAccountFromAuthorizedAccount),\n authToken: authorizationResult.auth_token,\n selectedAccount,\n };\n}\n\nconst AUTHORIZATION_STORAGE_KEY = 'authorization-cache';\n\nconst queryKey = ['wallet-authorization'];\n\nfunction cacheReviver(key: string, value: unknown) {\n if (key === 'publicKey') {\n return new PublicKey(value as PublicKeyInitData); // the PublicKeyInitData should match the actual data structure stored in AsyncStorage\n } else {\n return value;\n }\n}\nfunction usePersistAuthorization() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (auth: WalletAuthorization | null): Promise<void> => {\n await AsyncStorage.setItem(AUTHORIZATION_STORAGE_KEY, JSON.stringify(auth));\n },\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey });\n },\n });\n}\n\nfunction useFetchAuthorization() {\n return useQuery({\n queryFn: async (): Promise<WalletAuthorization | null> => {\n const cacheFetchResult = await AsyncStorage.getItem(AUTHORIZATION_STORAGE_KEY);\n\n // Return prior authorization, if found.\n return cacheFetchResult ? JSON.parse(cacheFetchResult, cacheReviver) : null;\n },\n queryKey,\n });\n}\n\nfunction useInvalidateAuthorizations() {\n const client = useQueryClient();\n return () => client.invalidateQueries({ queryKey });\n}\n\nexport function useAuthorization({ clusterId, identity }: { clusterId: SolanaClusterId; identity: AppIdentity }) {\n const fetchQuery = useFetchAuthorization();\n const invalidateAuthorizations = useInvalidateAuthorizations();\n const persistMutation = usePersistAuthorization();\n\n const handleAuthorizationResult = useCallback(\n async (authorizationResult: AuthorizationResult): Promise<WalletAuthorization> => {\n const nextAuthorization = getAuthorizationFromAuthorizationResult(\n authorizationResult,\n fetchQuery.data?.selectedAccount,\n );\n await persistMutation.mutateAsync(nextAuthorization);\n return nextAuthorization;\n },\n [fetchQuery.data?.selectedAccount, persistMutation],\n );\n\n const authorizeSession = useCallback(\n async (wallet: AuthorizeAPI) => {\n const authorizationResult = await wallet.authorize({\n auth_token: fetchQuery.data?.authToken,\n chain: clusterId,\n identity,\n });\n return (await handleAuthorizationResult(authorizationResult)).selectedAccount;\n },\n [fetchQuery.data?.authToken, clusterId, identity, handleAuthorizationResult],\n );\n\n const authorizeSessionWithSignIn = useCallback(\n async (wallet: AuthorizeAPI, signInPayload: SignInPayload) => {\n const authorizationResult = await wallet.authorize({\n auth_token: fetchQuery.data?.authToken,\n chain: clusterId,\n identity,\n sign_in_payload: signInPayload,\n });\n return (await handleAuthorizationResult(authorizationResult)).selectedAccount;\n },\n [fetchQuery.data?.authToken, clusterId, identity, handleAuthorizationResult],\n );\n\n const deauthorizeSession = useCallback(\n async (wallet: DeauthorizeAPI) => {\n if (fetchQuery.data?.authToken == null) {\n return;\n }\n await wallet.deauthorize({ auth_token: fetchQuery.data.authToken });\n await persistMutation.mutateAsync(null);\n },\n [fetchQuery.data?.authToken, persistMutation],\n );\n\n const deauthorizeSessions = useCallback(async () => {\n await invalidateAuthorizations();\n await persistMutation.mutateAsync(null);\n }, [invalidateAuthorizations, persistMutation]);\n\n return useMemo(\n () => ({\n accounts: fetchQuery.data?.accounts ?? null,\n authorizeSession,\n authorizeSessionWithSignIn,\n deauthorizeSession,\n deauthorizeSessions,\n isLoading: fetchQuery.isLoading,\n selectedAccount: fetchQuery.data?.selectedAccount ?? null,\n }),\n [\n authorizeSession,\n authorizeSessionWithSignIn,\n deauthorizeSession,\n deauthorizeSessions,\n fetchQuery.data?.accounts,\n fetchQuery.data?.selectedAccount,\n fetchQuery.isLoading,\n ],\n );\n}\n","import { Transaction, TransactionSignature, VersionedTransaction } from '@solana/web3.js';\nimport { AppIdentity, AuthorizeAPI, SignInPayload } from '@solana-mobile/mobile-wallet-adapter-protocol';\nimport { transact } from '@solana-mobile/mobile-wallet-adapter-protocol-web3js';\nimport { SolanaClusterId } from '@wallet-ui/core';\nimport { useCallback, useMemo } from 'react';\n\nimport { Account, useAuthorization } from './use-authorization';\n\nexport function useMobileWallet({ clusterId, identity }: { clusterId: SolanaClusterId; identity: AppIdentity }) {\n const { authorizeSessionWithSignIn, authorizeSession, deauthorizeSessions } = useAuthorization({\n clusterId,\n identity,\n });\n\n const connect = useCallback(\n async (): Promise<Account> => await transact(async wallet => await authorizeSession(wallet)),\n [authorizeSession],\n );\n\n const connectAnd = useCallback(\n async (cb: (wallet: AuthorizeAPI) => Promise<Account | void>): Promise<Account | void> => {\n return await transact(async wallet => await cb(wallet));\n },\n [],\n );\n\n const signIn = useCallback(\n async (signInPayload: SignInPayload): Promise<Account> =>\n await transact(async wallet => await authorizeSessionWithSignIn(wallet, signInPayload)),\n [authorizeSessionWithSignIn],\n );\n\n const disconnect = useCallback(async (): Promise<void> => {\n await deauthorizeSessions();\n }, [deauthorizeSessions]);\n\n const signAndSendTransaction = useCallback(\n async (\n transaction: Transaction | VersionedTransaction,\n minContextSlot: number,\n ): Promise<TransactionSignature> => {\n return await transact(async wallet => {\n await authorizeSession(wallet);\n const signatures = await wallet.signAndSendTransactions({\n minContextSlot,\n transactions: [transaction],\n });\n return signatures[0];\n });\n },\n [authorizeSession],\n );\n\n const signMessage = useCallback(\n async (message: Uint8Array): Promise<Uint8Array> => {\n return await transact(async wallet => {\n const authResult = await authorizeSession(wallet);\n const signedMessages = await wallet.signMessages({\n addresses: [authResult.address],\n payloads: [message],\n });\n return signedMessages[0];\n });\n },\n [authorizeSession],\n );\n\n return useMemo(\n () => ({\n connect,\n connectAnd,\n disconnect,\n signAndSendTransaction,\n signIn,\n signMessage,\n }),\n [connect, connectAnd, disconnect, signAndSendTransaction, signIn, signMessage],\n );\n}\n","import { useContext } from 'react';\n\nimport { MobileWalletAdapterProviderContext } from './mobile-wallet-adapter-provider';\nimport { useAuthorization } from './use-authorization';\nimport { useMobileWallet } from './use-mobile-wallet';\n\nexport function useMobileWalletAdapter() {\n const ctx = useContext(MobileWalletAdapterProviderContext);\n const { connect, connectAnd, signAndSendTransaction, signMessage, signIn } = useMobileWallet(ctx);\n const { selectedAccount, deauthorizeSessions } = useAuthorization(ctx);\n\n return {\n ...ctx,\n account: selectedAccount,\n connect,\n connectAnd,\n disconnect: deauthorizeSessions,\n signAndSendTransaction,\n signIn,\n signMessage,\n };\n}\n"]}
|