rename to transactionInstructions everywhere; still lots to fix in provider
This commit is contained in:
parent
681a97ba3f
commit
b20b5dabb1
|
@ -1,5 +1,5 @@
|
|||
import { Buffer } from "buffer";
|
||||
import { Keypair, PublicKey, Transaction } from "@solana/web3.js";
|
||||
import { Keypair, PublicKey, VersionedTransaction } from "@solana/web3.js";
|
||||
import { Wallet } from "./provider";
|
||||
|
||||
/**
|
||||
|
@ -30,14 +30,18 @@ export default class NodeWallet implements Wallet {
|
|||
return new NodeWallet(payer);
|
||||
}
|
||||
|
||||
async signTransaction(tx: Transaction): Promise<Transaction> {
|
||||
tx.partialSign(this.payer);
|
||||
async signTransaction(
|
||||
tx: VersionedTransaction
|
||||
): Promise<VersionedTransaction> {
|
||||
tx.sign([this.payer]);
|
||||
return tx;
|
||||
}
|
||||
|
||||
async signAllTransactions(txs: Transaction[]): Promise<Transaction[]> {
|
||||
async signAllTransactions(
|
||||
txs: VersionedTransaction[]
|
||||
): Promise<VersionedTransaction[]> {
|
||||
return txs.map((t) => {
|
||||
t.partialSign(this.payer);
|
||||
t.sign([this.payer]);
|
||||
return t;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Coder, BorshCoder } from "../coder/index.js";
|
|||
import NamespaceFactory, {
|
||||
RpcNamespace,
|
||||
InstructionNamespace,
|
||||
TransactionNamespace,
|
||||
TransactionInstructionsNamespace,
|
||||
AccountNamespace,
|
||||
SimulateNamespace,
|
||||
MethodsNamespace,
|
||||
|
@ -138,13 +138,13 @@ export class Program<IDL extends Idl = Idl> {
|
|||
readonly instruction: InstructionNamespace<IDL>;
|
||||
|
||||
/**
|
||||
* The namespace provides functions to build [[Transaction]] objects for each
|
||||
* The namespace provides functions to build [[TransactionInstruction\[\]]] objects for each
|
||||
* method of a program.
|
||||
*
|
||||
* ## Usage
|
||||
*
|
||||
* ```javascript
|
||||
* program.transaction.<method>(...args, ctx);
|
||||
* program.transactionInstructions.<method>(...args, ctx);
|
||||
* ```
|
||||
*
|
||||
* ## Parameters
|
||||
|
@ -159,7 +159,7 @@ export class Program<IDL extends Idl = Idl> {
|
|||
* To create an instruction for the `increment` method above,
|
||||
*
|
||||
* ```javascript
|
||||
* const tx = await program.transaction.increment({
|
||||
* const tx = await program.transactionInstructions.increment({
|
||||
* accounts: {
|
||||
* counter,
|
||||
* },
|
||||
|
@ -167,7 +167,7 @@ export class Program<IDL extends Idl = Idl> {
|
|||
* ```
|
||||
* @deprecated
|
||||
*/
|
||||
readonly transaction: TransactionNamespace<IDL>;
|
||||
readonly transactionInstructions: TransactionInstructionsNamespace<IDL>;
|
||||
|
||||
/**
|
||||
* The namespace provides functions to simulate transactions for each method
|
||||
|
@ -283,17 +283,24 @@ export class Program<IDL extends Idl = Idl> {
|
|||
this._events = new EventManager(this._programId, provider, this._coder);
|
||||
|
||||
// Dynamic namespaces.
|
||||
const [rpc, instruction, transaction, account, simulate, methods, views] =
|
||||
NamespaceFactory.build(
|
||||
idl,
|
||||
this._coder,
|
||||
programId,
|
||||
provider,
|
||||
getCustomResolver ?? (() => undefined)
|
||||
);
|
||||
const [
|
||||
rpc,
|
||||
instruction,
|
||||
transactionInstructions,
|
||||
account,
|
||||
simulate,
|
||||
methods,
|
||||
views,
|
||||
] = NamespaceFactory.build(
|
||||
idl,
|
||||
this._coder,
|
||||
programId,
|
||||
provider,
|
||||
getCustomResolver ?? (() => undefined)
|
||||
);
|
||||
this.rpc = rpc;
|
||||
this.instruction = instruction;
|
||||
this.transaction = transaction;
|
||||
this.transactionInstructions = transactionInstructions;
|
||||
this.account = account;
|
||||
this.simulate = simulate;
|
||||
this.methods = methods;
|
||||
|
|
|
@ -4,7 +4,9 @@ import { Coder } from "../../coder/index.js";
|
|||
import Provider from "../../provider.js";
|
||||
import { Idl, IdlInstruction } from "../../idl.js";
|
||||
import InstructionFactory, { InstructionNamespace } from "./instruction.js";
|
||||
import TransactionFactory, { TransactionNamespace } from "./transaction.js";
|
||||
import TransactionInstructionsFactory, {
|
||||
TransactionInstructionsNamespace,
|
||||
} from "./transaction-instructions.js";
|
||||
import RpcFactory, { RpcNamespace } from "./rpc.js";
|
||||
import AccountFactory, { AccountNamespace } from "./account.js";
|
||||
import SimulateFactory, { SimulateNamespace } from "./simulate.js";
|
||||
|
@ -15,7 +17,10 @@ import { CustomAccountResolver } from "../accounts-resolver.js";
|
|||
|
||||
// Re-exports.
|
||||
export { InstructionNamespace, InstructionFn } from "./instruction.js";
|
||||
export { TransactionNamespace, TransactionFn } from "./transaction.js";
|
||||
export {
|
||||
TransactionInstructionsNamespace,
|
||||
TransactionInstructionsFn,
|
||||
} from "./transaction-instructions.js";
|
||||
export { RpcNamespace, RpcFn } from "./rpc.js";
|
||||
export { AccountNamespace, AccountClient, ProgramAccount } from "./account.js";
|
||||
export { SimulateNamespace, SimulateFn } from "./simulate.js";
|
||||
|
@ -38,7 +43,7 @@ export default class NamespaceFactory {
|
|||
): [
|
||||
RpcNamespace<IDL>,
|
||||
InstructionNamespace<IDL>,
|
||||
TransactionNamespace<IDL>,
|
||||
TransactionInstructionsNamespace<IDL>,
|
||||
AccountNamespace<IDL>,
|
||||
SimulateNamespace<IDL>,
|
||||
MethodsNamespace<IDL>,
|
||||
|
@ -46,7 +51,7 @@ export default class NamespaceFactory {
|
|||
] {
|
||||
const rpc: RpcNamespace = {};
|
||||
const instruction: InstructionNamespace = {};
|
||||
const transaction: TransactionNamespace = {};
|
||||
const transactionInstructions: TransactionInstructionsNamespace = {};
|
||||
const simulate: SimulateNamespace = {};
|
||||
const methods: MethodsNamespace = {};
|
||||
const view: ViewNamespace = {};
|
||||
|
@ -63,11 +68,11 @@ export default class NamespaceFactory {
|
|||
(ixName, ix) => coder.instruction.encode(ixName, ix),
|
||||
programId
|
||||
);
|
||||
const txItem = TransactionFactory.build(idlIx, ixItem);
|
||||
const rpcItem = RpcFactory.build(idlIx, txItem, idlErrors, provider);
|
||||
const txIxsItem = TransactionInstructionsFactory.build(idlIx, ixItem);
|
||||
const rpcItem = RpcFactory.build(idlIx, txIxsItem, idlErrors, provider);
|
||||
const simulateItem = SimulateFactory.build(
|
||||
idlIx,
|
||||
txItem,
|
||||
txIxsItem,
|
||||
idlErrors,
|
||||
provider,
|
||||
coder,
|
||||
|
@ -80,7 +85,7 @@ export default class NamespaceFactory {
|
|||
programId,
|
||||
idlIx,
|
||||
ixItem,
|
||||
txItem,
|
||||
txIxsItem,
|
||||
rpcItem,
|
||||
simulateItem,
|
||||
viewItem,
|
||||
|
@ -91,7 +96,7 @@ export default class NamespaceFactory {
|
|||
const name = camelCase(idlIx.name);
|
||||
|
||||
instruction[name] = ixItem;
|
||||
transaction[name] = txItem;
|
||||
transactionInstructions[name] = txIxsItem;
|
||||
rpc[name] = rpcItem;
|
||||
simulate[name] = simulateItem;
|
||||
methods[name] = methodItem;
|
||||
|
@ -103,7 +108,7 @@ export default class NamespaceFactory {
|
|||
return [
|
||||
rpc as RpcNamespace<IDL>,
|
||||
instruction as InstructionNamespace<IDL>,
|
||||
transaction as TransactionNamespace<IDL>,
|
||||
transactionInstructions as TransactionInstructionsNamespace<IDL>,
|
||||
account,
|
||||
simulate as SimulateNamespace<IDL>,
|
||||
methods as MethodsNamespace<IDL>,
|
||||
|
|
|
@ -3,7 +3,6 @@ import {
|
|||
ConfirmOptions,
|
||||
PublicKey,
|
||||
Signer,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
TransactionSignature,
|
||||
} from "@solana/web3.js";
|
||||
|
@ -20,7 +19,7 @@ import { AccountNamespace } from "./account.js";
|
|||
import { InstructionFn } from "./instruction.js";
|
||||
import { RpcFn } from "./rpc.js";
|
||||
import { SimulateFn, SimulateResponse } from "./simulate.js";
|
||||
import { TransactionFn } from "./transaction.js";
|
||||
import { TransactionInstructionsFn } from "./transaction-instructions.js";
|
||||
import {
|
||||
AllInstructions,
|
||||
InstructionAccountAddresses,
|
||||
|
@ -40,7 +39,7 @@ export class MethodsBuilderFactory {
|
|||
programId: PublicKey,
|
||||
idlIx: AllInstructions<IDL>,
|
||||
ixFn: InstructionFn<IDL>,
|
||||
txFn: TransactionFn<IDL>,
|
||||
txIxsFn: TransactionInstructionsFn<IDL>,
|
||||
rpcFn: RpcFn<IDL>,
|
||||
simulateFn: SimulateFn<IDL>,
|
||||
viewFn: ViewFn<IDL> | undefined,
|
||||
|
@ -52,7 +51,7 @@ export class MethodsBuilderFactory {
|
|||
new MethodsBuilder(
|
||||
args,
|
||||
ixFn,
|
||||
txFn,
|
||||
txIxsFn,
|
||||
rpcFn,
|
||||
simulateFn,
|
||||
viewFn,
|
||||
|
@ -121,7 +120,7 @@ export class MethodsBuilder<IDL extends Idl, I extends AllInstructions<IDL>> {
|
|||
constructor(
|
||||
_args: Array<any>,
|
||||
private _ixFn: InstructionFn<IDL>,
|
||||
private _txFn: TransactionFn<IDL>,
|
||||
private _txIxsFn: TransactionInstructionsFn<IDL>,
|
||||
private _rpcFn: RpcFn<IDL>,
|
||||
private _simulateFn: SimulateFn<IDL>,
|
||||
private _viewFn: ViewFn<IDL> | undefined,
|
||||
|
@ -299,13 +298,13 @@ export class MethodsBuilder<IDL extends Idl, I extends AllInstructions<IDL>> {
|
|||
};
|
||||
}
|
||||
|
||||
public async transaction(): Promise<Transaction> {
|
||||
public async transactionInstructions(): Promise<TransactionInstruction[]> {
|
||||
if (this._autoResolveAccounts) {
|
||||
await this._accountsResolver.resolve();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return this._txFn(...this._args, {
|
||||
return this._txIxsFn(...this._args, {
|
||||
accounts: this._accounts,
|
||||
signers: this._signers,
|
||||
remainingAccounts: this._remainingAccounts,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { TransactionSignature } from "@solana/web3.js";
|
|||
import Provider from "../../provider.js";
|
||||
import { Idl } from "../../idl.js";
|
||||
import { splitArgsAndCtx } from "../context.js";
|
||||
import { TransactionFn } from "./transaction.js";
|
||||
import { TransactionInstructionsFn } from "./transaction-instructions.js";
|
||||
import { translateError } from "../../error.js";
|
||||
import {
|
||||
AllInstructions,
|
||||
|
@ -13,12 +13,12 @@ import {
|
|||
export default class RpcFactory {
|
||||
public static build<IDL extends Idl, I extends AllInstructions<IDL>>(
|
||||
idlIx: I,
|
||||
txFn: TransactionFn<IDL, I>,
|
||||
txIxsFn: TransactionInstructionsFn<IDL, I>,
|
||||
idlErrors: Map<number, string>,
|
||||
provider: Provider
|
||||
): RpcFn {
|
||||
const rpc: RpcFn<IDL, I> = async (...args) => {
|
||||
const tx = txFn(...args);
|
||||
const txIxs = txIxsFn(...args);
|
||||
const [, ctx] = splitArgsAndCtx(idlIx, [...args]);
|
||||
if (provider.sendAndConfirm === undefined) {
|
||||
throw new Error(
|
||||
|
@ -27,7 +27,7 @@ export default class RpcFactory {
|
|||
}
|
||||
try {
|
||||
return await provider.sendAndConfirm(
|
||||
tx,
|
||||
txIxs,
|
||||
ctx.signers ?? [],
|
||||
ctx.options
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@ import { PublicKey } from "@solana/web3.js";
|
|||
import Provider from "../../provider.js";
|
||||
import { SuccessfulTxSimulationResponse } from "src/utils/rpc.js";
|
||||
import { splitArgsAndCtx } from "../context.js";
|
||||
import { TransactionFn } from "./transaction.js";
|
||||
import { TransactionInstructionsFn } from "./transaction-instructions.js";
|
||||
import { EventParser, Event } from "../event.js";
|
||||
import { Coder } from "../../coder/index.js";
|
||||
import { Idl, IdlEvent } from "../../idl.js";
|
||||
|
@ -17,7 +17,7 @@ import {
|
|||
export default class SimulateFactory {
|
||||
public static build<IDL extends Idl, I extends AllInstructions<IDL>>(
|
||||
idlIx: AllInstructions<IDL>,
|
||||
txFn: TransactionFn<IDL>,
|
||||
txIxsFn: TransactionInstructionsFn<IDL>,
|
||||
idlErrors: Map<number, string>,
|
||||
provider: Provider,
|
||||
coder: Coder,
|
||||
|
@ -25,7 +25,7 @@ export default class SimulateFactory {
|
|||
idl: IDL
|
||||
): SimulateFn<IDL, I> {
|
||||
const simulate: SimulateFn<IDL> = async (...args) => {
|
||||
const tx = txFn(...args);
|
||||
const tx = txIxsFn(...args);
|
||||
const [, ctx] = splitArgsAndCtx(idlIx, [...args]);
|
||||
let resp: SuccessfulTxSimulationResponse | undefined = undefined;
|
||||
if (provider.simulate === undefined) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Transaction, TransactionInstruction } from "@solana/web3.js";
|
||||
import { TransactionInstruction } from "@solana/web3.js";
|
||||
import { Idl, IdlInstruction } from "../../idl.js";
|
||||
import { splitArgsAndCtx } from "../context.js";
|
||||
import { InstructionFn } from "./instruction.js";
|
||||
|
@ -8,12 +8,14 @@ import {
|
|||
MakeInstructionsNamespace,
|
||||
} from "./types.js";
|
||||
|
||||
export default class TransactionFactory {
|
||||
export default class TransactionInstructionsFactory {
|
||||
public static build<IDL extends Idl, I extends AllInstructions<IDL>>(
|
||||
idlIx: I,
|
||||
ixFn: InstructionFn<IDL, I>
|
||||
): TransactionFn<IDL, I> {
|
||||
const txFn: TransactionFn<IDL, I> = (...args): TransactionInstruction[] => {
|
||||
): TransactionInstructionsFn<IDL, I> {
|
||||
const txIxsFn: TransactionInstructionsFn<IDL, I> = (
|
||||
...args
|
||||
): TransactionInstruction[] => {
|
||||
const [, ctx] = splitArgsAndCtx(idlIx, [...args]);
|
||||
const tx: TransactionInstruction[] = [];
|
||||
if (ctx.preInstructions && ctx.instructions) {
|
||||
|
@ -26,18 +28,18 @@ export default class TransactionFactory {
|
|||
return tx;
|
||||
};
|
||||
|
||||
return txFn;
|
||||
return txIxsFn;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The namespace provides functions to build [[Transaction]] objects for each
|
||||
* The namespace provides functions to build [[TransactionInstruction\[\]]] objects for each
|
||||
* method of a program.
|
||||
*
|
||||
* ## Usage
|
||||
*
|
||||
* ```javascript
|
||||
* program.transaction.<method>(...args, ctx);
|
||||
* program.transactionInstructions.<method>(...args, ctx);
|
||||
* ```
|
||||
*
|
||||
* ## Parameters
|
||||
|
@ -52,22 +54,22 @@ export default class TransactionFactory {
|
|||
* To create an instruction for the `increment` method above,
|
||||
*
|
||||
* ```javascript
|
||||
* const tx = await program.transaction.increment({
|
||||
* const tx = await program.transactionInstructions.increment({
|
||||
* accounts: {
|
||||
* counter,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export type TransactionNamespace<
|
||||
export type TransactionInstructionsNamespace<
|
||||
IDL extends Idl = Idl,
|
||||
I extends AllInstructions<IDL> = AllInstructions<IDL>
|
||||
> = MakeInstructionsNamespace<IDL, I, TransactionInstruction[]>;
|
||||
|
||||
/**
|
||||
* Tx is a function to create a `TransactionInstruction[]` for a given program instruction.
|
||||
* TxIxs is a function to create a `TransactionInstruction[]` for a given program instruction.
|
||||
*/
|
||||
export type TransactionFn<
|
||||
export type TransactionInstructionsFn<
|
||||
IDL extends Idl = Idl,
|
||||
I extends AllInstructions<IDL> = AllInstructions<IDL>
|
||||
> = InstructionContextFn<IDL, I, TransactionInstruction[]>;
|
|
@ -15,31 +15,28 @@ import {
|
|||
} from "@solana/web3.js";
|
||||
import { bs58 } from "./utils/bytes/index.js";
|
||||
import { isBrowser } from "./utils/common.js";
|
||||
import {
|
||||
simulateTransaction,
|
||||
SuccessfulTxSimulationResponse,
|
||||
} from "./utils/rpc.js";
|
||||
import { SuccessfulTxSimulationResponse } from "./utils/rpc.js";
|
||||
|
||||
export default interface Provider {
|
||||
readonly connection: Connection;
|
||||
readonly publicKey?: PublicKey;
|
||||
|
||||
send?(
|
||||
tx: TransactionInstruction[],
|
||||
txIxs: TransactionInstruction[],
|
||||
signers?: Signer[],
|
||||
opts?: SendOptions
|
||||
): Promise<TransactionSignature>;
|
||||
sendAndConfirm?(
|
||||
tx: TransactionInstruction[],
|
||||
txIxs: TransactionInstruction[],
|
||||
signers?: Signer[],
|
||||
opts?: ConfirmOptions
|
||||
): Promise<TransactionSignature>;
|
||||
sendAll?(
|
||||
txWithSigners: { tx: TransactionInstruction[]; signers?: Signer[] }[],
|
||||
txWithSigners: { txIxs: TransactionInstruction[]; signers?: Signer[] }[],
|
||||
opts?: ConfirmOptions
|
||||
): Promise<Array<TransactionSignature>>;
|
||||
simulate?(
|
||||
tx: TransactionInstruction[],
|
||||
txIxs: TransactionInstruction[],
|
||||
signers?: Signer[],
|
||||
commitment?: Commitment,
|
||||
includeAccounts?: boolean | PublicKey[]
|
||||
|
@ -278,8 +275,10 @@ export class AnchorProvider implements Provider {
|
|||
if (signers) {
|
||||
tx = await this.wallet.signTransaction(tx);
|
||||
}
|
||||
const result = await simulateTransaction(
|
||||
this.connection,
|
||||
// TODO: update to the latest version that passes in versioned transactions
|
||||
// We have to figure out how to update all of the things above as well.
|
||||
// Since it has to go txIxs -> TxMsg -> VersionedTransaction
|
||||
const result = await this.connection.simulateTransaction(
|
||||
tx,
|
||||
signers,
|
||||
commitment,
|
||||
|
|
|
@ -5,7 +5,6 @@ import {
|
|||
Connection,
|
||||
PublicKey,
|
||||
TransactionSignature,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
Commitment,
|
||||
Signer,
|
||||
|
@ -13,6 +12,7 @@ import {
|
|||
SimulatedTransactionResponse,
|
||||
SendTransactionError,
|
||||
Context,
|
||||
VersionedTransaction,
|
||||
} from "@solana/web3.js";
|
||||
import { chunks } from "../utils/common.js";
|
||||
import { Address, translateAddress } from "../program/common.js";
|
||||
|
@ -49,8 +49,8 @@ export async function invoke(
|
|||
provider = getProvider();
|
||||
}
|
||||
|
||||
const tx = new Transaction();
|
||||
tx.add(
|
||||
const txInstructions: TransactionInstruction[] = [];
|
||||
txInstructions.push(
|
||||
new TransactionInstruction({
|
||||
programId,
|
||||
keys: accounts ?? [],
|
||||
|
@ -64,7 +64,7 @@ export async function invoke(
|
|||
);
|
||||
}
|
||||
|
||||
return await provider.sendAndConfirm(tx, []);
|
||||
return await provider.sendAndConfirm(txInstructions, []);
|
||||
}
|
||||
|
||||
const GET_MULTIPLE_ACCOUNTS_LIMIT: number = 99;
|
||||
|
@ -150,139 +150,6 @@ async function getMultipleAccountsAndContextCore(
|
|||
return accounts;
|
||||
}
|
||||
|
||||
// copy from @solana/web3.js that has a commitment param
|
||||
export async function simulateTransaction(
|
||||
connection: Connection,
|
||||
transaction: Transaction,
|
||||
signers?: Array<Signer>,
|
||||
commitment?: Commitment,
|
||||
includeAccounts?: boolean | Array<PublicKey>
|
||||
): Promise<RpcResponseAndContext<SimulatedTransactionResponse>> {
|
||||
if (signers && signers.length > 0) {
|
||||
transaction.sign(...signers);
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
const message = transaction._compile();
|
||||
const signData = message.serialize();
|
||||
// @ts-expect-error
|
||||
const wireTransaction = transaction._serialize(signData);
|
||||
const encodedTransaction = wireTransaction.toString("base64");
|
||||
const config: any = {
|
||||
encoding: "base64",
|
||||
commitment: commitment ?? connection.commitment,
|
||||
};
|
||||
|
||||
if (includeAccounts) {
|
||||
const addresses = (
|
||||
Array.isArray(includeAccounts) ? includeAccounts : message.nonProgramIds()
|
||||
).map((key) => key.toBase58());
|
||||
|
||||
config["accounts"] = {
|
||||
encoding: "base64",
|
||||
addresses,
|
||||
};
|
||||
}
|
||||
|
||||
if (signers) {
|
||||
config.sigVerify = true;
|
||||
}
|
||||
|
||||
const args = [encodedTransaction, config];
|
||||
// @ts-expect-error
|
||||
const unsafeRes = await connection._rpcRequest("simulateTransaction", args);
|
||||
const res = create(unsafeRes, SimulatedTransactionResponseStruct);
|
||||
if ("error" in res) {
|
||||
let logs;
|
||||
if ("data" in res.error) {
|
||||
logs = res.error.data.logs;
|
||||
if (logs && Array.isArray(logs)) {
|
||||
const traceIndent = "\n ";
|
||||
const logTrace = traceIndent + logs.join(traceIndent);
|
||||
console.error(res.error.message, logTrace);
|
||||
}
|
||||
}
|
||||
throw new SendTransactionError(
|
||||
"failed to simulate transaction: " + res.error.message,
|
||||
logs
|
||||
);
|
||||
}
|
||||
return res.result;
|
||||
}
|
||||
|
||||
// copy from @solana/web3.js
|
||||
function jsonRpcResult<T, U>(schema: Struct<T, U>) {
|
||||
return coerce(createRpcResult(schema), UnknownRpcResult, (value) => {
|
||||
if ("error" in value) {
|
||||
return value;
|
||||
} else {
|
||||
return {
|
||||
...value,
|
||||
result: create(value.result, schema),
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// copy from @solana/web3.js
|
||||
const UnknownRpcResult = createRpcResult(unknown());
|
||||
|
||||
// copy from @solana/web3.js
|
||||
function createRpcResult<T, U>(result: Struct<T, U>) {
|
||||
return union([
|
||||
pick({
|
||||
jsonrpc: literal("2.0"),
|
||||
id: string(),
|
||||
result,
|
||||
}),
|
||||
pick({
|
||||
jsonrpc: literal("2.0"),
|
||||
id: string(),
|
||||
error: pick({
|
||||
code: unknown(),
|
||||
message: string(),
|
||||
data: optional(any()),
|
||||
}),
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
// copy from @solana/web3.js
|
||||
function jsonRpcResultAndContext<T, U>(value: Struct<T, U>) {
|
||||
return jsonRpcResult(
|
||||
pick({
|
||||
context: pick({
|
||||
slot: number(),
|
||||
}),
|
||||
value,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// copy from @solana/web3.js
|
||||
const SimulatedTransactionResponseStruct = jsonRpcResultAndContext(
|
||||
pick({
|
||||
err: nullable(union([pick({}), string()])),
|
||||
logs: nullable(array(string())),
|
||||
accounts: optional(
|
||||
nullable(
|
||||
array(
|
||||
nullable(
|
||||
pick({
|
||||
executable: boolean(),
|
||||
owner: string(),
|
||||
lamports: number(),
|
||||
data: array(string()),
|
||||
rentEpoch: optional(number()),
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
unitsConsumed: optional(number()),
|
||||
})
|
||||
);
|
||||
|
||||
export type SuccessfulTxSimulationResponse = Omit<
|
||||
SimulatedTransactionResponse,
|
||||
"err"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import TransactionFactory from "../src/program/namespace/transaction";
|
||||
import TransactionInstructionsFactory from "../src/program/namespace/transaction-instructions";
|
||||
import InstructionFactory from "../src/program/namespace/instruction";
|
||||
import { BorshCoder } from "../src";
|
||||
import { PublicKey, TransactionInstruction } from "@solana/web3.js";
|
||||
|
||||
describe("Transaction", () => {
|
||||
describe("Transaction Instructions", () => {
|
||||
const preIx = new TransactionInstruction({
|
||||
keys: [],
|
||||
programId: PublicKey.default,
|
||||
|
@ -34,10 +34,13 @@ describe("Transaction", () => {
|
|||
(ixName, ix) => coder.instruction.encode(ixName, ix),
|
||||
programId
|
||||
);
|
||||
const txItem = TransactionFactory.build(idl.instructions[0], ixItem);
|
||||
const tx = txItem({ accounts: {}, preInstructions: [preIx] });
|
||||
expect(tx.instructions.length).toBe(2);
|
||||
expect(tx.instructions[0]).toMatchObject(preIx);
|
||||
const txIxsItem = TransactionInstructionsFactory.build(
|
||||
idl.instructions[0],
|
||||
ixItem
|
||||
);
|
||||
const txIxs = txIxsItem({ accounts: {}, preInstructions: [preIx] });
|
||||
expect(txIxs.length).toBe(2);
|
||||
expect(txIxs[0]).toMatchObject(preIx);
|
||||
});
|
||||
|
||||
it("should add post instructions after method ix", async () => {
|
||||
|
@ -48,10 +51,13 @@ describe("Transaction", () => {
|
|||
(ixName, ix) => coder.instruction.encode(ixName, ix),
|
||||
programId
|
||||
);
|
||||
const txItem = TransactionFactory.build(idl.instructions[0], ixItem);
|
||||
const tx = txItem({ accounts: {}, postInstructions: [postIx] });
|
||||
expect(tx.instructions.length).toBe(2);
|
||||
expect(tx.instructions[1]).toMatchObject(postIx);
|
||||
const txIxsItem = TransactionInstructionsFactory.build(
|
||||
idl.instructions[0],
|
||||
ixItem
|
||||
);
|
||||
const txIxs = txIxsItem({ accounts: {}, postInstructions: [postIx] });
|
||||
expect(txIxs.length).toBe(2);
|
||||
expect(txIxs[1]).toMatchObject(postIx);
|
||||
});
|
||||
|
||||
it("should throw error if both preInstructions and instructions are used", async () => {
|
||||
|
@ -62,10 +68,17 @@ describe("Transaction", () => {
|
|||
(ixName, ix) => coder.instruction.encode(ixName, ix),
|
||||
programId
|
||||
);
|
||||
const txItem = TransactionFactory.build(idl.instructions[0], ixItem);
|
||||
const txIxsItem = TransactionInstructionsFactory.build(
|
||||
idl.instructions[0],
|
||||
ixItem
|
||||
);
|
||||
|
||||
expect(() =>
|
||||
txItem({ accounts: {}, preInstructions: [preIx], instructions: [preIx] })
|
||||
txIxsItem({
|
||||
accounts: {},
|
||||
preInstructions: [preIx],
|
||||
instructions: [preIx],
|
||||
})
|
||||
).toThrow(new Error("instructions is deprecated, use preInstructions"));
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue