@solana/signers 2.0.0-experimental.3331786
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 +368 -0
- package/dist/index.browser.cjs +138 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.js +118 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.development.js +1200 -0
- package/dist/index.development.js.map +1 -0
- package/dist/index.native.js +118 -0
- package/dist/index.native.js.map +1 -0
- package/dist/index.node.cjs +138 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.js +118 -0
- package/dist/index.node.js.map +1 -0
- package/dist/index.production.min.js +33 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/keypair-signer.d.ts +22 -0
- package/dist/types/keypair-signer.d.ts.map +1 -0
- package/dist/types/message-modifying-signer.d.ts +18 -0
- package/dist/types/message-modifying-signer.d.ts.map +1 -0
- package/dist/types/message-partial-signer.d.ts +19 -0
- package/dist/types/message-partial-signer.d.ts.map +1 -0
- package/dist/types/message-signer.d.ts +16 -0
- package/dist/types/message-signer.d.ts.map +1 -0
- package/dist/types/signable-message.d.ts +12 -0
- package/dist/types/signable-message.d.ts.map +1 -0
- package/dist/types/transaction-modifying-signer.d.ts +18 -0
- package/dist/types/transaction-modifying-signer.d.ts.map +1 -0
- package/dist/types/transaction-partial-signer.d.ts +19 -0
- package/dist/types/transaction-partial-signer.d.ts.map +1 -0
- package/dist/types/transaction-sending-signer.d.ts +19 -0
- package/dist/types/transaction-sending-signer.d.ts.map +1 -0
- package/dist/types/transaction-signer.d.ts +17 -0
- package/dist/types/transaction-signer.d.ts.map +1 -0
- package/dist/types/types.d.ts +4 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +103 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2018 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,368 @@
|
|
|
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/signers/experimental.svg?style=flat
|
|
10
|
+
[npm-image]: https://img.shields.io/npm/v/@solana/signers/experimental.svg?style=flat
|
|
11
|
+
[npm-url]: https://www.npmjs.com/package/@solana/signers/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/signers
|
|
16
|
+
|
|
17
|
+
This package provides an abstraction layer over signing messages and transactions in Solana. It can be used standalone, but it is also exported as part of the Solana JavaScript SDK [`@solana/web3.js@experimental`](https://github.com/solana-labs/solana-web3.js/tree/master/packages/library).
|
|
18
|
+
|
|
19
|
+
You can think of signers as an abstract way to sign messages and transactions. This could be using a Crypto KeyPair, a wallet adapter in the browser, a Noop signer for testing purposes, or anything you want. Here's an example using a `CryptoKeyPair` signer:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { pipe } from '@solana/functional';
|
|
23
|
+
import { generateKeyPairSigner } from '@solana/signers';
|
|
24
|
+
import { createTransaction } from '@solana/transactions';
|
|
25
|
+
|
|
26
|
+
// Generate a key pair signer.
|
|
27
|
+
const mySigner = await generateKeyPairSigner();
|
|
28
|
+
mySigner.address; // Address;
|
|
29
|
+
|
|
30
|
+
// Sign one or multiple messages.
|
|
31
|
+
const myMessage = createSignableMessage('Hello world!');
|
|
32
|
+
const [messageSignatures] = await mySigner.signMessages([myMessage]);
|
|
33
|
+
|
|
34
|
+
// Sign one or multiple transactions.
|
|
35
|
+
const myTransaction = pipe(
|
|
36
|
+
createTransaction({ version: 0 })
|
|
37
|
+
// Add instructions, fee payer, lifetime, etc.
|
|
38
|
+
);
|
|
39
|
+
const [transactionSignatures] = await mySigner.signTransactions([myTransaction]);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
As you can see, this provides a consistent API regardless of how things are being signed behind the scenes. If tomorrow we need to use a browser wallet instead, we'd simply need to swap the `generateKeyPairSigner` function with the signer factory of our choice.
|
|
43
|
+
|
|
44
|
+
This package offers a total of five different types of signers that may be used in combination when applicable. Three of them allow us to sign transactions whereas the other two are used for regular message signing.
|
|
45
|
+
|
|
46
|
+
They are separated into three categories:
|
|
47
|
+
|
|
48
|
+
- **Partial signers**: Given a message or transaction, provide one or more signatures for it. These signers are not able to modify the given data which allows us to run many of them in parallel.
|
|
49
|
+
- **Modifying signers**: Can choose to modify a message or transaction before signing it with zero or more private keys. Because modifying a message or transaction invalidates any pre-existing signatures over it, modifying signers must do their work before any other signer.
|
|
50
|
+
- **Sending signers**: Given a transaction, signs it and sends it immediately to the blockchain. When applicable, the signer may also decide to modify the provided transaction before signing it. This interface accommodates wallets that simply cannot sign a transaction without sending it at the same time. This category of signers does not apply to regular messages.
|
|
51
|
+
|
|
52
|
+
Thus, we end up with the following interfaces.
|
|
53
|
+
|
|
54
|
+
| | Partial signers | Modifying signers | Sending signers |
|
|
55
|
+
| ------------------- | -------------------------- | ---------------------------- | -------------------------- |
|
|
56
|
+
| `TransactionSigner` | `TransactionPartialSigner` | `TransactionModifyingSigner` | `TransactionSendingSigner` |
|
|
57
|
+
| `MessageSigner` | `MessagePartialSigner` | `MessageModifyingSigner` | N/A |
|
|
58
|
+
|
|
59
|
+
We will go through each of these five signer interfaces and their respective characteristics in the documentation below.
|
|
60
|
+
|
|
61
|
+
This package also provides the following concrete signer implementations:
|
|
62
|
+
|
|
63
|
+
- The `KeyPairSigner` which uses a `CryptoKeyPair` to sign messages and transactions.
|
|
64
|
+
- The Noop signer which does not sign anything and is mostly useful for testing purposes or for indicating that an account will be signed in a different environment (e.g. sending a transaction to your server so it can sign it).
|
|
65
|
+
|
|
66
|
+
Additionally, this package allows transaction signers to be stored inside the account meta of an instruction. This allows us to create instructions by passing around signers instead of addresses when applicable which, in turn, allows us to sign an entire transaction automatically without having to scan through its instructions to find the required signers.
|
|
67
|
+
|
|
68
|
+
In the sections below, we'll go through all the provided signers in more detail before diving into storing signers inside instruction account metas and how to benefit from it.
|
|
69
|
+
|
|
70
|
+
## Signing messages
|
|
71
|
+
|
|
72
|
+
### Types
|
|
73
|
+
|
|
74
|
+
#### `SignableMessage`
|
|
75
|
+
|
|
76
|
+
Defines a message with any of the signatures that might have already been provided by other signers. This interface allows modifying signers to decide on whether or not they should modify the provided message depending on whether or not signatures already exist for such message. It also helps create a more consistent API by providing a structure analogous to transactions which also keep track of their signature dictionary.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
type SignableMessage = {
|
|
80
|
+
content: Uint8Array;
|
|
81
|
+
signatures: SignatureDictionary; // Record<Address, SignatureBytes>
|
|
82
|
+
};
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### `MessagePartialSigner<TAddress>`
|
|
86
|
+
|
|
87
|
+
An interface that signs an array of `SignableMessages` without modifying their content. It defines a `signMessages` function that returns a `SignatureDictionary` for each provided message. Such signature dictionaries are expected to be merged with the existing ones if any.
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const myMessagePartialSigner: MessagePartialSigner<'1234..5678'> = {
|
|
91
|
+
address: address('1234..5678'),
|
|
92
|
+
signMessages: async (messages: SignableMessage[]): Promise<SignatureDictionary[]> => {
|
|
93
|
+
// My custom signing logic.
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Characteristics**:
|
|
99
|
+
|
|
100
|
+
- **Parallel**. When multiple signers sign the same message, we can perform this operation in parallel to obtain all their signatures.
|
|
101
|
+
- **Flexible order**. The order in which we use these signers for a given message doesn’t matter.
|
|
102
|
+
|
|
103
|
+
#### `MessageModifyingSigner<TAddress>`
|
|
104
|
+
|
|
105
|
+
An interface that potentially modifies the content of the provided `SignableMessages` before signing them. E.g. this enables wallets to prefix or suffix nonces to the messages they sign. For each message, instead of returning a `SignatureDirectory`, its `modifyAndSignMessages` function returns its updated `SignableMessage` with a potentially modified content and signature dictionary.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const myMessageModifyingSigner: MessageModifyingSigner<'1234..5678'> = {
|
|
109
|
+
address: address('1234..5678'),
|
|
110
|
+
modifyAndSignMessages: async (messages: SignableMessage[]): Promise<SignableMessage[]> => {
|
|
111
|
+
// My custom signing logic.
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Characteristics**:
|
|
117
|
+
|
|
118
|
+
- **Sequential**. Contrary to partial signers, these cannot be executed in parallel as each call can modify the content of the message.
|
|
119
|
+
- **First signers**. For a given message, a modifying signer must always be used before a partial signer as the former will likely modify the message and thus impact the outcome of the latter.
|
|
120
|
+
- **Potential conflicts**. If more than one modifying signer is provided, the second signer may invalidate the signature of the first one. However, modifying signers may decide not to modify a message based on the existence of signatures for that message.
|
|
121
|
+
|
|
122
|
+
#### `MessageSigner<TAddress>`
|
|
123
|
+
|
|
124
|
+
Union interface that uses any of the available message signers.
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
type MessageSigner<TAddress extends string = string> =
|
|
128
|
+
| MessagePartialSigner<TAddress>
|
|
129
|
+
| MessageModifyingSigner<TAddress>;
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Functions
|
|
133
|
+
|
|
134
|
+
#### `createSignableMessage(content, signatures?)`
|
|
135
|
+
|
|
136
|
+
Creates a `SignableMessage` from a `Uint8Array` or a UTF-8 string. It optionally accepts a signature dictionary if the message already contains signatures.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
const myMessage = createSignableMessage(new Uint8Array([1, 2, 3]));
|
|
140
|
+
const myMessageFromText = createSignableMessage('Hello world!');
|
|
141
|
+
const myMessageWithSignatures = createSignableMessage('Hello world!', {
|
|
142
|
+
'1234..5678': new Uint8Array([1, 2, 3]),
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### Type guards
|
|
147
|
+
|
|
148
|
+
Each of the message interfaces described above comes with two type guards that allow us to check whether or not a given value is a message signer of the requested type. One that returns a boolean and one that asserts by throwing an error if the provided value is not of the expected interface.
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
const myAddress = address('1234..5678');
|
|
152
|
+
|
|
153
|
+
isMessagePartialSigner({ address: myAddress, signMessages: async () => {} }); // ✅ true
|
|
154
|
+
isMessagePartialSigner({ address: myAddress }); // ❌ false
|
|
155
|
+
assertIsMessagePartialSigner({ address: myAddress, signMessages: async () => {} }); // ✅ void
|
|
156
|
+
assertIsMessagePartialSigner({ address: myAddress }); // ❌ Throws an error.
|
|
157
|
+
|
|
158
|
+
isMessageModifyingSigner({ address: myAddress, modifyAndSignMessages: async () => {} }); // ✅ true
|
|
159
|
+
isMessageModifyingSigner({ address: myAddress }); // ❌ false
|
|
160
|
+
assertIsMessageModifyingSigner({ address: myAddress, modifyAndSignMessages: async () => {} }); // ✅ void
|
|
161
|
+
assertIsMessageModifyingSigner({ address: myAddress }); // ❌ Throws an error.
|
|
162
|
+
|
|
163
|
+
isMessageSigner({ address: myAddress, signMessages: async () => {} }); // ✅ true
|
|
164
|
+
isMessageSigner({ address: myAddress, modifyAndSignMessages: async () => {} }); // ✅ true
|
|
165
|
+
assertIsMessageSigner({ address: myAddress, signMessages: async () => {} }); // ✅ void
|
|
166
|
+
assertIsMessageSigner({ address: myAddress, modifyAndSignMessages: async () => {} }); // ✅ void
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Signing transactions
|
|
170
|
+
|
|
171
|
+
### Types
|
|
172
|
+
|
|
173
|
+
#### `TransactionPartialSigner<TAddress>`
|
|
174
|
+
|
|
175
|
+
An interface that signs an array of `CompilableTransactions` without modifying their content. It defines a `signTransactions` function that returns a `SignatureDictionary` for each provided transaction. Such signature dictionaries are expected to be merged with the existing ones if any.
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
const myTransactionPartialSigner: TransactionPartialSigner<'1234..5678'> = {
|
|
179
|
+
address: address('1234..5678'),
|
|
180
|
+
signTransactions: async (transactions: CompilableTransaction[]): Promise<SignatureDictionary[]> => {
|
|
181
|
+
// My custom signing logic.
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Characteristics**:
|
|
187
|
+
|
|
188
|
+
- **Parallel**. It returns a signature directory for each provided transaction without modifying them, making it possible for multiple partial signers to sign the same transaction in parallel.
|
|
189
|
+
- **Flexible order**. The order in which we use these signers for a given transaction doesn’t matter.
|
|
190
|
+
|
|
191
|
+
#### `TransactionModifyingSigner<TAddress>`
|
|
192
|
+
|
|
193
|
+
An interface that potentially modifies the provided `CompilableTransactions` before signing them. E.g. this enables wallets to inject additional instructions into the transaction before signing them. For each transaction, instead of returning a `SignatureDirectory`, its `modifyAndSignTransactions` function returns an updated `CompilableTransaction` with a potentially modified set of instructions and signature dictionary.
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
const myTransactionModifyingSigner: TransactionModifyingSigner<'1234..5678'> = {
|
|
197
|
+
address: address('1234..5678'),
|
|
198
|
+
modifyAndSignTransactions: async <T extends CompilableTransaction>(transactions: T[]): Promise<T[]> => {
|
|
199
|
+
// My custom signing logic.
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Characteristics**:
|
|
205
|
+
|
|
206
|
+
- **Sequential**. Contrary to partial signers, these cannot be executed in parallel as each call can modify the provided transactions.
|
|
207
|
+
- **First signers**. For a given transaction, a modifying signer must always be used before a partial signer as the former will likely modify the transaction and thus impact the outcome of the latter.
|
|
208
|
+
- **Potential conflicts**. If more than one modifying signer is provided, the second signer may invalidate the signature of the first one. However, modifying signers may decide not to modify a transaction based on the existence of signatures for that transaction.
|
|
209
|
+
|
|
210
|
+
#### `TransactionSendingSigner<TAddress>`
|
|
211
|
+
|
|
212
|
+
An interface that signs one or multiple transactions before sending them immediately to the blockchain. It defines a `signAndSendTransactions` function that returns the transaction signature (i.e. its identifier) for each provided `CompilableTransaction`. This interface is required for PDA wallets and other types of wallets that don't provide an interface for signing transactions without sending them.
|
|
213
|
+
|
|
214
|
+
Note that it is also possible for such signers to modify the provided transactions before signing and sending them. This enables use cases where the modified transactions cannot be shared with the app and thus must be sent directly.
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
const myTransactionSendingSigner: TransactionSendingSigner<'1234..5678'> = {
|
|
218
|
+
address: address('1234..5678'),
|
|
219
|
+
signAndSendTransactions: async (transactions: CompilableTransaction[]): Promise<SignatureBytes[]> => {
|
|
220
|
+
// My custom signing logic.
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Characteristics**:
|
|
226
|
+
|
|
227
|
+
- **Single signer**. Since this signer also sends the provided transactions, we can only use a single `TransactionSendingSigner` for a given set of transactions.
|
|
228
|
+
- **Last signer**. Trivially, that signer must also be the last one used.
|
|
229
|
+
- **Potential conflicts**. Since signers may decide to modify the given transactions before sending them, they may invalidate previous signatures. However, signers may decide not to modify a transaction based on the existence of signatures for that transaction.
|
|
230
|
+
- **Potential confirmation**. Whilst this is not required by this interface, it is also worth noting that most wallets will also wait for the transaction to be confirmed (typically with a `confirmed` commitment) before notifying the app that they are done.
|
|
231
|
+
|
|
232
|
+
#### `TransactionSigner<TAddress>`
|
|
233
|
+
|
|
234
|
+
Union interface that uses any of the available transaction signers.
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
type TransactionSigner<TAddress extends string = string> =
|
|
238
|
+
| TransactionPartialSigner<TAddress>
|
|
239
|
+
| TransactionModifyingSigner<TAddress>
|
|
240
|
+
| TransactionSendingSigner<TAddress>;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Functions
|
|
244
|
+
|
|
245
|
+
#### Type guards
|
|
246
|
+
|
|
247
|
+
Each of the transaction interfaces described above comes with two type guards that allow us to check whether or not a given value is a transaction signer of the requested type. One that returns a boolean and one that asserts by throwing an error if the provided value is not of the expected interface.
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
const myAddress = address('1234..5678');
|
|
251
|
+
|
|
252
|
+
isTransactionPartialSigner({ address: myAddress, signTransactions: async () => {} }); // ✅ true
|
|
253
|
+
isTransactionPartialSigner({ address: myAddress }); // ❌ false
|
|
254
|
+
assertIsTransactionPartialSigner({ address: myAddress, signTransactions: async () => {} }); // ✅ void
|
|
255
|
+
assertIsTransactionPartialSigner({ address: myAddress }); // ❌ Throws an error.
|
|
256
|
+
|
|
257
|
+
isTransactionModifyingSigner({ address: myAddress, modifyAndSignTransactions: async () => {} }); // ✅ true
|
|
258
|
+
isTransactionModifyingSigner({ address: myAddress }); // ❌ false
|
|
259
|
+
assertIsTransactionModifyingSigner({ address: myAddress, modifyAndSignTransactions: async () => {} }); // ✅ void
|
|
260
|
+
assertIsTransactionModifyingSigner({ address: myAddress }); // ❌ Throws an error.
|
|
261
|
+
|
|
262
|
+
isTransactionSendingSigner({ address: myAddress, signAndSignTransaction: async () => {} }); // ✅ true
|
|
263
|
+
isTransactionSendingSigner({ address: myAddress }); // ❌ false
|
|
264
|
+
assertIsTransactionSendingSigner({ address: myAddress, signAndSignTransaction: async () => {} }); // ✅ void
|
|
265
|
+
assertIsTransactionSendingSigner({ address: myAddress }); // ❌ Throws an error.
|
|
266
|
+
|
|
267
|
+
isTransactionSigner({ address: myAddress, signTransactions: async () => {} }); // ✅ true
|
|
268
|
+
isTransactionSigner({ address: myAddress, modifyAndSignTransactions: async () => {} }); // ✅ true
|
|
269
|
+
isTransactionSigner({ address: myAddress, signAndSignTransaction: async () => {} }); // ✅ true
|
|
270
|
+
assertIsTransactionSigner({ address: myAddress, signTransactions: async () => {} }); // ✅ void
|
|
271
|
+
assertIsTransactionSigner({ address: myAddress, modifyAndSignTransactions: async () => {} }); // ✅ void
|
|
272
|
+
assertIsTransactionSigner({ address: myAddress, signAndSignTransaction: async () => {} }); // ✅ void
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Creating and generating KeyPair signers
|
|
276
|
+
|
|
277
|
+
### Types
|
|
278
|
+
|
|
279
|
+
#### `KeyPairSigner<TAddress>`
|
|
280
|
+
|
|
281
|
+
Defines a signer that uses a `CryptoKeyPair` to sign messages and transactions. It implements both the `MessagePartialSigner` and `TransactionPartialSigner` interfaces and keeps track of the `CryptoKeyPair` instance used to sign messages and transactions.
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import { generateKeyPairSigner } from '@solana/signers';
|
|
285
|
+
|
|
286
|
+
const myKeyPairSigner = generateKeyPairSigner();
|
|
287
|
+
myKeyPairSigner.address; // Address;
|
|
288
|
+
myKeyPairSigner.keyPair; // CryptoKeyPair;
|
|
289
|
+
const [myMessageSignatures] = await myKeyPairSigner.signMessages([myMessage]);
|
|
290
|
+
const [myTransactionSignatures] = await myKeyPairSigner.signTransactions([myTransaction]);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Functions
|
|
294
|
+
|
|
295
|
+
#### `createSignerFromKeyPair()`
|
|
296
|
+
|
|
297
|
+
Creates a `KeyPairSigner` from a provided Crypto KeyPair. The `signMessages` and `signTransactions` functions of the returned signer will use the private key of the provided key pair to sign messages and transactions. Note that both the `signMessages` and `signTransactions` implementations are parallelized, meaning that they will sign all provided messages and transactions in parallel.
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
import { generateKeyPair } from '@solana/keys';
|
|
301
|
+
import { createSignerFromKeyPair, KeyPairSigner } from '@solana/signers';
|
|
302
|
+
|
|
303
|
+
const myKeyPair: CryptoKeyPair = await generateKeyPair();
|
|
304
|
+
const myKeyPairSigner: KeyPairSigner = await createSignerFromKeyPair(myKeyPair);
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
#### `generateKeyPairSigner()`
|
|
308
|
+
|
|
309
|
+
A convenience function that generates a new Crypto KeyPair and immediately creates a `KeyPairSigner` from it.
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
import { generateKeyPairSigner } from '@solana/signers';
|
|
313
|
+
|
|
314
|
+
const myKeyPairSigner = await generateKeyPairSigner();
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
#### `isKeyPairSigner()`
|
|
318
|
+
|
|
319
|
+
A type guard that returns `true` if the provided value is a `KeyPairSigner`.
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
const myKeyPairSigner = await generateKeyPairSigner();
|
|
323
|
+
isKeyPairSigner(myKeyPairSigner); // ✅ true
|
|
324
|
+
isKeyPairSigner({ address: address('1234..5678') }); // ❌ false
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### `assertIsKeyPairSigner()`
|
|
328
|
+
|
|
329
|
+
A type guard that throws an error if the provided value is not a `KeyPairSigner`.
|
|
330
|
+
|
|
331
|
+
```ts
|
|
332
|
+
const myKeyPairSigner = await generateKeyPairSigner();
|
|
333
|
+
assertIsKeyPairSigner(myKeyPairSigner); // ✅ void
|
|
334
|
+
assertIsKeyPairSigner({ address: address('1234..5678') }); // ❌ Throws an error.
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Creating Noop signers
|
|
338
|
+
|
|
339
|
+
### Functions
|
|
340
|
+
|
|
341
|
+
#### `createNoopSigner()`
|
|
342
|
+
|
|
343
|
+
_Coming soon..._
|
|
344
|
+
|
|
345
|
+
Creates a Noop (No-Operation) signer from a given address. It will return an implementation of both the `MessagePartialSigner` and `TransactionPartialSigner` interfaces that do not sign anything. Namely, signing a transaction or a message will return an empty `SignatureDictionary`.
|
|
346
|
+
|
|
347
|
+
This signer may be useful:
|
|
348
|
+
|
|
349
|
+
- For testing purposes.
|
|
350
|
+
- For indicating that a given account is a signer and taking the responsibility to provide the signature for that account ourselves. For instance, if we need to send the transaction to a server that will sign it and send it for us.
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
import { createNoopSigner } from '@solana/signers';
|
|
354
|
+
|
|
355
|
+
const myAddress = address('1234..5678');
|
|
356
|
+
const myNoopSigner = createNoopSigner(myAddress);
|
|
357
|
+
// ^ MessagePartialSigner<'1234..5678'> & TransactionPartialSigner<'1234..5678'>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Storing transaction signers inside instruction account metas
|
|
361
|
+
|
|
362
|
+
### Types
|
|
363
|
+
|
|
364
|
+
_Coming soon..._
|
|
365
|
+
|
|
366
|
+
### Functions
|
|
367
|
+
|
|
368
|
+
_Coming soon..._
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var addresses = require('@solana/addresses');
|
|
4
|
+
var keys = require('@solana/keys');
|
|
5
|
+
var transactions = require('@solana/transactions');
|
|
6
|
+
|
|
7
|
+
// src/keypair-signer.ts
|
|
8
|
+
|
|
9
|
+
// src/message-partial-signer.ts
|
|
10
|
+
function isMessagePartialSigner(value) {
|
|
11
|
+
return "signMessages" in value && typeof value.signMessages === "function";
|
|
12
|
+
}
|
|
13
|
+
function assertIsMessagePartialSigner(value) {
|
|
14
|
+
if (!isMessagePartialSigner(value)) {
|
|
15
|
+
throw new Error("The provided value does not implement the MessagePartialSigner interface");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// src/transaction-partial-signer.ts
|
|
20
|
+
function isTransactionPartialSigner(value) {
|
|
21
|
+
return "signTransactions" in value && typeof value.signTransactions === "function";
|
|
22
|
+
}
|
|
23
|
+
function assertIsTransactionPartialSigner(value) {
|
|
24
|
+
if (!isTransactionPartialSigner(value)) {
|
|
25
|
+
throw new Error("The provided value does not implement the TransactionPartialSigner interface");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// src/keypair-signer.ts
|
|
30
|
+
function isKeyPairSigner(value) {
|
|
31
|
+
return "keyPair" in value && typeof value.keyPair === "object" && isMessagePartialSigner(value) && isTransactionPartialSigner(value);
|
|
32
|
+
}
|
|
33
|
+
function assertIsKeyPairSigner(value) {
|
|
34
|
+
if (!isKeyPairSigner(value)) {
|
|
35
|
+
throw new Error("The provided value does not implement the KeyPairSigner interface");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function createSignerFromKeyPair(keyPair) {
|
|
39
|
+
const address = await addresses.getAddressFromPublicKey(keyPair.publicKey);
|
|
40
|
+
const out = {
|
|
41
|
+
address,
|
|
42
|
+
keyPair,
|
|
43
|
+
signMessages: (messages) => Promise.all(
|
|
44
|
+
messages.map(
|
|
45
|
+
async (message) => Object.freeze({ [address]: await keys.signBytes(keyPair.privateKey, message.content) })
|
|
46
|
+
)
|
|
47
|
+
),
|
|
48
|
+
signTransactions: (transactions$1) => Promise.all(
|
|
49
|
+
transactions$1.map(async (transaction) => {
|
|
50
|
+
const signedTransaction = await transactions.partiallySignTransaction([keyPair], transaction);
|
|
51
|
+
return Object.freeze({ [address]: signedTransaction.signatures[address] });
|
|
52
|
+
})
|
|
53
|
+
)
|
|
54
|
+
};
|
|
55
|
+
return Object.freeze(out);
|
|
56
|
+
}
|
|
57
|
+
async function generateKeyPairSigner() {
|
|
58
|
+
return createSignerFromKeyPair(await keys.generateKeyPair());
|
|
59
|
+
}
|
|
60
|
+
function isMessageModifyingSigner(value) {
|
|
61
|
+
return addresses.isAddress(value.address) && "modifyAndSignMessages" in value && typeof value.modifyAndSignMessages === "function";
|
|
62
|
+
}
|
|
63
|
+
function assertIsMessageModifyingSigner(value) {
|
|
64
|
+
if (!isMessageModifyingSigner(value)) {
|
|
65
|
+
throw new Error("The provided value does not implement the MessageModifyingSigner interface");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/message-signer.ts
|
|
70
|
+
function isMessageSigner(value) {
|
|
71
|
+
return isMessagePartialSigner(value) || isMessageModifyingSigner(value);
|
|
72
|
+
}
|
|
73
|
+
function assertIsMessageSigner(value) {
|
|
74
|
+
if (!isMessageSigner(value)) {
|
|
75
|
+
throw new Error("The provided value does not implement any of the MessageSigner interfaces");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
var o = globalThis.TextEncoder;
|
|
79
|
+
|
|
80
|
+
// src/signable-message.ts
|
|
81
|
+
function createSignableMessage(content, signatures = {}) {
|
|
82
|
+
return Object.freeze({
|
|
83
|
+
content: typeof content === "string" ? new o().encode(content) : content,
|
|
84
|
+
signatures: Object.freeze({ ...signatures })
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/transaction-modifying-signer.ts
|
|
89
|
+
function isTransactionModifyingSigner(value) {
|
|
90
|
+
return "modifyAndSignTransactions" in value && typeof value.modifyAndSignTransactions === "function";
|
|
91
|
+
}
|
|
92
|
+
function assertIsTransactionModifyingSigner(value) {
|
|
93
|
+
if (!isTransactionModifyingSigner(value)) {
|
|
94
|
+
throw new Error("The provided value does not implement the TransactionModifyingSigner interface");
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/transaction-sending-signer.ts
|
|
99
|
+
function isTransactionSendingSigner(value) {
|
|
100
|
+
return "signAndSendTransactions" in value && typeof value.signAndSendTransactions === "function";
|
|
101
|
+
}
|
|
102
|
+
function assertIsTransactionSendingSigner(value) {
|
|
103
|
+
if (!isTransactionSendingSigner(value)) {
|
|
104
|
+
throw new Error("The provided value does not implement the TransactionSendingSigner interface");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/transaction-signer.ts
|
|
109
|
+
function isTransactionSigner(value) {
|
|
110
|
+
return isTransactionPartialSigner(value) || isTransactionModifyingSigner(value) || isTransactionSendingSigner(value);
|
|
111
|
+
}
|
|
112
|
+
function assertIsTransactionSigner(value) {
|
|
113
|
+
if (!isTransactionSigner(value)) {
|
|
114
|
+
throw new Error("The provided value does not implement any of the TransactionSigner interfaces");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
exports.assertIsKeyPairSigner = assertIsKeyPairSigner;
|
|
119
|
+
exports.assertIsMessageModifyingSigner = assertIsMessageModifyingSigner;
|
|
120
|
+
exports.assertIsMessagePartialSigner = assertIsMessagePartialSigner;
|
|
121
|
+
exports.assertIsMessageSigner = assertIsMessageSigner;
|
|
122
|
+
exports.assertIsTransactionModifyingSigner = assertIsTransactionModifyingSigner;
|
|
123
|
+
exports.assertIsTransactionPartialSigner = assertIsTransactionPartialSigner;
|
|
124
|
+
exports.assertIsTransactionSendingSigner = assertIsTransactionSendingSigner;
|
|
125
|
+
exports.assertIsTransactionSigner = assertIsTransactionSigner;
|
|
126
|
+
exports.createSignableMessage = createSignableMessage;
|
|
127
|
+
exports.createSignerFromKeyPair = createSignerFromKeyPair;
|
|
128
|
+
exports.generateKeyPairSigner = generateKeyPairSigner;
|
|
129
|
+
exports.isKeyPairSigner = isKeyPairSigner;
|
|
130
|
+
exports.isMessageModifyingSigner = isMessageModifyingSigner;
|
|
131
|
+
exports.isMessagePartialSigner = isMessagePartialSigner;
|
|
132
|
+
exports.isMessageSigner = isMessageSigner;
|
|
133
|
+
exports.isTransactionModifyingSigner = isTransactionModifyingSigner;
|
|
134
|
+
exports.isTransactionPartialSigner = isTransactionPartialSigner;
|
|
135
|
+
exports.isTransactionSendingSigner = isTransactionSendingSigner;
|
|
136
|
+
exports.isTransactionSigner = isTransactionSigner;
|
|
137
|
+
//# sourceMappingURL=out.js.map
|
|
138
|
+
//# sourceMappingURL=index.browser.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/keypair-signer.ts","../src/message-partial-signer.ts","../src/transaction-partial-signer.ts","../src/message-modifying-signer.ts","../src/message-signer.ts","../../text-encoding-impl/src/index.browser.ts","../src/signable-message.ts","../src/transaction-modifying-signer.ts","../src/transaction-sending-signer.ts","../src/transaction-signer.ts"],"names":["TextDecoder","TextEncoder"],"mappings":"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","sourcesContent":["import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { generateKeyPair, signBytes } from '@solana/keys';\nimport { partiallySignTransaction } from '@solana/transactions';\n\nimport { isMessagePartialSigner, MessagePartialSigner } from './message-partial-signer';\nimport { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer';\n\n/** Defines a signer capable of signing messages and transactions using a CryptoKeyPair. */\nexport type KeyPairSigner<TAddress extends string = string> = MessagePartialSigner<TAddress> &\n TransactionPartialSigner<TAddress> & { keyPair: CryptoKeyPair };\n\n/** Checks whether the provided value implements the {@link KeyPairSigner} interface. */\nexport function isKeyPairSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): value is KeyPairSigner<TAddress> {\n return (\n 'keyPair' in value &&\n typeof value.keyPair === 'object' &&\n isMessagePartialSigner(value) &&\n isTransactionPartialSigner(value)\n );\n}\n\n/** Asserts that the provided value implements the {@link KeyPairSigner} interface. */\nexport function assertIsKeyPairSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): asserts value is KeyPairSigner<TAddress> {\n if (!isKeyPairSigner(value)) {\n // TODO: Coded error.\n throw new Error('The provided value does not implement the KeyPairSigner interface');\n }\n}\n\n/** Creates a KeyPairSigner from the provided Crypto KeyPair. */\nexport async function createSignerFromKeyPair(keyPair: CryptoKeyPair): Promise<KeyPairSigner> {\n const address = await getAddressFromPublicKey(keyPair.publicKey);\n const out: KeyPairSigner = {\n address,\n keyPair,\n signMessages: messages =>\n Promise.all(\n messages.map(async message =>\n Object.freeze({ [address]: await signBytes(keyPair.privateKey, message.content) })\n )\n ),\n signTransactions: transactions =>\n Promise.all(\n transactions.map(async transaction => {\n const signedTransaction = await partiallySignTransaction([keyPair], transaction);\n return Object.freeze({ [address]: signedTransaction.signatures[address] });\n })\n ),\n };\n\n return Object.freeze(out);\n}\n\n/** Securely generates a signer capable of signing messages and transactions using a Crypto KeyPair. */\nexport async function generateKeyPairSigner(): Promise<KeyPairSigner> {\n return createSignerFromKeyPair(await generateKeyPair());\n}\n","import { Address } from '@solana/addresses';\n\nimport { SignableMessage } from './signable-message';\nimport { SignatureDictionary } from './types';\n\n/** Defines a signer capable of signing messages. */\nexport type MessagePartialSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n signMessages(messages: readonly SignableMessage[]): Promise<readonly SignatureDictionary[]>;\n}>;\n\n/** Checks whether the provided value implements the {@link MessagePartialSigner} interface. */\nexport function isMessagePartialSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): value is MessagePartialSigner<TAddress> {\n return 'signMessages' in value && typeof value.signMessages === 'function';\n}\n\n/** Asserts that the provided value implements the {@link MessagePartialSigner} interface. */\nexport function assertIsMessagePartialSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): asserts value is MessagePartialSigner<TAddress> {\n if (!isMessagePartialSigner(value)) {\n // TODO: Coded error.\n throw new Error('The provided value does not implement the MessagePartialSigner interface');\n }\n}\n","import { Address } from '@solana/addresses';\nimport { CompilableTransaction } from '@solana/transactions';\n\nimport { SignatureDictionary } from './types';\n\n/** Defines a signer capable of signing transactions. */\nexport type TransactionPartialSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n signTransactions(transactions: readonly CompilableTransaction[]): Promise<readonly SignatureDictionary[]>;\n}>;\n\n/** Checks whether the provided value implements the {@link TransactionPartialSigner} interface. */\nexport function isTransactionPartialSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): value is TransactionPartialSigner<TAddress> {\n return 'signTransactions' in value && typeof value.signTransactions === 'function';\n}\n\n/** Asserts that the provided value implements the {@link TransactionPartialSigner} interface. */\nexport function assertIsTransactionPartialSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): asserts value is TransactionPartialSigner<TAddress> {\n if (!isTransactionPartialSigner(value)) {\n // TODO: Coded error.\n throw new Error('The provided value does not implement the TransactionPartialSigner interface');\n }\n}\n","import { Address, isAddress } from '@solana/addresses';\n\nimport { SignableMessage } from './signable-message';\n\n/** Defines a signer capable of signing messages. */\nexport type MessageModifyingSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n modifyAndSignMessages(messages: readonly SignableMessage[]): Promise<readonly SignableMessage[]>;\n}>;\n\n/** Checks whether the provided value implements the {@link MessageModifyingSigner} interface. */\nexport function isMessageModifyingSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): value is MessageModifyingSigner<TAddress> {\n return (\n isAddress(value.address) &&\n 'modifyAndSignMessages' in value &&\n typeof value.modifyAndSignMessages === 'function'\n );\n}\n\n/** Asserts that the provided value implements the {@link MessageModifyingSigner} interface. */\nexport function assertIsMessageModifyingSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): asserts value is MessageModifyingSigner<TAddress> {\n if (!isMessageModifyingSigner(value)) {\n // TODO: Coded error.\n throw new Error('The provided value does not implement the MessageModifyingSigner interface');\n }\n}\n","import { Address } from '@solana/addresses';\n\nimport { isMessageModifyingSigner, MessageModifyingSigner } from './message-modifying-signer';\nimport { isMessagePartialSigner, MessagePartialSigner } from './message-partial-signer';\n\n/** Defines a signer capable of signing messages. */\nexport type MessageSigner<TAddress extends string = string> =\n | MessagePartialSigner<TAddress>\n | MessageModifyingSigner<TAddress>;\n\n/** Checks whether the provided value implements the {@link MessageSigner} interface. */\nexport function isMessageSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): value is MessageSigner<TAddress> {\n return isMessagePartialSigner(value) || isMessageModifyingSigner(value);\n}\n\n/** Asserts that the provided value implements the {@link MessageSigner} interface. */\nexport function assertIsMessageSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): asserts value is MessageSigner<TAddress> {\n if (!isMessageSigner(value)) {\n // TODO: Coded error.\n throw new Error('The provided value does not implement any of the MessageSigner interfaces');\n }\n}\n","export const TextDecoder = globalThis.TextDecoder;\nexport const TextEncoder = globalThis.TextEncoder;\n","import { TextEncoder } from 'text-encoding-impl';\n\nimport { SignatureDictionary } from './types';\n\n/** Defines a message that needs signing and its current set of signatures if any. */\nexport type SignableMessage = Readonly<{\n content: Uint8Array;\n signatures: SignatureDictionary;\n}>;\n\n/**\n * Creates a signable message from a provided content.\n * If a string is provided, it will be UTF-8 encoded.\n */\nexport function createSignableMessage(\n content: string | Uint8Array,\n signatures: SignatureDictionary = {}\n): SignableMessage {\n return Object.freeze({\n content: typeof content === 'string' ? new TextEncoder().encode(content) : content,\n signatures: Object.freeze({ ...signatures }),\n });\n}\n","import { Address } from '@solana/addresses';\nimport { CompilableTransaction } from '@solana/transactions';\n\n/** Defines a signer capable of signing transactions. */\nexport type TransactionModifyingSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n modifyAndSignTransactions<TTransaction extends CompilableTransaction>(\n transactions: readonly TTransaction[]\n ): Promise<readonly TTransaction[]>;\n}>;\n\n/** Checks whether the provided value implements the {@link TransactionModifyingSigner} interface. */\nexport function isTransactionModifyingSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): value is TransactionModifyingSigner<TAddress> {\n return 'modifyAndSignTransactions' in value && typeof value.modifyAndSignTransactions === 'function';\n}\n\n/** Asserts that the provided value implements the {@link TransactionModifyingSigner} interface. */\nexport function assertIsTransactionModifyingSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): asserts value is TransactionModifyingSigner<TAddress> {\n if (!isTransactionModifyingSigner(value)) {\n // TODO: Coded error.\n throw new Error('The provided value does not implement the TransactionModifyingSigner interface');\n }\n}\n","import { Address } from '@solana/addresses';\nimport { SignatureBytes } from '@solana/keys';\nimport { CompilableTransaction } from '@solana/transactions';\n\n/** Defines a signer capable of signing and sending transactions simultaneously. */\nexport type TransactionSendingSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n signAndSendTransactions(transactions: readonly CompilableTransaction[]): Promise<readonly SignatureBytes[]>;\n}>;\n\n/** Checks whether the provided value implements the {@link TransactionSendingSigner} interface. */\nexport function isTransactionSendingSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): value is TransactionSendingSigner<TAddress> {\n return 'signAndSendTransactions' in value && typeof value.signAndSendTransactions === 'function';\n}\n\n/** Asserts that the provided value implements the {@link TransactionSendingSigner} interface. */\nexport function assertIsTransactionSendingSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): asserts value is TransactionSendingSigner<TAddress> {\n if (!isTransactionSendingSigner(value)) {\n // TODO: Coded error.\n throw new Error('The provided value does not implement the TransactionSendingSigner interface');\n }\n}\n","import { Address } from '@solana/addresses';\n\nimport { isTransactionModifyingSigner, TransactionModifyingSigner } from './transaction-modifying-signer';\nimport { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer';\nimport { isTransactionSendingSigner, TransactionSendingSigner } from './transaction-sending-signer';\n\n/** Defines a signer capable of signing transactions. */\nexport type TransactionSigner<TAddress extends string = string> =\n | TransactionPartialSigner<TAddress>\n | TransactionModifyingSigner<TAddress>\n | TransactionSendingSigner<TAddress>;\n\n/** Checks whether the provided value implements the {@link TransactionSigner} interface. */\nexport function isTransactionSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): value is TransactionSigner<TAddress> {\n return (\n isTransactionPartialSigner(value) || isTransactionModifyingSigner(value) || isTransactionSendingSigner(value)\n );\n}\n\n/** Asserts that the provided value implements the {@link TransactionSigner} interface. */\nexport function assertIsTransactionSigner<TAddress extends string>(value: {\n address: Address<TAddress>;\n [key: string]: unknown;\n}): asserts value is TransactionSigner<TAddress> {\n if (!isTransactionSigner(value)) {\n // TODO: Coded error.\n throw new Error('The provided value does not implement any of the TransactionSigner interfaces');\n }\n}\n"]}
|