@solana/react 2.0.0-canary-20240731173615

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +311 -0
  3. package/dist/index.browser.cjs +318 -0
  4. package/dist/index.browser.cjs.map +1 -0
  5. package/dist/index.browser.mjs +310 -0
  6. package/dist/index.browser.mjs.map +1 -0
  7. package/dist/index.native.mjs +310 -0
  8. package/dist/index.native.mjs.map +1 -0
  9. package/dist/index.node.cjs +318 -0
  10. package/dist/index.node.cjs.map +1 -0
  11. package/dist/index.node.mjs +310 -0
  12. package/dist/index.node.mjs.map +1 -0
  13. package/dist/types/abortable-promise.d.ts +2 -0
  14. package/dist/types/abortable-promise.d.ts.map +1 -0
  15. package/dist/types/chain.d.ts +5 -0
  16. package/dist/types/chain.d.ts.map +1 -0
  17. package/dist/types/index.d.ts +8 -0
  18. package/dist/types/index.d.ts.map +1 -0
  19. package/dist/types/useSignAndSendTransaction.d.ts +16 -0
  20. package/dist/types/useSignAndSendTransaction.d.ts.map +1 -0
  21. package/dist/types/useSignIn.d.ts +13 -0
  22. package/dist/types/useSignIn.d.ts.map +1 -0
  23. package/dist/types/useSignMessage.d.ts +11 -0
  24. package/dist/types/useSignMessage.d.ts.map +1 -0
  25. package/dist/types/useSignTransaction.d.ts +16 -0
  26. package/dist/types/useSignTransaction.d.ts.map +1 -0
  27. package/dist/types/useWalletAccountMessageSigner.d.ts +7 -0
  28. package/dist/types/useWalletAccountMessageSigner.d.ts.map +1 -0
  29. package/dist/types/useWalletAccountTransactionSendingSigner.d.ts +9 -0
  30. package/dist/types/useWalletAccountTransactionSendingSigner.d.ts.map +1 -0
  31. package/dist/types/useWalletAccountTransactionSigner.d.ts +10 -0
  32. package/dist/types/useWalletAccountTransactionSigner.d.ts.map +1 -0
  33. package/package.json +90 -0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2023 Solana Labs, Inc
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,311 @@
1
+ [![npm][npm-image]][npm-url]
2
+ [![npm-downloads][npm-downloads-image]][npm-url]
3
+ [![semantic-release][semantic-release-image]][semantic-release-url]
4
+ <br />
5
+ [![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]
6
+
7
+ [code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square
8
+ [code-style-prettier-url]: https://github.com/prettier/prettier
9
+ [npm-downloads-image]: https://img.shields.io/npm/dm/@solana/react/experimental.svg?style=flat
10
+ [npm-image]: https://img.shields.io/npm/v/@solana/react/experimental.svg?style=flat
11
+ [npm-url]: https://www.npmjs.com/package/@solana/react/v/experimental
12
+ [semantic-release-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
13
+ [semantic-release-url]: https://github.com/semantic-release/semantic-release
14
+
15
+ # @solana/react
16
+
17
+ This package contains React hooks for building Solana apps.
18
+
19
+ ## Hooks
20
+
21
+ ### `useSignIn(uiWalletAccount, chain)`
22
+
23
+ Given a `UiWallet` or `UiWalletAccount` this hook returns a function that you can call to trigger a wallet's [&lsquo;Sign In With Solana&rsquo;](https://phantom.app/learn/developers/sign-in-with-solana) feature.
24
+
25
+ #### Example
26
+
27
+ ```tsx
28
+ import { useSignIn } from '@solana/react';
29
+
30
+ function SignInButton({ wallet }) {
31
+ const csrfToken = useCsrfToken();
32
+ const signIn = useSignIn(wallet);
33
+ return (
34
+ <button
35
+ onClick={async () => {
36
+ try {
37
+ const { account, signedMessage, signature } = await signIn({
38
+ requestId: csrfToken,
39
+ });
40
+ // Authenticate the user, typically on the server, by verifying that
41
+ // `signedMessage` was signed by the person who holds the private key for
42
+ // `account.publicKey`.
43
+ //
44
+ // Authorize the user, also on the server, by decoding `signedMessage` as the
45
+ // text of a Sign In With Solana message, verifying that it was not modified
46
+ // from the values your application expects, and that its content is sufficient
47
+ // to grant them access.
48
+ window.alert(`You are now signed in with the address ${account.address}`);
49
+ } catch (e) {
50
+ console.error('Failed to sign in', e);
51
+ }
52
+ }}
53
+ >
54
+ Sign In
55
+ </button>
56
+ );
57
+ }
58
+ ```
59
+
60
+ ### `useWalletAccountMessageSigner(uiWalletAccount)`
61
+
62
+ Given a `UiWalletAccount`, this hook returns an object that conforms to the `MessageModifyingSigner` interface of `@solana/signers`.
63
+
64
+ #### Example
65
+
66
+ ```tsx
67
+ import { useWalletAccountMessageSigner } from '@solana/react';
68
+ import { createSignableMessage } from '@solana/signers';
69
+
70
+ function SignMessageButton({ account, text }) {
71
+ const messageSigner = useWalletAccountMessageSigner(account);
72
+ return (
73
+ <button
74
+ onClick={async () => {
75
+ try {
76
+ const signableMessage = createSignableMessage(text);
77
+ const [signedMessage] = await messageSigner.modifyAndSignMessages([signableMessage]);
78
+ const messageWasModified = signableMessage.content !== signedMessage.content;
79
+ const signatureBytes = signedMessage.signatures[messageSigner.address];
80
+ window.alert(
81
+ `Signature bytes: ${signatureBytes.toString()}${
82
+ messageWasModified ? ' (message was modified)' : ''
83
+ }`,
84
+ );
85
+ } catch (e) {
86
+ console.error('Failed to sign message', e);
87
+ }
88
+ }}
89
+ >
90
+ Sign Message: {text}
91
+ </button>
92
+ );
93
+ }
94
+ ```
95
+
96
+ > [!NOTE]
97
+ > The type `MessageModifyingSigner` is returned from this hook instead of `MessageSigner` or `MessagePartialSigner`. This is a conservative assumption based on the fact that your application can not control whether or not the wallet will modify the message before signing it.
98
+
99
+ ### `useWalletAccountTransactionSigner(uiWalletAccount, chain)`
100
+
101
+ Given a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns an object that conforms to the `TransactionModifyingSigner` interface of `@solana/signers`.
102
+
103
+ #### Example
104
+
105
+ ```tsx
106
+ import { useWalletAccountTransactionSigner } from '@solana/react';
107
+
108
+ function SignTransactionButton({ account, transaction }) {
109
+ const transactionSigner = useWalletAccountTransactionSigner(account, 'solana:devnet');
110
+ return (
111
+ <button
112
+ onClick={async () => {
113
+ try {
114
+ const [{ signatures }] = await transactionSigner.modifyAndSignTransactions([transaction]);
115
+ const signatureBytes = signatures[transactionSigner.address];
116
+ window.alert(`Signature bytes: ${signatureBytes.toString()}`);
117
+ } catch (e) {
118
+ console.error('Failed to sign transaction', e);
119
+ }
120
+ }}
121
+ >
122
+ Sign Transaction
123
+ </button>
124
+ );
125
+ }
126
+ ```
127
+
128
+ > [!NOTE]
129
+ > The type `TransactionModifyingSigner` is returned from this hook instead of `TransactionSigner` or `TransactionPartialSigner`. This is a conservative assumption based on the fact that your application can not control whether or not the wallet will modify the transaction before signing it (eg. to add guard instructions, or a priority fee budget).
130
+
131
+ ### `useWalletAccountTransactionSendingSigner(uiWalletAccount, chain)`
132
+
133
+ Given a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns an object that conforms to the `TransactionSendingSigner` interface of `@solana/signers`.
134
+
135
+ #### Example
136
+
137
+ ```tsx
138
+ import { useWalletAccountTransactionSendingSigner } from '@solana/react';
139
+ import {
140
+ appendTransactionMessageInstruction,
141
+ createSolanaRpc,
142
+ getBase58Decoder,
143
+ pipe,
144
+ setTransactionMessageFeePayerSigner,
145
+ setTransactionMessageLifetimeUsingBlockhash,
146
+ signAndSendTransactionMessageWithSigners,
147
+ } from '@solana/web3.js';
148
+
149
+ function RecordMemoButton({ account, rpc, text }) {
150
+ const signer = useWalletAccountTransactionSendingSigner(account, 'solana:devnet');
151
+ return (
152
+ <button
153
+ onClick={async () => {
154
+ try {
155
+ const { value: latestBlockhash } = await createSolanaRpc('https://api.devnet.solana.com')
156
+ .getLatestBlockhash()
157
+ .send();
158
+ const message = pipe(
159
+ createTransactionMessage({ version: 'legacy' }),
160
+ m => setTransactionMessageFeePayerSigner(signer, m),
161
+ m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
162
+ m => appendTransactionMessageInstruction(getAddMemoInstruction({ memo: text }), m),
163
+ );
164
+ const signatureBytes = await signAndSendTransactionMessageWithSigners(message);
165
+ const base58Signature = getBase58Decoder().decode(signature);
166
+ window.alert(`View transaction: https://explorer.solana.com/tx/${base58Signature}?cluster=devnet`);
167
+ } catch (e) {
168
+ console.error('Failed to record memo', e);
169
+ }
170
+ }}
171
+ >
172
+ Record Memo
173
+ </button>
174
+ );
175
+ }
176
+ ```
177
+
178
+ ### `useSignMessage(uiWalletAccount)`
179
+
180
+ Given a `UiWalletAccount`, this hook returns a function you can call to sign a byte array.
181
+
182
+ #### Arguments
183
+
184
+ A config object with the following properties:
185
+
186
+ - `message`: A `Uint8Array` of bytes to sign
187
+
188
+ #### Returns
189
+
190
+ An object with the following properties:
191
+
192
+ - `signature`: The 64-byte Ed25519 signature as a `Uint8Array`
193
+ - `signedMessage`: The `Uint8Array` of bytes signed by the wallet. These bytes might differ from the input bytes if the wallet modified the message
194
+
195
+ #### Example
196
+
197
+ ```tsx
198
+ import { useSignMessage } from '@solana/react';
199
+
200
+ function SignMessageButton({ account, messageBytes }) {
201
+ const signMessage = useSignMessage(account);
202
+ return (
203
+ <button
204
+ onClick={async () => {
205
+ try {
206
+ const { signature } = await signMessage({
207
+ message: messageBytes,
208
+ });
209
+ window.alert(`Signature bytes: ${signature.toString()}`);
210
+ } catch (e) {
211
+ console.error('Failed to sign message', e);
212
+ }
213
+ }}
214
+ >
215
+ Sign Message
216
+ </button>
217
+ );
218
+ }
219
+ ```
220
+
221
+ ### `useSignTransaction(uiWalletAccount, chain)`
222
+
223
+ Given a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns a function you can call to sign a serialized transaction.
224
+
225
+ #### Arguments
226
+
227
+ A config object with the following properties:
228
+
229
+ - `options`: An object with the following properties:
230
+ - `minContextSlot`: A slot at which any blockhash/nonce in the transaction is known to exist. This may be used by the signer and/or RPC to determine the validity of the blockhashes/nonces it has observed.
231
+ - `transaction`: A `Uint8Array` of bytes that conforms to the [Solana transaction schema](https://solana.com/docs/core/transactions#transaction)
232
+
233
+ #### Returns
234
+
235
+ An object with the following properties:
236
+
237
+ - `signedTransaction`: A `Uint8Array` of bytes that conforms to the [Solana transaction schema](https://solana.com/docs/core/transactions#transaction)
238
+
239
+ #### Example
240
+
241
+ ```tsx
242
+ import { useSignTransaction } from '@solana/react';
243
+
244
+ function SignTransactionButton({ account, transactionBytes }) {
245
+ const signTransaction = useSignTransaction(account, 'solana:devnet');
246
+ return (
247
+ <button
248
+ onClick={async () => {
249
+ try {
250
+ const { signedTransaction } = await signTransaction({
251
+ transaction: transactionBytes,
252
+ });
253
+ window.alert(`Signed transaction bytes: ${signedTransaction.toString()}`);
254
+ } catch (e) {
255
+ console.error('Failed to sign transaction', e);
256
+ }
257
+ }}
258
+ >
259
+ Sign Transaction
260
+ </button>
261
+ );
262
+ }
263
+ ```
264
+
265
+ ### `useSignAndSendTransaction(uiWalletAccount, chain)`
266
+
267
+ Given a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns a function you can call to sign and send a serialized transaction.
268
+
269
+ #### Arguments
270
+
271
+ A config object with the following properties:
272
+
273
+ - `options`: An object with the following properties:
274
+ - `minContextSlot`: A slot at which any blockhash/nonce in the transaction is known to exist. This may be used by the signer and/or RPC to determine the validity of the blockhashes/nonces it has observed.
275
+ - `transaction`: A `Uint8Array` of bytes that conforms to the [Solana transaction schema](https://solana.com/docs/core/transactions#transaction)
276
+
277
+ #### Returns
278
+
279
+ That function returns an object with the following properties:
280
+
281
+ - `signature`: A `Uint8Array` of bytes representing the signature of the sent transaction.
282
+
283
+ #### Example
284
+
285
+ ```tsx
286
+ import { getBase58Decoder } from '@solana/codecs-strings';
287
+ import { useSignAndSendTransaction } from '@solana/react';
288
+
289
+ function SignAndSendTransactionButton({ account, transactionBytes }) {
290
+ const signAndSendTransaction = useSignAndSendTransaction(account, 'solana:devnet');
291
+ return (
292
+ <button
293
+ onClick={async () => {
294
+ try {
295
+ const { signature } = await signAndSendTransaction({
296
+ transaction: transactionBytes,
297
+ });
298
+ const base58TransactionSignature = getBase58Decoder().decode(signature);
299
+ window.alert(
300
+ `View transaction: https://explorer.solana.com/tx/${base58TransactionSignature}?cluster=devnet`,
301
+ );
302
+ } catch (e) {
303
+ console.error('Failed to send transaction', e);
304
+ }
305
+ }}
306
+ >
307
+ Sign and Send Transaction
308
+ </button>
309
+ );
310
+ }
311
+ ```
@@ -0,0 +1,318 @@
1
+ 'use strict';
2
+
3
+ var walletStandardFeatures = require('@solana/wallet-standard-features');
4
+ var errors = require('@wallet-standard/errors');
5
+ var ui = require('@wallet-standard/ui');
6
+ var uiRegistry = require('@wallet-standard/ui-registry');
7
+ var react = require('react');
8
+ var addresses = require('@solana/addresses');
9
+ var errors$1 = require('@solana/errors');
10
+ var transactions = require('@solana/transactions');
11
+
12
+ // src/useSignAndSendTransaction.ts
13
+ function useSignAndSendTransaction(uiWalletAccount, chain) {
14
+ const signAndSendTransactions = useSignAndSendTransactions(uiWalletAccount, chain);
15
+ return react.useCallback(
16
+ async (input) => {
17
+ const [result] = await signAndSendTransactions(input);
18
+ return result;
19
+ },
20
+ [signAndSendTransactions]
21
+ );
22
+ }
23
+ function useSignAndSendTransactions(uiWalletAccount, chain) {
24
+ if (!uiWalletAccount.chains.includes(chain)) {
25
+ throw new errors.WalletStandardError(errors.WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {
26
+ address: uiWalletAccount.address,
27
+ chain,
28
+ featureName: walletStandardFeatures.SolanaSignAndSendTransaction,
29
+ supportedChains: [...uiWalletAccount.chains],
30
+ supportedFeatures: [...uiWalletAccount.features]
31
+ });
32
+ }
33
+ const signAndSendTransactionFeature = ui.getWalletAccountFeature(
34
+ uiWalletAccount,
35
+ walletStandardFeatures.SolanaSignAndSendTransaction
36
+ );
37
+ const account = uiRegistry.getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);
38
+ return react.useCallback(
39
+ async (...inputs) => {
40
+ const inputsWithChainAndAccount = inputs.map(({ options, ...rest }) => {
41
+ const minContextSlot = options?.minContextSlot;
42
+ return {
43
+ ...rest,
44
+ account,
45
+ chain,
46
+ ...minContextSlot != null ? {
47
+ options: {
48
+ minContextSlot: Number(minContextSlot)
49
+ }
50
+ } : null
51
+ };
52
+ });
53
+ const results = await signAndSendTransactionFeature.signAndSendTransaction(...inputsWithChainAndAccount);
54
+ return results;
55
+ },
56
+ [account, chain, signAndSendTransactionFeature]
57
+ );
58
+ }
59
+ function useSignIn(uiWalletHandle) {
60
+ const signIns = useSignIns(uiWalletHandle);
61
+ return react.useCallback(
62
+ async (input) => {
63
+ const [result] = await signIns(input);
64
+ return result;
65
+ },
66
+ [signIns]
67
+ );
68
+ }
69
+ function useSignIns(uiWalletHandle) {
70
+ let signMessageFeature;
71
+ if ("address" in uiWalletHandle && typeof uiWalletHandle.address === "string") {
72
+ uiRegistry.getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletHandle);
73
+ signMessageFeature = ui.getWalletAccountFeature(
74
+ uiWalletHandle,
75
+ walletStandardFeatures.SolanaSignIn
76
+ );
77
+ } else {
78
+ signMessageFeature = ui.getWalletFeature(uiWalletHandle, walletStandardFeatures.SolanaSignIn);
79
+ }
80
+ const wallet = uiRegistry.getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletHandle);
81
+ return react.useCallback(
82
+ async (...inputs) => {
83
+ const inputsWithAddressAndChainId = inputs.map((input) => ({
84
+ ...input,
85
+ // Prioritize the `UiWalletAccount` address if it exists.
86
+ ..."address" in uiWalletHandle ? { address: uiWalletHandle.address } : null
87
+ }));
88
+ const results = await signMessageFeature.signIn(...inputsWithAddressAndChainId);
89
+ const resultsWithoutSignatureType = results.map(
90
+ ({
91
+ account,
92
+ signatureType: _,
93
+ // Solana signatures are always of type `ed25519` so drop this property.
94
+ ...rest
95
+ }) => ({
96
+ ...rest,
97
+ account: uiRegistry.getOrCreateUiWalletAccountForStandardWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(
98
+ wallet,
99
+ account
100
+ )
101
+ })
102
+ );
103
+ return resultsWithoutSignatureType;
104
+ },
105
+ [signMessageFeature, uiWalletHandle, wallet]
106
+ );
107
+ }
108
+ function useSignMessage(...config) {
109
+ const signMessages = useSignMessages(...config);
110
+ return react.useCallback(
111
+ async (input) => {
112
+ const [result] = await signMessages(input);
113
+ return result;
114
+ },
115
+ [signMessages]
116
+ );
117
+ }
118
+ function useSignMessages(uiWalletAccount) {
119
+ const signMessageFeature = ui.getWalletAccountFeature(
120
+ uiWalletAccount,
121
+ walletStandardFeatures.SolanaSignMessage
122
+ );
123
+ const account = uiRegistry.getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);
124
+ return react.useCallback(
125
+ async (...inputs) => {
126
+ const inputsWithAccount = inputs.map((input) => ({ ...input, account }));
127
+ const results = await signMessageFeature.signMessage(...inputsWithAccount);
128
+ const resultsWithoutSignatureType = results.map(
129
+ ({
130
+ signatureType: _,
131
+ // Solana signatures are always of type `ed25519` so drop this property.
132
+ ...rest
133
+ }) => rest
134
+ );
135
+ return resultsWithoutSignatureType;
136
+ },
137
+ [signMessageFeature, account]
138
+ );
139
+ }
140
+ function useSignTransaction(uiWalletAccount, chain) {
141
+ const signTransactions = useSignTransactions(uiWalletAccount, chain);
142
+ return react.useCallback(
143
+ async (input) => {
144
+ const [result] = await signTransactions(input);
145
+ return result;
146
+ },
147
+ [signTransactions]
148
+ );
149
+ }
150
+ function useSignTransactions(uiWalletAccount, chain) {
151
+ if (!uiWalletAccount.chains.includes(chain)) {
152
+ throw new errors.WalletStandardError(errors.WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {
153
+ address: uiWalletAccount.address,
154
+ chain,
155
+ featureName: walletStandardFeatures.SolanaSignAndSendTransaction,
156
+ supportedChains: [...uiWalletAccount.chains],
157
+ supportedFeatures: [...uiWalletAccount.features]
158
+ });
159
+ }
160
+ const signTransactionFeature = ui.getWalletAccountFeature(
161
+ uiWalletAccount,
162
+ walletStandardFeatures.SolanaSignTransaction
163
+ );
164
+ const account = uiRegistry.getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);
165
+ return react.useCallback(
166
+ async (...inputs) => {
167
+ const inputsWithAccountAndChain = inputs.map(({ options, ...rest }) => {
168
+ const minContextSlot = options?.minContextSlot;
169
+ return {
170
+ ...rest,
171
+ account,
172
+ chain,
173
+ ...minContextSlot != null ? {
174
+ options: {
175
+ minContextSlot: Number(minContextSlot)
176
+ }
177
+ } : null
178
+ };
179
+ });
180
+ const results = await signTransactionFeature.signTransaction(...inputsWithAccountAndChain);
181
+ return results;
182
+ },
183
+ [signTransactionFeature, account, chain]
184
+ );
185
+ }
186
+
187
+ // src/abortable-promise.ts
188
+ function getAbortablePromise(promise, abortSignal) {
189
+ if (!abortSignal) {
190
+ return promise;
191
+ } else {
192
+ return Promise.race([
193
+ // This promise only ever rejects if the signal is aborted. Otherwise it idles forever.
194
+ // It's important that this come before the input promise; in the event of an abort, we
195
+ // want to throw even if the input promise's result is ready
196
+ new Promise((_, reject) => {
197
+ if (abortSignal.aborted) {
198
+ reject(abortSignal.reason);
199
+ } else {
200
+ abortSignal.addEventListener("abort", function() {
201
+ reject(this.reason);
202
+ });
203
+ }
204
+ }),
205
+ promise
206
+ ]);
207
+ }
208
+ }
209
+
210
+ // src/useWalletAccountMessageSigner.ts
211
+ function useWalletAccountMessageSigner(uiWalletAccount) {
212
+ const signMessage = useSignMessage(uiWalletAccount);
213
+ return react.useMemo(
214
+ () => ({
215
+ address: addresses.address(uiWalletAccount.address),
216
+ async modifyAndSignMessages(messages, config) {
217
+ config?.abortSignal?.throwIfAborted();
218
+ if (messages.length > 1) {
219
+ throw new errors$1.SolanaError(errors$1.SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED);
220
+ }
221
+ if (messages.length === 0) {
222
+ return messages;
223
+ }
224
+ const { content: originalMessage, signatures: originalSignatureMap } = messages[0];
225
+ const input = {
226
+ message: originalMessage
227
+ };
228
+ const { signedMessage, signature } = await getAbortablePromise(signMessage(input), config?.abortSignal);
229
+ const messageWasModified = originalMessage.length !== signedMessage.length || originalMessage.some((originalByte, ii) => originalByte !== signedMessage[ii]);
230
+ const originalSignature = originalSignatureMap[uiWalletAccount.address];
231
+ const signatureIsNew = !originalSignature?.every((originalByte, ii) => originalByte === signature[ii]);
232
+ if (!signatureIsNew && !messageWasModified) {
233
+ return messages;
234
+ }
235
+ const nextSignatureMap = messageWasModified ? { [uiWalletAccount.address]: signature } : { ...originalSignatureMap, [uiWalletAccount.address]: signature };
236
+ const outputMessages = Object.freeze([
237
+ Object.freeze({
238
+ content: signedMessage,
239
+ signatures: Object.freeze(nextSignatureMap)
240
+ })
241
+ ]);
242
+ return outputMessages;
243
+ }
244
+ }),
245
+ [uiWalletAccount, signMessage]
246
+ );
247
+ }
248
+ function useWalletAccountTransactionSigner(uiWalletAccount, chain) {
249
+ const encoderRef = react.useRef();
250
+ const signTransaction = useSignTransaction(uiWalletAccount, chain);
251
+ return react.useMemo(
252
+ () => ({
253
+ address: addresses.address(uiWalletAccount.address),
254
+ async modifyAndSignTransactions(transactions$1, config = {}) {
255
+ const { abortSignal, ...options } = config;
256
+ abortSignal?.throwIfAborted();
257
+ const transactionCodec = encoderRef.current ||= transactions.getTransactionCodec();
258
+ if (transactions$1.length > 1) {
259
+ throw new errors$1.SolanaError(errors$1.SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED);
260
+ }
261
+ if (transactions$1.length === 0) {
262
+ return transactions$1;
263
+ }
264
+ const [transaction] = transactions$1;
265
+ const wireTransactionBytes = transactionCodec.encode(transaction);
266
+ const inputWithOptions = {
267
+ ...options,
268
+ transaction: wireTransactionBytes
269
+ };
270
+ const { signedTransaction } = await getAbortablePromise(signTransaction(inputWithOptions), abortSignal);
271
+ const decodedSignedTransaction = transactionCodec.decode(
272
+ signedTransaction
273
+ );
274
+ return Object.freeze([decodedSignedTransaction]);
275
+ }
276
+ }),
277
+ [uiWalletAccount.address, signTransaction]
278
+ );
279
+ }
280
+ function useWalletAccountTransactionSendingSigner(uiWalletAccount, chain) {
281
+ const encoderRef = react.useRef();
282
+ const signAndSendTransaction = useSignAndSendTransaction(uiWalletAccount, chain);
283
+ return react.useMemo(
284
+ () => ({
285
+ address: addresses.address(uiWalletAccount.address),
286
+ async signAndSendTransactions(transactions$1, config = {}) {
287
+ const { abortSignal, ...options } = config;
288
+ abortSignal?.throwIfAborted();
289
+ const transactionEncoder = encoderRef.current ||= transactions.getTransactionEncoder();
290
+ if (transactions$1.length > 1) {
291
+ throw new errors$1.SolanaError(errors$1.SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED);
292
+ }
293
+ if (transactions$1.length === 0) {
294
+ return [];
295
+ }
296
+ const [transaction] = transactions$1;
297
+ const wireTransactionBytes = transactionEncoder.encode(transaction);
298
+ const inputWithOptions = {
299
+ ...options,
300
+ transaction: wireTransactionBytes
301
+ };
302
+ const { signature } = await getAbortablePromise(signAndSendTransaction(inputWithOptions), abortSignal);
303
+ return Object.freeze([signature]);
304
+ }
305
+ }),
306
+ [signAndSendTransaction, uiWalletAccount.address]
307
+ );
308
+ }
309
+
310
+ exports.useSignAndSendTransaction = useSignAndSendTransaction;
311
+ exports.useSignIn = useSignIn;
312
+ exports.useSignMessage = useSignMessage;
313
+ exports.useSignTransaction = useSignTransaction;
314
+ exports.useWalletAccountMessageSigner = useWalletAccountMessageSigner;
315
+ exports.useWalletAccountTransactionSendingSigner = useWalletAccountTransactionSendingSigner;
316
+ exports.useWalletAccountTransactionSigner = useWalletAccountTransactionSigner;
317
+ //# sourceMappingURL=index.browser.cjs.map
318
+ //# sourceMappingURL=index.browser.cjs.map