@solana/signers 2.0.0-experimental.af584fc → 2.0.0-experimental.d085c72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -16
- package/dist/index.browser.cjs +45 -4
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +43 -5
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +58 -13
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +43 -7
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +45 -6
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +43 -5
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +23 -20
- package/dist/types/account-signer-meta.d.ts +6 -4
- package/dist/types/account-signer-meta.d.ts.map +1 -0
- package/dist/types/add-signers.d.ts +9 -0
- package/dist/types/add-signers.d.ts.map +1 -0
- package/dist/types/deduplicate-signers.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/keypair-signer.d.ts.map +1 -0
- package/dist/types/message-modifying-signer.d.ts.map +1 -0
- package/dist/types/message-partial-signer.d.ts.map +1 -0
- package/dist/types/message-signer.d.ts.map +1 -0
- package/dist/types/noop-signer.d.ts +8 -0
- package/dist/types/noop-signer.d.ts.map +1 -0
- package/dist/types/sign-transaction.d.ts +3 -7
- package/dist/types/sign-transaction.d.ts.map +1 -0
- package/dist/types/signable-message.d.ts.map +1 -0
- package/dist/types/transaction-modifying-signer.d.ts.map +1 -0
- package/dist/types/transaction-partial-signer.d.ts.map +1 -0
- package/dist/types/transaction-sending-signer.d.ts.map +1 -0
- package/dist/types/transaction-signer.d.ts.map +1 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -336,25 +336,37 @@ assertIsKeyPairSigner({ address: address('1234..5678') }); // ❌ Throws an erro
|
|
|
336
336
|
|
|
337
337
|
## Creating Noop signers
|
|
338
338
|
|
|
339
|
-
|
|
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`.
|
|
339
|
+
For a given address, a Noop (No-Operation) signer can be created to offer an implementation of both the `MessagePartialSigner` and `TransactionPartialSigner` interfaces such that they do not sign anything. Namely, signing a transaction or a message with a `NoopSigner` will return an empty `SignatureDictionary`.
|
|
346
340
|
|
|
347
341
|
This signer may be useful:
|
|
348
342
|
|
|
349
343
|
- For testing purposes.
|
|
350
344
|
- 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
345
|
|
|
346
|
+
### Types
|
|
347
|
+
|
|
348
|
+
#### `NoopSigner<TAddress>`
|
|
349
|
+
|
|
350
|
+
Defines a Noop (No-Operation) signer.
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
const myNoopSigner: NoopSigner;
|
|
354
|
+
myNoopSigner satisfies MessagePartialSigner;
|
|
355
|
+
myNoopSigner satisfies TransactionPartialSigner;
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Functions
|
|
359
|
+
|
|
360
|
+
#### `createNoopSigner()`
|
|
361
|
+
|
|
362
|
+
Creates a Noop (No-Operation) signer from a given address.
|
|
363
|
+
|
|
352
364
|
```ts
|
|
353
365
|
import { createNoopSigner } from '@solana/signers';
|
|
354
366
|
|
|
355
|
-
const
|
|
356
|
-
const
|
|
357
|
-
//
|
|
367
|
+
const myNoopSigner = createNoopSigner(address('1234..5678'));
|
|
368
|
+
const [myMessageSignatures] = await myNoopSigner.signMessages([myMessage]); // <- Empty signature dictionary.
|
|
369
|
+
const [myTransactionSignatures] = await myNoopSigner.signTransactions([myTransaction]); // <- Empty signature dictionary.
|
|
358
370
|
```
|
|
359
371
|
|
|
360
372
|
## Storing transaction signers inside instruction account metas
|
|
@@ -379,10 +391,10 @@ const mySignerMeta: IAccountSignerMeta = {
|
|
|
379
391
|
|
|
380
392
|
#### `IInstructionWithSigners`
|
|
381
393
|
|
|
382
|
-
|
|
394
|
+
Composable type that allows `IAccountSignerMetas` to be used inside the instruction's `accounts` array.
|
|
383
395
|
|
|
384
396
|
```ts
|
|
385
|
-
const myInstructionWithSigners: IInstructionWithSigners = {
|
|
397
|
+
const myInstructionWithSigners: IInstruction & IInstructionWithSigners = {
|
|
386
398
|
programAddress: address('1234..5678'),
|
|
387
399
|
accounts: [
|
|
388
400
|
{
|
|
@@ -394,6 +406,21 @@ const myInstructionWithSigners: IInstructionWithSigners = {
|
|
|
394
406
|
};
|
|
395
407
|
```
|
|
396
408
|
|
|
409
|
+
#### `ITransactionWithSigners`
|
|
410
|
+
|
|
411
|
+
Composable type that allows `IAccountSignerMetas` to be used inside all of the transaction's account metas.
|
|
412
|
+
|
|
413
|
+
```ts
|
|
414
|
+
const myTransactionWithSigners: BaseTransaction & ITransactionWithSigners = {
|
|
415
|
+
instructions: [
|
|
416
|
+
myInstructionA as IInstruction & IInstructionWithSigners,
|
|
417
|
+
myInstructionB as IInstruction & IInstructionWithSigners,
|
|
418
|
+
myInstructionC as IInstruction,
|
|
419
|
+
],
|
|
420
|
+
version: 0,
|
|
421
|
+
};
|
|
422
|
+
```
|
|
423
|
+
|
|
397
424
|
### Functions
|
|
398
425
|
|
|
399
426
|
#### `getSignersFromInstruction()`
|
|
@@ -424,6 +451,39 @@ Similarly to `getSignersFromInstruction`, this function extracts and deduplicate
|
|
|
424
451
|
const transactionSigners = getSignersFromTransaction(myTransactionWithSigners);
|
|
425
452
|
```
|
|
426
453
|
|
|
454
|
+
#### `addSignersToInstruction()`
|
|
455
|
+
|
|
456
|
+
Helper function that adds the provided signers to any of the applicable account metas. For an account meta to match a provided signer it:
|
|
457
|
+
|
|
458
|
+
- Must have a signer role (`AccountRole.READONLY_SIGNER` or `AccountRole.WRITABLE_SIGNER`).
|
|
459
|
+
- Must have the same address as the provided signer.
|
|
460
|
+
- Must not have an attached signer already.
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
const myInstruction: IInstruction = {
|
|
464
|
+
accounts: [
|
|
465
|
+
{ address: '1111' as Address, role: AccountRole.READONLY_SIGNER },
|
|
466
|
+
{ address: '2222' as Address, role: AccountRole.WRITABLE_SIGNER },
|
|
467
|
+
],
|
|
468
|
+
// ...
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
const signerA: TransactionSigner<'1111'>;
|
|
472
|
+
const signerB: TransactionSigner<'2222'>;
|
|
473
|
+
const myInstructionWithSigners = addSignersToInstruction([mySignerA, mySignerB], myInstruction);
|
|
474
|
+
|
|
475
|
+
// myInstructionWithSigners.accounts[0].signer === mySignerA
|
|
476
|
+
// myInstructionWithSigners.accounts[1].signer === mySignerB
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
#### `addSignersToTransaction()`
|
|
480
|
+
|
|
481
|
+
Similarly to `addSignersToInstruction`, this function adds signer to all the applicable account metas of all the instructions inside a transaction.
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
const myTransactionWithSigners = addSignersToTransaction(mySigners, myTransaction);
|
|
485
|
+
```
|
|
486
|
+
|
|
427
487
|
## Signing transactions with signers
|
|
428
488
|
|
|
429
489
|
As we've seen in the previous section, we can store and extract `TransactionSigners` from instructions and transactions. This allows us to provide helper methods that sign transactions using the signers stored inside them.
|
|
@@ -440,12 +500,11 @@ If a composite signer implements both interfaces, it will be used as a modifying
|
|
|
440
500
|
const mySignedTransaction = partiallySignTransactionWithSigners(myTransaction);
|
|
441
501
|
```
|
|
442
502
|
|
|
443
|
-
It also accepts an optional `AbortSignal`
|
|
503
|
+
It also accepts an optional `AbortSignal` that will be propagated to all signers.
|
|
444
504
|
|
|
445
505
|
```ts
|
|
446
506
|
const mySignedTransaction = partiallySignTransactionWithSigners(myTransaction, {
|
|
447
507
|
abortSignal: myAbortController.signal,
|
|
448
|
-
signers: [myOtherSigner],
|
|
449
508
|
});
|
|
450
509
|
```
|
|
451
510
|
|
|
@@ -461,7 +520,6 @@ const mySignedTransaction = signTransactionWithSigners(myTransaction);
|
|
|
461
520
|
// With additional config.
|
|
462
521
|
const mySignedTransaction = signTransactionWithSigners(myTransaction, {
|
|
463
522
|
abortSignal: myAbortController.signal,
|
|
464
|
-
signers: [myOtherSigner],
|
|
465
523
|
});
|
|
466
524
|
|
|
467
525
|
// We now know the transaction is fully signed.
|
|
@@ -478,7 +536,6 @@ const myTransactionSignature = signAndSendTransactionWithSigners(myTransaction);
|
|
|
478
536
|
// With additional config.
|
|
479
537
|
const myTransactionSignature = signAndSendTransactionWithSigners(myTransaction, {
|
|
480
538
|
abortSignal: myAbortController.signal,
|
|
481
|
-
signers: [myOtherSigner],
|
|
482
539
|
});
|
|
483
540
|
```
|
|
484
541
|
|
package/dist/index.browser.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var instructions = require('@solana/instructions');
|
|
3
4
|
var addresses = require('@solana/addresses');
|
|
4
5
|
var keys = require('@solana/keys');
|
|
5
6
|
var transactions = require('@solana/transactions');
|
|
@@ -10,6 +11,10 @@ function deduplicateSigners(signers) {
|
|
|
10
11
|
signers.forEach((signer) => {
|
|
11
12
|
if (!deduplicated[signer.address]) {
|
|
12
13
|
deduplicated[signer.address] = signer;
|
|
14
|
+
} else if (deduplicated[signer.address] !== signer) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`Multiple distinct signers were identified for address "${signer.address}". Please ensure that you are using the same signer instance for each address.`
|
|
17
|
+
);
|
|
13
18
|
}
|
|
14
19
|
});
|
|
15
20
|
return Object.values(deduplicated);
|
|
@@ -24,6 +29,31 @@ function getSignersFromInstruction(instruction) {
|
|
|
24
29
|
function getSignersFromTransaction(transaction) {
|
|
25
30
|
return deduplicateSigners(transaction.instructions.flatMap(getSignersFromInstruction));
|
|
26
31
|
}
|
|
32
|
+
function addSignersToInstruction(signers, instruction) {
|
|
33
|
+
if (!instruction.accounts || instruction.accounts.length === 0) {
|
|
34
|
+
return instruction;
|
|
35
|
+
}
|
|
36
|
+
const signerByAddress = new Map(deduplicateSigners(signers).map((signer) => [signer.address, signer]));
|
|
37
|
+
return Object.freeze({
|
|
38
|
+
...instruction,
|
|
39
|
+
accounts: instruction.accounts.map((account) => {
|
|
40
|
+
const signer = signerByAddress.get(account.address);
|
|
41
|
+
if (!instructions.isSignerRole(account.role) || "signer" in account || !signer) {
|
|
42
|
+
return account;
|
|
43
|
+
}
|
|
44
|
+
return Object.freeze({ ...account, signer });
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function addSignersToTransaction(signers, transaction) {
|
|
49
|
+
if (transaction.instructions.length === 0) {
|
|
50
|
+
return transaction;
|
|
51
|
+
}
|
|
52
|
+
return Object.freeze({
|
|
53
|
+
...transaction,
|
|
54
|
+
instructions: transaction.instructions.map((instruction) => addSignersToInstruction(signers, instruction))
|
|
55
|
+
});
|
|
56
|
+
}
|
|
27
57
|
|
|
28
58
|
// src/message-partial-signer.ts
|
|
29
59
|
function isMessagePartialSigner(value) {
|
|
@@ -95,6 +125,16 @@ function assertIsMessageSigner(value) {
|
|
|
95
125
|
}
|
|
96
126
|
}
|
|
97
127
|
|
|
128
|
+
// src/noop-signer.ts
|
|
129
|
+
function createNoopSigner(address) {
|
|
130
|
+
const out = {
|
|
131
|
+
address,
|
|
132
|
+
signMessages: async (messages) => messages.map(() => Object.freeze({})),
|
|
133
|
+
signTransactions: async (transactions) => transactions.map(() => Object.freeze({}))
|
|
134
|
+
};
|
|
135
|
+
return Object.freeze(out);
|
|
136
|
+
}
|
|
137
|
+
|
|
98
138
|
// src/transaction-modifying-signer.ts
|
|
99
139
|
function isTransactionModifyingSigner(value) {
|
|
100
140
|
return "modifyAndSignTransactions" in value && typeof value.modifyAndSignTransactions === "function";
|
|
@@ -127,9 +167,8 @@ function assertIsTransactionSigner(value) {
|
|
|
127
167
|
|
|
128
168
|
// src/sign-transaction.ts
|
|
129
169
|
async function partiallySignTransactionWithSigners(transaction, config = {}) {
|
|
130
|
-
const signers = config.signers ?? [];
|
|
131
170
|
const { partialSigners, modifyingSigners } = categorizeTransactionSigners(
|
|
132
|
-
deduplicateSigners(
|
|
171
|
+
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)),
|
|
133
172
|
{ identifySendingSigner: false }
|
|
134
173
|
);
|
|
135
174
|
return signModifyingAndPartialTransactionSigners(transaction, modifyingSigners, partialSigners, config.abortSignal);
|
|
@@ -140,10 +179,9 @@ async function signTransactionWithSigners(transaction, config = {}) {
|
|
|
140
179
|
return signedTransaction;
|
|
141
180
|
}
|
|
142
181
|
async function signAndSendTransactionWithSigners(transaction, config = {}) {
|
|
143
|
-
const signers = config.signers ?? [];
|
|
144
182
|
const abortSignal = config.abortSignal;
|
|
145
183
|
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners(
|
|
146
|
-
deduplicateSigners(
|
|
184
|
+
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner))
|
|
147
185
|
);
|
|
148
186
|
abortSignal?.throwIfAborted();
|
|
149
187
|
const signedTransaction = await signModifyingAndPartialTransactionSigners(
|
|
@@ -227,6 +265,8 @@ function createSignableMessage(content, signatures = {}) {
|
|
|
227
265
|
});
|
|
228
266
|
}
|
|
229
267
|
|
|
268
|
+
exports.addSignersToInstruction = addSignersToInstruction;
|
|
269
|
+
exports.addSignersToTransaction = addSignersToTransaction;
|
|
230
270
|
exports.assertIsKeyPairSigner = assertIsKeyPairSigner;
|
|
231
271
|
exports.assertIsMessageModifyingSigner = assertIsMessageModifyingSigner;
|
|
232
272
|
exports.assertIsMessagePartialSigner = assertIsMessagePartialSigner;
|
|
@@ -235,6 +275,7 @@ exports.assertIsTransactionModifyingSigner = assertIsTransactionModifyingSigner;
|
|
|
235
275
|
exports.assertIsTransactionPartialSigner = assertIsTransactionPartialSigner;
|
|
236
276
|
exports.assertIsTransactionSendingSigner = assertIsTransactionSendingSigner;
|
|
237
277
|
exports.assertIsTransactionSigner = assertIsTransactionSigner;
|
|
278
|
+
exports.createNoopSigner = createNoopSigner;
|
|
238
279
|
exports.createSignableMessage = createSignableMessage;
|
|
239
280
|
exports.createSignerFromKeyPair = createSignerFromKeyPair;
|
|
240
281
|
exports.generateKeyPairSigner = generateKeyPairSigner;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/deduplicate-signers.ts","../src/account-signer-meta.ts","../src/keypair-signer.ts","../src/message-partial-signer.ts","../src/transaction-partial-signer.ts","../src/message-modifying-signer.ts","../src/message-signer.ts","../src/sign-transaction.ts","../src/transaction-modifying-signer.ts","../src/transaction-sending-signer.ts","../src/transaction-signer.ts","../../text-encoding-impl/src/index.browser.ts","../src/signable-message.ts"],"names":["transaction","TextDecoder","TextEncoder"],"mappings":"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","sourcesContent":["import { Address } from '@solana/addresses';\n\nimport { MessageSigner } from './message-signer';\nimport { TransactionSigner } from './transaction-signer';\n\n/** Removes all duplicated signers from a provided array by comparing their addresses. */\nexport function deduplicateSigners<TSigner extends MessageSigner | TransactionSigner>(\n signers: readonly TSigner[]\n): readonly TSigner[] {\n const deduplicated: Record<Address, TSigner> = {};\n signers.forEach(signer => {\n if (!deduplicated[signer.address]) {\n deduplicated[signer.address] = signer;\n }\n });\n return Object.values(deduplicated);\n}\n","import { AccountRole, IAccountLookupMeta, IAccountMeta, IInstruction } from '@solana/instructions';\nimport { BaseTransaction, TransactionVersion } from '@solana/transactions';\n\nimport { deduplicateSigners } from './deduplicate-signers';\nimport { TransactionSigner } from './transaction-signer';\n\n/** An extension of the IAccountMeta type that keeps track of its transaction signer. */\nexport interface IAccountSignerMeta<\n TAddress extends string = string,\n TSigner extends TransactionSigner = TransactionSigner\n> extends IAccountMeta<TAddress> {\n readonly role: AccountRole.READONLY_SIGNER | AccountRole.WRITABLE_SIGNER;\n readonly signer: TSigner;\n}\n\n/** A variation of the IInstruction type that allows IAccountSignerMeta in its accounts array. */\ntype IAccountMetaWithWithSigner<TSigner extends TransactionSigner = TransactionSigner> =\n | IAccountMeta\n | IAccountLookupMeta\n | IAccountSignerMeta<string, TSigner>;\nexport type IInstructionWithSigners<\n TProgramAddress extends string = string,\n TSigner extends TransactionSigner = TransactionSigner,\n TAccounts extends readonly IAccountMetaWithWithSigner<TSigner>[] = readonly IAccountMetaWithWithSigner<TSigner>[]\n> = IInstruction<TProgramAddress, TAccounts>;\n\n/** Extract all signers from an instruction that may contain IAccountSignerMeta accounts. */\nexport function getSignersFromInstruction<TSigner extends TransactionSigner = TransactionSigner>(\n instruction: IInstructionWithSigners<string, TSigner>\n): readonly TSigner[] {\n return deduplicateSigners(\n (instruction.accounts ?? []).flatMap(account => ('signer' in account ? account.signer : []))\n );\n}\n\n/** Extract all signers from a transaction that may contain IAccountSignerMeta accounts. */\nexport function getSignersFromTransaction<\n TSigner extends TransactionSigner = TransactionSigner,\n TInstruction extends IInstructionWithSigners<string, TSigner> = IInstructionWithSigners<string, TSigner>\n>(transaction: BaseTransaction<TransactionVersion, TInstruction>): readonly TSigner[] {\n return deduplicateSigners(transaction.instructions.flatMap(getSignersFromInstruction));\n}\n","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 { BaseSignerConfig, SignatureDictionary } from './types';\n\nexport type MessagePartialSignerConfig = BaseSignerConfig;\n\n/** Defines a signer capable of signing messages. */\nexport type MessagePartialSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n signMessages(\n messages: readonly SignableMessage[],\n config?: MessagePartialSignerConfig\n ): 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 { BaseSignerConfig, SignatureDictionary } from './types';\n\nexport type TransactionPartialSignerConfig = BaseSignerConfig;\n\n/** Defines a signer capable of signing transactions. */\nexport type TransactionPartialSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n signTransactions(\n transactions: readonly CompilableTransaction[],\n config?: TransactionPartialSignerConfig\n ): 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';\nimport { BaseSignerConfig } from './types';\n\nexport type MessageModifyingSignerConfig = BaseSignerConfig;\n\n/** Defines a signer capable of signing messages. */\nexport type MessageModifyingSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n modifyAndSignMessages(\n messages: readonly SignableMessage[],\n config?: MessageModifyingSignerConfig\n ): 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","import { SignatureBytes } from '@solana/keys';\nimport {\n assertTransactionIsFullySigned,\n CompilableTransaction,\n IFullySignedTransaction,\n ITransactionWithSignatures,\n TransactionVersion,\n} from '@solana/transactions';\n\nimport { getSignersFromTransaction, IInstructionWithSigners } from './account-signer-meta';\nimport { deduplicateSigners } from './deduplicate-signers';\nimport { isTransactionModifyingSigner, TransactionModifyingSigner } from './transaction-modifying-signer';\nimport { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer';\nimport { isTransactionSendingSigner, TransactionSendingSigner } from './transaction-sending-signer';\nimport { isTransactionSigner, TransactionSigner } from './transaction-signer';\n\ntype CompilableTransactionWithSigners = CompilableTransaction<\n TransactionVersion,\n IInstructionWithSigners<string, TransactionSigner>\n> &\n Partial<ITransactionWithSignatures>;\n\n/**\n * Signs a transaction using any signers that may be stored in IAccountSignerMeta instruction accounts\n * as well as any signers provided explicitly to this function.\n * It will ignore TransactionSendingSigners since this function does not send the transaction.\n */\nexport async function partiallySignTransactionWithSigners<\n TTransaction extends CompilableTransactionWithSigners = CompilableTransactionWithSigners\n>(\n transaction: TTransaction,\n config: {\n abortSignal?: AbortSignal;\n signers?: readonly TransactionSigner[];\n } = {}\n): Promise<TTransaction & ITransactionWithSignatures> {\n const signers = config.signers ?? [];\n const { partialSigners, modifyingSigners } = categorizeTransactionSigners(\n deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers]),\n { identifySendingSigner: false }\n );\n\n return signModifyingAndPartialTransactionSigners(transaction, modifyingSigners, partialSigners, config.abortSignal);\n}\n\n/**\n * Signs a transaction using any signers that may be stored in IAccountSignerMeta instruction accounts\n * as well as any signers provided explicitly to this function.\n * It will assert that the transaction is fully signed before returning.\n * It will ignore TransactionSendingSigners since this function does not send the transaction.\n */\nexport async function signTransactionWithSigners<\n TTransaction extends CompilableTransactionWithSigners = CompilableTransactionWithSigners\n>(\n transaction: TTransaction,\n config: {\n abortSignal?: AbortSignal;\n signers?: readonly TransactionSigner[];\n } = {}\n): Promise<TTransaction & IFullySignedTransaction> {\n const signedTransaction = await partiallySignTransactionWithSigners(transaction, config);\n assertTransactionIsFullySigned(signedTransaction);\n return signedTransaction;\n}\n\n/**\n * Signs and sends a transaction using any signers that may be stored in IAccountSignerMeta\n * instruction accounts as well as any signers provided explicitly to this function.\n * It will identify a single TransactionSendingSigners to use for sending the transaction, if any.\n * Otherwise, it will send the transaction using the provided fallbackSender.\n */\nexport async function signAndSendTransactionWithSigners<\n TTransaction extends CompilableTransactionWithSigners = CompilableTransactionWithSigners\n>(\n transaction: TTransaction,\n config: {\n abortSignal?: AbortSignal;\n fallbackSender?: (transaction: TTransaction & IFullySignedTransaction) => Promise<SignatureBytes>;\n signers?: readonly TransactionSigner[];\n } = {}\n): Promise<SignatureBytes> {\n const signers = config.signers ?? [];\n const abortSignal = config.abortSignal;\n const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners(\n deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers])\n );\n\n abortSignal?.throwIfAborted();\n const signedTransaction = await signModifyingAndPartialTransactionSigners(\n transaction,\n modifyingSigners,\n partialSigners,\n abortSignal\n );\n\n if (sendingSigner) {\n abortSignal?.throwIfAborted();\n const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal });\n return signature;\n }\n\n if (config.fallbackSender) {\n assertTransactionIsFullySigned(signedTransaction);\n return config.fallbackSender(signedTransaction);\n }\n\n // TODO: Coded error.\n throw new Error('No TransactionSendingSigner was identified and no fallback sender was provided.');\n}\n\n/**\n * Identifies each provided TransactionSigner and categorizes them into their respective types.\n * When a signer implements multiple interface, it will try to used to most powerful interface\n * but fallback to the least powerful interface when necessary.\n * For instance, if a signer implements TransactionSendingSigner and TransactionModifyingSigner,\n * it will be categorized as a TransactionSendingSigner if and only if no other signers implement\n * the TransactionSendingSigner interface.\n */\nfunction categorizeTransactionSigners(\n signers: readonly TransactionSigner[],\n config: { identifySendingSigner?: boolean } = {}\n): Readonly<{\n modifyingSigners: readonly TransactionModifyingSigner[];\n partialSigners: readonly TransactionPartialSigner[];\n sendingSigner: TransactionSendingSigner | null;\n}> {\n // Identify the unique sending signer that should be used.\n const identifySendingSigner = config.identifySendingSigner ?? true;\n const sendingSigner = identifySendingSigner ? identifyTransactionSendingSigner(signers) : null;\n\n // Now, focus on the other signers.\n // I.e. the modifying or partial signers that are not the identified sending signer.\n // Note that any other sending only signers will be discarded.\n const otherSigners = signers.filter(\n (signer): signer is TransactionModifyingSigner | TransactionPartialSigner =>\n signer !== sendingSigner && (isTransactionModifyingSigner(signer) || isTransactionPartialSigner(signer))\n );\n\n // Identify the modifying signers from the other signers.\n const modifyingSigners = identifyTransactionModifyingSigners(otherSigners);\n\n // Use any remaining signers as partial signers.\n const partialSigners = otherSigners\n .filter(isTransactionPartialSigner)\n .filter(signer => !(modifyingSigners as typeof otherSigners).includes(signer));\n\n return Object.freeze({ modifyingSigners, partialSigners, sendingSigner });\n}\n\n/** Identifies the best signer to use as a TransactionSendingSigner, if any */\nfunction identifyTransactionSendingSigner(signers: readonly TransactionSigner[]): TransactionSendingSigner | null {\n // Ensure there are any TransactionSendingSigners in the first place.\n const sendingSigners = signers.filter(isTransactionSendingSigner);\n if (sendingSigners.length === 0) return null;\n\n // Prefer sending signers that do not offer other interfaces.\n const sendingOnlySigners = sendingSigners.filter(\n signer => !isTransactionModifyingSigner(signer) && !isTransactionPartialSigner(signer)\n );\n if (sendingOnlySigners.length > 0) {\n return sendingOnlySigners[0];\n }\n\n // Otherwise, choose any sending signer.\n return sendingSigners[0];\n}\n\n/** Identifies the best signers to use as TransactionModifyingSigners, if any */\nfunction identifyTransactionModifyingSigners(\n signers: readonly (TransactionModifyingSigner | TransactionPartialSigner)[]\n): readonly TransactionModifyingSigner[] {\n // Ensure there are any TransactionModifyingSigner in the first place.\n const modifyingSigners = signers.filter(isTransactionModifyingSigner);\n if (modifyingSigners.length === 0) return [];\n\n // Prefer modifying signers that do not offer partial signing.\n const nonPartialSigners = modifyingSigners.filter(signer => !isTransactionPartialSigner(signer));\n if (nonPartialSigners.length > 0) return nonPartialSigners;\n\n // Otherwise, choose only one modifying signer (whichever).\n return [modifyingSigners[0]];\n}\n\n/**\n * Signs a transaction using the provided TransactionModifyingSigners\n * sequentially followed by the TransactionPartialSigners in parallel.\n */\nasync function signModifyingAndPartialTransactionSigners<\n TTransaction extends CompilableTransactionWithSigners = CompilableTransactionWithSigners\n>(\n transaction: TTransaction,\n modifyingSigners: readonly TransactionModifyingSigner[] = [],\n partialSigners: readonly TransactionPartialSigner[] = [],\n abortSignal?: AbortSignal\n): Promise<TTransaction & ITransactionWithSignatures> {\n // Handle modifying signers sequentially.\n const modifiedTransaction = await modifyingSigners.reduce(async (transaction, modifyingSigner) => {\n abortSignal?.throwIfAborted();\n const [tx] = await modifyingSigner.modifyAndSignTransactions([await transaction], { abortSignal });\n return Object.freeze(tx);\n }, Promise.resolve(transaction) as Promise<TTransaction>);\n\n // Handle partial signers in parallel.\n abortSignal?.throwIfAborted();\n const signatureDictionaries = await Promise.all(\n partialSigners.map(async partialSigner => {\n const [signatures] = await partialSigner.signTransactions([modifiedTransaction], { abortSignal });\n return signatures;\n })\n );\n const signedTransaction: TTransaction & ITransactionWithSignatures = {\n ...modifiedTransaction,\n signatures: Object.freeze(\n signatureDictionaries.reduce((signatures, signatureDictionary) => {\n return { ...signatures, ...signatureDictionary };\n }, modifiedTransaction.signatures ?? {})\n ),\n };\n\n return Object.freeze(signedTransaction);\n}\n","import { Address } from '@solana/addresses';\nimport { CompilableTransaction } from '@solana/transactions';\n\nimport { BaseSignerConfig } from './types';\n\nexport type TransactionModifyingSignerConfig = BaseSignerConfig;\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 config?: TransactionModifyingSignerConfig\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\nimport { BaseSignerConfig } from './types';\n\nexport type TransactionSendingSignerConfig = BaseSignerConfig;\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(\n transactions: readonly CompilableTransaction[],\n config?: TransactionSendingSignerConfig\n ): 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","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"]}
|
|
1
|
+
{"version":3,"sources":["../src/deduplicate-signers.ts","../src/account-signer-meta.ts","../src/add-signers.ts","../src/keypair-signer.ts","../src/message-partial-signer.ts","../src/transaction-partial-signer.ts","../src/message-modifying-signer.ts","../src/message-signer.ts","../src/noop-signer.ts","../src/sign-transaction.ts","../src/transaction-modifying-signer.ts","../src/transaction-sending-signer.ts","../src/transaction-signer.ts","../../text-encoding-impl/src/index.browser.ts","../src/signable-message.ts"],"names":["transaction","TextDecoder","TextEncoder"],"mappings":";AAMO,SAAS,mBACZ,SACkB;AAClB,QAAM,eAAyC,CAAC;AAChD,UAAQ,QAAQ,YAAU;AACtB,QAAI,CAAC,aAAa,OAAO,OAAO,GAAG;AAC/B,mBAAa,OAAO,OAAO,IAAI;AAAA,IACnC,WAAW,aAAa,OAAO,OAAO,MAAM,QAAQ;AAEhD,YAAM,IAAI;AAAA,QACN,0DAA0D,OAAO,OAAO;AAAA,MAE5E;AAAA,IACJ;AAAA,EACJ,CAAC;AACD,SAAO,OAAO,OAAO,YAAY;AACrC;;;ACcO,SAAS,0BACZ,aACkB;AAClB,SAAO;AAAA,KACF,YAAY,YAAY,CAAC,GAAG,QAAQ,aAAY,YAAY,UAAU,QAAQ,SAAS,CAAC,CAAE;AAAA,EAC/F;AACJ;AAGO,SAAS,0BAGd,aAA+C;AAC7C,SAAO,mBAAmB,YAAY,aAAa,QAAQ,yBAAyB,CAAC;AACzF;;;AClDA,SAAuB,oBAAoB;AAQpC,SAAS,wBACZ,SACA,aACsC;AACtC,MAAI,CAAC,YAAY,YAAY,YAAY,SAAS,WAAW,GAAG;AAC5D,WAAO;AAAA,EACX;AAEA,QAAM,kBAAkB,IAAI,IAAI,mBAAmB,OAAO,EAAE,IAAI,YAAU,CAAC,OAAO,SAAS,MAAM,CAAC,CAAC;AACnG,SAAO,OAAO,OAAO;AAAA,IACjB,GAAG;AAAA,IACH,UAAU,YAAY,SAAS,IAAI,aAAW;AAC1C,YAAM,SAAS,gBAAgB,IAAI,QAAQ,OAAO;AAClD,UAAI,CAAC,aAAa,QAAQ,IAAI,KAAK,YAAY,WAAW,CAAC,QAAQ;AAC/D,eAAO;AAAA,MACX;AACA,aAAO,OAAO,OAAO,EAAE,GAAG,SAAS,OAAO,CAAuB;AAAA,IACrE,CAAC;AAAA,EACL,CAAC;AACL;AAGO,SAAS,wBACZ,SACA,aACsC;AACtC,MAAI,YAAY,aAAa,WAAW,GAAG;AACvC,WAAO;AAAA,EACX;AAEA,SAAO,OAAO,OAAO;AAAA,IACjB,GAAG;AAAA,IACH,cAAc,YAAY,aAAa,IAAI,iBAAe,wBAAwB,SAAS,WAAW,CAAC;AAAA,EAC3G,CAAC;AACL;;;AC1CA,SAAkB,+BAA+B;AACjD,SAAS,iBAAiB,iBAAiB;AAC3C,SAAS,gCAAgC;;;ACelC,SAAS,uBAAgD,OAGpB;AACxC,SAAO,kBAAkB,SAAS,OAAO,MAAM,iBAAiB;AACpE;AAGO,SAAS,6BAAsD,OAGlB;AAChD,MAAI,CAAC,uBAAuB,KAAK,GAAG;AAEhC,UAAM,IAAI,MAAM,0EAA0E;AAAA,EAC9F;AACJ;;;AChBO,SAAS,2BAAoD,OAGpB;AAC5C,SAAO,sBAAsB,SAAS,OAAO,MAAM,qBAAqB;AAC5E;AAGO,SAAS,iCAA0D,OAGlB;AACpD,MAAI,CAAC,2BAA2B,KAAK,GAAG;AAEpC,UAAM,IAAI,MAAM,8EAA8E;AAAA,EAClG;AACJ;;;AFrBO,SAAS,gBAAyC,OAGpB;AACjC,SACI,aAAa,SACb,OAAO,MAAM,YAAY,YACzB,uBAAuB,KAAK,KAC5B,2BAA2B,KAAK;AAExC;AAGO,SAAS,sBAA+C,OAGlB;AACzC,MAAI,CAAC,gBAAgB,KAAK,GAAG;AAEzB,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACvF;AACJ;AAGA,eAAsB,wBAAwB,SAAgD;AAC1F,QAAM,UAAU,MAAM,wBAAwB,QAAQ,SAAS;AAC/D,QAAM,MAAqB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,cAAc,cACV,QAAQ;AAAA,MACJ,SAAS;AAAA,QAAI,OAAM,YACf,OAAO,OAAO,EAAE,CAAC,OAAO,GAAG,MAAM,UAAU,QAAQ,YAAY,QAAQ,OAAO,EAAE,CAAC;AAAA,MACrF;AAAA,IACJ;AAAA,IACJ,kBAAkB,kBACd,QAAQ;AAAA,MACJ,aAAa,IAAI,OAAM,gBAAe;AAClC,cAAM,oBAAoB,MAAM,yBAAyB,CAAC,OAAO,GAAG,WAAW;AAC/E,eAAO,OAAO,OAAO,EAAE,CAAC,OAAO,GAAG,kBAAkB,WAAW,OAAO,EAAE,CAAC;AAAA,MAC7E,CAAC;AAAA,IACL;AAAA,EACR;AAEA,SAAO,OAAO,OAAO,GAAG;AAC5B;AAGA,eAAsB,wBAAgD;AAClE,SAAO,wBAAwB,MAAM,gBAAgB,CAAC;AAC1D;;;AG9DA,SAAkB,iBAAiB;AAiB5B,SAAS,yBAAkD,OAGpB;AAC1C,SACI,UAAU,MAAM,OAAO,KACvB,2BAA2B,SAC3B,OAAO,MAAM,0BAA0B;AAE/C;AAGO,SAAS,+BAAwD,OAGlB;AAClD,MAAI,CAAC,yBAAyB,KAAK,GAAG;AAElC,UAAM,IAAI,MAAM,4EAA4E;AAAA,EAChG;AACJ;;;AC1BO,SAAS,gBAAyC,OAGpB;AACjC,SAAO,uBAAuB,KAAK,KAAK,yBAAyB,KAAK;AAC1E;AAGO,SAAS,sBAA+C,OAGlB;AACzC,MAAI,CAAC,gBAAgB,KAAK,GAAG;AAEzB,UAAM,IAAI,MAAM,2EAA2E;AAAA,EAC/F;AACJ;;;ACjBO,SAAS,iBAAiB,SAA8B;AAC3D,QAAM,MAAkB;AAAA,IACpB;AAAA,IACA,cAAc,OAAM,aAAY,SAAS,IAAI,MAAM,OAAO,OAAO,CAAC,CAAC,CAAC;AAAA,IACpE,kBAAkB,OAAM,iBAAgB,aAAa,IAAI,MAAM,OAAO,OAAO,CAAC,CAAC,CAAC;AAAA,EACpF;AAEA,SAAO,OAAO,OAAO,GAAG;AAC5B;;;ACjBA;AAAA,EACI;AAAA,OAIG;;;ACWA,SAAS,6BAAsD,OAGpB;AAC9C,SAAO,+BAA+B,SAAS,OAAO,MAAM,8BAA8B;AAC9F;AAGO,SAAS,mCAA4D,OAGlB;AACtD,MAAI,CAAC,6BAA6B,KAAK,GAAG;AAEtC,UAAM,IAAI,MAAM,gFAAgF;AAAA,EACpG;AACJ;;;ACfO,SAAS,2BAAoD,OAGpB;AAC5C,SAAO,6BAA6B,SAAS,OAAO,MAAM,4BAA4B;AAC1F;AAGO,SAAS,iCAA0D,OAGlB;AACpD,MAAI,CAAC,2BAA2B,KAAK,GAAG;AAEpC,UAAM,IAAI,MAAM,8EAA8E;AAAA,EAClG;AACJ;;;ACrBO,SAAS,oBAA6C,OAGpB;AACrC,SACI,2BAA2B,KAAK,KAAK,6BAA6B,KAAK,KAAK,2BAA2B,KAAK;AAEpH;AAGO,SAAS,0BAAmD,OAGlB;AAC7C,MAAI,CAAC,oBAAoB,KAAK,GAAG;AAE7B,UAAM,IAAI,MAAM,+EAA+E;AAAA,EACnG;AACJ;;;AHPA,eAAsB,oCAGlB,aACA,SAAwC,CAAC,GACS;AAClD,QAAM,EAAE,gBAAgB,iBAAiB,IAAI;AAAA,IACzC,mBAAmB,0BAA0B,WAAW,EAAE,OAAO,mBAAmB,CAAC;AAAA,IACrF,EAAE,uBAAuB,MAAM;AAAA,EACnC;AAEA,SAAO,0CAA0C,aAAa,kBAAkB,gBAAgB,OAAO,WAAW;AACtH;AAQA,eAAsB,2BAGlB,aACA,SAAwC,CAAC,GACM;AAC/C,QAAM,oBAAoB,MAAM,oCAAoC,aAAa,MAAM;AACvF,iCAA+B,iBAAiB;AAChD,SAAO;AACX;AAQA,eAAsB,kCAGlB,aACA,SAGI,CAAC,GACkB;AACvB,QAAM,cAAc,OAAO;AAC3B,QAAM,EAAE,gBAAgB,kBAAkB,cAAc,IAAI;AAAA,IACxD,mBAAmB,0BAA0B,WAAW,EAAE,OAAO,mBAAmB,CAAC;AAAA,EACzF;AAEA,eAAa,eAAe;AAC5B,QAAM,oBAAoB,MAAM;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,MAAI,eAAe;AACf,iBAAa,eAAe;AAC5B,UAAM,CAAC,SAAS,IAAI,MAAM,cAAc,wBAAwB,CAAC,iBAAiB,GAAG,EAAE,YAAY,CAAC;AACpG,WAAO;AAAA,EACX;AAEA,MAAI,OAAO,gBAAgB;AACvB,mCAA+B,iBAAiB;AAChD,WAAO,OAAO,eAAe,iBAAiB;AAAA,EAClD;AAGA,QAAM,IAAI,MAAM,iFAAiF;AACrG;AAUA,SAAS,6BACL,SACA,SAA8C,CAAC,GAKhD;AAEC,QAAM,wBAAwB,OAAO,yBAAyB;AAC9D,QAAM,gBAAgB,wBAAwB,iCAAiC,OAAO,IAAI;AAK1F,QAAM,eAAe,QAAQ;AAAA,IACzB,CAAC,WACG,WAAW,kBAAkB,6BAA6B,MAAM,KAAK,2BAA2B,MAAM;AAAA,EAC9G;AAGA,QAAM,mBAAmB,oCAAoC,YAAY;AAGzE,QAAM,iBAAiB,aAClB,OAAO,0BAA0B,EACjC,OAAO,YAAU,CAAE,iBAAyC,SAAS,MAAM,CAAC;AAEjF,SAAO,OAAO,OAAO,EAAE,kBAAkB,gBAAgB,cAAc,CAAC;AAC5E;AAGA,SAAS,iCAAiC,SAAwE;AAE9G,QAAM,iBAAiB,QAAQ,OAAO,0BAA0B;AAChE,MAAI,eAAe,WAAW;AAAG,WAAO;AAGxC,QAAM,qBAAqB,eAAe;AAAA,IACtC,YAAU,CAAC,6BAA6B,MAAM,KAAK,CAAC,2BAA2B,MAAM;AAAA,EACzF;AACA,MAAI,mBAAmB,SAAS,GAAG;AAC/B,WAAO,mBAAmB,CAAC;AAAA,EAC/B;AAGA,SAAO,eAAe,CAAC;AAC3B;AAGA,SAAS,oCACL,SACqC;AAErC,QAAM,mBAAmB,QAAQ,OAAO,4BAA4B;AACpE,MAAI,iBAAiB,WAAW;AAAG,WAAO,CAAC;AAG3C,QAAM,oBAAoB,iBAAiB,OAAO,YAAU,CAAC,2BAA2B,MAAM,CAAC;AAC/F,MAAI,kBAAkB,SAAS;AAAG,WAAO;AAGzC,SAAO,CAAC,iBAAiB,CAAC,CAAC;AAC/B;AAMA,eAAe,0CAGX,aACA,mBAA0D,CAAC,GAC3D,iBAAsD,CAAC,GACvD,aACkD;AAElD,QAAM,sBAAsB,MAAM,iBAAiB,OAAO,OAAOA,cAAa,oBAAoB;AAC9F,iBAAa,eAAe;AAC5B,UAAM,CAAC,EAAE,IAAI,MAAM,gBAAgB,0BAA0B,CAAC,MAAMA,YAAW,GAAG,EAAE,YAAY,CAAC;AACjG,WAAO,OAAO,OAAO,EAAE;AAAA,EAC3B,GAAG,QAAQ,QAAQ,WAAW,CAA0B;AAGxD,eAAa,eAAe;AAC5B,QAAM,wBAAwB,MAAM,QAAQ;AAAA,IACxC,eAAe,IAAI,OAAM,kBAAiB;AACtC,YAAM,CAAC,UAAU,IAAI,MAAM,cAAc,iBAAiB,CAAC,mBAAmB,GAAG,EAAE,YAAY,CAAC;AAChG,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AACA,QAAM,oBAA+D;AAAA,IACjE,GAAG;AAAA,IACH,YAAY,OAAO;AAAA,MACf,sBAAsB,OAAO,CAAC,YAAY,wBAAwB;AAC9D,eAAO,EAAE,GAAG,YAAY,GAAG,oBAAoB;AAAA,MACnD,GAAG,oBAAoB,cAAc,CAAC,CAAC;AAAA,IAC3C;AAAA,EACJ;AAEA,SAAO,OAAO,OAAO,iBAAiB;AAC1C;;;AIhNO,IAAMC,IAAc,WAAW;AAA/B,IACMC,IAAc,WAAW;;;ACa/B,SAAS,sBACZ,SACA,aAAkC,CAAC,GACpB;AACf,SAAO,OAAO,OAAO;AAAA,IACjB,SAAS,OAAO,YAAY,WAAW,IAAI,EAAY,EAAE,OAAO,OAAO,IAAI;AAAA,IAC3E,YAAY,OAAO,OAAO,EAAE,GAAG,WAAW,CAAC;AAAA,EAC/C,CAAC;AACL","sourcesContent":["import { Address } from '@solana/addresses';\n\nimport { MessageSigner } from './message-signer';\nimport { TransactionSigner } from './transaction-signer';\n\n/** Removes all duplicated signers from a provided array by comparing their addresses. */\nexport function deduplicateSigners<TSigner extends MessageSigner | TransactionSigner>(\n signers: readonly TSigner[]\n): readonly TSigner[] {\n const deduplicated: Record<Address, TSigner> = {};\n signers.forEach(signer => {\n if (!deduplicated[signer.address]) {\n deduplicated[signer.address] = signer;\n } else if (deduplicated[signer.address] !== signer) {\n // TODO: Coded error.\n throw new Error(\n `Multiple distinct signers were identified for address \"${signer.address}\". ` +\n `Please ensure that you are using the same signer instance for each address.`\n );\n }\n });\n return Object.values(deduplicated);\n}\n","import { AccountRole, IAccountLookupMeta, IAccountMeta, IInstruction } from '@solana/instructions';\nimport { BaseTransaction, TransactionVersion } from '@solana/transactions';\n\nimport { deduplicateSigners } from './deduplicate-signers';\nimport { TransactionSigner } from './transaction-signer';\n\n/** An extension of the IAccountMeta type that keeps track of its transaction signer. */\nexport interface IAccountSignerMeta<\n TAddress extends string = string,\n TSigner extends TransactionSigner = TransactionSigner\n> extends IAccountMeta<TAddress> {\n readonly role: AccountRole.READONLY_SIGNER | AccountRole.WRITABLE_SIGNER;\n readonly signer: TSigner;\n}\n\ntype IAccountMetaWithWithSigner<TSigner extends TransactionSigner = TransactionSigner> =\n | IAccountMeta\n | IAccountLookupMeta\n | IAccountSignerMeta<string, TSigner>;\n\n/** A variation of the instruction type that allows IAccountSignerMeta in its account metas. */\nexport type IInstructionWithSigners<\n TSigner extends TransactionSigner = TransactionSigner,\n TAccounts extends readonly IAccountMetaWithWithSigner<TSigner>[] = readonly IAccountMetaWithWithSigner<TSigner>[]\n> = Pick<IInstruction<string, TAccounts>, 'accounts'>;\n\n/** A variation of the transaction type that allows IAccountSignerMeta in its account metas. */\nexport type ITransactionWithSigners<\n TSigner extends TransactionSigner = TransactionSigner,\n TAccounts extends readonly IAccountMetaWithWithSigner<TSigner>[] = readonly IAccountMetaWithWithSigner<TSigner>[]\n> = Pick<\n BaseTransaction<TransactionVersion, IInstruction & IInstructionWithSigners<TSigner, TAccounts>>,\n 'instructions'\n>;\n\n/** Extract all signers from an instruction that may contain IAccountSignerMeta accounts. */\nexport function getSignersFromInstruction<TSigner extends TransactionSigner = TransactionSigner>(\n instruction: IInstructionWithSigners<TSigner>\n): readonly TSigner[] {\n return deduplicateSigners(\n (instruction.accounts ?? []).flatMap(account => ('signer' in account ? account.signer : []))\n );\n}\n\n/** Extract all signers from a transaction that may contain IAccountSignerMeta accounts. */\nexport function getSignersFromTransaction<\n TSigner extends TransactionSigner = TransactionSigner,\n TTransaction extends ITransactionWithSigners<TSigner> = ITransactionWithSigners<TSigner>\n>(transaction: TTransaction): readonly TSigner[] {\n return deduplicateSigners(transaction.instructions.flatMap(getSignersFromInstruction));\n}\n","import { IInstruction, isSignerRole } from '@solana/instructions';\nimport { BaseTransaction } from '@solana/transactions';\n\nimport { IAccountSignerMeta, IInstructionWithSigners, ITransactionWithSigners } from './account-signer-meta';\nimport { deduplicateSigners } from './deduplicate-signers';\nimport { TransactionSigner } from './transaction-signer';\n\n/** Attaches the provided signers to the account metas of an instruction when applicable. */\nexport function addSignersToInstruction<TInstruction extends IInstruction>(\n signers: TransactionSigner[],\n instruction: TInstruction | (TInstruction & IInstructionWithSigners)\n): TInstruction & IInstructionWithSigners {\n if (!instruction.accounts || instruction.accounts.length === 0) {\n return instruction as TInstruction & IInstructionWithSigners;\n }\n\n const signerByAddress = new Map(deduplicateSigners(signers).map(signer => [signer.address, signer]));\n return Object.freeze({\n ...instruction,\n accounts: instruction.accounts.map(account => {\n const signer = signerByAddress.get(account.address);\n if (!isSignerRole(account.role) || 'signer' in account || !signer) {\n return account;\n }\n return Object.freeze({ ...account, signer } as IAccountSignerMeta);\n }),\n });\n}\n\n/** Attaches the provided signers to the account metas of a transaction when applicable. */\nexport function addSignersToTransaction<TTransaction extends BaseTransaction>(\n signers: TransactionSigner[],\n transaction: TTransaction | (TTransaction & ITransactionWithSigners)\n): TTransaction & ITransactionWithSigners {\n if (transaction.instructions.length === 0) {\n return transaction as TTransaction & ITransactionWithSigners;\n }\n\n return Object.freeze({\n ...transaction,\n instructions: transaction.instructions.map(instruction => addSignersToInstruction(signers, instruction)),\n });\n}\n","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 { BaseSignerConfig, SignatureDictionary } from './types';\n\nexport type MessagePartialSignerConfig = BaseSignerConfig;\n\n/** Defines a signer capable of signing messages. */\nexport type MessagePartialSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n signMessages(\n messages: readonly SignableMessage[],\n config?: MessagePartialSignerConfig\n ): 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 { BaseSignerConfig, SignatureDictionary } from './types';\n\nexport type TransactionPartialSignerConfig = BaseSignerConfig;\n\n/** Defines a signer capable of signing transactions. */\nexport type TransactionPartialSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n signTransactions(\n transactions: readonly CompilableTransaction[],\n config?: TransactionPartialSignerConfig\n ): 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';\nimport { BaseSignerConfig } from './types';\n\nexport type MessageModifyingSignerConfig = BaseSignerConfig;\n\n/** Defines a signer capable of signing messages. */\nexport type MessageModifyingSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n modifyAndSignMessages(\n messages: readonly SignableMessage[],\n config?: MessageModifyingSignerConfig\n ): 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","import { Address } from '@solana/addresses';\n\nimport { MessagePartialSigner } from './message-partial-signer';\nimport { TransactionPartialSigner } from './transaction-partial-signer';\n\n/** Defines a no-operation signer that pretends to partially sign messages and transactions. */\nexport type NoopSigner<TAddress extends string = string> = MessagePartialSigner<TAddress> &\n TransactionPartialSigner<TAddress>;\n\n/** Creates a NoopSigner from the provided Address. */\nexport function createNoopSigner(address: Address): NoopSigner {\n const out: NoopSigner = {\n address,\n signMessages: async messages => messages.map(() => Object.freeze({})),\n signTransactions: async transactions => transactions.map(() => Object.freeze({})),\n };\n\n return Object.freeze(out);\n}\n","import { SignatureBytes } from '@solana/keys';\nimport {\n assertTransactionIsFullySigned,\n CompilableTransaction,\n IFullySignedTransaction,\n ITransactionWithSignatures,\n} from '@solana/transactions';\n\nimport { getSignersFromTransaction, ITransactionWithSigners } from './account-signer-meta';\nimport { deduplicateSigners } from './deduplicate-signers';\nimport { isTransactionModifyingSigner, TransactionModifyingSigner } from './transaction-modifying-signer';\nimport { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer';\nimport { isTransactionSendingSigner, TransactionSendingSigner } from './transaction-sending-signer';\nimport { isTransactionSigner, TransactionSigner } from './transaction-signer';\n\ntype CompilableTransactionWithSigners = CompilableTransaction &\n ITransactionWithSigners &\n Partial<ITransactionWithSignatures>;\n\n/**\n * Signs a transaction using any signers that may be stored in IAccountSignerMeta instruction accounts\n * as well as any signers provided explicitly to this function.\n * It will ignore TransactionSendingSigners since this function does not send the transaction.\n */\nexport async function partiallySignTransactionWithSigners<\n TTransaction extends CompilableTransactionWithSigners = CompilableTransactionWithSigners\n>(\n transaction: TTransaction,\n config: { abortSignal?: AbortSignal } = {}\n): Promise<TTransaction & ITransactionWithSignatures> {\n const { partialSigners, modifyingSigners } = categorizeTransactionSigners(\n deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)),\n { identifySendingSigner: false }\n );\n\n return signModifyingAndPartialTransactionSigners(transaction, modifyingSigners, partialSigners, config.abortSignal);\n}\n\n/**\n * Signs a transaction using any signers that may be stored in IAccountSignerMeta instruction accounts\n * as well as any signers provided explicitly to this function.\n * It will assert that the transaction is fully signed before returning.\n * It will ignore TransactionSendingSigners since this function does not send the transaction.\n */\nexport async function signTransactionWithSigners<\n TTransaction extends CompilableTransactionWithSigners = CompilableTransactionWithSigners\n>(\n transaction: TTransaction,\n config: { abortSignal?: AbortSignal } = {}\n): Promise<TTransaction & IFullySignedTransaction> {\n const signedTransaction = await partiallySignTransactionWithSigners(transaction, config);\n assertTransactionIsFullySigned(signedTransaction);\n return signedTransaction;\n}\n\n/**\n * Signs and sends a transaction using any signers that may be stored in IAccountSignerMeta\n * instruction accounts as well as any signers provided explicitly to this function.\n * It will identify a single TransactionSendingSigners to use for sending the transaction, if any.\n * Otherwise, it will send the transaction using the provided fallbackSender.\n */\nexport async function signAndSendTransactionWithSigners<\n TTransaction extends CompilableTransactionWithSigners = CompilableTransactionWithSigners\n>(\n transaction: TTransaction,\n config: {\n abortSignal?: AbortSignal;\n fallbackSender?: (transaction: TTransaction & IFullySignedTransaction) => Promise<SignatureBytes>;\n } = {}\n): Promise<SignatureBytes> {\n const abortSignal = config.abortSignal;\n const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners(\n deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner))\n );\n\n abortSignal?.throwIfAborted();\n const signedTransaction = await signModifyingAndPartialTransactionSigners(\n transaction,\n modifyingSigners,\n partialSigners,\n abortSignal\n );\n\n if (sendingSigner) {\n abortSignal?.throwIfAborted();\n const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal });\n return signature;\n }\n\n if (config.fallbackSender) {\n assertTransactionIsFullySigned(signedTransaction);\n return config.fallbackSender(signedTransaction);\n }\n\n // TODO: Coded error.\n throw new Error('No TransactionSendingSigner was identified and no fallback sender was provided.');\n}\n\n/**\n * Identifies each provided TransactionSigner and categorizes them into their respective types.\n * When a signer implements multiple interface, it will try to used to most powerful interface\n * but fallback to the least powerful interface when necessary.\n * For instance, if a signer implements TransactionSendingSigner and TransactionModifyingSigner,\n * it will be categorized as a TransactionSendingSigner if and only if no other signers implement\n * the TransactionSendingSigner interface.\n */\nfunction categorizeTransactionSigners(\n signers: readonly TransactionSigner[],\n config: { identifySendingSigner?: boolean } = {}\n): Readonly<{\n modifyingSigners: readonly TransactionModifyingSigner[];\n partialSigners: readonly TransactionPartialSigner[];\n sendingSigner: TransactionSendingSigner | null;\n}> {\n // Identify the unique sending signer that should be used.\n const identifySendingSigner = config.identifySendingSigner ?? true;\n const sendingSigner = identifySendingSigner ? identifyTransactionSendingSigner(signers) : null;\n\n // Now, focus on the other signers.\n // I.e. the modifying or partial signers that are not the identified sending signer.\n // Note that any other sending only signers will be discarded.\n const otherSigners = signers.filter(\n (signer): signer is TransactionModifyingSigner | TransactionPartialSigner =>\n signer !== sendingSigner && (isTransactionModifyingSigner(signer) || isTransactionPartialSigner(signer))\n );\n\n // Identify the modifying signers from the other signers.\n const modifyingSigners = identifyTransactionModifyingSigners(otherSigners);\n\n // Use any remaining signers as partial signers.\n const partialSigners = otherSigners\n .filter(isTransactionPartialSigner)\n .filter(signer => !(modifyingSigners as typeof otherSigners).includes(signer));\n\n return Object.freeze({ modifyingSigners, partialSigners, sendingSigner });\n}\n\n/** Identifies the best signer to use as a TransactionSendingSigner, if any */\nfunction identifyTransactionSendingSigner(signers: readonly TransactionSigner[]): TransactionSendingSigner | null {\n // Ensure there are any TransactionSendingSigners in the first place.\n const sendingSigners = signers.filter(isTransactionSendingSigner);\n if (sendingSigners.length === 0) return null;\n\n // Prefer sending signers that do not offer other interfaces.\n const sendingOnlySigners = sendingSigners.filter(\n signer => !isTransactionModifyingSigner(signer) && !isTransactionPartialSigner(signer)\n );\n if (sendingOnlySigners.length > 0) {\n return sendingOnlySigners[0];\n }\n\n // Otherwise, choose any sending signer.\n return sendingSigners[0];\n}\n\n/** Identifies the best signers to use as TransactionModifyingSigners, if any */\nfunction identifyTransactionModifyingSigners(\n signers: readonly (TransactionModifyingSigner | TransactionPartialSigner)[]\n): readonly TransactionModifyingSigner[] {\n // Ensure there are any TransactionModifyingSigner in the first place.\n const modifyingSigners = signers.filter(isTransactionModifyingSigner);\n if (modifyingSigners.length === 0) return [];\n\n // Prefer modifying signers that do not offer partial signing.\n const nonPartialSigners = modifyingSigners.filter(signer => !isTransactionPartialSigner(signer));\n if (nonPartialSigners.length > 0) return nonPartialSigners;\n\n // Otherwise, choose only one modifying signer (whichever).\n return [modifyingSigners[0]];\n}\n\n/**\n * Signs a transaction using the provided TransactionModifyingSigners\n * sequentially followed by the TransactionPartialSigners in parallel.\n */\nasync function signModifyingAndPartialTransactionSigners<\n TTransaction extends CompilableTransactionWithSigners = CompilableTransactionWithSigners\n>(\n transaction: TTransaction,\n modifyingSigners: readonly TransactionModifyingSigner[] = [],\n partialSigners: readonly TransactionPartialSigner[] = [],\n abortSignal?: AbortSignal\n): Promise<TTransaction & ITransactionWithSignatures> {\n // Handle modifying signers sequentially.\n const modifiedTransaction = await modifyingSigners.reduce(async (transaction, modifyingSigner) => {\n abortSignal?.throwIfAborted();\n const [tx] = await modifyingSigner.modifyAndSignTransactions([await transaction], { abortSignal });\n return Object.freeze(tx);\n }, Promise.resolve(transaction) as Promise<TTransaction>);\n\n // Handle partial signers in parallel.\n abortSignal?.throwIfAborted();\n const signatureDictionaries = await Promise.all(\n partialSigners.map(async partialSigner => {\n const [signatures] = await partialSigner.signTransactions([modifiedTransaction], { abortSignal });\n return signatures;\n })\n );\n const signedTransaction: TTransaction & ITransactionWithSignatures = {\n ...modifiedTransaction,\n signatures: Object.freeze(\n signatureDictionaries.reduce((signatures, signatureDictionary) => {\n return { ...signatures, ...signatureDictionary };\n }, modifiedTransaction.signatures ?? {})\n ),\n };\n\n return Object.freeze(signedTransaction);\n}\n","import { Address } from '@solana/addresses';\nimport { CompilableTransaction } from '@solana/transactions';\n\nimport { BaseSignerConfig } from './types';\n\nexport type TransactionModifyingSignerConfig = BaseSignerConfig;\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 config?: TransactionModifyingSignerConfig\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\nimport { BaseSignerConfig } from './types';\n\nexport type TransactionSendingSignerConfig = BaseSignerConfig;\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(\n transactions: readonly CompilableTransaction[],\n config?: TransactionSendingSignerConfig\n ): 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","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"]}
|
package/dist/index.browser.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isSignerRole } from '@solana/instructions';
|
|
1
2
|
import { getAddressFromPublicKey, isAddress } from '@solana/addresses';
|
|
2
3
|
import { generateKeyPair, signBytes } from '@solana/keys';
|
|
3
4
|
import { assertTransactionIsFullySigned, partiallySignTransaction } from '@solana/transactions';
|
|
@@ -8,6 +9,10 @@ function deduplicateSigners(signers) {
|
|
|
8
9
|
signers.forEach((signer) => {
|
|
9
10
|
if (!deduplicated[signer.address]) {
|
|
10
11
|
deduplicated[signer.address] = signer;
|
|
12
|
+
} else if (deduplicated[signer.address] !== signer) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`Multiple distinct signers were identified for address "${signer.address}". Please ensure that you are using the same signer instance for each address.`
|
|
15
|
+
);
|
|
11
16
|
}
|
|
12
17
|
});
|
|
13
18
|
return Object.values(deduplicated);
|
|
@@ -22,6 +27,31 @@ function getSignersFromInstruction(instruction) {
|
|
|
22
27
|
function getSignersFromTransaction(transaction) {
|
|
23
28
|
return deduplicateSigners(transaction.instructions.flatMap(getSignersFromInstruction));
|
|
24
29
|
}
|
|
30
|
+
function addSignersToInstruction(signers, instruction) {
|
|
31
|
+
if (!instruction.accounts || instruction.accounts.length === 0) {
|
|
32
|
+
return instruction;
|
|
33
|
+
}
|
|
34
|
+
const signerByAddress = new Map(deduplicateSigners(signers).map((signer) => [signer.address, signer]));
|
|
35
|
+
return Object.freeze({
|
|
36
|
+
...instruction,
|
|
37
|
+
accounts: instruction.accounts.map((account) => {
|
|
38
|
+
const signer = signerByAddress.get(account.address);
|
|
39
|
+
if (!isSignerRole(account.role) || "signer" in account || !signer) {
|
|
40
|
+
return account;
|
|
41
|
+
}
|
|
42
|
+
return Object.freeze({ ...account, signer });
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function addSignersToTransaction(signers, transaction) {
|
|
47
|
+
if (transaction.instructions.length === 0) {
|
|
48
|
+
return transaction;
|
|
49
|
+
}
|
|
50
|
+
return Object.freeze({
|
|
51
|
+
...transaction,
|
|
52
|
+
instructions: transaction.instructions.map((instruction) => addSignersToInstruction(signers, instruction))
|
|
53
|
+
});
|
|
54
|
+
}
|
|
25
55
|
|
|
26
56
|
// src/message-partial-signer.ts
|
|
27
57
|
function isMessagePartialSigner(value) {
|
|
@@ -93,6 +123,16 @@ function assertIsMessageSigner(value) {
|
|
|
93
123
|
}
|
|
94
124
|
}
|
|
95
125
|
|
|
126
|
+
// src/noop-signer.ts
|
|
127
|
+
function createNoopSigner(address) {
|
|
128
|
+
const out = {
|
|
129
|
+
address,
|
|
130
|
+
signMessages: async (messages) => messages.map(() => Object.freeze({})),
|
|
131
|
+
signTransactions: async (transactions) => transactions.map(() => Object.freeze({}))
|
|
132
|
+
};
|
|
133
|
+
return Object.freeze(out);
|
|
134
|
+
}
|
|
135
|
+
|
|
96
136
|
// src/transaction-modifying-signer.ts
|
|
97
137
|
function isTransactionModifyingSigner(value) {
|
|
98
138
|
return "modifyAndSignTransactions" in value && typeof value.modifyAndSignTransactions === "function";
|
|
@@ -125,9 +165,8 @@ function assertIsTransactionSigner(value) {
|
|
|
125
165
|
|
|
126
166
|
// src/sign-transaction.ts
|
|
127
167
|
async function partiallySignTransactionWithSigners(transaction, config = {}) {
|
|
128
|
-
const signers = config.signers ?? [];
|
|
129
168
|
const { partialSigners, modifyingSigners } = categorizeTransactionSigners(
|
|
130
|
-
deduplicateSigners(
|
|
169
|
+
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)),
|
|
131
170
|
{ identifySendingSigner: false }
|
|
132
171
|
);
|
|
133
172
|
return signModifyingAndPartialTransactionSigners(transaction, modifyingSigners, partialSigners, config.abortSignal);
|
|
@@ -138,10 +177,9 @@ async function signTransactionWithSigners(transaction, config = {}) {
|
|
|
138
177
|
return signedTransaction;
|
|
139
178
|
}
|
|
140
179
|
async function signAndSendTransactionWithSigners(transaction, config = {}) {
|
|
141
|
-
const signers = config.signers ?? [];
|
|
142
180
|
const abortSignal = config.abortSignal;
|
|
143
181
|
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners(
|
|
144
|
-
deduplicateSigners(
|
|
182
|
+
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner))
|
|
145
183
|
);
|
|
146
184
|
abortSignal?.throwIfAborted();
|
|
147
185
|
const signedTransaction = await signModifyingAndPartialTransactionSigners(
|
|
@@ -225,6 +263,6 @@ function createSignableMessage(content, signatures = {}) {
|
|
|
225
263
|
});
|
|
226
264
|
}
|
|
227
265
|
|
|
228
|
-
export { assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, getSignersFromInstruction, getSignersFromTransaction, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner, partiallySignTransactionWithSigners, signAndSendTransactionWithSigners, signTransactionWithSigners };
|
|
266
|
+
export { addSignersToInstruction, addSignersToTransaction, assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, createNoopSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, getSignersFromInstruction, getSignersFromTransaction, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner, partiallySignTransactionWithSigners, signAndSendTransactionWithSigners, signTransactionWithSigners };
|
|
229
267
|
//# sourceMappingURL=out.js.map
|
|
230
268
|
//# sourceMappingURL=index.browser.js.map
|