Skip to content

Instantly share code, notes, and snippets.

View NotoriousPyro's full-sized avatar

NotoriousPyro

View GitHub Profile
export class ConfirmTransactionFailureError extends Error {
constructor(signature: string) {
super("Failed to confirm transaction:" + signature);
this.name = "ConfirmTransactionFailure";
}
}
export class TransactionConfirmer {
private subscriptionId: number;
private signatures = new Map<string, Logs>();
@NotoriousPyro
NotoriousPyro / lmdb-values-generator.ts
Created June 5, 2024 19:58
lmdb relational value async generator
import { open } from "lmdb";
type lmdb = ReturnType<typeof open>
/**
* For databases where there are different types stored under different keys in the same DB, this function
* allows iteration over the values of that relation. Otherwise, you might return the wrong type.
* It can't be used in DBs that do not have a fixed first key for each type stored.
* @param db opened lmdb database
* @param relation the key that uniquely identifies the type of the object
@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
Last active June 4, 2024 21:53
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 June 4, 2024 22:08
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 June 11, 2024 20:51
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 / 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.
*