Skip to content

Commit

Permalink
restart/update farm
Browse files Browse the repository at this point in the history
  • Loading branch information
cruzshia committed Aug 12, 2022
1 parent 310abfa commit 9662862
Show file tree
Hide file tree
Showing 24 changed files with 1,489 additions and 526 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"editor.formatOnSave": false,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.tabSize": 2,
// format flow
Expand Down
104 changes: 104 additions & 0 deletions src/common/accountInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { AccountInfo, Commitment, Connection, PublicKey } from "@solana/web3.js";

import { chunkArray } from "./lodash";
import { createLogger } from "./logger";

interface MultipleAccountsJsonRpcResponse {
jsonrpc: string;
id: string;
error?: {
code: number;
message: string;
};
result: {
context: { slot: number };
value: { data: Array<string>; executable: boolean; lamports: number; owner: string; rentEpoch: number }[];
};
}

export interface GetMultipleAccountsInfoConfig {
batchRequest?: boolean;
commitment?: Commitment;
}

const logger = createLogger("Raydium.accountInfo.util");

export async function getMultipleAccountsInfo(
connection: Connection,
publicKeys: PublicKey[],
config?: GetMultipleAccountsInfoConfig,
): Promise<(AccountInfo<Buffer> | null)[]> {
const { batchRequest, commitment } = {
batchRequest: false,
...config,
};

const chunkedKeys = chunkArray(publicKeys, 100);
let results: (AccountInfo<Buffer> | null)[][] = new Array(chunkedKeys.length).fill([]);

if (batchRequest) {
const batch = chunkedKeys.map((keys) => {
const args = connection._buildArgs([keys.map((key) => key.toBase58())], commitment, "base64");
return {
methodName: "getMultipleAccounts",
args,
};
});
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const unsafeResponse: MultipleAccountsJsonRpcResponse[] = await connection._rpcBatchRequest(batch);
results = unsafeResponse.map((unsafeRes: MultipleAccountsJsonRpcResponse) => {
if (unsafeRes.error) {
logger.error(`failed to get info for multiple accounts, RPC_ERROR, ${unsafeRes.error.message}`);
throw new Error("failed to get info for multiple accounts");
}

return unsafeRes.result.value.map((accountInfo) => {
if (accountInfo) {
const { data, executable, lamports, owner, rentEpoch } = accountInfo;

if (data.length !== 2 && data[1] !== "base64") {
logger.error(`info must be base64 encoded, RPC_ERROR`);
throw new Error("info must be base64 encoded");
}

return {
data: Buffer.from(data[0], "base64"),
executable,
lamports,
owner: new PublicKey(owner),
rentEpoch,
};
}
return null;
});
});
} else {
try {
results = (await Promise.all(
chunkedKeys.map((keys) => connection.getMultipleAccountsInfo(keys, commitment)),
)) as (AccountInfo<Buffer> | null)[][];
} catch (error) {
if (error instanceof Error) {
logger.error(`failed to get info for multiple accounts, RPC_ERROR, ${error.message}`);
throw new Error("failed to get info for multiple accounts");
}
}
}

return results.flat();
}

export async function getMultipleAccountsInfoWithCustomFlags<T extends { pubkey: PublicKey }>(
connection: Connection,
publicKeysWithCustomFlag: T[],
config?: GetMultipleAccountsInfoConfig,
): Promise<({ accountInfo: AccountInfo<Buffer> | null } & T)[]> {
const multipleAccountsInfo = await getMultipleAccountsInfo(
connection,
publicKeysWithCustomFlag.map((o) => o.pubkey),
config,
);

return publicKeysWithCustomFlag.map((o, idx) => ({ ...o, accountInfo: multipleAccountsInfo[idx] }));
}
5 changes: 4 additions & 1 deletion src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ export * from "./logger";
export * from "./utility";
export * from "./bignumber";
export * from "./pubKey";
export * from "./txTools";
export * from "./txTool";
export * from "./owner";
export * from "./lodash";
export * from "./accountInfo";
22 changes: 22 additions & 0 deletions src/common/lodash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* https://youmightnotneed.com/lodash/
*/

export function chunkArray<T>(arr: T[], chunkSize = 1, cache: T[][] = []): T[][] {
const tmp = [...arr];
if (chunkSize <= 0) return cache;
while (tmp.length) cache.push(tmp.splice(0, chunkSize));
return cache;
}

export function intersection<T>(arr: T[], ...args: T[][]): T[] {
return arr.filter((item) => args.every((arr) => arr.includes(item)));
}

export function xor<T>(arr: T[], ...args: T[][]): T[] {
return arr.filter((item) => args.every((arr) => !arr.includes(item)));
}

export function uniq<T>(arr: T[]): T[] {
return [...new Set(arr)];
}
2 changes: 1 addition & 1 deletion src/common/pubKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface AccountMetaProps {
isWritable?: boolean;
}

export function accountMeta({ pubkey, isSigner = false, isWritable = false }: AccountMetaProps): AccountMeta {
export function accountMeta({ pubkey, isSigner = false, isWritable = true }: AccountMetaProps): AccountMeta {
return {
pubkey,
isWritable,
Expand Down
85 changes: 85 additions & 0 deletions src/common/txTool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {
Connection,
PublicKey,
sendAndConfirmTransaction,
Signer,
Transaction,
TransactionInstruction,
} from "@solana/web3.js";

import { Owner } from "./owner";

interface TxBuilderInit {
connection: Connection;
feePayer: PublicKey;
owner?: Owner;
signAllTransactions?: (transactions: Transaction[]) => Promise<Transaction[]>;
}

export class TxBuilder {
private connection: Connection;
private owner?: Owner;
private instructions: TransactionInstruction[] = [];
private endInstructions: TransactionInstruction[] = [];
private signers: Signer[] = [];
private feePayer: PublicKey;
private signAllTransactions?: (transactions: Transaction[]) => Promise<Transaction[]>;

constructor(params: TxBuilderInit) {
this.connection = params.connection;
this.feePayer = params.feePayer;
this.signAllTransactions = params.signAllTransactions;
this.owner = params.owner;
}

public addInstruction({
instructions = [],
endInstructions = [],
signers = [],
}: {
instructions?: TransactionInstruction[];
endInstructions?: TransactionInstruction[];
signers?: Signer[];
}): TxBuilder {
this.instructions.push(...instructions);
this.endInstructions.push(...endInstructions);
this.signers.push(...signers);
return this;
}

public async build(): Promise<{
transaction: Transaction;
signers: Signer[];
excute: () => Promise<string>;
}> {
const recentBlockHash = await getRecentBlockhash(this.connection);

const transaction = new Transaction();
transaction.recentBlockhash = recentBlockHash;
transaction.add(...this.instructions, ...this.endInstructions);
transaction.feePayer = this.feePayer;

return {
transaction,
signers: this.signers,
excute: async (): Promise<string> => {
if (this.owner) {
return sendAndConfirmTransaction(this.connection, transaction, this.signers);
}
if (this.signAllTransactions) {
const signedTx = await this.signAllTransactions([transaction]);
return this.connection.sendRawTransaction(signedTx[0].serialize());
}
throw new Error("please connect wallet first");
},
};
}
}

export async function getRecentBlockhash(connection: Connection): Promise<string> {
try {
return (await connection.getLatestBlockhash?.())?.blockhash || (await connection.getRecentBlockhash()).blockhash;
} catch {
return (await connection.getRecentBlockhash()).blockhash;
}
}
37 changes: 0 additions & 37 deletions src/common/txTools.ts

This file was deleted.

Loading

0 comments on commit 9662862

Please sign in to comment.