Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .changeset/witty-things-care.md
Original file line number Diff line number Diff line change
@@ -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());
```
3 changes: 1 addition & 2 deletions packages/kit-plugin-litesvm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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
Expand Down
18 changes: 2 additions & 16 deletions packages/kit-plugin-litesvm/src/transaction-planner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
pipe,
setTransactionMessageComputeUnitPrice,
setTransactionMessageFeePayerSigner,
TransactionSigner,
} from '@solana/kit';

/**
Expand Down Expand Up @@ -35,32 +34,19 @@ 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.
*/
priorityFees?: MicroLamports;
} = {},
) {
return <T extends Partial<ClientWithPayer>>(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 <T extends ClientWithPayer>(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),
);
},
Expand Down
22 changes: 3 additions & 19 deletions packages/kit-plugin-litesvm/test/transaction-planner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
3 changes: 1 addition & 2 deletions packages/kit-plugin-rpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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
Expand Down
18 changes: 2 additions & 16 deletions packages/kit-plugin-rpc/src/transaction-planner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
pipe,
setTransactionMessageComputeUnitPrice,
setTransactionMessageFeePayerSigner,
TransactionSigner,
} from '@solana/kit';

/**
Expand Down Expand Up @@ -38,32 +37,19 @@ 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.
*/
priorityFees?: MicroLamports;
} = {},
) {
return <T extends Partial<ClientWithPayer>>(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 <T extends ClientWithPayer>(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),
);
Expand Down
22 changes: 3 additions & 19 deletions packages/kit-plugin-rpc/test/transaction-planner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
Loading