Skip to content

Instantly share code, notes, and snippets.

View NotoriousPyro's full-sized avatar

NotoriousPyro

View GitHub Profile
@NotoriousPyro
NotoriousPyro / clients.ts
Last active May 28, 2024 17:21
Quicknode /markets implementation (for adding new markets)
// define a couple of fetchers, one for /quote and one for everything else
// if the endpoint url is a QN endpoint, use the custom fetcher that appends the param useQNMarketCache=true
export const quoteFetcher = createJupiterApiClient({
basePath: config.jupiter.endpoint,
fetchApi: config.jupiter.endpoint.search(/https:\/\/jupiter-swap-api.quiknode.pro\/[A-Z0-9]*/) !== -1
? QuicknodeQuoteFetcherWithCustomAgent(agent)
: FetcherWithCustomAgent(agent),
})
export const swapInstructionFetcher = createJupiterApiClient({
[2024-05-23T03:05:03.015Z] [Main]: Ledger Error [program: Jupiter] [
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]",
"Program log: CreateIdempotent",
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 4338 of 899550 compute units",
@NotoriousPyro
NotoriousPyro / addresstables_uncached.ts
Created May 21, 2024 22:30
AddressTableLookup uncached
export const getAddressLookupTableAccounts_Uncached = async (
addressLookupTableAddresses: string[]
): Promise<AddressLookupTableAccount[]> => {
const keys = Array.from([...new Set(addressLookupTableAddresses)]);
const addressLookupTableAccountInfos = await getAccountInfos(await Promise.all(keys.map(async key => Promise.resolve(new PublicKey(key)))));
return await Promise.all(
addressLookupTableAccountInfos.map(
async (account, index) => {
const addressLookupTableAddress = keys[index];
if (addressLookupTableAddress) {
@NotoriousPyro
NotoriousPyro / _worker.js
Created May 18, 2024 15:31
Solana RPC Cloudflare Worker
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname.startsWith("/api")) {
url.pathname = url.pathname.replace("/api", `/${env.API_KEY}`);
const upgradeHeader = request.headers.get('Upgrade');
const newUrl = `https://api.sexonsol.com${url.pathname}`;
if (upgradeHeader === 'websocket') {
const resp = await fetch(newUrl, {
headers: {
@NotoriousPyro
NotoriousPyro / example.ts
Last active May 21, 2024 19:38
Jupiter IDL types and decompiling swap data
const decodedA = await decodeSwapInstructionData<Route["Arguments"]>(swapinstA.swapInstruction.data);
const decodedB = await decodeSwapInstructionData<Route["Arguments"]>(swapinstB.swapInstruction.data);
// do whatever you want
const Route_AccountsStrict: Route["AccountsStrict"] = {
tokenProgram: TOKEN_PROGRAM_ID,
userTransferAuthority: keypair.publicKey,
userSourceTokenAccount: inputMintATA,
userDestinationTokenAccount: inputMintATA,
@NotoriousPyro
NotoriousPyro / jupiter-full-js-example.js
Last active May 23, 2024 20:10
Full example of how to swap tokens with jupiter
const { Connection, Keypair, VersionedTransaction } = require ('@solana/web3.js');
const bs58 = require ('bs58');
const axios = require('axios');
// It is recommended that you use your own RPC endpoint.
// This RPC endpoint is only for demonstration purposes so that this example will run.
const connection = new Connection('');
const keypair = Keypair.fromSecretKey(bs58.decode(''));
@NotoriousPyro
NotoriousPyro / BurnATAs.ts
Last active May 21, 2024 22:34
Burn your unwanted ATAs on Solana with this script
import { GetProgramAccountsFilter, PublicKey, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
import { connection } from "../src/connection";
import config from "../src/lib/Config";
import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID, createBurnCheckedInstruction, createCloseAccountInstruction, getAssociatedTokenAddressSync, unpackAccount, unpackMint } from "@solana/spl-token";
// Not really tested more than two but you can probably fit more in.
const maxMintsPerTx = 2;
// Replace this with your own keypair
const owningAccount = config.keypair;
// This creates a tx like this: https://solscan.io/tx/5PegaAnFzaEdVWYfzHFVTzJyZr8wHKRhijgtXyGhNzaQj4HfW5U8BqaaHNhGkCbZRDePns5cnFJAb18RCx4cuLqB
@NotoriousPyro
NotoriousPyro / confirm-tx.ts
Last active May 21, 2024 22:35
Solana example confirm tx and save the created ATAs in a database, so they don't need re-creating
await confirmTransaction(signature).then(
async (logs) => {
logger.log("Confirmed", logs.signature);
const createdAtas = mintIdempotentInstructions.map(instruction => {
return {
ata: instruction.keys[1].pubkey,
mint: instruction.keys[3].pubkey,
owner: instruction.keys[5].pubkey,
};
})
@NotoriousPyro
NotoriousPyro / solana-rewards.ts
Last active May 15, 2024 19:42
Solana Rewards distribution
import { PublicKey, Transaction, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
import config from "../src/lib/Config";
import BigNumber from "bignumber.js";
import { createAssociatedTokenAccountIdempotentInstruction, createTransferCheckedInstruction, getAssociatedTokenAddress, getAssociatedTokenAddressSync } from "@solana/spl-token";
import { connection } from "../src/connection";
import { createComputeBudgetInstruction } from "../src/lib/TransactionBuilder";
/**
* Distributes rewards based on a a token amount a user has, e.g. staked or LP tokens.
*
@NotoriousPyro
NotoriousPyro / AccountBalanceManager.ts
Created May 6, 2024 17:20
AccountBalanceManager for Solana, can monitor the ATAs of various token balances in an account.
import { Account, Mint, TOKEN_PROGRAM_ID, getAssociatedTokenAddress, unpackAccount, unpackMint } from "@solana/spl-token";
import { AccountChangeCallback, AccountInfo, Connection, Keypair, PublicKey } from "@solana/web3.js";
import { WellKnownTokenMint } from "../../const";
import { ToDecimal } from "../../utils";
import { BigNumber } from "bignumber.js";
import { TradeQueueItem, TradeExecutor } from "./trade";
import BalanceQueue from "../queues/balance";
export type BalanceChangeCallback = (queue: BalanceQueue<TradeQueueItem, TradeExecutor>) => Promise<TradeExecutor>;
export type BalanceChangeParams = [callback: BalanceChangeCallback, args: BalanceQueue<TradeQueueItem, TradeExecutor>]