From 727a511ab2b863733c0b4e18ea9feaf9e65a36a9 Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Fri, 12 Apr 2024 13:32:44 +0100 Subject: [PATCH] Clean up signers (#2477) - remove unused functions - remove `new` prefix from stuff I duplicated and have now removed the original of - remove imports of old functions from `@solana/transaction` This should leave the final new API for `signers`. --- packages/signers/src/__tests__/__setup__.ts | 50 +++----- .../src/__tests__/account-signer-meta-test.ts | 52 +------- .../signers/src/__tests__/add-signers-test.ts | 8 +- .../src/__tests__/keypair-signer-test.ts | 53 +-------- .../signers/src/__tests__/noop-signer-test.ts | 6 +- .../src/__tests__/sign-transaction-test.ts | 112 +++++++++--------- .../transaction-modifying-signer-test.ts | 2 - .../transaction-partial-signer-test.ts | 2 - .../transaction-sending-signer-test.ts | 2 - .../src/__tests__/transaction-signer-test.ts | 6 - .../transaction-with-single-sending-signer.ts | 48 -------- packages/signers/src/account-signer-meta.ts | 25 +--- packages/signers/src/add-signers.ts | 11 +- packages/signers/src/keypair-signer.ts | 15 +-- packages/signers/src/noop-signer.ts | 1 - packages/signers/src/sign-transaction.ts | 12 +- .../src/transaction-modifying-signer.ts | 8 +- .../signers/src/transaction-partial-signer.ts | 8 +- .../signers/src/transaction-sending-signer.ts | 8 +- .../transaction-with-single-sending-signer.ts | 48 +------- 20 files changed, 105 insertions(+), 372 deletions(-) diff --git a/packages/signers/src/__tests__/__setup__.ts b/packages/signers/src/__tests__/__setup__.ts index 9b961ee60563..db7c9431aec1 100644 --- a/packages/signers/src/__tests__/__setup__.ts +++ b/packages/signers/src/__tests__/__setup__.ts @@ -3,19 +3,13 @@ import { AccountRole, IInstruction } from '@solana/instructions'; import type { Blockhash } from '@solana/rpc-types'; import { CompilableTransactionMessage } from '@solana/transaction-messages'; import { - appendTransactionInstruction, - CompilableTransaction, - createTransaction, - setTransactionFeePayer, - setTransactionLifetimeUsingBlockhash, -} from '@solana/transactions'; + appendTransactionMessageInstruction, + createTransactionMessage, + setTransactionMessageFeePayer, + setTransactionMessageLifetimeUsingBlockhash, +} from '@solana/transaction-messages'; -import { - IAccountSignerMeta, - IInstructionWithSigners, - ITransactionMessageWithSigners, - ITransactionWithSigners, -} from '../account-signer-meta'; +import { IAccountSignerMeta, IInstructionWithSigners, ITransactionMessageWithSigners } from '../account-signer-meta'; import { MessageModifyingSigner } from '../message-modifying-signer'; import { MessagePartialSigner } from '../message-partial-signer'; import { TransactionModifyingSigner } from '../transaction-modifying-signer'; @@ -33,28 +27,16 @@ export function createMockInstructionWithSigners(signers: TransactionSigner[]): }; } -export function createMockTransactionWithSigners( - signers: TransactionSigner[], -): CompilableTransaction & ITransactionWithSigners { - const transaction = createTransaction({ version: 0 }); - const transactionWithFeePayer = setTransactionFeePayer(signers[0]?.address ?? '1111', transaction); - const compilableTransaction = setTransactionLifetimeUsingBlockhash( - { blockhash: 'dummy_blockhash' as Blockhash, lastValidBlockHeight: 42n }, - transactionWithFeePayer, - ); - return appendTransactionInstruction(createMockInstructionWithSigners(signers), compilableTransaction); -} - export function createMockTransactionMessageWithSigners( signers: TransactionSigner[], ): CompilableTransactionMessage & ITransactionMessageWithSigners { - const transaction = createTransaction({ version: 0 }); - const transactionWithFeePayer = setTransactionFeePayer(signers[0]?.address ?? '1111', transaction); - const compilableTransaction = setTransactionLifetimeUsingBlockhash( + const transaction = createTransactionMessage({ version: 0 }); + const transactionWithFeePayer = setTransactionMessageFeePayer(signers[0]?.address ?? '1111', transaction); + const compilableTransaction = setTransactionMessageLifetimeUsingBlockhash( { blockhash: 'dummy_blockhash' as Blockhash, lastValidBlockHeight: 42n }, transactionWithFeePayer, ); - return appendTransactionInstruction(createMockInstructionWithSigners(signers), compilableTransaction); + return appendTransactionMessageInstruction(createMockInstructionWithSigners(signers), compilableTransaction); } export function createMockMessagePartialSigner(address: Address): MessagePartialSigner & { signMessages: jest.Mock } { @@ -69,20 +51,20 @@ export function createMockMessageModifyingSigner( export function createMockTransactionPartialSigner( address: Address, -): TransactionPartialSigner & { newSignTransactions: jest.Mock; signTransactions: jest.Mock } { - return { address, newSignTransactions: jest.fn(), signTransactions: jest.fn() }; +): TransactionPartialSigner & { signTransactions: jest.Mock } { + return { address, signTransactions: jest.fn() }; } export function createMockTransactionModifyingSigner( address: Address, -): TransactionModifyingSigner & { modifyAndSignTransactions: jest.Mock; newModifyAndSignTransactions: jest.Mock } { - return { address, modifyAndSignTransactions: jest.fn(), newModifyAndSignTransactions: jest.fn() }; +): TransactionModifyingSigner & { modifyAndSignTransactions: jest.Mock } { + return { address, modifyAndSignTransactions: jest.fn() }; } export function createMockTransactionSendingSigner( address: Address, -): TransactionSendingSigner & { newSignAndSendTransactions: jest.Mock; signAndSendTransactions: jest.Mock } { - return { address, newSignAndSendTransactions: jest.fn(), signAndSendTransactions: jest.fn() }; +): TransactionSendingSigner & { signAndSendTransactions: jest.Mock } { + return { address, signAndSendTransactions: jest.fn() }; } export function createMockTransactionCompositeSigner(address: Address) { diff --git a/packages/signers/src/__tests__/account-signer-meta-test.ts b/packages/signers/src/__tests__/account-signer-meta-test.ts index 18c972cbaec2..40625cfc900a 100644 --- a/packages/signers/src/__tests__/account-signer-meta-test.ts +++ b/packages/signers/src/__tests__/account-signer-meta-test.ts @@ -1,19 +1,13 @@ import { Address } from '@solana/addresses'; import { createTransactionMessage } from '@solana/transaction-messages'; -import { createTransaction } from '@solana/transactions'; -import { - getSignersFromInstruction, - getSignersFromTransaction, - getSignersFromTransactionMessage, -} from '../account-signer-meta'; +import { getSignersFromInstruction, getSignersFromTransactionMessage } from '../account-signer-meta'; import { setTransactionFeePayerSigner } from '../fee-payer-signer'; import { createMockInstructionWithSigners, createMockTransactionMessageWithSigners, createMockTransactionModifyingSigner, createMockTransactionPartialSigner, - createMockTransactionWithSigners, } from './__setup__'; describe('getSignersFromInstruction', () => { @@ -47,50 +41,6 @@ describe('getSignersFromInstruction', () => { }); }); -describe('getSignersFromTransaction', () => { - it('extracts signers from the account meta of the provided transaction', () => { - // Given a transaction with two signers A and B. - const signerA = createMockTransactionPartialSigner('1111' as Address); - const signerB = createMockTransactionModifyingSigner('2222' as Address); - const transaction = createMockTransactionWithSigners([signerA, signerB]); - - // When we extract the signers from the transaction's account metas. - const extractedSigners = getSignersFromTransaction(transaction); - - // Then we expect signer A and B to be part of the extracted signers. - expect(extractedSigners).toHaveLength(2); - expect(extractedSigners[0]).toBe(signerA); - expect(extractedSigners[1]).toBe(signerB); - }); - - it('extracts the fee payer signer of the provided transaction', () => { - // Given a transaction with a signer fee payer. - const feePayerSigner = createMockTransactionPartialSigner('1111' as Address); - const transaction = setTransactionFeePayerSigner(feePayerSigner, createTransaction({ version: 0 })); - - // When we extract the signers from the transaction. - const extractedSigners = getSignersFromTransaction(transaction); - - // Then we expect the extracted signers to contain the fee payer signer. - expect(extractedSigners).toHaveLength(1); - expect(extractedSigners[0]).toBe(feePayerSigner); - }); - - it('removes duplicated signers', () => { - // Given a transaction with duplicated signers using the same reference. - const signerA = createMockTransactionPartialSigner('1111' as Address); - const signerB = createMockTransactionModifyingSigner('2222' as Address); - const transaction = createMockTransactionWithSigners([signerA, signerB, signerA, signerA]); - - // When we extract the signers from the transaction's account metas. - const extractedSigners = getSignersFromTransaction(transaction); - - // Then we expect the extracted signers to be deduplicated. - expect(extractedSigners).toHaveLength(2); - expect(extractedSigners.map(signer => signer.address).sort()).toStrictEqual(['1111', '2222']); - }); -}); - describe('getSignersFromTransactionMessage', () => { it('extracts signers from the account meta of the provided transaction', () => { // Given a transaction with two signers A and B. diff --git a/packages/signers/src/__tests__/add-signers-test.ts b/packages/signers/src/__tests__/add-signers-test.ts index c563dc20b9d4..a9bf66847a6f 100644 --- a/packages/signers/src/__tests__/add-signers-test.ts +++ b/packages/signers/src/__tests__/add-signers-test.ts @@ -3,7 +3,7 @@ import '@solana/test-matchers/toBeFrozenObject'; import { Address } from '@solana/addresses'; import { SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS, SolanaError } from '@solana/errors'; import { AccountRole, IInstruction } from '@solana/instructions'; -import { BaseTransaction } from '@solana/transactions'; +import { BaseTransactionMessage } from '@solana/transaction-messages'; import { IAccountSignerMeta, IInstructionWithSigners } from '../account-signer-meta'; import { addSignersToInstruction, addSignersToTransactionMessage } from '../add-signers'; @@ -169,7 +169,7 @@ describe('addSignersToTransactionMessage', () => { data: new Uint8Array([]), programAddress: '9999' as Address, }; - const transaction: BaseTransaction = { + const transaction: BaseTransactionMessage = { instructions: [instructionA, instructionB], version: 0, }; @@ -192,7 +192,7 @@ describe('addSignersToTransactionMessage', () => { it('freezes the returned transaction', () => { // Given a one-instruction transaction with signer account metas. - const transaction: BaseTransaction = { + const transaction: BaseTransactionMessage = { instructions: [ { accounts: [{ address: '1111' as Address, role: AccountRole.READONLY_SIGNER }], @@ -215,7 +215,7 @@ describe('addSignersToTransactionMessage', () => { it('returns the transaction as-is if it has no instructions', () => { // Given transaction with no instructions. - const transaction: BaseTransaction = { instructions: [], version: 0 }; + const transaction: BaseTransactionMessage = { instructions: [], version: 0 }; // When we try to add signers to the transaction. const signer = createMockTransactionPartialSigner('1111' as Address); diff --git a/packages/signers/src/__tests__/keypair-signer-test.ts b/packages/signers/src/__tests__/keypair-signer-test.ts index 296cca616e6c..1d00f168a20c 100644 --- a/packages/signers/src/__tests__/keypair-signer-test.ts +++ b/packages/signers/src/__tests__/keypair-signer-test.ts @@ -3,12 +3,7 @@ import '@solana/test-matchers/toBeFrozenObject'; import { address, getAddressFromPublicKey } from '@solana/addresses'; import { SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER, SolanaError } from '@solana/errors'; import { generateKeyPair, SignatureBytes, signBytes } from '@solana/keys'; -import { - CompilableTransaction, - newPartiallySignTransaction, - NewTransaction, - partiallySignTransaction, -} from '@solana/transactions'; +import { newPartiallySignTransaction, NewTransaction } from '@solana/transactions'; import { assertIsKeyPairSigner, @@ -43,7 +38,6 @@ describe('isKeyPairSigner', () => { const mySigner = { address: myAddress, keyPair: getMockCryptoKeyPair(), - newSignTransactions: () => Promise.resolve([]), signMessages: () => Promise.resolve([]), signTransactions: () => Promise.resolve([]), } satisfies KeyPairSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; @@ -62,7 +56,6 @@ describe('assertIsKeyPairSigner', () => { const mySigner = { address: myAddress, keyPair: getMockCryptoKeyPair(), - newSignTransactions: () => Promise.resolve([]), signMessages: () => Promise.resolve([]), signTransactions: () => Promise.resolve([]), } satisfies KeyPairSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; @@ -142,7 +135,7 @@ describe('createSignerFromKeyPair', () => { expect(jest.mocked(signBytes)).toHaveBeenNthCalledWith(2, myKeyPair.privateKey, messages[1].content); }); - it('signs transactions using the newSignTransactions function', async () => { + it('signs transactions using the signTransactions function', async () => { expect.assertions(7); // Given a KeyPairSigner created from a mock CryptoKeyPair. @@ -166,7 +159,7 @@ describe('createSignerFromKeyPair', () => { }); // When we sign both transactions using that signer. - const signatureDictionaries = await mySigner.newSignTransactions(mockTransactions); + const signatureDictionaries = await mySigner.signTransactions(mockTransactions); // Then the signature directories contain the expected signatures. expect(signatureDictionaries[0]).toStrictEqual({ [myAddress]: mockSignatures[0] }); @@ -181,46 +174,6 @@ describe('createSignerFromKeyPair', () => { expect(jest.mocked(newPartiallySignTransaction)).toHaveBeenNthCalledWith(1, [myKeyPair], mockTransactions[0]); expect(jest.mocked(newPartiallySignTransaction)).toHaveBeenNthCalledWith(2, [myKeyPair], mockTransactions[1]); }); - - it('signs transactions using the signTransactions function', async () => { - expect.assertions(7); - - // Given a KeyPairSigner created from a mock CryptoKeyPair. - const myKeyPair = getMockCryptoKeyPair(); - const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'); - jest.mocked(getAddressFromPublicKey).mockResolvedValueOnce(myAddress); - const mySigner = await createSignerFromKeyPair(myKeyPair); - - // And given we have a couple of mock transactions to sign. - const mockTransactions = [{} as CompilableTransaction, {} as CompilableTransaction]; - - // And given we mock the next two calls of the partiallySignTransaction function. - const mockSignatures = [new Uint8Array([101, 101, 101]), new Uint8Array([201, 201, 201])] as SignatureBytes[]; - jest.mocked(partiallySignTransaction).mockResolvedValueOnce({ - ...mockTransactions[0], - signatures: { [myAddress]: mockSignatures[0] }, - }); - jest.mocked(partiallySignTransaction).mockResolvedValueOnce({ - ...mockTransactions[1], - signatures: { [myAddress]: mockSignatures[1] }, - }); - - // When we sign both transactions using that signer. - const signatureDictionaries = await mySigner.signTransactions(mockTransactions); - - // Then the signature directories contain the expected signatures. - expect(signatureDictionaries[0]).toStrictEqual({ [myAddress]: mockSignatures[0] }); - expect(signatureDictionaries[1]).toStrictEqual({ [myAddress]: mockSignatures[1] }); - - // And the signature directories are frozen. - expect(signatureDictionaries[0]).toBeFrozenObject(); - expect(signatureDictionaries[1]).toBeFrozenObject(); - - // And partiallySignTransaction was called twice with the expected parameters. - expect(jest.mocked(partiallySignTransaction)).toHaveBeenCalledTimes(2); - expect(jest.mocked(partiallySignTransaction)).toHaveBeenNthCalledWith(1, [myKeyPair], mockTransactions[0]); - expect(jest.mocked(partiallySignTransaction)).toHaveBeenNthCalledWith(2, [myKeyPair], mockTransactions[1]); - }); }); describe('generateKeyPairSigner', () => { diff --git a/packages/signers/src/__tests__/noop-signer-test.ts b/packages/signers/src/__tests__/noop-signer-test.ts index 7ef385e174d9..dd0443f6f8ff 100644 --- a/packages/signers/src/__tests__/noop-signer-test.ts +++ b/packages/signers/src/__tests__/noop-signer-test.ts @@ -1,7 +1,7 @@ import '@solana/test-matchers/toBeFrozenObject'; import { address } from '@solana/addresses'; -import { CompilableTransaction, NewTransaction } from '@solana/transactions'; +import { NewTransaction } from '@solana/transactions'; import { createNoopSigner, NoopSigner } from '../noop-signer'; import { createSignableMessage } from '../signable-message'; @@ -55,7 +55,7 @@ describe('createNoopSigner', () => { const mockTransactions = [{} as NewTransaction, {} as NewTransaction]; // When we sign both transactions using that signer. - const signatureDictionaries = await mySigner.newSignTransactions(mockTransactions); + const signatureDictionaries = await mySigner.signTransactions(mockTransactions); // Then the signature directories are empty and frozen. expect(signatureDictionaries[0]).toStrictEqual({}); @@ -71,7 +71,7 @@ describe('createNoopSigner', () => { const mySigner = createNoopSigner(address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy')); // And given we have a couple of mock transactions to sign. - const mockTransactions = [{} as CompilableTransaction, {} as CompilableTransaction]; + const mockTransactions = [{} as NewTransaction, {} as NewTransaction]; // When we sign both transactions using that signer. const signatureDictionaries = await mySigner.signTransactions(mockTransactions); diff --git a/packages/signers/src/__tests__/sign-transaction-test.ts b/packages/signers/src/__tests__/sign-transaction-test.ts index d563bf44e48d..a04ca4636f1e 100644 --- a/packages/signers/src/__tests__/sign-transaction-test.ts +++ b/packages/signers/src/__tests__/sign-transaction-test.ts @@ -55,8 +55,8 @@ describe('partiallySignTransactionWithSigners', () => { // And given signer A and B are mocked to provide the following signatures. const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature', '2222': null } }; - signerA.newModifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); - signerB.newSignTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); + signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); + signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); // When we partially sign this transaction. const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage); @@ -68,10 +68,10 @@ describe('partiallySignTransactionWithSigners', () => { }); // And the signers were called with the expected parameters. - expect(signerA.newModifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { + expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined, }); - expect(signerB.newSignTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); + expect(signerB.signTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); }); it('signs modifying signers before partial signers', async () => { @@ -83,11 +83,11 @@ describe('partiallySignTransactionWithSigners', () => { // And mock implementations for both signers such that they append events to an array. const events: string[] = []; - signerA.newModifyAndSignTransactions.mockImplementation((transactions: NewTransaction[]) => { + signerA.modifyAndSignTransactions.mockImplementation((transactions: NewTransaction[]) => { events.push('signerA'); return transactions.map(tx => ({ ...tx, signatures: { '1111': '1111_signature' } })); }); - signerB.newSignTransactions.mockImplementation((transactions: NewTransaction[]) => { + signerB.signTransactions.mockImplementation((transactions: NewTransaction[]) => { events.push('signerB'); return transactions.map(() => ({ '2222': '2222_signature' })); }); @@ -134,8 +134,8 @@ describe('partiallySignTransactionWithSigners', () => { signatures: { ...tx.signatures, [address]: `${address}_signature` }, })); }; - signerA.newModifyAndSignTransactions.mockImplementation(mockImplementation('signerA', '1111')); - signerB.newModifyAndSignTransactions.mockImplementation(mockImplementation('signerB', '2222')); + signerA.modifyAndSignTransactions.mockImplementation(mockImplementation('signerA', '1111')); + signerB.modifyAndSignTransactions.mockImplementation(mockImplementation('signerB', '2222')); // And given a transaction that contains theses two signers in its account metas. const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]); @@ -177,8 +177,8 @@ describe('partiallySignTransactionWithSigners', () => { events.push(`${signerId} ends`); return transactions.map(() => ({ [address]: `${address}_signature` })); }; - signerA.newSignTransactions.mockImplementation(mockImplementation('signerA', '1111', 500)); - signerB.newSignTransactions.mockImplementation(mockImplementation('signerB', '2222', 600)); + signerA.signTransactions.mockImplementation(mockImplementation('signerA', '1111', 500)); + signerB.signTransactions.mockImplementation(mockImplementation('signerB', '2222', 600)); // And given a transaction that contains theses two signers in its account metas. const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]); @@ -225,7 +225,7 @@ describe('partiallySignTransactionWithSigners', () => { jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction); // And given signer B's partial interface is mocked to provide the following signatures. - signerB.newSignTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); + signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); // When we partially sign this transaction. const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage); @@ -234,9 +234,9 @@ describe('partiallySignTransactionWithSigners', () => { expect(signedTransaction.signatures).toStrictEqual({ '1111': null, '2222': '2222_signature' }); // And only the partial signer function was called. - expect(signerB.newSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined }); - expect(signerA.newSignAndSendTransactions).not.toHaveBeenCalled(); - expect(signerB.newSignAndSendTransactions).not.toHaveBeenCalled(); + expect(signerB.signTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined }); + expect(signerA.signAndSendTransactions).not.toHaveBeenCalled(); + expect(signerB.signAndSendTransactions).not.toHaveBeenCalled(); }); it('uses a composite signer as a modifying signer when there are no other modifying signers', async () => { @@ -260,18 +260,18 @@ describe('partiallySignTransactionWithSigners', () => { // And given the following mocked signatures. const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature' } }; - signerA.newModifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); - signerB.newSignTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); + signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); + signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); // When we partially sign this transaction. const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage); // Then signer A was used as a modifying signer. - expect(signerA.newSignTransactions).not.toHaveBeenCalled(); - expect(signerA.newModifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { + expect(signerA.signTransactions).not.toHaveBeenCalled(); + expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined, }); - expect(signerB.newSignTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); + expect(signerB.signTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); // And it contains the expected signatures. expect(signedTransaction.signatures).toStrictEqual({ @@ -301,16 +301,16 @@ describe('partiallySignTransactionWithSigners', () => { // And given the following mocked signatures. const modifiedTransaction = { ...unsignedTransaction, signatures: { '2222': '2222_signature' } }; - signerA.newSignTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); - signerB.newModifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); + signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); + signerB.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); // When we partially sign this transaction. const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage); // Then signer A was used as a partial signer. - expect(signerA.newSignTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); - expect(signerA.newModifyAndSignTransactions).not.toHaveBeenCalled(); - expect(signerB.newModifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { + expect(signerA.signTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); + expect(signerA.modifyAndSignTransactions).not.toHaveBeenCalled(); + expect(signerB.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined, }); @@ -336,7 +336,7 @@ describe('partiallySignTransactionWithSigners', () => { }; jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction); - signer.newSignTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); + signer.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); // When we partially sign this transaction. const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage); @@ -413,8 +413,8 @@ describe('signTransactionWithSigners', () => { // And given signer A and B are mocked to provide the following signatures. const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature' } }; - signerA.newModifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); - signerB.newSignTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); + signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); + signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); // When we sign this transaction. const signedTransaction = await signTransactionMessageWithSigners(transactionMessage); @@ -429,10 +429,10 @@ describe('signTransactionWithSigners', () => { signedTransaction satisfies FullySignedTransaction; // And the signers were called with the expected parameters. - expect(signerA.newModifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { + expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined, }); - expect(signerB.newSignTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); + expect(signerB.signTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); }); it('asserts the transaction is fully signed', async () => { @@ -452,7 +452,7 @@ describe('signTransactionWithSigners', () => { jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction); // And given signer A is mocked to provide the following signatures. - signerA.newSignTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); + signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); // When we try to sign this transaction. const promise = signTransactionMessageWithSigners(transactionMessage); @@ -532,16 +532,16 @@ describe('signAndSendTransactionWithSigners', () => { jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction); // And given signer A and B are mocked to provide the following return values. - signerA.newSignTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); - signerB.newSignAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); + signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); + signerB.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); // When we sign and send this transaction. assertIsTransactionMessageWithSingleSendingSigner(transactionMessage); const transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage); // Then the sending signer was used to send the transaction. - expect(signerA.newSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined }); - expect(signerB.newSignAndSendTransactions).toHaveBeenCalledWith( + expect(signerA.signTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined }); + expect(signerB.signAndSendTransactions).toHaveBeenCalledWith( [{ ...unsignedTransaction, signatures: { '1111': '1111_signature', '2222': null } }], { abortSignal: undefined }, ); @@ -555,7 +555,7 @@ describe('signAndSendTransactionWithSigners', () => { // Given a transaction with a mocked partial signer but no sending signer. const signer = createMockTransactionPartialSigner('1111' as Address); - signer.newSignTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); + signer.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); const transactionMessage = createMockTransactionMessageWithSigners([signer]); const unsignedTransaction: NewTransaction = { messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes, @@ -593,20 +593,20 @@ describe('signAndSendTransactionWithSigners', () => { }; jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction); - signerA.newSignAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); - signerB.newSignTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); + signerA.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); + signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]); // When we sign and send this transaction. assertIsTransactionMessageWithSingleSendingSigner(transactionMessage); const transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage); // Then the composite signer was used as a sending signer. - expect(signerA.newSignAndSendTransactions).toHaveBeenCalledWith( + expect(signerA.signAndSendTransactions).toHaveBeenCalledWith( [{ ...unsignedTransaction, signatures: { '1111': null, '2222': '2222_signature' } }], { abortSignal: undefined }, ); - expect(signerA.newSignTransactions).not.toHaveBeenCalled(); - expect(signerA.newModifyAndSignTransactions).not.toHaveBeenCalled(); + expect(signerA.signTransactions).not.toHaveBeenCalled(); + expect(signerA.modifyAndSignTransactions).not.toHaveBeenCalled(); // And the returned signature matches the one returned by that sending signer. expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3])); @@ -630,23 +630,23 @@ describe('signAndSendTransactionWithSigners', () => { // And given the following mocked signatures for these signers. const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature', '2222': null } }; - signerA.newModifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); - signerB.newSignAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); + signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); + signerB.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); // When we sign and send this transaction. assertIsTransactionMessageWithSingleSendingSigner(transaction); const transactionSignature = await signAndSendTransactionMessageWithSigners(transaction); // Then the composite signer was used as a modifying signer. - expect(signerA.newModifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { + expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined, }); - expect(signerA.newSignTransactions).not.toHaveBeenCalled(); - expect(signerA.newSignAndSendTransactions).not.toHaveBeenCalled(); + expect(signerA.signTransactions).not.toHaveBeenCalled(); + expect(signerA.signAndSendTransactions).not.toHaveBeenCalled(); // And the sending only signer was used to send the transaction. expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3])); - expect(signerB.newSignAndSendTransactions).toHaveBeenCalledWith([modifiedTransaction], { + expect(signerB.signAndSendTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined, }); }); @@ -671,29 +671,29 @@ describe('signAndSendTransactionWithSigners', () => { jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction); // And given the following mocked signatures for these signers. - signerA.newSignTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); - signerB.newSignAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); + signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]); + signerB.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': null, '2222': null, '3333': '3333_signature' }, }; - signerC.newModifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); + signerC.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]); // When we sign and send this transaction. assertIsTransactionMessageWithSingleSendingSigner(transaction); const transactionSignature = await signAndSendTransactionMessageWithSigners(transaction); // Then the composite signer was used as a partial signer. - expect(signerA.newSignTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); - expect(signerA.newModifyAndSignTransactions).not.toHaveBeenCalled(); - expect(signerA.newSignAndSendTransactions).not.toHaveBeenCalled(); + expect(signerA.signTransactions).toHaveBeenCalledWith([modifiedTransaction], { abortSignal: undefined }); + expect(signerA.modifyAndSignTransactions).not.toHaveBeenCalled(); + expect(signerA.signAndSendTransactions).not.toHaveBeenCalled(); // And the other signers were used as expected. - expect(signerC.newModifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { + expect(signerC.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], { abortSignal: undefined, }); expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3])); - expect(signerB.newSignAndSendTransactions).toHaveBeenCalledWith( + expect(signerB.signAndSendTransactions).toHaveBeenCalledWith( [ { ...unsignedTransaction, @@ -709,7 +709,7 @@ describe('signAndSendTransactionWithSigners', () => { // Given a transaction with a mocked sending signer. const signer = createMockTransactionSendingSigner('1111' as Address); - signer.newSignAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); + signer.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); const transactionMessage = createMockTransactionMessageWithSigners([signer]); const unsignedTransaction: NewTransaction = { messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes, @@ -738,7 +738,7 @@ describe('signAndSendTransactionWithSigners', () => { // Given a transaction with a mocked sending signer. const signer = createMockTransactionSendingSigner('1111' as Address); - signer.newSignAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); + signer.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]); const transactionMessage = createMockTransactionMessageWithSigners([signer]); const unsignedTransaction: NewTransaction = { messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes, diff --git a/packages/signers/src/__tests__/transaction-modifying-signer-test.ts b/packages/signers/src/__tests__/transaction-modifying-signer-test.ts index a1a0935815f0..221d89323bfb 100644 --- a/packages/signers/src/__tests__/transaction-modifying-signer-test.ts +++ b/packages/signers/src/__tests__/transaction-modifying-signer-test.ts @@ -13,7 +13,6 @@ describe('isTransactionModifyingSigner', () => { const mySigner = { address: myAddress, modifyAndSignTransactions: () => Promise.resolve([]), - newModifyAndSignTransactions: () => Promise.resolve([]), } satisfies TransactionModifyingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; expect(isTransactionModifyingSigner(mySigner)).toBe(true); @@ -28,7 +27,6 @@ describe('assertIsTransactionModifyingSigner', () => { const mySigner = { address: myAddress, modifyAndSignTransactions: () => Promise.resolve([]), - newModifyAndSignTransactions: () => Promise.resolve([]), } satisfies TransactionModifyingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; const expectedError = new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER, { diff --git a/packages/signers/src/__tests__/transaction-partial-signer-test.ts b/packages/signers/src/__tests__/transaction-partial-signer-test.ts index 7bcbe8252188..6db748c20ef2 100644 --- a/packages/signers/src/__tests__/transaction-partial-signer-test.ts +++ b/packages/signers/src/__tests__/transaction-partial-signer-test.ts @@ -12,7 +12,6 @@ describe('isTransactionPartialSigner', () => { const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'); const mySigner = { address: myAddress, - newSignTransactions: () => Promise.resolve([]), signTransactions: () => Promise.resolve([]), } satisfies TransactionPartialSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; @@ -27,7 +26,6 @@ describe('assertIsTransactionPartialSigner', () => { const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'); const mySigner = { address: myAddress, - newSignTransactions: () => Promise.resolve([]), signTransactions: () => Promise.resolve([]), } satisfies TransactionPartialSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; diff --git a/packages/signers/src/__tests__/transaction-sending-signer-test.ts b/packages/signers/src/__tests__/transaction-sending-signer-test.ts index f41c649392ac..7dc56e1309c0 100644 --- a/packages/signers/src/__tests__/transaction-sending-signer-test.ts +++ b/packages/signers/src/__tests__/transaction-sending-signer-test.ts @@ -12,7 +12,6 @@ describe('isTransactionSendingSigner', () => { const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'); const mySigner = { address: myAddress, - newSignAndSendTransactions: () => Promise.resolve([]), signAndSendTransactions: () => Promise.resolve([]), } satisfies TransactionSendingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; @@ -27,7 +26,6 @@ describe('assertIsTransactionSendingSigner', () => { const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'); const mySigner = { address: myAddress, - newSignAndSendTransactions: () => Promise.resolve([]), signAndSendTransactions: () => Promise.resolve([]), } satisfies TransactionSendingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; diff --git a/packages/signers/src/__tests__/transaction-signer-test.ts b/packages/signers/src/__tests__/transaction-signer-test.ts index 94e8ef18bca0..b51fe6ffa25a 100644 --- a/packages/signers/src/__tests__/transaction-signer-test.ts +++ b/packages/signers/src/__tests__/transaction-signer-test.ts @@ -8,17 +8,14 @@ describe('isTransactionSigner', () => { const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'); const myPartialSigner = { address: myAddress, - newSignTransactions: () => Promise.resolve([]), signTransactions: () => Promise.resolve([]), } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; const myModifyingSigner = { address: myAddress, modifyAndSignTransactions: () => Promise.resolve([]), - newModifyAndSignTransactions: () => Promise.resolve([]), } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; const mySendingSigner = { address: myAddress, - newSignAndSendTransactions: () => Promise.resolve([]), signAndSendTransactions: () => Promise.resolve([]), } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; @@ -41,17 +38,14 @@ describe('assertIsTransactionSigner', () => { const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'); const myPartialSigner = { address: myAddress, - newSignTransactions: () => Promise.resolve([]), signTransactions: () => Promise.resolve([]), } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; const myModifyingSigner = { address: myAddress, modifyAndSignTransactions: () => Promise.resolve([]), - newModifyAndSignTransactions: () => Promise.resolve([]), } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; const mySendingSigner = { address: myAddress, - newSignAndSendTransactions: () => Promise.resolve([]), signAndSendTransactions: () => Promise.resolve([]), } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>; diff --git a/packages/signers/src/__tests__/transaction-with-single-sending-signer.ts b/packages/signers/src/__tests__/transaction-with-single-sending-signer.ts index f96d6465b75d..682b39c44cd7 100644 --- a/packages/signers/src/__tests__/transaction-with-single-sending-signer.ts +++ b/packages/signers/src/__tests__/transaction-with-single-sending-signer.ts @@ -7,7 +7,6 @@ import { import { assertIsTransactionMessageWithSingleSendingSigner, - assertIsTransactionWithSingleSendingSigner, isTransactionMessageWithSingleSendingSigner, } from '../transaction-with-single-sending-signer'; import { @@ -16,7 +15,6 @@ import { createMockTransactionModifyingSigner, createMockTransactionPartialSigner, createMockTransactionSendingSigner, - createMockTransactionWithSigners, } from './__setup__'; describe('isTransactionMessageWithSingleSendingSigner', () => { @@ -106,49 +104,3 @@ describe('assertIsTransactionMessageWithSingleSendingSigner', () => { ); }); }); - -describe('assertIsTransactionWithSingleSendingSigner', () => { - it('succeeds if a transaction contains a single sending only signer', () => { - // Given a transaction with a single sending signer. - const signer = createMockTransactionSendingSigner('2222' as Address); - const transaction = createMockTransactionWithSigners([signer]); - - // Then we expect the assertion to succeed. - expect(() => assertIsTransactionWithSingleSendingSigner(transaction)).not.toThrow(); - }); - - it('succeeds if a transaction contains multiple sending signer composites', () => { - // Given a transaction with a two sending signers that can also be used as other signer interfaces. - const signerA = createMockTransactionCompositeSigner('1111' as Address); - const signerB = createMockTransactionCompositeSigner('2222' as Address); - const transaction = createMockTransactionWithSigners([signerA, signerB]); - - // Then we expect the assertion to succeed because we can use one of them - // as a sending signer and the other as a modifying or partial signer. - expect(() => assertIsTransactionWithSingleSendingSigner(transaction)).not.toThrow(); - }); - - it('fails if a transaction contains multiple sending only signer', () => { - // Given a transaction with a two sending only signers. - const signerA = createMockTransactionSendingSigner('1111' as Address); - const signerB = createMockTransactionSendingSigner('2222' as Address); - const transaction = createMockTransactionWithSigners([signerA, signerB]); - - // Then we expect the assertion to fail. - expect(() => assertIsTransactionWithSingleSendingSigner(transaction)).toThrow( - new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS), - ); - }); - - it('fails if a transaction contains no sending signer at all', () => { - // Given a transaction with no sending signer. - const signerA = createMockTransactionPartialSigner('1111' as Address); - const signerB = createMockTransactionModifyingSigner('2222' as Address); - const transaction = createMockTransactionWithSigners([signerA, signerB]); - - // Then we expect the assertion to fail. - expect(() => assertIsTransactionWithSingleSendingSigner(transaction)).toThrow( - new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING), - ); - }); -}); diff --git a/packages/signers/src/account-signer-meta.ts b/packages/signers/src/account-signer-meta.ts index e20ca4c27c61..2b366cf58782 100644 --- a/packages/signers/src/account-signer-meta.ts +++ b/packages/signers/src/account-signer-meta.ts @@ -1,6 +1,5 @@ import { AccountRole, IAccountLookupMeta, IAccountMeta, IInstruction } from '@solana/instructions'; -import { BaseTransactionMessage } from '@solana/transaction-messages'; -import { BaseTransaction, TransactionVersion } from '@solana/transactions'; +import { BaseTransactionMessage, NewTransactionVersion } from '@solana/transaction-messages'; import { deduplicateSigners } from './deduplicate-signers'; import { TransactionSigner } from './transaction-signer'; @@ -25,21 +24,12 @@ export type IInstructionWithSigners< TAccounts extends readonly IAccountMetaWithSigner[] = readonly IAccountMetaWithSigner[], > = Pick, 'accounts'>; -/** A variation of the transaction type that allows IAccountSignerMeta in its account metas. */ -export type ITransactionWithSigners< - TSigner extends TransactionSigner = TransactionSigner, - TAccounts extends readonly IAccountMetaWithSigner[] = readonly IAccountMetaWithSigner[], -> = Pick< - BaseTransaction>, - 'instructions' -> & { feePayerSigner?: TSigner }; - /** A variation of the transaction message type that allows IAccountSignerMeta in its account metas. */ export type ITransactionMessageWithSigners< TSigner extends TransactionSigner = TransactionSigner, TAccounts extends readonly IAccountMetaWithSigner[] = readonly IAccountMetaWithSigner[], > = Pick< - BaseTransactionMessage>, + BaseTransactionMessage>, 'instructions' > & { feePayerSigner?: TSigner }; @@ -52,17 +42,6 @@ export function getSignersFromInstruction = ITransactionWithSigners, ->(transaction: TTransaction): readonly TSigner[] { - return deduplicateSigners([ - ...(transaction.feePayerSigner ? [transaction.feePayerSigner] : []), - ...transaction.instructions.flatMap(getSignersFromInstruction), - ]); -} - /** Extract all signers from a transaction message that may contain IAccountSignerMeta accounts. */ export function getSignersFromTransactionMessage< TSigner extends TransactionSigner = TransactionSigner, diff --git a/packages/signers/src/add-signers.ts b/packages/signers/src/add-signers.ts index 1bcbdc5574e9..6ab5ac49a7fb 100644 --- a/packages/signers/src/add-signers.ts +++ b/packages/signers/src/add-signers.ts @@ -1,12 +1,7 @@ import { IInstruction, isSignerRole } from '@solana/instructions'; import { BaseTransactionMessage } from '@solana/transaction-messages'; -import { - IAccountSignerMeta, - IInstructionWithSigners, - ITransactionMessageWithSigners, - ITransactionWithSigners, -} from './account-signer-meta'; +import { IAccountSignerMeta, IInstructionWithSigners, ITransactionMessageWithSigners } from './account-signer-meta'; import { deduplicateSigners } from './deduplicate-signers'; import { TransactionSigner } from './transaction-signer'; @@ -35,10 +30,10 @@ export function addSignersToInstruction( /** Attaches the provided signers to the account metas of a transaction message when applicable. */ export function addSignersToTransactionMessage( signers: TransactionSigner[], - transactionMessage: TTransactionMessage | (ITransactionWithSigners & TTransactionMessage), + transactionMessage: TTransactionMessage | (ITransactionMessageWithSigners & TTransactionMessage), ): ITransactionMessageWithSigners & TTransactionMessage { if (transactionMessage.instructions.length === 0) { - return transactionMessage as ITransactionWithSigners & TTransactionMessage; + return transactionMessage as ITransactionMessageWithSigners & TTransactionMessage; } return Object.freeze({ diff --git a/packages/signers/src/keypair-signer.ts b/packages/signers/src/keypair-signer.ts index 5fe270425e64..1af6ed725f6f 100644 --- a/packages/signers/src/keypair-signer.ts +++ b/packages/signers/src/keypair-signer.ts @@ -1,7 +1,7 @@ import { Address, getAddressFromPublicKey } from '@solana/addresses'; import { SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER, SolanaError } from '@solana/errors'; import { createKeyPairFromBytes, generateKeyPair, signBytes } from '@solana/keys'; -import { newPartiallySignTransaction, partiallySignTransaction } from '@solana/transactions'; +import { newPartiallySignTransaction } from '@solana/transactions'; import { isMessagePartialSigner, MessagePartialSigner } from './message-partial-signer'; import { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer'; @@ -41,14 +41,6 @@ export async function createSignerFromKeyPair(keyPair: CryptoKeyPair): Promise - Promise.all( - transactions.map(async transaction => { - const signedTransaction = await newPartiallySignTransaction([keyPair], transaction); - // we know that the address has signed `signedTransaction` because it comes from the keypair - return Object.freeze({ [address]: signedTransaction.signatures[address]! }); - }), - ), signMessages: messages => Promise.all( messages.map(async message => @@ -58,8 +50,9 @@ export async function createSignerFromKeyPair(keyPair: CryptoKeyPair): Promise Promise.all( transactions.map(async transaction => { - const signedTransaction = await partiallySignTransaction([keyPair], transaction); - return Object.freeze({ [address]: signedTransaction.signatures[address] }); + const signedTransaction = await newPartiallySignTransaction([keyPair], transaction); + // we know that the address has signed `signedTransaction` because it comes from the keypair + return Object.freeze({ [address]: signedTransaction.signatures[address]! }); }), ), }; diff --git a/packages/signers/src/noop-signer.ts b/packages/signers/src/noop-signer.ts index f81081a70c8f..0c743fb72ea0 100644 --- a/packages/signers/src/noop-signer.ts +++ b/packages/signers/src/noop-signer.ts @@ -11,7 +11,6 @@ export type NoopSigner = MessagePartialSigner< export function createNoopSigner(address: Address): NoopSigner { const out: NoopSigner = { address, - newSignTransactions: transactions => Promise.resolve(transactions.map(() => Object.freeze({}))), signMessages: messages => Promise.resolve(messages.map(() => Object.freeze({}))), signTransactions: transactions => Promise.resolve(transactions.map(() => Object.freeze({}))), }; diff --git a/packages/signers/src/sign-transaction.ts b/packages/signers/src/sign-transaction.ts index 9d7526e0e3fb..7fbe441f3a17 100644 --- a/packages/signers/src/sign-transaction.ts +++ b/packages/signers/src/sign-transaction.ts @@ -8,7 +8,7 @@ import { NewTransaction, } from '@solana/transactions'; -import { getSignersFromTransaction, ITransactionMessageWithSigners } from './account-signer-meta'; +import { getSignersFromTransactionMessage, ITransactionMessageWithSigners } from './account-signer-meta'; import { deduplicateSigners } from './deduplicate-signers'; import { isTransactionModifyingSigner, TransactionModifyingSigner } from './transaction-modifying-signer'; import { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer'; @@ -27,7 +27,7 @@ export async function partiallySignTransactionMessageWithSigners< TTransactionMessage extends CompilableTransactionMessageWithSigners = CompilableTransactionMessageWithSigners, >(transactionMessage: TTransactionMessage, config: { abortSignal?: AbortSignal } = {}): Promise { const { partialSigners, modifyingSigners } = categorizeTransactionSigners( - deduplicateSigners(getSignersFromTransaction(transactionMessage).filter(isTransactionSigner)), + deduplicateSigners(getSignersFromTransactionMessage(transactionMessage).filter(isTransactionSigner)), { identifySendingSigner: false }, ); @@ -69,7 +69,7 @@ export async function signAndSendTransactionMessageWithSigners< >(transaction: TTransactionMessage, config: { abortSignal?: AbortSignal } = {}): Promise { const abortSignal = config.abortSignal; const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners( - deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)), + deduplicateSigners(getSignersFromTransactionMessage(transaction).filter(isTransactionSigner)), ); abortSignal?.throwIfAborted(); @@ -85,7 +85,7 @@ export async function signAndSendTransactionMessageWithSigners< } abortSignal?.throwIfAborted(); - const [signature] = await sendingSigner.newSignAndSendTransactions([signedTransaction], { abortSignal }); + const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal }); abortSignal?.throwIfAborted(); return signature; @@ -183,7 +183,7 @@ async function signModifyingAndPartialTransactionSigners< const modifiedTransaction = await modifyingSigners.reduce( async (transaction, modifyingSigner) => { abortSignal?.throwIfAborted(); - const [tx] = await modifyingSigner.newModifyAndSignTransactions([await transaction], { abortSignal }); + const [tx] = await modifyingSigner.modifyAndSignTransactions([await transaction], { abortSignal }); return Object.freeze(tx); }, Promise.resolve(transaction) as Promise, @@ -193,7 +193,7 @@ async function signModifyingAndPartialTransactionSigners< abortSignal?.throwIfAborted(); const signatureDictionaries = await Promise.all( partialSigners.map(async partialSigner => { - const [signatures] = await partialSigner.newSignTransactions([modifiedTransaction], { abortSignal }); + const [signatures] = await partialSigner.signTransactions([modifiedTransaction], { abortSignal }); return signatures; }), ); diff --git a/packages/signers/src/transaction-modifying-signer.ts b/packages/signers/src/transaction-modifying-signer.ts index f3fd7e6a69ae..15eb73fc7505 100644 --- a/packages/signers/src/transaction-modifying-signer.ts +++ b/packages/signers/src/transaction-modifying-signer.ts @@ -1,6 +1,6 @@ import { Address } from '@solana/addresses'; import { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER, SolanaError } from '@solana/errors'; -import { CompilableTransaction, NewTransaction } from '@solana/transactions'; +import { NewTransaction } from '@solana/transactions'; import { BaseSignerConfig } from './types'; @@ -9,11 +9,7 @@ export type TransactionModifyingSignerConfig = BaseSignerConfig; /** Defines a signer capable of signing transactions. */ export type TransactionModifyingSigner = Readonly<{ address: Address; - modifyAndSignTransactions( - transactions: readonly TTransaction[], - config?: TransactionModifyingSignerConfig, - ): Promise; - newModifyAndSignTransactions( + modifyAndSignTransactions( transactions: readonly NewTransaction[], config?: TransactionModifyingSignerConfig, ): Promise; diff --git a/packages/signers/src/transaction-partial-signer.ts b/packages/signers/src/transaction-partial-signer.ts index 157d83c3e55a..a6f72e6f104d 100644 --- a/packages/signers/src/transaction-partial-signer.ts +++ b/packages/signers/src/transaction-partial-signer.ts @@ -1,6 +1,6 @@ import { Address } from '@solana/addresses'; import { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER, SolanaError } from '@solana/errors'; -import { CompilableTransaction, NewTransaction } from '@solana/transactions'; +import { NewTransaction } from '@solana/transactions'; import { BaseSignerConfig, SignatureDictionary } from './types'; @@ -9,12 +9,8 @@ export type TransactionPartialSignerConfig = BaseSignerConfig; /** Defines a signer capable of signing transactions. */ export type TransactionPartialSigner = Readonly<{ address: Address; - newSignTransactions( - transactions: readonly NewTransaction[], - config?: TransactionPartialSignerConfig, - ): Promise; signTransactions( - transactions: readonly CompilableTransaction[], + transactions: readonly NewTransaction[], config?: TransactionPartialSignerConfig, ): Promise; }>; diff --git a/packages/signers/src/transaction-sending-signer.ts b/packages/signers/src/transaction-sending-signer.ts index 825b9678b82d..1e34d1d88e39 100644 --- a/packages/signers/src/transaction-sending-signer.ts +++ b/packages/signers/src/transaction-sending-signer.ts @@ -1,7 +1,7 @@ import { Address } from '@solana/addresses'; import { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER, SolanaError } from '@solana/errors'; import { SignatureBytes } from '@solana/keys'; -import { CompilableTransaction, NewTransaction } from '@solana/transactions'; +import { NewTransaction } from '@solana/transactions'; import { BaseSignerConfig } from './types'; @@ -10,12 +10,8 @@ export type TransactionSendingSignerConfig = BaseSignerConfig; /** Defines a signer capable of signing and sending transactions simultaneously. */ export type TransactionSendingSigner = Readonly<{ address: Address; - newSignAndSendTransactions( - transactions: readonly NewTransaction[], - config?: TransactionSendingSignerConfig, - ): Promise; signAndSendTransactions( - transactions: readonly CompilableTransaction[], + transactions: readonly NewTransaction[], config?: TransactionSendingSignerConfig, ): Promise; }>; diff --git a/packages/signers/src/transaction-with-single-sending-signer.ts b/packages/signers/src/transaction-with-single-sending-signer.ts index 75b295168028..384cef3906c1 100644 --- a/packages/signers/src/transaction-with-single-sending-signer.ts +++ b/packages/signers/src/transaction-with-single-sending-signer.ts @@ -4,14 +4,8 @@ import { SolanaError, } from '@solana/errors'; import { CompilableTransactionMessage } from '@solana/transaction-messages'; -import { CompilableTransaction } from '@solana/transactions'; -import { - getSignersFromTransaction, - getSignersFromTransactionMessage, - ITransactionMessageWithSigners, - ITransactionWithSigners, -} from './account-signer-meta'; +import { getSignersFromTransactionMessage, ITransactionMessageWithSigners } from './account-signer-meta'; import { isTransactionModifyingSigner } from './transaction-modifying-signer'; import { isTransactionPartialSigner } from './transaction-partial-signer'; import { isTransactionSendingSigner } from './transaction-sending-signer'; @@ -57,43 +51,3 @@ export function assertIsTransactionMessageWithSingleSendingSigner< throw new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS); } } - -/** Defines a transaction with exactly one {@link TransactionSendingSigner}. */ -export type ITransactionWithSingleSendingSigner = ITransactionWithSigners & { - readonly __transactionWithSingleSendingSigner: unique symbol; -}; - -/** Checks whether the provided transaction has exactly one {@link TransactionSendingSigner}. */ -export function _isTransactionWithSingleSendingSigner( - transaction: TTransaction, -): transaction is ITransactionWithSingleSendingSigner & TTransaction { - try { - assertIsTransactionWithSingleSendingSigner(transaction); - return true; - } catch { - return false; - } -} - -/** Asserts that the provided transaction has exactly one {@link TransactionSendingSigner}. */ -export function assertIsTransactionWithSingleSendingSigner( - transaction: TTransaction, -): asserts transaction is ITransactionWithSingleSendingSigner & TTransaction { - const signers = getSignersFromTransaction(transaction); - const sendingSigners = signers.filter(isTransactionSendingSigner); - - if (sendingSigners.length === 0) { - throw new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING); - } - - // When identifying if there are multiple sending signers, we only need to check for - // sending signers that do not implement other transaction signer interfaces as - // they will be used as these other signer interfaces in case of a conflict. - const sendingOnlySigners = sendingSigners.filter( - signer => !isTransactionPartialSigner(signer) && !isTransactionModifyingSigner(signer), - ); - - if (sendingOnlySigners.length > 1) { - throw new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS); - } -}