diff --git a/.changeset/witty-things-care.md b/.changeset/witty-things-care.md new file mode 100644 index 0000000..2a36bb7 --- /dev/null +++ b/.changeset/witty-things-care.md @@ -0,0 +1,15 @@ +--- +'@solana/kit-plugin-rpc': minor +'@solana/kit-plugin-litesvm': minor +--- + +Remove the `payer` config option from `rpcTransactionPlanner` and `litesvmTransactionPlanner`. The payer must now be set on the client before applying these plugins. + +**BREAKING CHANGES** + +**`payer` config option removed from transaction planner plugins.** The payer can no longer be passed as a config override. Use a payer plugin on the client instead. + +```diff +- createClient().use(rpcTransactionPlanner({ payer: myPayer })); ++ createClient().use(payer(myPayer)).use(rpcTransactionPlanner()); +``` diff --git a/packages/kit-plugin-litesvm/README.md b/packages/kit-plugin-litesvm/README.md index 851a131..3c172da 100644 --- a/packages/kit-plugin-litesvm/README.md +++ b/packages/kit-plugin-litesvm/README.md @@ -127,7 +127,7 @@ This plugin provides a default transaction planner that creates transaction mess ### Installation -This plugin requires a payer to be set on the client or passed as an option. +The client must have a `payer` set before applying this plugin. ```ts import { createClient } from '@solana/kit'; @@ -147,7 +147,6 @@ const client = await createClient() ### Options -- `payer`: Transaction signer for fees (defaults to client's payer if any). - `priorityFees`: Priority fees in micro lamports per compute unit. ### Features diff --git a/packages/kit-plugin-litesvm/src/transaction-planner.ts b/packages/kit-plugin-litesvm/src/transaction-planner.ts index 21f1838..a6dfde0 100644 --- a/packages/kit-plugin-litesvm/src/transaction-planner.ts +++ b/packages/kit-plugin-litesvm/src/transaction-planner.ts @@ -7,7 +7,6 @@ import { pipe, setTransactionMessageComputeUnitPrice, setTransactionMessageFeePayerSigner, - TransactionSigner, } from '@solana/kit'; /** @@ -35,11 +34,6 @@ import { */ export function litesvmTransactionPlanner( config: { - /** - * The transaction signer who will pay for the transaction fees. - * Defaults to the client's payer or throws if not present. - */ - payer?: TransactionSigner; /** * The priority fees to be set on the transaction in micro lamports per compute unit. * Defaults to using no priority fees. @@ -47,20 +41,12 @@ export function litesvmTransactionPlanner( priorityFees?: MicroLamports; } = {}, ) { - return >(client: T) => { - const payer = config.payer ?? client.payer; - if (!payer) { - throw new Error( - 'A payer is required to create the LiteSVM transaction planner. ' + - 'Please provide one in the config of this plugin or on the client under `payer`.', - ); - } - + return (client: T) => { const transactionPlanner = createTransactionPlanner({ createTransactionMessage: () => { return pipe( createTransactionMessage({ version: 0 }), - tx => setTransactionMessageFeePayerSigner(payer, tx), + tx => setTransactionMessageFeePayerSigner(client.payer, tx), tx => (config.priorityFees ? setTransactionMessageComputeUnitPrice(config.priorityFees, tx) : tx), ); }, diff --git a/packages/kit-plugin-litesvm/test/transaction-planner.test.ts b/packages/kit-plugin-litesvm/test/transaction-planner.test.ts index 06eb167..f58b9d5 100644 --- a/packages/kit-plugin-litesvm/test/transaction-planner.test.ts +++ b/packages/kit-plugin-litesvm/test/transaction-planner.test.ts @@ -35,24 +35,8 @@ describe('litesvmTransactionPlanner', () => { expect(transactionPlan.message.feePayer).toBe(payer); }); - it('requires a payer on the client by default', () => { - expect(() => createClient().use(litesvmTransactionPlanner())).toThrow(); - }); - - it('also accepts a payer directly', () => { - const payer = {} as TransactionSigner; - expect(() => createClient().use(litesvmTransactionPlanner({ payer }))).not.toThrow(); - }); - - it('uses the provided payer over the one set on the client', async () => { - const [clientPayer, explicitPayer] = await Promise.all([generateKeyPairSigner(), generateKeyPairSigner()]); - const client = createClient() - .use(() => ({ payer: clientPayer })) - .use(litesvmTransactionPlanner({ payer: explicitPayer })); - - const instructionPlan = singleInstructionPlan(MOCK_INSTRUCTION); - const transactionPlan = (await client.transactionPlanner(instructionPlan)) as SingleTransactionPlan; - expect(transactionPlan.kind).toBe('single'); - expect(transactionPlan.message.feePayer).toBe(explicitPayer); + it('requires a payer on the client', () => { + // @ts-expect-error TypeScript fails but we don't throw an error at runtime. + expect(() => createClient().use(litesvmTransactionPlanner())).not.toThrow(); }); }); diff --git a/packages/kit-plugin-rpc/README.md b/packages/kit-plugin-rpc/README.md index 9832237..81fee76 100644 --- a/packages/kit-plugin-rpc/README.md +++ b/packages/kit-plugin-rpc/README.md @@ -279,7 +279,7 @@ This plugin provides a default transaction planner that creates transaction mess ### Installation -This plugin requires a payer to be set on the client or passed as an option. +The client must have a `payer` set before applying this plugin. ```ts import { createClient } from '@solana/kit'; @@ -301,7 +301,6 @@ const client = await createClient() ### Options -- `payer`: Transaction signer for fees (defaults to client's payer if any). - `priorityFees`: Priority fees in micro lamports per compute unit. ### Features diff --git a/packages/kit-plugin-rpc/src/transaction-planner.ts b/packages/kit-plugin-rpc/src/transaction-planner.ts index 4a49cc2..e091458 100644 --- a/packages/kit-plugin-rpc/src/transaction-planner.ts +++ b/packages/kit-plugin-rpc/src/transaction-planner.ts @@ -8,7 +8,6 @@ import { pipe, setTransactionMessageComputeUnitPrice, setTransactionMessageFeePayerSigner, - TransactionSigner, } from '@solana/kit'; /** @@ -38,11 +37,6 @@ import { */ export function rpcTransactionPlanner( config: { - /** - * The transaction signer who will pay for the transaction fees. - * Defaults to the client's payer or throws if not present. - */ - payer?: TransactionSigner; /** * The priority fees to be set on the transaction in micro lamports per compute unit. * Defaults to using no priority fees. @@ -50,20 +44,12 @@ export function rpcTransactionPlanner( priorityFees?: MicroLamports; } = {}, ) { - return >(client: T) => { - const payer = config.payer ?? client.payer; - if (!payer) { - throw new Error( - 'A payer is required to create the RPC transaction planner. ' + - 'Please provide one in the config of this plugin or on the client under `payer`.', - ); - } - + return (client: T) => { const transactionPlanner = createTransactionPlanner({ createTransactionMessage: () => { return pipe( createTransactionMessage({ version: 0 }), - tx => setTransactionMessageFeePayerSigner(payer, tx), + tx => setTransactionMessageFeePayerSigner(client.payer, tx), tx => fillTransactionMessageProvisoryComputeUnitLimit(tx), tx => (config.priorityFees ? setTransactionMessageComputeUnitPrice(config.priorityFees, tx) : tx), ); diff --git a/packages/kit-plugin-rpc/test/transaction-planner.test.ts b/packages/kit-plugin-rpc/test/transaction-planner.test.ts index 31a7155..27cb5e6 100644 --- a/packages/kit-plugin-rpc/test/transaction-planner.test.ts +++ b/packages/kit-plugin-rpc/test/transaction-planner.test.ts @@ -35,24 +35,8 @@ describe('rpcTransactionPlanner', () => { expect(transactionPlan.message.feePayer).toBe(payer); }); - it('requires a payer on the client by default', () => { - expect(() => createClient().use(rpcTransactionPlanner())).toThrow(); - }); - - it('also accepts a payer directly', () => { - const payer = {} as TransactionSigner; - expect(() => createClient().use(rpcTransactionPlanner({ payer }))).not.toThrow(); - }); - - it('uses the provided payer over the one set on the client', async () => { - const [clientPayer, explicitPayer] = await Promise.all([generateKeyPairSigner(), generateKeyPairSigner()]); - const client = createClient() - .use(() => ({ payer: clientPayer })) - .use(rpcTransactionPlanner({ payer: explicitPayer })); - - const instructionPlan = singleInstructionPlan(MOCK_INSTRUCTION); - const transactionPlan = (await client.transactionPlanner(instructionPlan)) as SingleTransactionPlan; - expect(transactionPlan.kind).toBe('single'); - expect(transactionPlan.message.feePayer).toBe(explicitPayer); + it('requires a payer on the client', () => { + // @ts-expect-error TypeScript fails but we don't throw an error at runtime. + expect(() => createClient().use(rpcTransactionPlanner())).not.toThrow(); }); });