@solana/instruction-plans 5.2.0-canary-20251219213520 → 5.2.0-canary-20251228203229
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/dist/index.browser.cjs +26 -1
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.mjs +27 -2
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.native.mjs +27 -2
- package/dist/index.native.mjs.map +1 -1
- package/dist/index.node.cjs +26 -1
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +27 -2
- package/dist/index.node.mjs.map +1 -1
- package/dist/types/transaction-plan-executor.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/index.browser.cjs
CHANGED
|
@@ -208,6 +208,7 @@ function createTransactionPlanExecutor(config) {
|
|
|
208
208
|
abortSignal,
|
|
209
209
|
canceled: abortSignal?.aborted ?? false
|
|
210
210
|
};
|
|
211
|
+
assertDivisibleSequentialPlansOnly(plan);
|
|
211
212
|
const cancelHandler = () => {
|
|
212
213
|
context.canceled = true;
|
|
213
214
|
};
|
|
@@ -242,12 +243,15 @@ async function traverse(transactionPlan, context) {
|
|
|
242
243
|
}
|
|
243
244
|
}
|
|
244
245
|
async function traverseSequential(transactionPlan, context) {
|
|
246
|
+
if (!transactionPlan.divisible) {
|
|
247
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED);
|
|
248
|
+
}
|
|
245
249
|
const results = [];
|
|
246
250
|
for (const subPlan of transactionPlan.plans) {
|
|
247
251
|
const result = await traverse(subPlan, context);
|
|
248
252
|
results.push(result);
|
|
249
253
|
}
|
|
250
|
-
return
|
|
254
|
+
return sequentialTransactionPlanResult(results);
|
|
251
255
|
}
|
|
252
256
|
async function traverseParallel(transactionPlan, context) {
|
|
253
257
|
const results = await Promise.all(transactionPlan.plans.map((plan) => traverse(plan, context)));
|
|
@@ -287,6 +291,27 @@ function findErrorFromTransactionPlanResult(result) {
|
|
|
287
291
|
}
|
|
288
292
|
}
|
|
289
293
|
}
|
|
294
|
+
function assertDivisibleSequentialPlansOnly(transactionPlan) {
|
|
295
|
+
const kind = transactionPlan.kind;
|
|
296
|
+
switch (kind) {
|
|
297
|
+
case "sequential":
|
|
298
|
+
if (!transactionPlan.divisible) {
|
|
299
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED);
|
|
300
|
+
}
|
|
301
|
+
for (const subPlan of transactionPlan.plans) {
|
|
302
|
+
assertDivisibleSequentialPlansOnly(subPlan);
|
|
303
|
+
}
|
|
304
|
+
return;
|
|
305
|
+
case "parallel":
|
|
306
|
+
for (const subPlan of transactionPlan.plans) {
|
|
307
|
+
assertDivisibleSequentialPlansOnly(subPlan);
|
|
308
|
+
}
|
|
309
|
+
return;
|
|
310
|
+
case "single":
|
|
311
|
+
default:
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
290
315
|
|
|
291
316
|
// src/transaction-plan.ts
|
|
292
317
|
function parallelTransactionPlan(plans) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/instruction-plan.ts","../src/transaction-plan-result.ts","../src/transaction-plan-executor.ts","../src/transaction-plan.ts","../src/transaction-planner.ts"],"names":["SolanaError","SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE","getTransactionMessageSize","appendTransactionMessageInstruction","TRANSACTION_SIZE_LIMIT","SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN","getSignatureFromTransaction","traverse","result","context","SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN","SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND","getAbortablePromise","SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN","traverseSequential","traverseParallel","traverseSingle","SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND","candidate","message","appendTransactionMessageInstructions","isSolanaError"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["import {\n SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE,\n SolanaError,\n} from '@solana/errors';\nimport { Instruction } from '@solana/instructions';\nimport {\n appendTransactionMessageInstruction,\n BaseTransactionMessage,\n TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { getTransactionMessageSize, TRANSACTION_SIZE_LIMIT } from '@solana/transactions';\n\n/**\n * A set of instructions with constraints on how they can be executed.\n *\n * This is structured as a recursive tree of plans in order to allow for\n * parallel execution, sequential execution and combinations of both.\n *\n * Namely the following plans are supported:\n * - {@link SingleInstructionPlan} - A plan that contains a single instruction.\n * This is a simple instruction wrapper and the simplest leaf in this tree.\n * - {@link ParallelInstructionPlan} - A plan that contains other plans that\n * can be executed in parallel.\n * - {@link SequentialInstructionPlan} - A plan that contains other plans that\n * must be executed sequentially. It also defines whether the plan is divisible\n * meaning that instructions inside it can be split into separate transactions.\n * - {@link MessagePackerInstructionPlan} - A plan that can dynamically pack\n * instructions into transaction messages.\n *\n * Helpers are provided for each of these plans to make it easier to create them.\n *\n * @example\n * ```ts\n * const myInstructionPlan: InstructionPlan = parallelInstructionPlan([\n * sequentialInstructionPlan([instructionA, instructionB]),\n * instructionC,\n * instructionD,\n * ]);\n * ```\n *\n * @see {@link SingleInstructionPlan}\n * @see {@link ParallelInstructionPlan}\n * @see {@link SequentialInstructionPlan}\n * @see {@link MessagePackerInstructionPlan}\n */\nexport type InstructionPlan =\n | MessagePackerInstructionPlan\n | ParallelInstructionPlan\n | SequentialInstructionPlan\n | SingleInstructionPlan;\n\n/**\n * A plan wrapping other plans that must be executed sequentially.\n *\n * It also defines whether nested plans are divisible — meaning that\n * the instructions inside them can be split into separate transactions.\n * When `divisible` is `false`, the instructions inside the plan should\n * all be executed atomically — either in a single transaction or in a\n * transaction bundle.\n *\n * You may use the {@link sequentialInstructionPlan} and {@link nonDivisibleSequentialInstructionPlan}\n * helpers to create objects of this type.\n *\n * @example Simple sequential plan with two instructions.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, instructionB]);\n * plan satisfies SequentialInstructionPlan;\n * ```\n *\n * @example Non-divisible sequential plan with two instructions.\n * ```ts\n * const plan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n * plan satisfies SequentialInstructionPlan & { divisible: false };\n * ```\n *\n * @example Sequential plan with nested parallel plans.\n * Here, instructions A and B can be executed in parallel, but they must both be finalized\n * before instructions C and D can be sent — which can also be executed in parallel.\n * ```ts\n * const plan = sequentialInstructionPlan([\n * parallelInstructionPlan([instructionA, instructionB]),\n * parallelInstructionPlan([instructionC, instructionD]),\n * ]);\n * plan satisfies SequentialInstructionPlan & { divisible: false };\n * ```\n *\n * @see {@link sequentialInstructionPlan}\n * @see {@link nonDivisibleSequentialInstructionPlan}\n */\nexport type SequentialInstructionPlan = Readonly<{\n divisible: boolean;\n kind: 'sequential';\n plans: InstructionPlan[];\n}>;\n\n/**\n * A plan wrapping other plans that can be executed in parallel.\n *\n * This means direct children of this plan can be executed in separate\n * parallel transactions without consequence.\n * However, the children themselves can define additional constraints\n * for that specific branch of the tree — such as the {@link SequentialInstructionPlan}.\n *\n * You may use the {@link parallelInstructionPlan} helper to create objects of this type.\n *\n * @example Simple parallel plan with two instructions.\n * ```ts\n * const plan = parallelInstructionPlan([instructionA, instructionB]);\n * plan satisfies ParallelInstructionPlan;\n * ```\n *\n * @example Parallel plan with nested sequential plans.\n * Here, instructions A and B must be executed sequentially and so must instructions C and D,\n * but both pairs can be executed in parallel.\n * ```ts\n * const plan = parallelInstructionPlan([\n * sequentialInstructionPlan([instructionA, instructionB]),\n * sequentialInstructionPlan([instructionC, instructionD]),\n * ]);\n * plan satisfies ParallelInstructionPlan;\n * ```\n *\n * @see {@link parallelInstructionPlan}\n */\nexport type ParallelInstructionPlan = Readonly<{\n kind: 'parallel';\n plans: InstructionPlan[];\n}>;\n\n/**\n * A plan that contains a single instruction.\n *\n * This is a simple instruction wrapper that transforms an instruction into a plan.\n *\n * You may use the {@link singleInstructionPlan} helper to create objects of this type.\n *\n * @example\n * ```ts\n * const plan = singleInstructionPlan(instructionA);\n * plan satisfies SingleInstructionPlan;\n * ```\n *\n * @see {@link singleInstructionPlan}\n */\nexport type SingleInstructionPlan<TInstruction extends Instruction = Instruction> = Readonly<{\n instruction: TInstruction;\n kind: 'single';\n}>;\n\n/**\n * A plan that can dynamically pack instructions into transaction messages.\n *\n * This plan provides a {@link MessagePacker} via the `getMessagePacker`\n * method, which enables instructions to be dynamically packed into the\n * provided transaction message until there are no more instructions to pack.\n * The returned {@link MessagePacker} offers a `packMessageToCapacity(message)`\n * method that packs the provided message — when possible — and a `done()` method\n * that checks whether there are more instructions to pack.\n *\n * Several helper functions are provided to create objects of this type such as\n * {@link getLinearMessagePackerInstructionPlan} or {@link getMessagePackerInstructionPlanFromInstructions}.\n *\n * @example An message packer plan for a write instruction that uses as many bytes as possible.\n * ```ts\n * const plan = getLinearMessagePackerInstructionPlan({\n * totalLength: dataToWrite.length,\n * getInstruction: (offset, length) =>\n * getWriteInstruction({\n * offset,\n * data: dataToWrite.slice(offset, offset + length),\n * }),\n * });\n * plan satisfies MessagePackerInstructionPlan;\n * ```\n *\n * @example A message packer plan for multiple realloc instructions.\n * ```ts\n * const plan = getReallocMessagePackerInstructionPlan({\n * totalSize: additionalDataSize,\n * getInstruction: (size) => getExtendInstruction({ length: size }),\n * });\n * plan satisfies MessagePackerInstructionPlan;\n * ```\n *\n * @example Using a message packer plan.\n * ```ts\n * let plan: MessagePackerInstructionPlan;\n * const messagePacker = plan.getMessagePacker();\n *\n * while (!messagePacker.done()) {\n * try {\n * transactionMessage = messagePacker.packMessageToCapacity(transactionMessage);\n * } catch (error) {\n * // The current transaction message cannot be used to pack this plan.\n * // We should create a new one and try again.\n * }\n * }\n * ```\n *\n * @see {@link getLinearMessagePackerInstructionPlan}\n * @see {@link getMessagePackerInstructionPlanFromInstructions}\n * @see {@link getReallocMessagePackerInstructionPlan}\n */\nexport type MessagePackerInstructionPlan = Readonly<{\n getMessagePacker: () => MessagePacker;\n kind: 'messagePacker';\n}>;\n\n/**\n * The message packer returned by the {@link MessagePackerInstructionPlan}.\n *\n * It offers a `packMessageToCapacity(transactionMessage)` method that packs as many instructions\n * as possible into the provided transaction message, while still being able to fit into the\n * transaction size limit. It returns the updated transaction message with the packed instructions\n * or throws an error if the current transaction message cannot accommodate this plan.\n *\n * The `done()` method checks whether there are more instructions to pack into\n * transaction messages.\n *\n * @example\n * ```ts\n * let plan: MessagePackerInstructionPlan;\n * const messagePacker = plan.getMessagePacker();\n *\n * while (!messagePacker.done()) {\n * try {\n * transactionMessage = messagePacker.packMessageToCapacity(transactionMessage);\n * } catch (error) {\n * // The current transaction message cannot be used to pack this plan.\n * // We should create a new one and try again.\n * }\n * }\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n */\nexport type MessagePacker = Readonly<{\n /** Checks whether the message packer has more instructions to pack into transaction messages. */\n done: () => boolean;\n /**\n * Packs the provided transaction message with instructions or throws if not possible.\n *\n * @throws {@link SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN}\n * if the provided transaction message cannot be used to fill the next instructions.\n * @throws {@link SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE}\n * if the message packer is already done and no more instructions can be packed.\n */\n packMessageToCapacity: (\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n ) => BaseTransactionMessage & TransactionMessageWithFeePayer;\n}>;\n\n/**\n * Creates a {@link ParallelInstructionPlan} from an array of nested plans.\n *\n * It can accept {@link Instruction} objects directly, which will be wrapped\n * in {@link SingleInstructionPlan | SingleInstructionPlans} automatically.\n *\n * @example Using explicit {@link SingleInstructionPlan | SingleInstructionPlans}.\n * ```ts\n * const plan = parallelInstructionPlan([\n * singleInstructionPlan(instructionA),\n * singleInstructionPlan(instructionB),\n * ]);\n * ```\n *\n * @example Using {@link Instruction | Instructions} directly.\n * ```ts\n * const plan = parallelInstructionPlan([instructionA, instructionB]);\n * ```\n *\n * @see {@link ParallelInstructionPlan}\n */\nexport function parallelInstructionPlan(plans: (Instruction | InstructionPlan)[]): ParallelInstructionPlan {\n return Object.freeze({\n kind: 'parallel',\n plans: parseSingleInstructionPlans(plans),\n });\n}\n\n/**\n * Creates a divisible {@link SequentialInstructionPlan} from an array of nested plans.\n *\n * It can accept {@link Instruction} objects directly, which will be wrapped\n * in {@link SingleInstructionPlan | SingleInstructionPlans} automatically.\n *\n * @example Using explicit {@link SingleInstructionPlan | SingleInstructionPlans}.\n * ```ts\n * const plan = sequentialInstructionPlan([\n * singleInstructionPlan(instructionA),\n * singleInstructionPlan(instructionB),\n * ]);\n * ```\n *\n * @example Using {@link Instruction | Instructions} directly.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, instructionB]);\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n */\nexport function sequentialInstructionPlan(\n plans: (Instruction | InstructionPlan)[],\n): SequentialInstructionPlan & { divisible: true } {\n return Object.freeze({\n divisible: true,\n kind: 'sequential',\n plans: parseSingleInstructionPlans(plans),\n });\n}\n\n/**\n * Creates a non-divisible {@link SequentialInstructionPlan} from an array of nested plans.\n *\n * It can accept {@link Instruction} objects directly, which will be wrapped\n * in {@link SingleInstructionPlan | SingleInstructionPlans} automatically.\n *\n * @example Using explicit {@link SingleInstructionPlan | SingleInstructionPlans}.\n * ```ts\n * const plan = nonDivisibleSequentialInstructionPlan([\n * singleInstructionPlan(instructionA),\n * singleInstructionPlan(instructionB),\n * ]);\n * ```\n *\n * @example Using {@link Instruction | Instructions} directly.\n * ```ts\n * const plan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n */\nexport function nonDivisibleSequentialInstructionPlan(\n plans: (Instruction | InstructionPlan)[],\n): SequentialInstructionPlan & { divisible: false } {\n return Object.freeze({\n divisible: false,\n kind: 'sequential',\n plans: parseSingleInstructionPlans(plans),\n });\n}\n\n/**\n * Creates a {@link SingleInstructionPlan} from an {@link Instruction} object.\n *\n * @example\n * ```ts\n * const plan = singleInstructionPlan(instructionA);\n * ```\n *\n * @see {@link SingleInstructionPlan}\n */\nexport function singleInstructionPlan(instruction: Instruction): SingleInstructionPlan {\n return Object.freeze({ instruction, kind: 'single' });\n}\n\nfunction parseSingleInstructionPlans(plans: (Instruction | InstructionPlan)[]): InstructionPlan[] {\n return plans.map(plan => ('kind' in plan ? plan : singleInstructionPlan(plan)));\n}\n\n/**\n * Creates a {@link MessagePackerInstructionPlan} that packs instructions\n * such that each instruction consumes as many bytes as possible from the given\n * `totalLength` while still being able to fit into the given transaction messages.\n *\n * This is particularly useful for instructions that write data to accounts and must\n * span multiple transactions due to their size limit.\n *\n * This message packer will first call `getInstruction` with a length of zero to\n * determine the base size of the instruction before figuring out how many\n * additional bytes can be packed into the transaction message. That remaining space\n * will then be used to call `getInstruction` again with the appropriate length.\n *\n * @param getInstruction - A function that returns an instruction for a given offset and length.\n * @param totalLength - The total length of the data to write, in bytes.\n *\n * @example\n * ```ts\n * const plan = getLinearMessagePackerInstructionPlan({\n * totalLength: dataToWrite.length,\n * getInstruction: (offset, length) =>\n * getWriteInstruction({\n * offset,\n * data: dataToWrite.slice(offset, offset + length),\n * }),\n * });\n * plan satisfies MessagePackerInstructionPlan;\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n */\nexport function getLinearMessagePackerInstructionPlan({\n getInstruction,\n totalLength: totalBytes,\n}: {\n getInstruction: (offset: number, length: number) => Instruction;\n totalLength: number;\n}): MessagePackerInstructionPlan {\n return Object.freeze({\n getMessagePacker: () => {\n let offset = 0;\n return Object.freeze({\n done: () => offset >= totalBytes,\n packMessageToCapacity: (message: BaseTransactionMessage & TransactionMessageWithFeePayer) => {\n if (offset >= totalBytes) {\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE);\n }\n\n const messageSizeWithBaseInstruction = getTransactionMessageSize(\n appendTransactionMessageInstruction(getInstruction(offset, 0), message),\n );\n const freeSpace =\n TRANSACTION_SIZE_LIMIT -\n messageSizeWithBaseInstruction /* Includes the base instruction (length: 0). */ -\n 1; /* Leeway for shortU16 numbers in transaction headers. */\n\n if (freeSpace <= 0) {\n const messageSize = getTransactionMessageSize(message);\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n // (+1) We need to pack at least one byte of data otherwise\n // there is no point packing the base instruction alone.\n numBytesRequired: messageSizeWithBaseInstruction - messageSize + 1,\n // (-1) Leeway for shortU16 numbers in transaction headers.\n numFreeBytes: TRANSACTION_SIZE_LIMIT - messageSize - 1,\n });\n }\n\n const length = Math.min(totalBytes - offset, freeSpace);\n const instruction = getInstruction(offset, length);\n offset += length;\n return appendTransactionMessageInstruction(instruction, message);\n },\n });\n },\n kind: 'messagePacker',\n });\n}\n\n/**\n * Creates a {@link MessagePackerInstructionPlan} from a list of instructions.\n *\n * This can be useful to prepare a set of instructions that can be iterated over\n * — e.g. to pack a list of instructions that gradually reallocate the size of an account\n * one `REALLOC_LIMIT` (10'240 bytes) at a time.\n *\n * @example\n * ```ts\n * const plan = getMessagePackerInstructionPlanFromInstructions([\n * instructionA,\n * instructionB,\n * instructionC,\n * ]);\n *\n * const messagePacker = plan.getMessagePacker();\n * firstTransactionMessage = messagePacker.packMessageToCapacity(firstTransactionMessage);\n * // Contains instruction A and instruction B.\n * secondTransactionMessage = messagePacker.packMessageToCapacity(secondTransactionMessage);\n * // Contains instruction C.\n * messagePacker.done(); // true\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n * @see {@link getReallocMessagePackerInstructionPlan}\n */\nexport function getMessagePackerInstructionPlanFromInstructions<TInstruction extends Instruction = Instruction>(\n instructions: TInstruction[],\n): MessagePackerInstructionPlan {\n return Object.freeze({\n getMessagePacker: () => {\n let instructionIndex = 0;\n return Object.freeze({\n done: () => instructionIndex >= instructions.length,\n packMessageToCapacity: (message: BaseTransactionMessage & TransactionMessageWithFeePayer) => {\n if (instructionIndex >= instructions.length) {\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE);\n }\n\n const originalMessageSize = getTransactionMessageSize(message);\n\n for (let index = instructionIndex; index < instructions.length; index++) {\n message = appendTransactionMessageInstruction(instructions[index], message);\n const messageSize = getTransactionMessageSize(message);\n\n if (messageSize > TRANSACTION_SIZE_LIMIT) {\n if (index === instructionIndex) {\n throw new SolanaError(\n SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n {\n numBytesRequired: messageSize - originalMessageSize,\n numFreeBytes: TRANSACTION_SIZE_LIMIT - originalMessageSize,\n },\n );\n }\n instructionIndex = index;\n return message;\n }\n }\n\n instructionIndex = instructions.length;\n return message;\n },\n });\n },\n kind: 'messagePacker',\n });\n}\n\nconst REALLOC_LIMIT = 10_240;\n\n/**\n * Creates a {@link MessagePackerInstructionPlan} that packs a list of realloc instructions.\n *\n * That is, it splits instruction by chunks of `REALLOC_LIMIT` (10'240) bytes until\n * the given total size is reached.\n *\n * @example\n * ```ts\n * const plan = getReallocMessagePackerInstructionPlan({\n * totalSize: additionalDataSize,\n * getInstruction: (size) => getExtendInstruction({ length: size }),\n * });\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n */\nexport function getReallocMessagePackerInstructionPlan({\n getInstruction,\n totalSize,\n}: {\n getInstruction: (size: number) => Instruction;\n totalSize: number;\n}): MessagePackerInstructionPlan {\n const numberOfInstructions = Math.ceil(totalSize / REALLOC_LIMIT);\n const lastInstructionSize = totalSize % REALLOC_LIMIT;\n const instructions = new Array(numberOfInstructions)\n .fill(0)\n .map((_, i) => getInstruction(i === numberOfInstructions - 1 ? lastInstructionSize : REALLOC_LIMIT));\n\n return getMessagePackerInstructionPlanFromInstructions(instructions);\n}\n","import { Signature } from '@solana/keys';\nimport { BaseTransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\n\n/**\n * The result of executing a transaction plan.\n *\n * This is structured as a recursive tree of results that mirrors the structure\n * of the original transaction plan, capturing the execution status at each level.\n *\n * Namely, the following result types are supported:\n * - {@link SingleTransactionPlanResult} - A result for a single transaction message\n * containing its execution status.\n * - {@link ParallelTransactionPlanResult} - A result containing other results that\n * were executed in parallel.\n * - {@link SequentialTransactionPlanResult} - A result containing other results that\n * were executed sequentially. It also retains the divisibility property from the\n * original plan.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n *\n * @see {@link SingleTransactionPlanResult}\n * @see {@link ParallelTransactionPlanResult}\n * @see {@link SequentialTransactionPlanResult}\n * @see {@link TransactionPlanResultStatus}\n */\nexport type TransactionPlanResult<TContext extends TransactionPlanResultContext = TransactionPlanResultContext> =\n | ParallelTransactionPlanResult<TContext>\n | SequentialTransactionPlanResult<TContext>\n | SingleTransactionPlanResult<TContext>;\n\n/** A context object that may be passed along with successful results. */\nexport type TransactionPlanResultContext = Record<number | string | symbol, unknown>;\n\n/**\n * A result for a sequential transaction plan.\n *\n * This represents the execution result of a {@link SequentialTransactionPlan} and\n * contains child results that were executed sequentially. It also retains the\n * divisibility property from the original plan.\n *\n * You may use the {@link sequentialTransactionPlanResult} and\n * {@link nonDivisibleSequentialTransactionPlanResult} helpers to create objects of this type.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n *\n * @example\n * ```ts\n * const result = sequentialTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult;\n * ```\n *\n * @example\n * Non-divisible sequential result.\n * ```ts\n * const result = nonDivisibleSequentialTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult & { divisible: false };\n * ```\n *\n * @see {@link sequentialTransactionPlanResult}\n * @see {@link nonDivisibleSequentialTransactionPlanResult}\n */\nexport type SequentialTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n> = Readonly<{\n divisible: boolean;\n kind: 'sequential';\n plans: TransactionPlanResult<TContext>[];\n}>;\n\n/**\n * A result for a parallel transaction plan.\n *\n * This represents the execution result of a {@link ParallelTransactionPlan} and\n * contains child results that were executed in parallel.\n *\n * You may use the {@link parallelTransactionPlanResult} helper to create objects of this type.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n *\n * @example\n * ```ts\n * const result = parallelTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies ParallelTransactionPlanResult;\n * ```\n *\n * @see {@link parallelTransactionPlanResult}\n */\nexport type ParallelTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n> = Readonly<{\n kind: 'parallel';\n plans: TransactionPlanResult<TContext>[];\n}>;\n\n/**\n * A result for a single transaction plan.\n *\n * This represents the execution result of a {@link SingleTransactionPlan} and\n * contains the original transaction message along with its execution status.\n *\n * You may use the {@link successfulSingleTransactionPlanResult},\n * {@link failedSingleTransactionPlanResult}, or {@link canceledSingleTransactionPlanResult}\n * helpers to create objects of this type.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n * @template TTransactionMessage - The type of the transaction message\n *\n * @example\n * Successful result with a transaction and context.\n * ```ts\n * const result = successfulSingleTransactionPlanResult(\n * transactionMessage,\n * transaction\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @example\n * Failed result with an error.\n * ```ts\n * const result = failedSingleTransactionPlanResult(\n * transactionMessage,\n * new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @example\n * Canceled result.\n * ```ts\n * const result = canceledSingleTransactionPlanResult(transactionMessage);\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link successfulSingleTransactionPlanResult}\n * @see {@link failedSingleTransactionPlanResult}\n * @see {@link canceledSingleTransactionPlanResult}\n */\nexport type SingleTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n> = Readonly<{\n kind: 'single';\n message: TTransactionMessage;\n status: TransactionPlanResultStatus<TContext>;\n}>;\n\n/**\n * The status of a single transaction plan execution.\n *\n * This represents the outcome of executing a single transaction message and can be one of:\n * - `successful` - The transaction was successfully executed. Contains the transaction\n * and an optional context object.\n * - `failed` - The transaction execution failed. Contains the error that caused the failure.\n * - `canceled` - The transaction execution was canceled.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n */\nexport type TransactionPlanResultStatus<TContext extends TransactionPlanResultContext = TransactionPlanResultContext> =\n | Readonly<{ context: TContext; kind: 'successful'; signature: Signature; transaction?: Transaction }>\n | Readonly<{ error: Error; kind: 'failed' }>\n | Readonly<{ kind: 'canceled' }>;\n\n/**\n * Creates a divisible {@link SequentialTransactionPlanResult} from an array of nested results.\n *\n * This function creates a sequential result with the `divisible` property set to `true`,\n * indicating that the nested plans were executed sequentially but could have been\n * split into separate transactions or batches.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n * @param plans - The child results that were executed sequentially\n *\n * @example\n * ```ts\n * const result = sequentialTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult & { divisible: true };\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n */\nexport function sequentialTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(plans: TransactionPlanResult<TContext>[]): SequentialTransactionPlanResult<TContext> & { divisible: true } {\n return Object.freeze({ divisible: true, kind: 'sequential', plans });\n}\n\n/**\n * Creates a non-divisible {@link SequentialTransactionPlanResult} from an array of nested results.\n *\n * This function creates a sequential result with the `divisible` property set to `false`,\n * indicating that the nested plans were executed sequentially and could not have been\n * split into separate transactions or batches (e.g., they were executed as a transaction bundle).\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n * @param plans - The child results that were executed sequentially\n *\n * @example\n * ```ts\n * const result = nonDivisibleSequentialTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult & { divisible: false };\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n */\nexport function nonDivisibleSequentialTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(plans: TransactionPlanResult<TContext>[]): SequentialTransactionPlanResult<TContext> & { divisible: false } {\n return Object.freeze({ divisible: false, kind: 'sequential', plans });\n}\n\n/**\n * Creates a {@link ParallelTransactionPlanResult} from an array of nested results.\n *\n * This function creates a parallel result indicating that the nested plans\n * were executed in parallel.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n * @param plans - The child results that were executed in parallel\n *\n * @example\n * ```ts\n * const result = parallelTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies ParallelTransactionPlanResult;\n * ```\n *\n * @see {@link ParallelTransactionPlanResult}\n */\nexport function parallelTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(plans: TransactionPlanResult<TContext>[]): ParallelTransactionPlanResult<TContext> {\n return Object.freeze({ kind: 'parallel', plans });\n}\n\n/**\n * Creates a successful {@link SingleTransactionPlanResult} from a transaction message and transaction.\n *\n * This function creates a single result with a 'successful' status, indicating that\n * the transaction was successfully executed. It also includes the original transaction\n * message, the executed transaction, and an optional context object.\n *\n * @template TContext - The type of the context object\n * @template TTransactionMessage - The type of the transaction message\n * @param transactionMessage - The original transaction message\n * @param transaction - The successfully executed transaction\n * @param context - Optional context object to be included with the result\n *\n * @example\n * ```ts\n * const result = successfulSingleTransactionPlanResult(\n * transactionMessage,\n * transaction\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function successfulSingleTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n transaction: Transaction,\n context?: TContext,\n): SingleTransactionPlanResult<TContext, TTransactionMessage> {\n return Object.freeze({\n kind: 'single',\n message: transactionMessage,\n status: Object.freeze({\n context: context ?? ({} as TContext),\n kind: 'successful',\n signature: getSignatureFromTransaction(transaction),\n transaction,\n }),\n });\n}\n\n/**\n * Creates a successful {@link SingleTransactionPlanResult} from a transaction message and signature.\n *\n * This function creates a single result with a 'successful' status, indicating that\n * the transaction was successfully executed. It also includes the original transaction\n * message, the signature of the executed transaction, and an optional context object.\n *\n * @template TContext - The type of the context object\n * @template TTransactionMessage - The type of the transaction message\n * @param transactionMessage - The original transaction message\n * @param signature - The signature of the successfully executed transaction\n * @param context - Optional context object to be included with the result\n *\n * @example\n * ```ts\n * const result = successfulSingleTransactionPlanResult(\n * transactionMessage,\n * signature\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function successfulSingleTransactionPlanResultFromSignature<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n signature: Signature,\n context?: TContext,\n): SingleTransactionPlanResult<TContext, TTransactionMessage> {\n return Object.freeze({\n kind: 'single',\n message: transactionMessage,\n status: Object.freeze({ context: context ?? ({} as TContext), kind: 'successful', signature }),\n });\n}\n\n/**\n * Creates a failed {@link SingleTransactionPlanResult} from a transaction message and error.\n *\n * This function creates a single result with a 'failed' status, indicating that\n * the transaction execution failed. It includes the original transaction message\n * and the error that caused the failure.\n *\n * @template TContext - The type of the context object (not used in failed results)\n * @template TTransactionMessage - The type of the transaction message\n * @param transactionMessage - The original transaction message\n * @param error - The error that caused the transaction to fail\n *\n * @example\n * ```ts\n * const result = failedSingleTransactionPlanResult(\n * transactionMessage,\n * new SolanaError({\n * code: 123,\n * message: 'Transaction simulation failed',\n * }),\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function failedSingleTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(transactionMessage: TTransactionMessage, error: Error): SingleTransactionPlanResult<TContext, TTransactionMessage> {\n return Object.freeze({\n kind: 'single',\n message: transactionMessage,\n status: Object.freeze({ error, kind: 'failed' }),\n });\n}\n\n/**\n * Creates a canceled {@link SingleTransactionPlanResult} from a transaction message.\n *\n * This function creates a single result with a 'canceled' status, indicating that\n * the transaction execution was canceled. It includes the original transaction message.\n *\n * @template TContext - The type of the context object (not used in canceled results)\n * @template TTransactionMessage - The type of the transaction message\n * @param transactionMessage - The original transaction message\n *\n * @example\n * ```ts\n * const result = canceledSingleTransactionPlanResult(transactionMessage);\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function canceledSingleTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(transactionMessage: TTransactionMessage): SingleTransactionPlanResult<TContext, TTransactionMessage> {\n return Object.freeze({\n kind: 'single',\n message: transactionMessage,\n status: Object.freeze({ kind: 'canceled' }),\n });\n}\n\n/**\n * Flattens a {@link TransactionPlanResult} into an array of {@link SingleTransactionPlanResult}.\n * @param result The transaction plan result to flatten\n * @returns An array of single transaction plan results\n */\nexport function flattenTransactionPlanResult(result: TransactionPlanResult): SingleTransactionPlanResult[] {\n const transactionPlanResults: SingleTransactionPlanResult[] = [];\n\n function traverse(result: TransactionPlanResult) {\n if (result.kind === 'single') {\n transactionPlanResults.push(result);\n } else {\n for (const subResult of result.plans) {\n traverse(subResult);\n }\n }\n }\n\n traverse(result);\n return transactionPlanResults;\n}\n\n/**\n * A {@link SingleTransactionPlanResult} with 'successful' status.\n */\nexport type SuccessfulSingleTransactionPlanResult = SingleTransactionPlanResult & { status: { kind: 'successful' } };\n\n/**\n * A {@link SingleTransactionPlanResult} with 'failed' status.\n */\nexport type FailedSingleTransactionPlanResult = SingleTransactionPlanResult & { status: { kind: 'failed' } };\n\n/**\n * A {@link SingleTransactionPlanResult} with 'canceled' status.\n */\nexport type CanceledSingleTransactionPlanResult = SingleTransactionPlanResult & { status: { kind: 'canceled' } };\n\n/**\n * A summary of a {@link TransactionPlanResult}, categorizing transactions by their execution status.\n * - `successful`: Indicates whether all transactions were successful (i.e., no failed or canceled transactions).\n * - `successfulTransactions`: An array of successful transactions, each including its signature.\n * - `failedTransactions`: An array of failed transactions, each including the error that caused the failure.\n * - `canceledTransactions`: An array of canceled transactions.\n */\nexport type TransactionPlanResultSummary = Readonly<{\n canceledTransactions: CanceledSingleTransactionPlanResult[];\n failedTransactions: FailedSingleTransactionPlanResult[];\n successful: boolean;\n successfulTransactions: SuccessfulSingleTransactionPlanResult[];\n}>;\n\n/**\n * Summarize a {@link TransactionPlanResult} into a {@link TransactionPlanResultSummary}.\n * @param result The transaction plan result to summarize\n * @returns A summary of the transaction plan result\n */\nexport function summarizeTransactionPlanResult(result: TransactionPlanResult): TransactionPlanResultSummary {\n const successfulTransactions: TransactionPlanResultSummary['successfulTransactions'] = [];\n const failedTransactions: TransactionPlanResultSummary['failedTransactions'] = [];\n const canceledTransactions: TransactionPlanResultSummary['canceledTransactions'] = [];\n\n const flattenedResults = flattenTransactionPlanResult(result);\n\n for (const singleResult of flattenedResults) {\n switch (singleResult.status.kind) {\n case 'successful': {\n successfulTransactions.push(singleResult as SuccessfulSingleTransactionPlanResult);\n break;\n }\n case 'failed': {\n failedTransactions.push(singleResult as FailedSingleTransactionPlanResult);\n break;\n }\n case 'canceled': {\n canceledTransactions.push(singleResult as CanceledSingleTransactionPlanResult);\n break;\n }\n }\n }\n\n return Object.freeze({\n canceledTransactions,\n failedTransactions,\n successful: failedTransactions.length === 0 && canceledTransactions.length === 0,\n successfulTransactions,\n });\n}\n","import {\n SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND,\n SolanaError,\n} from '@solana/errors';\nimport { Signature } from '@solana/keys';\nimport { getAbortablePromise } from '@solana/promises';\nimport { BaseTransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\nimport { Transaction } from '@solana/transactions';\n\nimport type {\n ParallelTransactionPlan,\n SequentialTransactionPlan,\n SingleTransactionPlan,\n TransactionPlan,\n} from './transaction-plan';\nimport {\n canceledSingleTransactionPlanResult,\n failedSingleTransactionPlanResult,\n nonDivisibleSequentialTransactionPlanResult,\n parallelTransactionPlanResult,\n sequentialTransactionPlanResult,\n successfulSingleTransactionPlanResult,\n successfulSingleTransactionPlanResultFromSignature,\n type TransactionPlanResult,\n type TransactionPlanResultContext,\n} from './transaction-plan-result';\n\nexport type TransactionPlanExecutor<TContext extends TransactionPlanResultContext = TransactionPlanResultContext> = (\n transactionPlan: TransactionPlan,\n config?: { abortSignal?: AbortSignal },\n) => Promise<TransactionPlanResult<TContext>>;\n\ntype ExecuteResult<TContext extends TransactionPlanResultContext> = {\n context?: TContext;\n} & ({ signature: Signature } | { transaction: Transaction });\n\ntype ExecuteTransactionMessage = <TContext extends TransactionPlanResultContext = TransactionPlanResultContext>(\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n config?: { abortSignal?: AbortSignal },\n) => Promise<ExecuteResult<TContext>>;\n\n/**\n * Configuration object for creating a new transaction plan executor.\n *\n * @see {@link createTransactionPlanExecutor}\n */\nexport type TransactionPlanExecutorConfig = {\n /** Called whenever a transaction message must be sent to the blockchain. */\n executeTransactionMessage: ExecuteTransactionMessage;\n};\n\n/**\n * Creates a new transaction plan executor based on the provided configuration.\n *\n * The executor will traverse the provided `TransactionPlan` sequentially or in parallel,\n * executing each transaction message using the `executeTransactionMessage` function.\n *\n * - If that function is successful, the executor will return a successful `TransactionPlanResult`\n * for that message including the transaction and any custom context.\n * - If that function throws an error, the executor will stop processing and cancel all\n * remaining transaction messages in the plan.\n * - If the `abortSignal` is triggered, the executor will immediately stop processing the plan and\n * return a `TransactionPlanResult` with the status set to `canceled`.\n *\n * @example\n * ```ts\n * const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n *\n * const transactionPlanExecutor = createTransactionPlanExecutor({\n * executeTransactionMessage: (message) => {\n * const transaction = await signTransactionMessageWithSigners(message);\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * return { transaction };\n * }\n * });\n * ```\n *\n * @see {@link TransactionPlannerConfig}\n */\nexport function createTransactionPlanExecutor(config: TransactionPlanExecutorConfig): TransactionPlanExecutor {\n return async (plan, { abortSignal } = {}): Promise<TransactionPlanResult> => {\n const context: TraverseContext = {\n ...config,\n abortSignal: abortSignal,\n canceled: abortSignal?.aborted ?? false,\n };\n\n const cancelHandler = () => {\n context.canceled = true;\n };\n abortSignal?.addEventListener('abort', cancelHandler);\n const transactionPlanResult = await traverse(plan, context);\n abortSignal?.removeEventListener('abort', cancelHandler);\n\n if (context.canceled) {\n const abortReason = abortSignal?.aborted ? abortSignal.reason : undefined;\n const context = { cause: findErrorFromTransactionPlanResult(transactionPlanResult) ?? abortReason };\n // Here we want the `transactionPlanResult` to be available in the error context\n // so applications can create recovery plans but we don't want this object to be\n // serialized with the error. This is why we set it as a non-enumerable property.\n Object.defineProperty(context, 'transactionPlanResult', {\n configurable: false,\n enumerable: false,\n value: transactionPlanResult,\n writable: false,\n });\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, context);\n }\n\n return transactionPlanResult;\n };\n}\n\ntype TraverseContext = TransactionPlanExecutorConfig & {\n abortSignal?: AbortSignal;\n canceled: boolean;\n};\n\nasync function traverse(transactionPlan: TransactionPlan, context: TraverseContext): Promise<TransactionPlanResult> {\n const kind = transactionPlan.kind;\n switch (kind) {\n case 'sequential':\n return await traverseSequential(transactionPlan, context);\n case 'parallel':\n return await traverseParallel(transactionPlan, context);\n case 'single':\n return await traverseSingle(transactionPlan, context);\n default:\n transactionPlan satisfies never;\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND, { kind });\n }\n}\n\nasync function traverseSequential(\n transactionPlan: SequentialTransactionPlan,\n context: TraverseContext,\n): Promise<TransactionPlanResult> {\n const results: TransactionPlanResult[] = [];\n\n for (const subPlan of transactionPlan.plans) {\n const result = await traverse(subPlan, context);\n results.push(result);\n }\n\n return transactionPlan.divisible\n ? sequentialTransactionPlanResult(results)\n : nonDivisibleSequentialTransactionPlanResult(results);\n}\n\nasync function traverseParallel(\n transactionPlan: ParallelTransactionPlan,\n context: TraverseContext,\n): Promise<TransactionPlanResult> {\n const results = await Promise.all(transactionPlan.plans.map(plan => traverse(plan, context)));\n return parallelTransactionPlanResult(results);\n}\n\nasync function traverseSingle(\n transactionPlan: SingleTransactionPlan,\n context: TraverseContext,\n): Promise<TransactionPlanResult> {\n if (context.canceled) {\n return canceledSingleTransactionPlanResult(transactionPlan.message);\n }\n\n try {\n const result = await getAbortablePromise(\n context.executeTransactionMessage(transactionPlan.message, { abortSignal: context.abortSignal }),\n context.abortSignal,\n );\n if ('transaction' in result) {\n return successfulSingleTransactionPlanResult(transactionPlan.message, result.transaction, result.context);\n } else {\n return successfulSingleTransactionPlanResultFromSignature(\n transactionPlan.message,\n result.signature,\n result.context,\n );\n }\n } catch (error) {\n context.canceled = true;\n return failedSingleTransactionPlanResult(transactionPlan.message, error as Error);\n }\n}\n\nfunction findErrorFromTransactionPlanResult(result: TransactionPlanResult): Error | undefined {\n if (result.kind === 'single') {\n return result.status.kind === 'failed' ? result.status.error : undefined;\n }\n for (const plan of result.plans) {\n const error = findErrorFromTransactionPlanResult(plan);\n if (error) {\n return error;\n }\n }\n}\n","import { BaseTransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\n/**\n * A set of transaction messages with constraints on how they can be executed.\n *\n * This is structured as a recursive tree of plans to allow for\n * parallel execution, sequential execution and combinations of both.\n *\n * Namely, the following plans are supported:\n * - {@link SingleTransactionPlan} - A plan that contains a single transaction message.\n * This is the simplest leaf in this tree.\n * - {@link ParallelTransactionPlan} - A plan that contains other plans that\n * can be executed in parallel.\n * - {@link SequentialTransactionPlan} - A plan that contains other plans that\n * must be executed sequentially. It also defines whether the plan is divisible\n * meaning that transaction messages inside it can be split into separate batches.\n *\n * Helpers are provided for each of these plans to make it easier to create them.\n *\n * @example\n * ```ts\n * const myTransactionPlan: TransactionPlan = parallelTransactionPlan([\n * sequentialTransactionPlan([messageA, messageB]),\n * messageC,\n * ]);\n * ```\n *\n * @see {@link SingleTransactionPlan}\n * @see {@link ParallelTransactionPlan}\n * @see {@link SequentialTransactionPlan}\n */\nexport type TransactionPlan = ParallelTransactionPlan | SequentialTransactionPlan | SingleTransactionPlan;\n\n/**\n * A plan wrapping other plans that must be executed sequentially.\n *\n * It also defines whether nested plans are divisible — meaning that\n * the transaction messages inside them can be split into separate batches.\n * When `divisible` is `false`, the transaction messages inside the plan should\n * all be executed atomically — usually in a transaction bundle.\n *\n * You may use the {@link sequentialTransactionPlan} and {@link nonDivisibleSequentialTransactionPlan}\n * helpers to create objects of this type.\n *\n * @example\n * Simple sequential plan with two transaction messages.\n * ```ts\n * const plan = sequentialTransactionPlan([messageA, messageB]);\n * plan satisfies SequentialTransactionPlan;\n * ```\n *\n * @example\n * Non-divisible sequential plan with two transaction messages.\n * ```ts\n * const plan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n * plan satisfies SequentialTransactionPlan & { divisible: false };\n * ```\n *\n * @example\n * Sequential plan with nested parallel plans.\n * Here, messages A and B can be executed in parallel, but they must both be finalized\n * before messages C and D can be sent — which can also be executed in parallel.\n * ```ts\n * const plan = sequentialTransactionPlan([\n * parallelTransactionPlan([messageA, messageB]),\n * parallelTransactionPlan([messageC, messageD]),\n * ]);\n * ```\n *\n * @see {@link sequentialTransactionPlan}\n * @see {@link nonDivisibleSequentialTransactionPlan}\n */\nexport type SequentialTransactionPlan = Readonly<{\n divisible: boolean;\n kind: 'sequential';\n plans: TransactionPlan[];\n}>;\n\n/**\n * A plan wrapping other plans that can be executed in parallel.\n *\n * This means direct children of this plan can be executed in separate\n * parallel transactions without causing any side effects.\n * However, the children themselves can define additional constraints\n * for that specific branch of the tree — such as the {@link SequentialTransactionPlan}.\n *\n * You may use the {@link parallelTransactionPlan} helper to create objects of this type.\n *\n * @example\n * Simple parallel plan with two transaction messages.\n * ```ts\n * const plan = parallelTransactionPlan([messageA, messageB]);\n * plan satisfies ParallelTransactionPlan;\n * ```\n *\n * @example\n * Parallel plan with nested sequential plans.\n * Here, messages A and B must be executed sequentially and so must messages C and D,\n * but both pairs can be executed in parallel.\n * ```ts\n * const plan = parallelTransactionPlan([\n * sequentialTransactionPlan([messageA, messageB]),\n * sequentialTransactionPlan([messageC, messageD]),\n * ]);\n * plan satisfies ParallelTransactionPlan;\n * ```\n *\n * @see {@link parallelTransactionPlan}\n */\nexport type ParallelTransactionPlan = Readonly<{\n kind: 'parallel';\n plans: TransactionPlan[];\n}>;\n\n/**\n * A plan that contains a single transaction message.\n *\n * This is a simple transaction message wrapper that transforms a message into a plan.\n *\n * You may use the {@link singleTransactionPlan} helper to create objects of this type.\n *\n * @example\n * ```ts\n * const plan = singleTransactionPlan(transactionMessage);\n * plan satisfies SingleTransactionPlan;\n * ```\n *\n * @see {@link singleTransactionPlan}\n */\nexport type SingleTransactionPlan<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n> = Readonly<{\n kind: 'single';\n message: TTransactionMessage;\n}>;\n\n/**\n * Creates a {@link ParallelTransactionPlan} from an array of nested plans.\n *\n * It can accept {@link TransactionMessage} objects directly, which will be wrapped\n * in {@link SingleTransactionPlan | SingleTransactionPlans} automatically.\n *\n * @example\n * Using explicit {@link SingleTransactionPlan | SingleTransactionPlans}.\n * ```ts\n * const plan = parallelTransactionPlan([\n * singleTransactionPlan(messageA),\n * singleTransactionPlan(messageB),\n * ]);\n * ```\n *\n * @example\n * Using {@link TransactionMessage | TransactionMessages} directly.\n * ```ts\n * const plan = parallelTransactionPlan([messageA, messageB]);\n * ```\n *\n * @see {@link ParallelTransactionPlan}\n */\nexport function parallelTransactionPlan(\n plans: (TransactionPlan | (BaseTransactionMessage & TransactionMessageWithFeePayer))[],\n): ParallelTransactionPlan {\n return Object.freeze({ kind: 'parallel', plans: parseSingleTransactionPlans(plans) });\n}\n\n/**\n * Creates a divisible {@link SequentialTransactionPlan} from an array of nested plans.\n *\n * It can accept {@link TransactionMessage} objects directly, which will be wrapped\n * in {@link SingleTransactionPlan | SingleTransactionPlans} automatically.\n *\n * @example\n * Using explicit {@link SingleTransactionPlan | SingleTransactionPlans}.\n * ```ts\n * const plan = sequentialTransactionPlan([\n * singleTransactionPlan(messageA),\n * singleTransactionPlan(messageB),\n * ]);\n * ```\n *\n * @example\n * Using {@link TransactionMessage | TransactionMessages} directly.\n * ```ts\n * const plan = sequentialTransactionPlan([messageA, messageB]);\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n */\nexport function sequentialTransactionPlan(\n plans: (TransactionPlan | (BaseTransactionMessage & TransactionMessageWithFeePayer))[],\n): SequentialTransactionPlan & { divisible: true } {\n return Object.freeze({ divisible: true, kind: 'sequential', plans: parseSingleTransactionPlans(plans) });\n}\n\n/**\n * Creates a non-divisible {@link SequentialTransactionPlan} from an array of nested plans.\n *\n * It can accept {@link TransactionMessage} objects directly, which will be wrapped\n * in {@link SingleTransactionPlan | SingleTransactionPlans} automatically.\n *\n * @example\n * Using explicit {@link SingleTransactionPlan | SingleTransactionPlans}.\n * ```ts\n * const plan = nonDivisibleSequentialTransactionPlan([\n * singleTransactionPlan(messageA),\n * singleTransactionPlan(messageB),\n * ]);\n * ```\n *\n * @example\n * Using {@link TransactionMessage | TransactionMessages} directly.\n * ```ts\n * const plan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n */\nexport function nonDivisibleSequentialTransactionPlan(\n plans: (TransactionPlan | (BaseTransactionMessage & TransactionMessageWithFeePayer))[],\n): SequentialTransactionPlan & { divisible: false } {\n return Object.freeze({ divisible: false, kind: 'sequential', plans: parseSingleTransactionPlans(plans) });\n}\n\n/**\n * Creates a {@link SingleTransactionPlan} from a {@link TransactionMessage} object.\n *\n * @example\n * ```ts\n * const plan = singleTransactionPlan(transactionMessage);\n * plan satisfies SingleTransactionPlan;\n * ```\n *\n * @see {@link SingleTransactionPlan}\n */\nexport function singleTransactionPlan<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(transactionMessage: TTransactionMessage): SingleTransactionPlan<TTransactionMessage> {\n return Object.freeze({ kind: 'single', message: transactionMessage });\n}\n\nfunction parseSingleTransactionPlans(\n plans: (TransactionPlan | (BaseTransactionMessage & TransactionMessageWithFeePayer))[],\n): TransactionPlan[] {\n return plans.map(plan => ('kind' in plan ? plan : singleTransactionPlan(plan)));\n}\n\n/**\n * Retrieves all individual {@link SingleTransactionPlan} instances from a transaction plan tree.\n *\n * This function recursively traverses any nested structure of transaction plans and extracts\n * all the single transaction plans they contain. It's useful when you need to access all\n * the actual transaction messages that will be executed, regardless of their organization\n * in the plan tree (parallel or sequential).\n *\n * @param transactionPlan - The transaction plan to extract single plans from\n * @returns An array of all single transaction plans contained in the tree\n *\n * @example\n * ```ts\n * const plan = parallelTransactionPlan([\n * sequentialTransactionPlan([messageA, messageB]),\n * nonDivisibleSequentialTransactionPlan([messageC, messageD]),\n * messageE,\n * ]);\n *\n * const singlePlans = getAllSingleTransactionPlans(plan);\n * // Array of `SingleTransactionPlan` containing:\n * // messageA, messageB, messageC and messageD.\n * ```\n */\nexport function getAllSingleTransactionPlans(transactionPlan: TransactionPlan): SingleTransactionPlan[] {\n if (transactionPlan.kind === 'single') {\n return [transactionPlan];\n }\n return transactionPlan.plans.flatMap(getAllSingleTransactionPlans);\n}\n","import {\n isSolanaError,\n SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN,\n SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND,\n SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND,\n SolanaError,\n} from '@solana/errors';\nimport { getAbortablePromise } from '@solana/promises';\nimport {\n appendTransactionMessageInstructions,\n BaseTransactionMessage,\n TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { getTransactionMessageSize, TRANSACTION_SIZE_LIMIT } from '@solana/transactions';\n\nimport {\n InstructionPlan,\n MessagePackerInstructionPlan,\n ParallelInstructionPlan,\n SequentialInstructionPlan,\n SingleInstructionPlan,\n} from './instruction-plan';\nimport {\n getAllSingleTransactionPlans,\n nonDivisibleSequentialTransactionPlan,\n parallelTransactionPlan,\n sequentialTransactionPlan,\n SingleTransactionPlan,\n singleTransactionPlan,\n TransactionPlan,\n} from './transaction-plan';\n\n/**\n * Plans one or more transactions according to the provided instruction plan.\n *\n * @param instructionPlan - The instruction plan to be planned and executed.\n * @param config - Optional configuration object that can include an `AbortSignal` to cancel the planning process.\n *\n * @see {@link InstructionPlan}\n * @see {@link TransactionPlan}\n */\nexport type TransactionPlanner = (\n instructionPlan: InstructionPlan,\n config?: { abortSignal?: AbortSignal },\n) => Promise<TransactionPlan>;\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] };\n\ntype CreateTransactionMessage = (config?: {\n abortSignal?: AbortSignal;\n}) =>\n | Promise<BaseTransactionMessage & TransactionMessageWithFeePayer>\n | (BaseTransactionMessage & TransactionMessageWithFeePayer);\n\ntype OnTransactionMessageUpdated = (\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n config?: { abortSignal?: AbortSignal },\n) =>\n | Promise<BaseTransactionMessage & TransactionMessageWithFeePayer>\n | (BaseTransactionMessage & TransactionMessageWithFeePayer);\n\n/**\n * Configuration object for creating a new transaction planner.\n *\n * @see {@link createTransactionPlanner}\n */\nexport type TransactionPlannerConfig = {\n /** Called whenever a new transaction message is needed. */\n createTransactionMessage: CreateTransactionMessage;\n /**\n * Called whenever a transaction message is updated — e.g. new instructions were added.\n * This function must return the updated transaction message back — even if no changes were made.\n */\n onTransactionMessageUpdated?: OnTransactionMessageUpdated;\n};\n\n/**\n * Creates a new transaction planner based on the provided configuration.\n *\n * At the very least, the `createTransactionMessage` function must be provided.\n * This function is used to create new transaction messages whenever needed.\n *\n * Additionally, the `onTransactionMessageUpdated` function can be provided\n * to update transaction messages during the planning process. This function will\n * be called whenever a transaction message is updated, e.g. when new instructions\n * are added to a transaction message. It accepts the updated transaction message\n * and must return a transaction message back, even if no changes were made.\n *\n * @example\n * ```ts\n * const transactionPlanner = createTransactionPlanner({\n * createTransactionMessage: () => pipe(\n * createTransactionMessage({ version: 0 }),\n * message => setTransactionMessageFeePayerSigner(mySigner, message),\n * )\n * });\n * ```\n *\n * @see {@link TransactionPlannerConfig}\n */\nexport function createTransactionPlanner(config: TransactionPlannerConfig): TransactionPlanner {\n return async (instructionPlan, { abortSignal } = {}): Promise<TransactionPlan> => {\n const plan = await traverse(instructionPlan, {\n abortSignal,\n createTransactionMessage: config.createTransactionMessage,\n onTransactionMessageUpdated: config.onTransactionMessageUpdated ?? (msg => msg),\n parent: null,\n parentCandidates: [],\n });\n\n if (!plan) {\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN);\n }\n\n return freezeTransactionPlan(plan);\n };\n}\n\ntype MutableTransactionPlan = Mutable<TransactionPlan>;\ntype MutableSingleTransactionPlan = Mutable<SingleTransactionPlan>;\n\ntype TraverseContext = {\n abortSignal?: AbortSignal;\n createTransactionMessage: CreateTransactionMessage;\n onTransactionMessageUpdated: OnTransactionMessageUpdated;\n parent: InstructionPlan | null;\n parentCandidates: MutableSingleTransactionPlan[];\n};\n\nasync function traverse(\n instructionPlan: InstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n context.abortSignal?.throwIfAborted();\n const kind = instructionPlan.kind;\n switch (kind) {\n case 'sequential':\n return await traverseSequential(instructionPlan, context);\n case 'parallel':\n return await traverseParallel(instructionPlan, context);\n case 'single':\n return await traverseSingle(instructionPlan, context);\n case 'messagePacker':\n return await traverseMessagePacker(instructionPlan, context);\n default:\n instructionPlan satisfies never;\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, { kind });\n }\n}\n\nasync function traverseSequential(\n instructionPlan: SequentialInstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n let candidate: MutableSingleTransactionPlan | null = null;\n\n // Check if the sequential plan must fit entirely in its parent candidates\n // due to constraints like being inside a parallel plan or not being divisible.\n const mustEntirelyFitInParentCandidate =\n context.parent && (context.parent.kind === 'parallel' || !instructionPlan.divisible);\n\n // If so, try to fit the entire plan inside one of the parent candidates.\n if (mustEntirelyFitInParentCandidate) {\n const candidate = await selectAndMutateCandidate(context, context.parentCandidates, message =>\n fitEntirePlanInsideMessage(instructionPlan, message),\n );\n // If that's possible, we the candidate is mutated and we can return null.\n // Otherwise, we proceed with the normal traversal and no parent candidate.\n if (candidate) {\n return null;\n }\n } else {\n // Otherwise, we can use the first parent candidate, if any,\n // since we know it must be a divisible sequential plan.\n candidate = context.parentCandidates.length > 0 ? context.parentCandidates[0] : null;\n }\n\n const transactionPlans: TransactionPlan[] = [];\n for (const plan of instructionPlan.plans) {\n const transactionPlan = await traverse(plan, {\n ...context,\n parent: instructionPlan,\n parentCandidates: candidate ? [candidate] : [],\n });\n if (transactionPlan) {\n candidate = getSequentialCandidate(transactionPlan);\n const newPlans =\n transactionPlan.kind === 'sequential' && (transactionPlan.divisible || !instructionPlan.divisible)\n ? transactionPlan.plans\n : [transactionPlan];\n transactionPlans.push(...newPlans);\n }\n }\n\n // Wrap in a sequential plan or simplify.\n if (transactionPlans.length === 1) {\n return transactionPlans[0];\n }\n if (transactionPlans.length === 0) {\n return null;\n }\n return {\n divisible: instructionPlan.divisible,\n kind: 'sequential',\n plans: transactionPlans,\n };\n}\n\nasync function traverseParallel(\n instructionPlan: ParallelInstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n const candidates: MutableSingleTransactionPlan[] = [...context.parentCandidates];\n const transactionPlans: TransactionPlan[] = [];\n\n // Reorder children so message packer plans are last.\n const sortedChildren = Array.from(instructionPlan.plans).sort(\n (a, b) => Number(a.kind === 'messagePacker') - Number(b.kind === 'messagePacker'),\n );\n\n for (const plan of sortedChildren) {\n const transactionPlan = await traverse(plan, {\n ...context,\n parent: instructionPlan,\n parentCandidates: candidates,\n });\n if (transactionPlan) {\n candidates.push(...getParallelCandidates(transactionPlan));\n const newPlans = transactionPlan.kind === 'parallel' ? transactionPlan.plans : [transactionPlan];\n transactionPlans.push(...newPlans);\n }\n }\n\n // Wrap in a parallel plan or simplify.\n if (transactionPlans.length === 1) {\n return transactionPlans[0];\n }\n if (transactionPlans.length === 0) {\n return null;\n }\n return { kind: 'parallel', plans: transactionPlans };\n}\n\nasync function traverseSingle(\n instructionPlan: SingleInstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n const predicate = (message: BaseTransactionMessage & TransactionMessageWithFeePayer) =>\n appendTransactionMessageInstructions([instructionPlan.instruction], message);\n const candidate = await selectAndMutateCandidate(context, context.parentCandidates, predicate);\n if (candidate) {\n return null;\n }\n const message = await createNewMessage(context, predicate);\n return { kind: 'single', message };\n}\n\nasync function traverseMessagePacker(\n instructionPlan: MessagePackerInstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n const messagePacker = instructionPlan.getMessagePacker();\n const transactionPlans: SingleTransactionPlan[] = [];\n const candidates = [...context.parentCandidates];\n\n while (!messagePacker.done()) {\n const candidate = await selectAndMutateCandidate(context, candidates, messagePacker.packMessageToCapacity);\n if (!candidate) {\n const message = await createNewMessage(context, messagePacker.packMessageToCapacity);\n const newPlan: MutableSingleTransactionPlan = { kind: 'single', message };\n transactionPlans.push(newPlan);\n }\n }\n\n if (transactionPlans.length === 1) {\n return transactionPlans[0];\n }\n if (transactionPlans.length === 0) {\n return null;\n }\n if (context.parent?.kind === 'parallel') {\n return { kind: 'parallel', plans: transactionPlans };\n }\n return {\n divisible: context.parent?.kind === 'sequential' ? context.parent.divisible : true,\n kind: 'sequential',\n plans: transactionPlans,\n };\n}\n\nfunction getSequentialCandidate(latestPlan: MutableTransactionPlan): MutableSingleTransactionPlan | null {\n if (latestPlan.kind === 'single') {\n return latestPlan;\n }\n if (latestPlan.kind === 'sequential' && latestPlan.plans.length > 0) {\n return getSequentialCandidate(latestPlan.plans[latestPlan.plans.length - 1]);\n }\n return null;\n}\n\nfunction getParallelCandidates(latestPlan: TransactionPlan): MutableSingleTransactionPlan[] {\n return getAllSingleTransactionPlans(latestPlan);\n}\n\nasync function selectAndMutateCandidate(\n context: Pick<TraverseContext, 'abortSignal' | 'onTransactionMessageUpdated'>,\n candidates: MutableSingleTransactionPlan[],\n predicate: (\n message: BaseTransactionMessage & TransactionMessageWithFeePayer,\n ) => BaseTransactionMessage & TransactionMessageWithFeePayer,\n): Promise<MutableSingleTransactionPlan | null> {\n for (const candidate of candidates) {\n try {\n const message = await getAbortablePromise(\n Promise.resolve(\n context.onTransactionMessageUpdated(predicate(candidate.message), {\n abortSignal: context.abortSignal,\n }),\n ),\n context.abortSignal,\n );\n if (getTransactionMessageSize(message) <= TRANSACTION_SIZE_LIMIT) {\n candidate.message = message;\n return candidate;\n }\n } catch (error) {\n if (isSolanaError(error, SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN)) {\n // Try the next candidate.\n } else {\n throw error;\n }\n }\n }\n return null;\n}\n\nasync function createNewMessage(\n context: Pick<TraverseContext, 'abortSignal' | 'createTransactionMessage' | 'onTransactionMessageUpdated'>,\n predicate: (\n message: BaseTransactionMessage & TransactionMessageWithFeePayer,\n ) => BaseTransactionMessage & TransactionMessageWithFeePayer,\n): Promise<BaseTransactionMessage & TransactionMessageWithFeePayer> {\n const newMessage = await getAbortablePromise(\n Promise.resolve(context.createTransactionMessage({ abortSignal: context.abortSignal })),\n context.abortSignal,\n );\n const updatedMessage = await getAbortablePromise(\n Promise.resolve(\n context.onTransactionMessageUpdated(predicate(newMessage), { abortSignal: context.abortSignal }),\n ),\n context.abortSignal,\n );\n const updatedMessageSize = getTransactionMessageSize(updatedMessage);\n if (updatedMessageSize > TRANSACTION_SIZE_LIMIT) {\n const newMessageSize = getTransactionMessageSize(newMessage);\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n numBytesRequired: updatedMessageSize - newMessageSize,\n numFreeBytes: TRANSACTION_SIZE_LIMIT - newMessageSize,\n });\n }\n return updatedMessage;\n}\n\nfunction freezeTransactionPlan(plan: MutableTransactionPlan): TransactionPlan {\n const kind = plan.kind;\n switch (kind) {\n case 'single':\n return singleTransactionPlan(plan.message);\n case 'sequential':\n return plan.divisible\n ? sequentialTransactionPlan(plan.plans.map(freezeTransactionPlan))\n : nonDivisibleSequentialTransactionPlan(plan.plans.map(freezeTransactionPlan));\n case 'parallel':\n return parallelTransactionPlan(plan.plans.map(freezeTransactionPlan));\n default:\n plan satisfies never;\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND, { kind });\n }\n}\n\nfunction fitEntirePlanInsideMessage(\n instructionPlan: InstructionPlan,\n message: BaseTransactionMessage & TransactionMessageWithFeePayer,\n): BaseTransactionMessage & TransactionMessageWithFeePayer {\n let newMessage: BaseTransactionMessage & TransactionMessageWithFeePayer = message;\n\n const kind = instructionPlan.kind;\n switch (kind) {\n case 'sequential':\n case 'parallel':\n for (const plan of instructionPlan.plans) {\n newMessage = fitEntirePlanInsideMessage(plan, newMessage);\n }\n return newMessage;\n case 'single':\n newMessage = appendTransactionMessageInstructions([instructionPlan.instruction], message);\n // eslint-disable-next-line no-case-declarations\n const newMessageSize = getTransactionMessageSize(newMessage);\n if (newMessageSize > TRANSACTION_SIZE_LIMIT) {\n const baseMessageSize = getTransactionMessageSize(message);\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n numBytesRequired: newMessageSize - baseMessageSize,\n numFreeBytes: TRANSACTION_SIZE_LIMIT - baseMessageSize,\n });\n }\n return newMessage;\n case 'messagePacker':\n // eslint-disable-next-line no-case-declarations\n const messagePacker = instructionPlan.getMessagePacker();\n while (!messagePacker.done()) {\n newMessage = messagePacker.packMessageToCapacity(message);\n }\n return newMessage;\n default:\n instructionPlan satisfies never;\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, { kind });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/instruction-plan.ts","../src/transaction-plan-result.ts","../src/transaction-plan-executor.ts","../src/transaction-plan.ts","../src/transaction-planner.ts"],"names":["SolanaError","SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE","getTransactionMessageSize","appendTransactionMessageInstruction","TRANSACTION_SIZE_LIMIT","SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN","getSignatureFromTransaction","traverse","result","context","SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN","SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND","SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED","getAbortablePromise","SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN","traverseSequential","traverseParallel","traverseSingle","SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND","candidate","message","appendTransactionMessageInstructions","isSolanaError"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["import {\n SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE,\n SolanaError,\n} from '@solana/errors';\nimport { Instruction } from '@solana/instructions';\nimport {\n appendTransactionMessageInstruction,\n BaseTransactionMessage,\n TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { getTransactionMessageSize, TRANSACTION_SIZE_LIMIT } from '@solana/transactions';\n\n/**\n * A set of instructions with constraints on how they can be executed.\n *\n * This is structured as a recursive tree of plans in order to allow for\n * parallel execution, sequential execution and combinations of both.\n *\n * Namely the following plans are supported:\n * - {@link SingleInstructionPlan} - A plan that contains a single instruction.\n * This is a simple instruction wrapper and the simplest leaf in this tree.\n * - {@link ParallelInstructionPlan} - A plan that contains other plans that\n * can be executed in parallel.\n * - {@link SequentialInstructionPlan} - A plan that contains other plans that\n * must be executed sequentially. It also defines whether the plan is divisible\n * meaning that instructions inside it can be split into separate transactions.\n * - {@link MessagePackerInstructionPlan} - A plan that can dynamically pack\n * instructions into transaction messages.\n *\n * Helpers are provided for each of these plans to make it easier to create them.\n *\n * @example\n * ```ts\n * const myInstructionPlan: InstructionPlan = parallelInstructionPlan([\n * sequentialInstructionPlan([instructionA, instructionB]),\n * instructionC,\n * instructionD,\n * ]);\n * ```\n *\n * @see {@link SingleInstructionPlan}\n * @see {@link ParallelInstructionPlan}\n * @see {@link SequentialInstructionPlan}\n * @see {@link MessagePackerInstructionPlan}\n */\nexport type InstructionPlan =\n | MessagePackerInstructionPlan\n | ParallelInstructionPlan\n | SequentialInstructionPlan\n | SingleInstructionPlan;\n\n/**\n * A plan wrapping other plans that must be executed sequentially.\n *\n * It also defines whether nested plans are divisible — meaning that\n * the instructions inside them can be split into separate transactions.\n * When `divisible` is `false`, the instructions inside the plan should\n * all be executed atomically — either in a single transaction or in a\n * transaction bundle.\n *\n * You may use the {@link sequentialInstructionPlan} and {@link nonDivisibleSequentialInstructionPlan}\n * helpers to create objects of this type.\n *\n * @example Simple sequential plan with two instructions.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, instructionB]);\n * plan satisfies SequentialInstructionPlan;\n * ```\n *\n * @example Non-divisible sequential plan with two instructions.\n * ```ts\n * const plan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n * plan satisfies SequentialInstructionPlan & { divisible: false };\n * ```\n *\n * @example Sequential plan with nested parallel plans.\n * Here, instructions A and B can be executed in parallel, but they must both be finalized\n * before instructions C and D can be sent — which can also be executed in parallel.\n * ```ts\n * const plan = sequentialInstructionPlan([\n * parallelInstructionPlan([instructionA, instructionB]),\n * parallelInstructionPlan([instructionC, instructionD]),\n * ]);\n * plan satisfies SequentialInstructionPlan & { divisible: false };\n * ```\n *\n * @see {@link sequentialInstructionPlan}\n * @see {@link nonDivisibleSequentialInstructionPlan}\n */\nexport type SequentialInstructionPlan = Readonly<{\n divisible: boolean;\n kind: 'sequential';\n plans: InstructionPlan[];\n}>;\n\n/**\n * A plan wrapping other plans that can be executed in parallel.\n *\n * This means direct children of this plan can be executed in separate\n * parallel transactions without consequence.\n * However, the children themselves can define additional constraints\n * for that specific branch of the tree — such as the {@link SequentialInstructionPlan}.\n *\n * You may use the {@link parallelInstructionPlan} helper to create objects of this type.\n *\n * @example Simple parallel plan with two instructions.\n * ```ts\n * const plan = parallelInstructionPlan([instructionA, instructionB]);\n * plan satisfies ParallelInstructionPlan;\n * ```\n *\n * @example Parallel plan with nested sequential plans.\n * Here, instructions A and B must be executed sequentially and so must instructions C and D,\n * but both pairs can be executed in parallel.\n * ```ts\n * const plan = parallelInstructionPlan([\n * sequentialInstructionPlan([instructionA, instructionB]),\n * sequentialInstructionPlan([instructionC, instructionD]),\n * ]);\n * plan satisfies ParallelInstructionPlan;\n * ```\n *\n * @see {@link parallelInstructionPlan}\n */\nexport type ParallelInstructionPlan = Readonly<{\n kind: 'parallel';\n plans: InstructionPlan[];\n}>;\n\n/**\n * A plan that contains a single instruction.\n *\n * This is a simple instruction wrapper that transforms an instruction into a plan.\n *\n * You may use the {@link singleInstructionPlan} helper to create objects of this type.\n *\n * @example\n * ```ts\n * const plan = singleInstructionPlan(instructionA);\n * plan satisfies SingleInstructionPlan;\n * ```\n *\n * @see {@link singleInstructionPlan}\n */\nexport type SingleInstructionPlan<TInstruction extends Instruction = Instruction> = Readonly<{\n instruction: TInstruction;\n kind: 'single';\n}>;\n\n/**\n * A plan that can dynamically pack instructions into transaction messages.\n *\n * This plan provides a {@link MessagePacker} via the `getMessagePacker`\n * method, which enables instructions to be dynamically packed into the\n * provided transaction message until there are no more instructions to pack.\n * The returned {@link MessagePacker} offers a `packMessageToCapacity(message)`\n * method that packs the provided message — when possible — and a `done()` method\n * that checks whether there are more instructions to pack.\n *\n * Several helper functions are provided to create objects of this type such as\n * {@link getLinearMessagePackerInstructionPlan} or {@link getMessagePackerInstructionPlanFromInstructions}.\n *\n * @example An message packer plan for a write instruction that uses as many bytes as possible.\n * ```ts\n * const plan = getLinearMessagePackerInstructionPlan({\n * totalLength: dataToWrite.length,\n * getInstruction: (offset, length) =>\n * getWriteInstruction({\n * offset,\n * data: dataToWrite.slice(offset, offset + length),\n * }),\n * });\n * plan satisfies MessagePackerInstructionPlan;\n * ```\n *\n * @example A message packer plan for multiple realloc instructions.\n * ```ts\n * const plan = getReallocMessagePackerInstructionPlan({\n * totalSize: additionalDataSize,\n * getInstruction: (size) => getExtendInstruction({ length: size }),\n * });\n * plan satisfies MessagePackerInstructionPlan;\n * ```\n *\n * @example Using a message packer plan.\n * ```ts\n * let plan: MessagePackerInstructionPlan;\n * const messagePacker = plan.getMessagePacker();\n *\n * while (!messagePacker.done()) {\n * try {\n * transactionMessage = messagePacker.packMessageToCapacity(transactionMessage);\n * } catch (error) {\n * // The current transaction message cannot be used to pack this plan.\n * // We should create a new one and try again.\n * }\n * }\n * ```\n *\n * @see {@link getLinearMessagePackerInstructionPlan}\n * @see {@link getMessagePackerInstructionPlanFromInstructions}\n * @see {@link getReallocMessagePackerInstructionPlan}\n */\nexport type MessagePackerInstructionPlan = Readonly<{\n getMessagePacker: () => MessagePacker;\n kind: 'messagePacker';\n}>;\n\n/**\n * The message packer returned by the {@link MessagePackerInstructionPlan}.\n *\n * It offers a `packMessageToCapacity(transactionMessage)` method that packs as many instructions\n * as possible into the provided transaction message, while still being able to fit into the\n * transaction size limit. It returns the updated transaction message with the packed instructions\n * or throws an error if the current transaction message cannot accommodate this plan.\n *\n * The `done()` method checks whether there are more instructions to pack into\n * transaction messages.\n *\n * @example\n * ```ts\n * let plan: MessagePackerInstructionPlan;\n * const messagePacker = plan.getMessagePacker();\n *\n * while (!messagePacker.done()) {\n * try {\n * transactionMessage = messagePacker.packMessageToCapacity(transactionMessage);\n * } catch (error) {\n * // The current transaction message cannot be used to pack this plan.\n * // We should create a new one and try again.\n * }\n * }\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n */\nexport type MessagePacker = Readonly<{\n /** Checks whether the message packer has more instructions to pack into transaction messages. */\n done: () => boolean;\n /**\n * Packs the provided transaction message with instructions or throws if not possible.\n *\n * @throws {@link SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN}\n * if the provided transaction message cannot be used to fill the next instructions.\n * @throws {@link SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE}\n * if the message packer is already done and no more instructions can be packed.\n */\n packMessageToCapacity: (\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n ) => BaseTransactionMessage & TransactionMessageWithFeePayer;\n}>;\n\n/**\n * Creates a {@link ParallelInstructionPlan} from an array of nested plans.\n *\n * It can accept {@link Instruction} objects directly, which will be wrapped\n * in {@link SingleInstructionPlan | SingleInstructionPlans} automatically.\n *\n * @example Using explicit {@link SingleInstructionPlan | SingleInstructionPlans}.\n * ```ts\n * const plan = parallelInstructionPlan([\n * singleInstructionPlan(instructionA),\n * singleInstructionPlan(instructionB),\n * ]);\n * ```\n *\n * @example Using {@link Instruction | Instructions} directly.\n * ```ts\n * const plan = parallelInstructionPlan([instructionA, instructionB]);\n * ```\n *\n * @see {@link ParallelInstructionPlan}\n */\nexport function parallelInstructionPlan(plans: (Instruction | InstructionPlan)[]): ParallelInstructionPlan {\n return Object.freeze({\n kind: 'parallel',\n plans: parseSingleInstructionPlans(plans),\n });\n}\n\n/**\n * Creates a divisible {@link SequentialInstructionPlan} from an array of nested plans.\n *\n * It can accept {@link Instruction} objects directly, which will be wrapped\n * in {@link SingleInstructionPlan | SingleInstructionPlans} automatically.\n *\n * @example Using explicit {@link SingleInstructionPlan | SingleInstructionPlans}.\n * ```ts\n * const plan = sequentialInstructionPlan([\n * singleInstructionPlan(instructionA),\n * singleInstructionPlan(instructionB),\n * ]);\n * ```\n *\n * @example Using {@link Instruction | Instructions} directly.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, instructionB]);\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n */\nexport function sequentialInstructionPlan(\n plans: (Instruction | InstructionPlan)[],\n): SequentialInstructionPlan & { divisible: true } {\n return Object.freeze({\n divisible: true,\n kind: 'sequential',\n plans: parseSingleInstructionPlans(plans),\n });\n}\n\n/**\n * Creates a non-divisible {@link SequentialInstructionPlan} from an array of nested plans.\n *\n * It can accept {@link Instruction} objects directly, which will be wrapped\n * in {@link SingleInstructionPlan | SingleInstructionPlans} automatically.\n *\n * @example Using explicit {@link SingleInstructionPlan | SingleInstructionPlans}.\n * ```ts\n * const plan = nonDivisibleSequentialInstructionPlan([\n * singleInstructionPlan(instructionA),\n * singleInstructionPlan(instructionB),\n * ]);\n * ```\n *\n * @example Using {@link Instruction | Instructions} directly.\n * ```ts\n * const plan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n */\nexport function nonDivisibleSequentialInstructionPlan(\n plans: (Instruction | InstructionPlan)[],\n): SequentialInstructionPlan & { divisible: false } {\n return Object.freeze({\n divisible: false,\n kind: 'sequential',\n plans: parseSingleInstructionPlans(plans),\n });\n}\n\n/**\n * Creates a {@link SingleInstructionPlan} from an {@link Instruction} object.\n *\n * @example\n * ```ts\n * const plan = singleInstructionPlan(instructionA);\n * ```\n *\n * @see {@link SingleInstructionPlan}\n */\nexport function singleInstructionPlan(instruction: Instruction): SingleInstructionPlan {\n return Object.freeze({ instruction, kind: 'single' });\n}\n\nfunction parseSingleInstructionPlans(plans: (Instruction | InstructionPlan)[]): InstructionPlan[] {\n return plans.map(plan => ('kind' in plan ? plan : singleInstructionPlan(plan)));\n}\n\n/**\n * Creates a {@link MessagePackerInstructionPlan} that packs instructions\n * such that each instruction consumes as many bytes as possible from the given\n * `totalLength` while still being able to fit into the given transaction messages.\n *\n * This is particularly useful for instructions that write data to accounts and must\n * span multiple transactions due to their size limit.\n *\n * This message packer will first call `getInstruction` with a length of zero to\n * determine the base size of the instruction before figuring out how many\n * additional bytes can be packed into the transaction message. That remaining space\n * will then be used to call `getInstruction` again with the appropriate length.\n *\n * @param getInstruction - A function that returns an instruction for a given offset and length.\n * @param totalLength - The total length of the data to write, in bytes.\n *\n * @example\n * ```ts\n * const plan = getLinearMessagePackerInstructionPlan({\n * totalLength: dataToWrite.length,\n * getInstruction: (offset, length) =>\n * getWriteInstruction({\n * offset,\n * data: dataToWrite.slice(offset, offset + length),\n * }),\n * });\n * plan satisfies MessagePackerInstructionPlan;\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n */\nexport function getLinearMessagePackerInstructionPlan({\n getInstruction,\n totalLength: totalBytes,\n}: {\n getInstruction: (offset: number, length: number) => Instruction;\n totalLength: number;\n}): MessagePackerInstructionPlan {\n return Object.freeze({\n getMessagePacker: () => {\n let offset = 0;\n return Object.freeze({\n done: () => offset >= totalBytes,\n packMessageToCapacity: (message: BaseTransactionMessage & TransactionMessageWithFeePayer) => {\n if (offset >= totalBytes) {\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE);\n }\n\n const messageSizeWithBaseInstruction = getTransactionMessageSize(\n appendTransactionMessageInstruction(getInstruction(offset, 0), message),\n );\n const freeSpace =\n TRANSACTION_SIZE_LIMIT -\n messageSizeWithBaseInstruction /* Includes the base instruction (length: 0). */ -\n 1; /* Leeway for shortU16 numbers in transaction headers. */\n\n if (freeSpace <= 0) {\n const messageSize = getTransactionMessageSize(message);\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n // (+1) We need to pack at least one byte of data otherwise\n // there is no point packing the base instruction alone.\n numBytesRequired: messageSizeWithBaseInstruction - messageSize + 1,\n // (-1) Leeway for shortU16 numbers in transaction headers.\n numFreeBytes: TRANSACTION_SIZE_LIMIT - messageSize - 1,\n });\n }\n\n const length = Math.min(totalBytes - offset, freeSpace);\n const instruction = getInstruction(offset, length);\n offset += length;\n return appendTransactionMessageInstruction(instruction, message);\n },\n });\n },\n kind: 'messagePacker',\n });\n}\n\n/**\n * Creates a {@link MessagePackerInstructionPlan} from a list of instructions.\n *\n * This can be useful to prepare a set of instructions that can be iterated over\n * — e.g. to pack a list of instructions that gradually reallocate the size of an account\n * one `REALLOC_LIMIT` (10'240 bytes) at a time.\n *\n * @example\n * ```ts\n * const plan = getMessagePackerInstructionPlanFromInstructions([\n * instructionA,\n * instructionB,\n * instructionC,\n * ]);\n *\n * const messagePacker = plan.getMessagePacker();\n * firstTransactionMessage = messagePacker.packMessageToCapacity(firstTransactionMessage);\n * // Contains instruction A and instruction B.\n * secondTransactionMessage = messagePacker.packMessageToCapacity(secondTransactionMessage);\n * // Contains instruction C.\n * messagePacker.done(); // true\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n * @see {@link getReallocMessagePackerInstructionPlan}\n */\nexport function getMessagePackerInstructionPlanFromInstructions<TInstruction extends Instruction = Instruction>(\n instructions: TInstruction[],\n): MessagePackerInstructionPlan {\n return Object.freeze({\n getMessagePacker: () => {\n let instructionIndex = 0;\n return Object.freeze({\n done: () => instructionIndex >= instructions.length,\n packMessageToCapacity: (message: BaseTransactionMessage & TransactionMessageWithFeePayer) => {\n if (instructionIndex >= instructions.length) {\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE);\n }\n\n const originalMessageSize = getTransactionMessageSize(message);\n\n for (let index = instructionIndex; index < instructions.length; index++) {\n message = appendTransactionMessageInstruction(instructions[index], message);\n const messageSize = getTransactionMessageSize(message);\n\n if (messageSize > TRANSACTION_SIZE_LIMIT) {\n if (index === instructionIndex) {\n throw new SolanaError(\n SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n {\n numBytesRequired: messageSize - originalMessageSize,\n numFreeBytes: TRANSACTION_SIZE_LIMIT - originalMessageSize,\n },\n );\n }\n instructionIndex = index;\n return message;\n }\n }\n\n instructionIndex = instructions.length;\n return message;\n },\n });\n },\n kind: 'messagePacker',\n });\n}\n\nconst REALLOC_LIMIT = 10_240;\n\n/**\n * Creates a {@link MessagePackerInstructionPlan} that packs a list of realloc instructions.\n *\n * That is, it splits instruction by chunks of `REALLOC_LIMIT` (10'240) bytes until\n * the given total size is reached.\n *\n * @example\n * ```ts\n * const plan = getReallocMessagePackerInstructionPlan({\n * totalSize: additionalDataSize,\n * getInstruction: (size) => getExtendInstruction({ length: size }),\n * });\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n */\nexport function getReallocMessagePackerInstructionPlan({\n getInstruction,\n totalSize,\n}: {\n getInstruction: (size: number) => Instruction;\n totalSize: number;\n}): MessagePackerInstructionPlan {\n const numberOfInstructions = Math.ceil(totalSize / REALLOC_LIMIT);\n const lastInstructionSize = totalSize % REALLOC_LIMIT;\n const instructions = new Array(numberOfInstructions)\n .fill(0)\n .map((_, i) => getInstruction(i === numberOfInstructions - 1 ? lastInstructionSize : REALLOC_LIMIT));\n\n return getMessagePackerInstructionPlanFromInstructions(instructions);\n}\n","import { Signature } from '@solana/keys';\nimport { BaseTransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\n\n/**\n * The result of executing a transaction plan.\n *\n * This is structured as a recursive tree of results that mirrors the structure\n * of the original transaction plan, capturing the execution status at each level.\n *\n * Namely, the following result types are supported:\n * - {@link SingleTransactionPlanResult} - A result for a single transaction message\n * containing its execution status.\n * - {@link ParallelTransactionPlanResult} - A result containing other results that\n * were executed in parallel.\n * - {@link SequentialTransactionPlanResult} - A result containing other results that\n * were executed sequentially. It also retains the divisibility property from the\n * original plan.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n *\n * @see {@link SingleTransactionPlanResult}\n * @see {@link ParallelTransactionPlanResult}\n * @see {@link SequentialTransactionPlanResult}\n * @see {@link TransactionPlanResultStatus}\n */\nexport type TransactionPlanResult<TContext extends TransactionPlanResultContext = TransactionPlanResultContext> =\n | ParallelTransactionPlanResult<TContext>\n | SequentialTransactionPlanResult<TContext>\n | SingleTransactionPlanResult<TContext>;\n\n/** A context object that may be passed along with successful results. */\nexport type TransactionPlanResultContext = Record<number | string | symbol, unknown>;\n\n/**\n * A result for a sequential transaction plan.\n *\n * This represents the execution result of a {@link SequentialTransactionPlan} and\n * contains child results that were executed sequentially. It also retains the\n * divisibility property from the original plan.\n *\n * You may use the {@link sequentialTransactionPlanResult} and\n * {@link nonDivisibleSequentialTransactionPlanResult} helpers to create objects of this type.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n *\n * @example\n * ```ts\n * const result = sequentialTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult;\n * ```\n *\n * @example\n * Non-divisible sequential result.\n * ```ts\n * const result = nonDivisibleSequentialTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult & { divisible: false };\n * ```\n *\n * @see {@link sequentialTransactionPlanResult}\n * @see {@link nonDivisibleSequentialTransactionPlanResult}\n */\nexport type SequentialTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n> = Readonly<{\n divisible: boolean;\n kind: 'sequential';\n plans: TransactionPlanResult<TContext>[];\n}>;\n\n/**\n * A result for a parallel transaction plan.\n *\n * This represents the execution result of a {@link ParallelTransactionPlan} and\n * contains child results that were executed in parallel.\n *\n * You may use the {@link parallelTransactionPlanResult} helper to create objects of this type.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n *\n * @example\n * ```ts\n * const result = parallelTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies ParallelTransactionPlanResult;\n * ```\n *\n * @see {@link parallelTransactionPlanResult}\n */\nexport type ParallelTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n> = Readonly<{\n kind: 'parallel';\n plans: TransactionPlanResult<TContext>[];\n}>;\n\n/**\n * A result for a single transaction plan.\n *\n * This represents the execution result of a {@link SingleTransactionPlan} and\n * contains the original transaction message along with its execution status.\n *\n * You may use the {@link successfulSingleTransactionPlanResult},\n * {@link failedSingleTransactionPlanResult}, or {@link canceledSingleTransactionPlanResult}\n * helpers to create objects of this type.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n * @template TTransactionMessage - The type of the transaction message\n *\n * @example\n * Successful result with a transaction and context.\n * ```ts\n * const result = successfulSingleTransactionPlanResult(\n * transactionMessage,\n * transaction\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @example\n * Failed result with an error.\n * ```ts\n * const result = failedSingleTransactionPlanResult(\n * transactionMessage,\n * new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @example\n * Canceled result.\n * ```ts\n * const result = canceledSingleTransactionPlanResult(transactionMessage);\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link successfulSingleTransactionPlanResult}\n * @see {@link failedSingleTransactionPlanResult}\n * @see {@link canceledSingleTransactionPlanResult}\n */\nexport type SingleTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n> = Readonly<{\n kind: 'single';\n message: TTransactionMessage;\n status: TransactionPlanResultStatus<TContext>;\n}>;\n\n/**\n * The status of a single transaction plan execution.\n *\n * This represents the outcome of executing a single transaction message and can be one of:\n * - `successful` - The transaction was successfully executed. Contains the transaction\n * and an optional context object.\n * - `failed` - The transaction execution failed. Contains the error that caused the failure.\n * - `canceled` - The transaction execution was canceled.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n */\nexport type TransactionPlanResultStatus<TContext extends TransactionPlanResultContext = TransactionPlanResultContext> =\n | Readonly<{ context: TContext; kind: 'successful'; signature: Signature; transaction?: Transaction }>\n | Readonly<{ error: Error; kind: 'failed' }>\n | Readonly<{ kind: 'canceled' }>;\n\n/**\n * Creates a divisible {@link SequentialTransactionPlanResult} from an array of nested results.\n *\n * This function creates a sequential result with the `divisible` property set to `true`,\n * indicating that the nested plans were executed sequentially but could have been\n * split into separate transactions or batches.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n * @param plans - The child results that were executed sequentially\n *\n * @example\n * ```ts\n * const result = sequentialTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult & { divisible: true };\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n */\nexport function sequentialTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(plans: TransactionPlanResult<TContext>[]): SequentialTransactionPlanResult<TContext> & { divisible: true } {\n return Object.freeze({ divisible: true, kind: 'sequential', plans });\n}\n\n/**\n * Creates a non-divisible {@link SequentialTransactionPlanResult} from an array of nested results.\n *\n * This function creates a sequential result with the `divisible` property set to `false`,\n * indicating that the nested plans were executed sequentially and could not have been\n * split into separate transactions or batches (e.g., they were executed as a transaction bundle).\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n * @param plans - The child results that were executed sequentially\n *\n * @example\n * ```ts\n * const result = nonDivisibleSequentialTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult & { divisible: false };\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n */\nexport function nonDivisibleSequentialTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(plans: TransactionPlanResult<TContext>[]): SequentialTransactionPlanResult<TContext> & { divisible: false } {\n return Object.freeze({ divisible: false, kind: 'sequential', plans });\n}\n\n/**\n * Creates a {@link ParallelTransactionPlanResult} from an array of nested results.\n *\n * This function creates a parallel result indicating that the nested plans\n * were executed in parallel.\n *\n * @template TContext - The type of the context object that may be passed along with successful results\n * @param plans - The child results that were executed in parallel\n *\n * @example\n * ```ts\n * const result = parallelTransactionPlanResult([\n * singleResultA,\n * singleResultB,\n * ]);\n * result satisfies ParallelTransactionPlanResult;\n * ```\n *\n * @see {@link ParallelTransactionPlanResult}\n */\nexport function parallelTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(plans: TransactionPlanResult<TContext>[]): ParallelTransactionPlanResult<TContext> {\n return Object.freeze({ kind: 'parallel', plans });\n}\n\n/**\n * Creates a successful {@link SingleTransactionPlanResult} from a transaction message and transaction.\n *\n * This function creates a single result with a 'successful' status, indicating that\n * the transaction was successfully executed. It also includes the original transaction\n * message, the executed transaction, and an optional context object.\n *\n * @template TContext - The type of the context object\n * @template TTransactionMessage - The type of the transaction message\n * @param transactionMessage - The original transaction message\n * @param transaction - The successfully executed transaction\n * @param context - Optional context object to be included with the result\n *\n * @example\n * ```ts\n * const result = successfulSingleTransactionPlanResult(\n * transactionMessage,\n * transaction\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function successfulSingleTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n transaction: Transaction,\n context?: TContext,\n): SingleTransactionPlanResult<TContext, TTransactionMessage> {\n return Object.freeze({\n kind: 'single',\n message: transactionMessage,\n status: Object.freeze({\n context: context ?? ({} as TContext),\n kind: 'successful',\n signature: getSignatureFromTransaction(transaction),\n transaction,\n }),\n });\n}\n\n/**\n * Creates a successful {@link SingleTransactionPlanResult} from a transaction message and signature.\n *\n * This function creates a single result with a 'successful' status, indicating that\n * the transaction was successfully executed. It also includes the original transaction\n * message, the signature of the executed transaction, and an optional context object.\n *\n * @template TContext - The type of the context object\n * @template TTransactionMessage - The type of the transaction message\n * @param transactionMessage - The original transaction message\n * @param signature - The signature of the successfully executed transaction\n * @param context - Optional context object to be included with the result\n *\n * @example\n * ```ts\n * const result = successfulSingleTransactionPlanResult(\n * transactionMessage,\n * signature\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function successfulSingleTransactionPlanResultFromSignature<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n signature: Signature,\n context?: TContext,\n): SingleTransactionPlanResult<TContext, TTransactionMessage> {\n return Object.freeze({\n kind: 'single',\n message: transactionMessage,\n status: Object.freeze({ context: context ?? ({} as TContext), kind: 'successful', signature }),\n });\n}\n\n/**\n * Creates a failed {@link SingleTransactionPlanResult} from a transaction message and error.\n *\n * This function creates a single result with a 'failed' status, indicating that\n * the transaction execution failed. It includes the original transaction message\n * and the error that caused the failure.\n *\n * @template TContext - The type of the context object (not used in failed results)\n * @template TTransactionMessage - The type of the transaction message\n * @param transactionMessage - The original transaction message\n * @param error - The error that caused the transaction to fail\n *\n * @example\n * ```ts\n * const result = failedSingleTransactionPlanResult(\n * transactionMessage,\n * new SolanaError({\n * code: 123,\n * message: 'Transaction simulation failed',\n * }),\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function failedSingleTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(transactionMessage: TTransactionMessage, error: Error): SingleTransactionPlanResult<TContext, TTransactionMessage> {\n return Object.freeze({\n kind: 'single',\n message: transactionMessage,\n status: Object.freeze({ error, kind: 'failed' }),\n });\n}\n\n/**\n * Creates a canceled {@link SingleTransactionPlanResult} from a transaction message.\n *\n * This function creates a single result with a 'canceled' status, indicating that\n * the transaction execution was canceled. It includes the original transaction message.\n *\n * @template TContext - The type of the context object (not used in canceled results)\n * @template TTransactionMessage - The type of the transaction message\n * @param transactionMessage - The original transaction message\n *\n * @example\n * ```ts\n * const result = canceledSingleTransactionPlanResult(transactionMessage);\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function canceledSingleTransactionPlanResult<\n TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(transactionMessage: TTransactionMessage): SingleTransactionPlanResult<TContext, TTransactionMessage> {\n return Object.freeze({\n kind: 'single',\n message: transactionMessage,\n status: Object.freeze({ kind: 'canceled' }),\n });\n}\n\n/**\n * Flattens a {@link TransactionPlanResult} into an array of {@link SingleTransactionPlanResult}.\n * @param result The transaction plan result to flatten\n * @returns An array of single transaction plan results\n */\nexport function flattenTransactionPlanResult(result: TransactionPlanResult): SingleTransactionPlanResult[] {\n const transactionPlanResults: SingleTransactionPlanResult[] = [];\n\n function traverse(result: TransactionPlanResult) {\n if (result.kind === 'single') {\n transactionPlanResults.push(result);\n } else {\n for (const subResult of result.plans) {\n traverse(subResult);\n }\n }\n }\n\n traverse(result);\n return transactionPlanResults;\n}\n\n/**\n * A {@link SingleTransactionPlanResult} with 'successful' status.\n */\nexport type SuccessfulSingleTransactionPlanResult = SingleTransactionPlanResult & { status: { kind: 'successful' } };\n\n/**\n * A {@link SingleTransactionPlanResult} with 'failed' status.\n */\nexport type FailedSingleTransactionPlanResult = SingleTransactionPlanResult & { status: { kind: 'failed' } };\n\n/**\n * A {@link SingleTransactionPlanResult} with 'canceled' status.\n */\nexport type CanceledSingleTransactionPlanResult = SingleTransactionPlanResult & { status: { kind: 'canceled' } };\n\n/**\n * A summary of a {@link TransactionPlanResult}, categorizing transactions by their execution status.\n * - `successful`: Indicates whether all transactions were successful (i.e., no failed or canceled transactions).\n * - `successfulTransactions`: An array of successful transactions, each including its signature.\n * - `failedTransactions`: An array of failed transactions, each including the error that caused the failure.\n * - `canceledTransactions`: An array of canceled transactions.\n */\nexport type TransactionPlanResultSummary = Readonly<{\n canceledTransactions: CanceledSingleTransactionPlanResult[];\n failedTransactions: FailedSingleTransactionPlanResult[];\n successful: boolean;\n successfulTransactions: SuccessfulSingleTransactionPlanResult[];\n}>;\n\n/**\n * Summarize a {@link TransactionPlanResult} into a {@link TransactionPlanResultSummary}.\n * @param result The transaction plan result to summarize\n * @returns A summary of the transaction plan result\n */\nexport function summarizeTransactionPlanResult(result: TransactionPlanResult): TransactionPlanResultSummary {\n const successfulTransactions: TransactionPlanResultSummary['successfulTransactions'] = [];\n const failedTransactions: TransactionPlanResultSummary['failedTransactions'] = [];\n const canceledTransactions: TransactionPlanResultSummary['canceledTransactions'] = [];\n\n const flattenedResults = flattenTransactionPlanResult(result);\n\n for (const singleResult of flattenedResults) {\n switch (singleResult.status.kind) {\n case 'successful': {\n successfulTransactions.push(singleResult as SuccessfulSingleTransactionPlanResult);\n break;\n }\n case 'failed': {\n failedTransactions.push(singleResult as FailedSingleTransactionPlanResult);\n break;\n }\n case 'canceled': {\n canceledTransactions.push(singleResult as CanceledSingleTransactionPlanResult);\n break;\n }\n }\n }\n\n return Object.freeze({\n canceledTransactions,\n failedTransactions,\n successful: failedTransactions.length === 0 && canceledTransactions.length === 0,\n successfulTransactions,\n });\n}\n","import {\n SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED,\n SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND,\n SolanaError,\n} from '@solana/errors';\nimport { Signature } from '@solana/keys';\nimport { getAbortablePromise } from '@solana/promises';\nimport { BaseTransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\nimport { Transaction } from '@solana/transactions';\n\nimport type {\n ParallelTransactionPlan,\n SequentialTransactionPlan,\n SingleTransactionPlan,\n TransactionPlan,\n} from './transaction-plan';\nimport {\n canceledSingleTransactionPlanResult,\n failedSingleTransactionPlanResult,\n parallelTransactionPlanResult,\n sequentialTransactionPlanResult,\n successfulSingleTransactionPlanResult,\n successfulSingleTransactionPlanResultFromSignature,\n type TransactionPlanResult,\n type TransactionPlanResultContext,\n} from './transaction-plan-result';\n\nexport type TransactionPlanExecutor<TContext extends TransactionPlanResultContext = TransactionPlanResultContext> = (\n transactionPlan: TransactionPlan,\n config?: { abortSignal?: AbortSignal },\n) => Promise<TransactionPlanResult<TContext>>;\n\ntype ExecuteResult<TContext extends TransactionPlanResultContext> = {\n context?: TContext;\n} & ({ signature: Signature } | { transaction: Transaction });\n\ntype ExecuteTransactionMessage = <TContext extends TransactionPlanResultContext = TransactionPlanResultContext>(\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n config?: { abortSignal?: AbortSignal },\n) => Promise<ExecuteResult<TContext>>;\n\n/**\n * Configuration object for creating a new transaction plan executor.\n *\n * @see {@link createTransactionPlanExecutor}\n */\nexport type TransactionPlanExecutorConfig = {\n /** Called whenever a transaction message must be sent to the blockchain. */\n executeTransactionMessage: ExecuteTransactionMessage;\n};\n\n/**\n * Creates a new transaction plan executor based on the provided configuration.\n *\n * The executor will traverse the provided `TransactionPlan` sequentially or in parallel,\n * executing each transaction message using the `executeTransactionMessage` function.\n *\n * - If that function is successful, the executor will return a successful `TransactionPlanResult`\n * for that message including the transaction and any custom context.\n * - If that function throws an error, the executor will stop processing and cancel all\n * remaining transaction messages in the plan.\n * - If the `abortSignal` is triggered, the executor will immediately stop processing the plan and\n * return a `TransactionPlanResult` with the status set to `canceled`.\n *\n * @example\n * ```ts\n * const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n *\n * const transactionPlanExecutor = createTransactionPlanExecutor({\n * executeTransactionMessage: (message) => {\n * const transaction = await signTransactionMessageWithSigners(message);\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * return { transaction };\n * }\n * });\n * ```\n *\n * @see {@link TransactionPlannerConfig}\n */\nexport function createTransactionPlanExecutor(config: TransactionPlanExecutorConfig): TransactionPlanExecutor {\n return async (plan, { abortSignal } = {}): Promise<TransactionPlanResult> => {\n const context: TraverseContext = {\n ...config,\n abortSignal: abortSignal,\n canceled: abortSignal?.aborted ?? false,\n };\n\n // Fail early if there are non-divisible sequential plans in the\n // transaction plan as they are not supported by this executor.\n assertDivisibleSequentialPlansOnly(plan);\n\n const cancelHandler = () => {\n context.canceled = true;\n };\n abortSignal?.addEventListener('abort', cancelHandler);\n const transactionPlanResult = await traverse(plan, context);\n abortSignal?.removeEventListener('abort', cancelHandler);\n\n if (context.canceled) {\n const abortReason = abortSignal?.aborted ? abortSignal.reason : undefined;\n const context = { cause: findErrorFromTransactionPlanResult(transactionPlanResult) ?? abortReason };\n // Here we want the `transactionPlanResult` to be available in the error context\n // so applications can create recovery plans but we don't want this object to be\n // serialized with the error. This is why we set it as a non-enumerable property.\n Object.defineProperty(context, 'transactionPlanResult', {\n configurable: false,\n enumerable: false,\n value: transactionPlanResult,\n writable: false,\n });\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, context);\n }\n\n return transactionPlanResult;\n };\n}\n\ntype TraverseContext = TransactionPlanExecutorConfig & {\n abortSignal?: AbortSignal;\n canceled: boolean;\n};\n\nasync function traverse(transactionPlan: TransactionPlan, context: TraverseContext): Promise<TransactionPlanResult> {\n const kind = transactionPlan.kind;\n switch (kind) {\n case 'sequential':\n return await traverseSequential(transactionPlan, context);\n case 'parallel':\n return await traverseParallel(transactionPlan, context);\n case 'single':\n return await traverseSingle(transactionPlan, context);\n default:\n transactionPlan satisfies never;\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND, { kind });\n }\n}\n\nasync function traverseSequential(\n transactionPlan: SequentialTransactionPlan,\n context: TraverseContext,\n): Promise<TransactionPlanResult> {\n if (!transactionPlan.divisible) {\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED);\n }\n\n const results: TransactionPlanResult[] = [];\n\n for (const subPlan of transactionPlan.plans) {\n const result = await traverse(subPlan, context);\n results.push(result);\n }\n\n return sequentialTransactionPlanResult(results);\n}\n\nasync function traverseParallel(\n transactionPlan: ParallelTransactionPlan,\n context: TraverseContext,\n): Promise<TransactionPlanResult> {\n const results = await Promise.all(transactionPlan.plans.map(plan => traverse(plan, context)));\n return parallelTransactionPlanResult(results);\n}\n\nasync function traverseSingle(\n transactionPlan: SingleTransactionPlan,\n context: TraverseContext,\n): Promise<TransactionPlanResult> {\n if (context.canceled) {\n return canceledSingleTransactionPlanResult(transactionPlan.message);\n }\n\n try {\n const result = await getAbortablePromise(\n context.executeTransactionMessage(transactionPlan.message, { abortSignal: context.abortSignal }),\n context.abortSignal,\n );\n if ('transaction' in result) {\n return successfulSingleTransactionPlanResult(transactionPlan.message, result.transaction, result.context);\n } else {\n return successfulSingleTransactionPlanResultFromSignature(\n transactionPlan.message,\n result.signature,\n result.context,\n );\n }\n } catch (error) {\n context.canceled = true;\n return failedSingleTransactionPlanResult(transactionPlan.message, error as Error);\n }\n}\n\nfunction findErrorFromTransactionPlanResult(result: TransactionPlanResult): Error | undefined {\n if (result.kind === 'single') {\n return result.status.kind === 'failed' ? result.status.error : undefined;\n }\n for (const plan of result.plans) {\n const error = findErrorFromTransactionPlanResult(plan);\n if (error) {\n return error;\n }\n }\n}\n\nfunction assertDivisibleSequentialPlansOnly(transactionPlan: TransactionPlan): void {\n const kind = transactionPlan.kind;\n switch (kind) {\n case 'sequential':\n if (!transactionPlan.divisible) {\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED);\n }\n for (const subPlan of transactionPlan.plans) {\n assertDivisibleSequentialPlansOnly(subPlan);\n }\n return;\n case 'parallel':\n for (const subPlan of transactionPlan.plans) {\n assertDivisibleSequentialPlansOnly(subPlan);\n }\n return;\n case 'single':\n default:\n return;\n }\n}\n","import { BaseTransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\n/**\n * A set of transaction messages with constraints on how they can be executed.\n *\n * This is structured as a recursive tree of plans to allow for\n * parallel execution, sequential execution and combinations of both.\n *\n * Namely, the following plans are supported:\n * - {@link SingleTransactionPlan} - A plan that contains a single transaction message.\n * This is the simplest leaf in this tree.\n * - {@link ParallelTransactionPlan} - A plan that contains other plans that\n * can be executed in parallel.\n * - {@link SequentialTransactionPlan} - A plan that contains other plans that\n * must be executed sequentially. It also defines whether the plan is divisible\n * meaning that transaction messages inside it can be split into separate batches.\n *\n * Helpers are provided for each of these plans to make it easier to create them.\n *\n * @example\n * ```ts\n * const myTransactionPlan: TransactionPlan = parallelTransactionPlan([\n * sequentialTransactionPlan([messageA, messageB]),\n * messageC,\n * ]);\n * ```\n *\n * @see {@link SingleTransactionPlan}\n * @see {@link ParallelTransactionPlan}\n * @see {@link SequentialTransactionPlan}\n */\nexport type TransactionPlan = ParallelTransactionPlan | SequentialTransactionPlan | SingleTransactionPlan;\n\n/**\n * A plan wrapping other plans that must be executed sequentially.\n *\n * It also defines whether nested plans are divisible — meaning that\n * the transaction messages inside them can be split into separate batches.\n * When `divisible` is `false`, the transaction messages inside the plan should\n * all be executed atomically — usually in a transaction bundle.\n *\n * You may use the {@link sequentialTransactionPlan} and {@link nonDivisibleSequentialTransactionPlan}\n * helpers to create objects of this type.\n *\n * @example\n * Simple sequential plan with two transaction messages.\n * ```ts\n * const plan = sequentialTransactionPlan([messageA, messageB]);\n * plan satisfies SequentialTransactionPlan;\n * ```\n *\n * @example\n * Non-divisible sequential plan with two transaction messages.\n * ```ts\n * const plan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n * plan satisfies SequentialTransactionPlan & { divisible: false };\n * ```\n *\n * @example\n * Sequential plan with nested parallel plans.\n * Here, messages A and B can be executed in parallel, but they must both be finalized\n * before messages C and D can be sent — which can also be executed in parallel.\n * ```ts\n * const plan = sequentialTransactionPlan([\n * parallelTransactionPlan([messageA, messageB]),\n * parallelTransactionPlan([messageC, messageD]),\n * ]);\n * ```\n *\n * @see {@link sequentialTransactionPlan}\n * @see {@link nonDivisibleSequentialTransactionPlan}\n */\nexport type SequentialTransactionPlan = Readonly<{\n divisible: boolean;\n kind: 'sequential';\n plans: TransactionPlan[];\n}>;\n\n/**\n * A plan wrapping other plans that can be executed in parallel.\n *\n * This means direct children of this plan can be executed in separate\n * parallel transactions without causing any side effects.\n * However, the children themselves can define additional constraints\n * for that specific branch of the tree — such as the {@link SequentialTransactionPlan}.\n *\n * You may use the {@link parallelTransactionPlan} helper to create objects of this type.\n *\n * @example\n * Simple parallel plan with two transaction messages.\n * ```ts\n * const plan = parallelTransactionPlan([messageA, messageB]);\n * plan satisfies ParallelTransactionPlan;\n * ```\n *\n * @example\n * Parallel plan with nested sequential plans.\n * Here, messages A and B must be executed sequentially and so must messages C and D,\n * but both pairs can be executed in parallel.\n * ```ts\n * const plan = parallelTransactionPlan([\n * sequentialTransactionPlan([messageA, messageB]),\n * sequentialTransactionPlan([messageC, messageD]),\n * ]);\n * plan satisfies ParallelTransactionPlan;\n * ```\n *\n * @see {@link parallelTransactionPlan}\n */\nexport type ParallelTransactionPlan = Readonly<{\n kind: 'parallel';\n plans: TransactionPlan[];\n}>;\n\n/**\n * A plan that contains a single transaction message.\n *\n * This is a simple transaction message wrapper that transforms a message into a plan.\n *\n * You may use the {@link singleTransactionPlan} helper to create objects of this type.\n *\n * @example\n * ```ts\n * const plan = singleTransactionPlan(transactionMessage);\n * plan satisfies SingleTransactionPlan;\n * ```\n *\n * @see {@link singleTransactionPlan}\n */\nexport type SingleTransactionPlan<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n> = Readonly<{\n kind: 'single';\n message: TTransactionMessage;\n}>;\n\n/**\n * Creates a {@link ParallelTransactionPlan} from an array of nested plans.\n *\n * It can accept {@link TransactionMessage} objects directly, which will be wrapped\n * in {@link SingleTransactionPlan | SingleTransactionPlans} automatically.\n *\n * @example\n * Using explicit {@link SingleTransactionPlan | SingleTransactionPlans}.\n * ```ts\n * const plan = parallelTransactionPlan([\n * singleTransactionPlan(messageA),\n * singleTransactionPlan(messageB),\n * ]);\n * ```\n *\n * @example\n * Using {@link TransactionMessage | TransactionMessages} directly.\n * ```ts\n * const plan = parallelTransactionPlan([messageA, messageB]);\n * ```\n *\n * @see {@link ParallelTransactionPlan}\n */\nexport function parallelTransactionPlan(\n plans: (TransactionPlan | (BaseTransactionMessage & TransactionMessageWithFeePayer))[],\n): ParallelTransactionPlan {\n return Object.freeze({ kind: 'parallel', plans: parseSingleTransactionPlans(plans) });\n}\n\n/**\n * Creates a divisible {@link SequentialTransactionPlan} from an array of nested plans.\n *\n * It can accept {@link TransactionMessage} objects directly, which will be wrapped\n * in {@link SingleTransactionPlan | SingleTransactionPlans} automatically.\n *\n * @example\n * Using explicit {@link SingleTransactionPlan | SingleTransactionPlans}.\n * ```ts\n * const plan = sequentialTransactionPlan([\n * singleTransactionPlan(messageA),\n * singleTransactionPlan(messageB),\n * ]);\n * ```\n *\n * @example\n * Using {@link TransactionMessage | TransactionMessages} directly.\n * ```ts\n * const plan = sequentialTransactionPlan([messageA, messageB]);\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n */\nexport function sequentialTransactionPlan(\n plans: (TransactionPlan | (BaseTransactionMessage & TransactionMessageWithFeePayer))[],\n): SequentialTransactionPlan & { divisible: true } {\n return Object.freeze({ divisible: true, kind: 'sequential', plans: parseSingleTransactionPlans(plans) });\n}\n\n/**\n * Creates a non-divisible {@link SequentialTransactionPlan} from an array of nested plans.\n *\n * It can accept {@link TransactionMessage} objects directly, which will be wrapped\n * in {@link SingleTransactionPlan | SingleTransactionPlans} automatically.\n *\n * @example\n * Using explicit {@link SingleTransactionPlan | SingleTransactionPlans}.\n * ```ts\n * const plan = nonDivisibleSequentialTransactionPlan([\n * singleTransactionPlan(messageA),\n * singleTransactionPlan(messageB),\n * ]);\n * ```\n *\n * @example\n * Using {@link TransactionMessage | TransactionMessages} directly.\n * ```ts\n * const plan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n */\nexport function nonDivisibleSequentialTransactionPlan(\n plans: (TransactionPlan | (BaseTransactionMessage & TransactionMessageWithFeePayer))[],\n): SequentialTransactionPlan & { divisible: false } {\n return Object.freeze({ divisible: false, kind: 'sequential', plans: parseSingleTransactionPlans(plans) });\n}\n\n/**\n * Creates a {@link SingleTransactionPlan} from a {@link TransactionMessage} object.\n *\n * @example\n * ```ts\n * const plan = singleTransactionPlan(transactionMessage);\n * plan satisfies SingleTransactionPlan;\n * ```\n *\n * @see {@link SingleTransactionPlan}\n */\nexport function singleTransactionPlan<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer = BaseTransactionMessage &\n TransactionMessageWithFeePayer,\n>(transactionMessage: TTransactionMessage): SingleTransactionPlan<TTransactionMessage> {\n return Object.freeze({ kind: 'single', message: transactionMessage });\n}\n\nfunction parseSingleTransactionPlans(\n plans: (TransactionPlan | (BaseTransactionMessage & TransactionMessageWithFeePayer))[],\n): TransactionPlan[] {\n return plans.map(plan => ('kind' in plan ? plan : singleTransactionPlan(plan)));\n}\n\n/**\n * Retrieves all individual {@link SingleTransactionPlan} instances from a transaction plan tree.\n *\n * This function recursively traverses any nested structure of transaction plans and extracts\n * all the single transaction plans they contain. It's useful when you need to access all\n * the actual transaction messages that will be executed, regardless of their organization\n * in the plan tree (parallel or sequential).\n *\n * @param transactionPlan - The transaction plan to extract single plans from\n * @returns An array of all single transaction plans contained in the tree\n *\n * @example\n * ```ts\n * const plan = parallelTransactionPlan([\n * sequentialTransactionPlan([messageA, messageB]),\n * nonDivisibleSequentialTransactionPlan([messageC, messageD]),\n * messageE,\n * ]);\n *\n * const singlePlans = getAllSingleTransactionPlans(plan);\n * // Array of `SingleTransactionPlan` containing:\n * // messageA, messageB, messageC and messageD.\n * ```\n */\nexport function getAllSingleTransactionPlans(transactionPlan: TransactionPlan): SingleTransactionPlan[] {\n if (transactionPlan.kind === 'single') {\n return [transactionPlan];\n }\n return transactionPlan.plans.flatMap(getAllSingleTransactionPlans);\n}\n","import {\n isSolanaError,\n SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN,\n SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND,\n SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND,\n SolanaError,\n} from '@solana/errors';\nimport { getAbortablePromise } from '@solana/promises';\nimport {\n appendTransactionMessageInstructions,\n BaseTransactionMessage,\n TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { getTransactionMessageSize, TRANSACTION_SIZE_LIMIT } from '@solana/transactions';\n\nimport {\n InstructionPlan,\n MessagePackerInstructionPlan,\n ParallelInstructionPlan,\n SequentialInstructionPlan,\n SingleInstructionPlan,\n} from './instruction-plan';\nimport {\n getAllSingleTransactionPlans,\n nonDivisibleSequentialTransactionPlan,\n parallelTransactionPlan,\n sequentialTransactionPlan,\n SingleTransactionPlan,\n singleTransactionPlan,\n TransactionPlan,\n} from './transaction-plan';\n\n/**\n * Plans one or more transactions according to the provided instruction plan.\n *\n * @param instructionPlan - The instruction plan to be planned and executed.\n * @param config - Optional configuration object that can include an `AbortSignal` to cancel the planning process.\n *\n * @see {@link InstructionPlan}\n * @see {@link TransactionPlan}\n */\nexport type TransactionPlanner = (\n instructionPlan: InstructionPlan,\n config?: { abortSignal?: AbortSignal },\n) => Promise<TransactionPlan>;\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] };\n\ntype CreateTransactionMessage = (config?: {\n abortSignal?: AbortSignal;\n}) =>\n | Promise<BaseTransactionMessage & TransactionMessageWithFeePayer>\n | (BaseTransactionMessage & TransactionMessageWithFeePayer);\n\ntype OnTransactionMessageUpdated = (\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n config?: { abortSignal?: AbortSignal },\n) =>\n | Promise<BaseTransactionMessage & TransactionMessageWithFeePayer>\n | (BaseTransactionMessage & TransactionMessageWithFeePayer);\n\n/**\n * Configuration object for creating a new transaction planner.\n *\n * @see {@link createTransactionPlanner}\n */\nexport type TransactionPlannerConfig = {\n /** Called whenever a new transaction message is needed. */\n createTransactionMessage: CreateTransactionMessage;\n /**\n * Called whenever a transaction message is updated — e.g. new instructions were added.\n * This function must return the updated transaction message back — even if no changes were made.\n */\n onTransactionMessageUpdated?: OnTransactionMessageUpdated;\n};\n\n/**\n * Creates a new transaction planner based on the provided configuration.\n *\n * At the very least, the `createTransactionMessage` function must be provided.\n * This function is used to create new transaction messages whenever needed.\n *\n * Additionally, the `onTransactionMessageUpdated` function can be provided\n * to update transaction messages during the planning process. This function will\n * be called whenever a transaction message is updated, e.g. when new instructions\n * are added to a transaction message. It accepts the updated transaction message\n * and must return a transaction message back, even if no changes were made.\n *\n * @example\n * ```ts\n * const transactionPlanner = createTransactionPlanner({\n * createTransactionMessage: () => pipe(\n * createTransactionMessage({ version: 0 }),\n * message => setTransactionMessageFeePayerSigner(mySigner, message),\n * )\n * });\n * ```\n *\n * @see {@link TransactionPlannerConfig}\n */\nexport function createTransactionPlanner(config: TransactionPlannerConfig): TransactionPlanner {\n return async (instructionPlan, { abortSignal } = {}): Promise<TransactionPlan> => {\n const plan = await traverse(instructionPlan, {\n abortSignal,\n createTransactionMessage: config.createTransactionMessage,\n onTransactionMessageUpdated: config.onTransactionMessageUpdated ?? (msg => msg),\n parent: null,\n parentCandidates: [],\n });\n\n if (!plan) {\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN);\n }\n\n return freezeTransactionPlan(plan);\n };\n}\n\ntype MutableTransactionPlan = Mutable<TransactionPlan>;\ntype MutableSingleTransactionPlan = Mutable<SingleTransactionPlan>;\n\ntype TraverseContext = {\n abortSignal?: AbortSignal;\n createTransactionMessage: CreateTransactionMessage;\n onTransactionMessageUpdated: OnTransactionMessageUpdated;\n parent: InstructionPlan | null;\n parentCandidates: MutableSingleTransactionPlan[];\n};\n\nasync function traverse(\n instructionPlan: InstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n context.abortSignal?.throwIfAborted();\n const kind = instructionPlan.kind;\n switch (kind) {\n case 'sequential':\n return await traverseSequential(instructionPlan, context);\n case 'parallel':\n return await traverseParallel(instructionPlan, context);\n case 'single':\n return await traverseSingle(instructionPlan, context);\n case 'messagePacker':\n return await traverseMessagePacker(instructionPlan, context);\n default:\n instructionPlan satisfies never;\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, { kind });\n }\n}\n\nasync function traverseSequential(\n instructionPlan: SequentialInstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n let candidate: MutableSingleTransactionPlan | null = null;\n\n // Check if the sequential plan must fit entirely in its parent candidates\n // due to constraints like being inside a parallel plan or not being divisible.\n const mustEntirelyFitInParentCandidate =\n context.parent && (context.parent.kind === 'parallel' || !instructionPlan.divisible);\n\n // If so, try to fit the entire plan inside one of the parent candidates.\n if (mustEntirelyFitInParentCandidate) {\n const candidate = await selectAndMutateCandidate(context, context.parentCandidates, message =>\n fitEntirePlanInsideMessage(instructionPlan, message),\n );\n // If that's possible, we the candidate is mutated and we can return null.\n // Otherwise, we proceed with the normal traversal and no parent candidate.\n if (candidate) {\n return null;\n }\n } else {\n // Otherwise, we can use the first parent candidate, if any,\n // since we know it must be a divisible sequential plan.\n candidate = context.parentCandidates.length > 0 ? context.parentCandidates[0] : null;\n }\n\n const transactionPlans: TransactionPlan[] = [];\n for (const plan of instructionPlan.plans) {\n const transactionPlan = await traverse(plan, {\n ...context,\n parent: instructionPlan,\n parentCandidates: candidate ? [candidate] : [],\n });\n if (transactionPlan) {\n candidate = getSequentialCandidate(transactionPlan);\n const newPlans =\n transactionPlan.kind === 'sequential' && (transactionPlan.divisible || !instructionPlan.divisible)\n ? transactionPlan.plans\n : [transactionPlan];\n transactionPlans.push(...newPlans);\n }\n }\n\n // Wrap in a sequential plan or simplify.\n if (transactionPlans.length === 1) {\n return transactionPlans[0];\n }\n if (transactionPlans.length === 0) {\n return null;\n }\n return {\n divisible: instructionPlan.divisible,\n kind: 'sequential',\n plans: transactionPlans,\n };\n}\n\nasync function traverseParallel(\n instructionPlan: ParallelInstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n const candidates: MutableSingleTransactionPlan[] = [...context.parentCandidates];\n const transactionPlans: TransactionPlan[] = [];\n\n // Reorder children so message packer plans are last.\n const sortedChildren = Array.from(instructionPlan.plans).sort(\n (a, b) => Number(a.kind === 'messagePacker') - Number(b.kind === 'messagePacker'),\n );\n\n for (const plan of sortedChildren) {\n const transactionPlan = await traverse(plan, {\n ...context,\n parent: instructionPlan,\n parentCandidates: candidates,\n });\n if (transactionPlan) {\n candidates.push(...getParallelCandidates(transactionPlan));\n const newPlans = transactionPlan.kind === 'parallel' ? transactionPlan.plans : [transactionPlan];\n transactionPlans.push(...newPlans);\n }\n }\n\n // Wrap in a parallel plan or simplify.\n if (transactionPlans.length === 1) {\n return transactionPlans[0];\n }\n if (transactionPlans.length === 0) {\n return null;\n }\n return { kind: 'parallel', plans: transactionPlans };\n}\n\nasync function traverseSingle(\n instructionPlan: SingleInstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n const predicate = (message: BaseTransactionMessage & TransactionMessageWithFeePayer) =>\n appendTransactionMessageInstructions([instructionPlan.instruction], message);\n const candidate = await selectAndMutateCandidate(context, context.parentCandidates, predicate);\n if (candidate) {\n return null;\n }\n const message = await createNewMessage(context, predicate);\n return { kind: 'single', message };\n}\n\nasync function traverseMessagePacker(\n instructionPlan: MessagePackerInstructionPlan,\n context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n const messagePacker = instructionPlan.getMessagePacker();\n const transactionPlans: SingleTransactionPlan[] = [];\n const candidates = [...context.parentCandidates];\n\n while (!messagePacker.done()) {\n const candidate = await selectAndMutateCandidate(context, candidates, messagePacker.packMessageToCapacity);\n if (!candidate) {\n const message = await createNewMessage(context, messagePacker.packMessageToCapacity);\n const newPlan: MutableSingleTransactionPlan = { kind: 'single', message };\n transactionPlans.push(newPlan);\n }\n }\n\n if (transactionPlans.length === 1) {\n return transactionPlans[0];\n }\n if (transactionPlans.length === 0) {\n return null;\n }\n if (context.parent?.kind === 'parallel') {\n return { kind: 'parallel', plans: transactionPlans };\n }\n return {\n divisible: context.parent?.kind === 'sequential' ? context.parent.divisible : true,\n kind: 'sequential',\n plans: transactionPlans,\n };\n}\n\nfunction getSequentialCandidate(latestPlan: MutableTransactionPlan): MutableSingleTransactionPlan | null {\n if (latestPlan.kind === 'single') {\n return latestPlan;\n }\n if (latestPlan.kind === 'sequential' && latestPlan.plans.length > 0) {\n return getSequentialCandidate(latestPlan.plans[latestPlan.plans.length - 1]);\n }\n return null;\n}\n\nfunction getParallelCandidates(latestPlan: TransactionPlan): MutableSingleTransactionPlan[] {\n return getAllSingleTransactionPlans(latestPlan);\n}\n\nasync function selectAndMutateCandidate(\n context: Pick<TraverseContext, 'abortSignal' | 'onTransactionMessageUpdated'>,\n candidates: MutableSingleTransactionPlan[],\n predicate: (\n message: BaseTransactionMessage & TransactionMessageWithFeePayer,\n ) => BaseTransactionMessage & TransactionMessageWithFeePayer,\n): Promise<MutableSingleTransactionPlan | null> {\n for (const candidate of candidates) {\n try {\n const message = await getAbortablePromise(\n Promise.resolve(\n context.onTransactionMessageUpdated(predicate(candidate.message), {\n abortSignal: context.abortSignal,\n }),\n ),\n context.abortSignal,\n );\n if (getTransactionMessageSize(message) <= TRANSACTION_SIZE_LIMIT) {\n candidate.message = message;\n return candidate;\n }\n } catch (error) {\n if (isSolanaError(error, SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN)) {\n // Try the next candidate.\n } else {\n throw error;\n }\n }\n }\n return null;\n}\n\nasync function createNewMessage(\n context: Pick<TraverseContext, 'abortSignal' | 'createTransactionMessage' | 'onTransactionMessageUpdated'>,\n predicate: (\n message: BaseTransactionMessage & TransactionMessageWithFeePayer,\n ) => BaseTransactionMessage & TransactionMessageWithFeePayer,\n): Promise<BaseTransactionMessage & TransactionMessageWithFeePayer> {\n const newMessage = await getAbortablePromise(\n Promise.resolve(context.createTransactionMessage({ abortSignal: context.abortSignal })),\n context.abortSignal,\n );\n const updatedMessage = await getAbortablePromise(\n Promise.resolve(\n context.onTransactionMessageUpdated(predicate(newMessage), { abortSignal: context.abortSignal }),\n ),\n context.abortSignal,\n );\n const updatedMessageSize = getTransactionMessageSize(updatedMessage);\n if (updatedMessageSize > TRANSACTION_SIZE_LIMIT) {\n const newMessageSize = getTransactionMessageSize(newMessage);\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n numBytesRequired: updatedMessageSize - newMessageSize,\n numFreeBytes: TRANSACTION_SIZE_LIMIT - newMessageSize,\n });\n }\n return updatedMessage;\n}\n\nfunction freezeTransactionPlan(plan: MutableTransactionPlan): TransactionPlan {\n const kind = plan.kind;\n switch (kind) {\n case 'single':\n return singleTransactionPlan(plan.message);\n case 'sequential':\n return plan.divisible\n ? sequentialTransactionPlan(plan.plans.map(freezeTransactionPlan))\n : nonDivisibleSequentialTransactionPlan(plan.plans.map(freezeTransactionPlan));\n case 'parallel':\n return parallelTransactionPlan(plan.plans.map(freezeTransactionPlan));\n default:\n plan satisfies never;\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND, { kind });\n }\n}\n\nfunction fitEntirePlanInsideMessage(\n instructionPlan: InstructionPlan,\n message: BaseTransactionMessage & TransactionMessageWithFeePayer,\n): BaseTransactionMessage & TransactionMessageWithFeePayer {\n let newMessage: BaseTransactionMessage & TransactionMessageWithFeePayer = message;\n\n const kind = instructionPlan.kind;\n switch (kind) {\n case 'sequential':\n case 'parallel':\n for (const plan of instructionPlan.plans) {\n newMessage = fitEntirePlanInsideMessage(plan, newMessage);\n }\n return newMessage;\n case 'single':\n newMessage = appendTransactionMessageInstructions([instructionPlan.instruction], message);\n // eslint-disable-next-line no-case-declarations\n const newMessageSize = getTransactionMessageSize(newMessage);\n if (newMessageSize > TRANSACTION_SIZE_LIMIT) {\n const baseMessageSize = getTransactionMessageSize(message);\n throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n numBytesRequired: newMessageSize - baseMessageSize,\n numFreeBytes: TRANSACTION_SIZE_LIMIT - baseMessageSize,\n });\n }\n return newMessage;\n case 'messagePacker':\n // eslint-disable-next-line no-case-declarations\n const messagePacker = instructionPlan.getMessagePacker();\n while (!messagePacker.done()) {\n newMessage = messagePacker.packMessageToCapacity(message);\n }\n return newMessage;\n default:\n instructionPlan satisfies never;\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, { kind });\n }\n}\n"]}
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SolanaError, SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE, SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND, SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN, SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, isSolanaError } from '@solana/errors';
|
|
1
|
+
import { SolanaError, SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE, SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND, SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED, SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN, SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, isSolanaError } from '@solana/errors';
|
|
2
2
|
import { appendTransactionMessageInstruction, appendTransactionMessageInstructions } from '@solana/transaction-messages';
|
|
3
3
|
import { getTransactionMessageSize, TRANSACTION_SIZE_LIMIT, getSignatureFromTransaction } from '@solana/transactions';
|
|
4
4
|
import { getAbortablePromise } from '@solana/promises';
|
|
@@ -206,6 +206,7 @@ function createTransactionPlanExecutor(config) {
|
|
|
206
206
|
abortSignal,
|
|
207
207
|
canceled: abortSignal?.aborted ?? false
|
|
208
208
|
};
|
|
209
|
+
assertDivisibleSequentialPlansOnly(plan);
|
|
209
210
|
const cancelHandler = () => {
|
|
210
211
|
context.canceled = true;
|
|
211
212
|
};
|
|
@@ -240,12 +241,15 @@ async function traverse(transactionPlan, context) {
|
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
243
|
async function traverseSequential(transactionPlan, context) {
|
|
244
|
+
if (!transactionPlan.divisible) {
|
|
245
|
+
throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED);
|
|
246
|
+
}
|
|
243
247
|
const results = [];
|
|
244
248
|
for (const subPlan of transactionPlan.plans) {
|
|
245
249
|
const result = await traverse(subPlan, context);
|
|
246
250
|
results.push(result);
|
|
247
251
|
}
|
|
248
|
-
return
|
|
252
|
+
return sequentialTransactionPlanResult(results);
|
|
249
253
|
}
|
|
250
254
|
async function traverseParallel(transactionPlan, context) {
|
|
251
255
|
const results = await Promise.all(transactionPlan.plans.map((plan) => traverse(plan, context)));
|
|
@@ -285,6 +289,27 @@ function findErrorFromTransactionPlanResult(result) {
|
|
|
285
289
|
}
|
|
286
290
|
}
|
|
287
291
|
}
|
|
292
|
+
function assertDivisibleSequentialPlansOnly(transactionPlan) {
|
|
293
|
+
const kind = transactionPlan.kind;
|
|
294
|
+
switch (kind) {
|
|
295
|
+
case "sequential":
|
|
296
|
+
if (!transactionPlan.divisible) {
|
|
297
|
+
throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED);
|
|
298
|
+
}
|
|
299
|
+
for (const subPlan of transactionPlan.plans) {
|
|
300
|
+
assertDivisibleSequentialPlansOnly(subPlan);
|
|
301
|
+
}
|
|
302
|
+
return;
|
|
303
|
+
case "parallel":
|
|
304
|
+
for (const subPlan of transactionPlan.plans) {
|
|
305
|
+
assertDivisibleSequentialPlansOnly(subPlan);
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
case "single":
|
|
309
|
+
default:
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
288
313
|
|
|
289
314
|
// src/transaction-plan.ts
|
|
290
315
|
function parallelTransactionPlan(plans) {
|