Skip to content

Instantly share code, notes, and snippets.

@rubpy
Created July 27, 2024 00:56
Show Gist options
  • Save rubpy/9f548d1ef33001810727fb88e685f960 to your computer and use it in GitHub Desktop.
Save rubpy/9f548d1ef33001810727fb88e685f960 to your computer and use it in GitHub Desktop.
import web3 from "@solana/web3.js";
import * as BufferLayout from "@solana/buffer-layout";
import bs58 from "bs58";
//////////////////////////////////////////////////
class BorshString extends BufferLayout.Layout<string> {
constructor(property?: string) {
super(-1, property);
}
getSpan(b?: Uint8Array, offset?: number): number {
offset = offset || 0;
if (!b || b.byteLength < offset + 4) {
throw new RangeError("invalid string encoding");
}
const len = Buffer.from(b.buffer, b.byteOffset, b.length).readUInt32LE(offset);
if ((offset + len) > b.byteLength) {
throw new RangeError("encoding overruns Buffer");
}
return len + 4;
}
decode(b: Uint8Array, offset?: number): string {
offset = offset || 0;
const span = this.getSpan(b, offset);
return span <= 4 ? "" : Buffer.from(b.buffer, b.byteOffset, b.length).subarray(offset + 4, offset + span).toString("utf-8");
}
encode(src: string, b: Uint8Array, offset?: number): number {
if (typeof src !== "string") {
src = String(src);
}
offset = offset || 0;
const srcBuf = Buffer.from(src, "utf-8");
const span = srcBuf.length;
if (span > 0xffffffff) {
throw new RangeError("unsupported data size");
}
if ((offset + span + 4) > b.length) {
throw new RangeError("encoding overruns Buffer");
}
const dstBuf = Buffer.from(b.buffer, b.byteOffset, b.length);
dstBuf.writeUInt32LE(span, offset);
srcBuf.copy(dstBuf, offset + 4);
return span + 4;
}
}
//////////////////////////////////////////////////
const IDL_DISCRIMINATOR_SIZE = 8;
const PUMP_PROGRAM_ID = new web3.PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");
const PUMP_CREATE_INSTRUCTION_DISCRIMINATOR = Buffer.from([0x18, 0x1e, 0xc8, 0x28, 0x05, 0x1c, 0x07, 0x77]);
export interface PumpCreateInstruction {
accounts: {
mint: web3.PublicKey;
mintAuthority: web3.PublicKey;
bondingCurve: web3.PublicKey;
associatedBondingCurve: web3.PublicKey;
global: web3.PublicKey;
mplTokenMetadata: web3.PublicKey;
metadata: web3.PublicKey;
user: web3.PublicKey;
systemProgram: web3.PublicKey;
tokenProgram: web3.PublicKey;
associatedTokenProgram: web3.PublicKey;
rent: web3.PublicKey;
eventAuthority: web3.PublicKey;
program: web3.PublicKey;
};
args: {
name: string;
symbol: string;
uri: string;
};
}
export const PumpCreateInstructionLayout = BufferLayout.struct<PumpCreateInstruction["args"]>([
new BorshString("name"),
new BorshString("symbol"),
new BorshString("uri"),
]);
function decodePumpCreateInstruction(instruction: web3.PartiallyDecodedInstruction): PumpCreateInstruction | null {
if ((instruction === null || typeof instruction !== "object" || instruction.data === "")
|| !instruction.programId.equals(PUMP_PROGRAM_ID)) {
return null;
}
const accs = instruction.accounts;
if (accs.length !== 14
|| !accs[8].equals(web3.SystemProgram.programId)
|| !accs[13].equals(PUMP_PROGRAM_ID)) {
return null;
}
let data: Uint8Array | null = null;
try {
data = bs58.decode(instruction.data);
} catch (e) {
return null;
}
if (data.byteLength < IDL_DISCRIMINATOR_SIZE
|| PUMP_CREATE_INSTRUCTION_DISCRIMINATOR.compare(data, 0, IDL_DISCRIMINATOR_SIZE) !== 0) {
return null;
}
let args: PumpCreateInstruction["args"] | null = null;
try {
args = PumpCreateInstructionLayout.decode(Buffer.from(data), IDL_DISCRIMINATOR_SIZE);
} catch (e) {
return null;
}
return {
accounts: {
mint: accs[0],
mintAuthority: accs[1],
bondingCurve: accs[2],
associatedBondingCurve: accs[3],
global: accs[4],
mplTokenMetadata: accs[5],
metadata: accs[6],
user: accs[7],
systemProgram: accs[8],
tokenProgram: accs[9],
associatedTokenProgram: accs[10],
rent: accs[11],
eventAuthority: accs[12],
program: accs[13],
},
args,
};
}
//////////////////////////////////////////////////
(() => {
const mockedPumpCreateInstruction: web3.PartiallyDecodedInstruction = {
programId: new web3.PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
accounts: [
new web3.PublicKey("DNKDa1QVTJyPG7QB6ZnRuUL28ZZH6sDCwkTt4z2ypump"),
new web3.PublicKey("TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM"),
new web3.PublicKey("7Wsoh4CTWrJ8wychQ4qm8hSasxd3b6g5Ac6ZCbSp3gR5"),
new web3.PublicKey("77prkrDYMYyGyPrJqPAT2KZAZw6ujiaBtAV2GouHSagY"),
new web3.PublicKey("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"),
new web3.PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"),
new web3.PublicKey("AwNcWv7mJwi9F5VsgmUbet9QMp7Ep6odb56GTPPDDmbW"),
new web3.PublicKey("3fpr6BgYQTi8Bvpt6sSEP7WKvthV4BqtespH9qKN9WMg"),
new web3.PublicKey("11111111111111111111111111111111"),
new web3.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
new web3.PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"),
new web3.PublicKey("SysvarRent111111111111111111111111111111111"),
new web3.PublicKey("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"),
new web3.PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
],
data: "DKTQu9nyWyPQWAeaeTAKqdT64um3H6dTnF85fkSqJ3cMsfGPN9CCF3x3epKY6vjQM5CRzQzsvFvrkdifFxgvYDwbbxzmXb77JwTYFKdRs6XTCNw6u6LPtPxadSPCGawR6s94kjj",
};
console.log(decodePumpCreateInstruction(mockedPumpCreateInstruction));
/*
---------- OUTPUT ----------
{
accounts: {
mint: DNKDa1QVTJyPG7QB6ZnRuUL28ZZH6sDCwkTt4z2ypump,
mintAuthority: TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM,
bondingCurve: 7Wsoh4CTWrJ8wychQ4qm8hSasxd3b6g5Ac6ZCbSp3gR5,
associatedBondingCurve: 77prkrDYMYyGyPrJqPAT2KZAZw6ujiaBtAV2GouHSagY,
global: 4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf,
mplTokenMetadata: metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s,
metadata: AwNcWv7mJwi9F5VsgmUbet9QMp7Ep6odb56GTPPDDmbW,
user: 3fpr6BgYQTi8Bvpt6sSEP7WKvthV4BqtespH9qKN9WMg,
systemProgram: 11111111111111111111111111111111,
tokenProgram: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA,
associatedTokenProgram: ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL,
rent: SysvarRent111111111111111111111111111111111,
eventAuthority: Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1,
program: 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P,
},
args: {
name: 'Ugly',
symbol: 'ugly',
uri: 'https://cf-ipfs.com/ipfs/QmWtc83TNHMghpKkDputMD4D84rnjx7VcSULmLM7PqqqN2'
}
}
----------------------------
*/
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment