UNPKG

@symmetry-hq/baskets-v2-sdk

Version:

Symmetry Baskets V2 SDK

197 lines (179 loc) 5.37 kB
/** * This blob of a file is pulled together from different files from the metaplex * repository. * Metaplex does not have a NPM package at the current time to make this easier, so instead of * trying to reference their stuff, I copied all of the minimum necessary code into this file */ import { BinaryReader, BinaryWriter, deserializeUnchecked } from "borsh"; import { Connection, PublicKey } from "@solana/web3.js"; import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; export const METADATA_PROGRAM_ID = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" as StringPublicKey; export const METADATA_PREFIX = "metadata"; // Borsh extension for pubkey stuff // eslint-disable-next-line @typescript-eslint/no-explicit-any (BinaryReader.prototype as any).readPubkey = function () { const reader = this as unknown as BinaryReader; const array = reader.readFixedArray(32); return new PublicKey(array); }; // eslint-disable-next-line @typescript-eslint/no-explicit-any (BinaryWriter.prototype as any).writePubkey = function (value: PublicKey) { const writer = this as unknown as BinaryWriter; writer.writeFixedArray(value.toBuffer()); }; // eslint-disable-next-line @typescript-eslint/no-explicit-any (BinaryReader.prototype as any).readPubkeyAsString = function () { const reader = this as unknown as BinaryReader; const array = reader.readFixedArray(32); return bs58.encode(array) as StringPublicKey; }; // eslint-disable-next-line @typescript-eslint/no-explicit-any (BinaryWriter.prototype as any).writePubkeyAsString = function ( value: StringPublicKey ) { const writer = this as unknown as BinaryWriter; writer.writeFixedArray(bs58.decode(value)); }; export type StringPublicKey = string; export enum MetadataKey { Uninitialized = 0, MetadataV1 = 4, EditionV1 = 1, MasterEditionV1 = 2, MasterEditionV2 = 6, EditionMarker = 7, } class Creator { address: StringPublicKey; verified: boolean; share: number; constructor(args: { address: StringPublicKey; verified: boolean; share: number; }) { this.address = args.address; this.verified = args.verified; this.share = args.share; } } class Data { name: string; symbol: string; uri: string; sellerFeeBasisPoints: number; creators: Creator[] | null; constructor(args: { name: string; symbol: string; uri: string; sellerFeeBasisPoints: number; creators: Creator[] | null; }) { this.name = args.name; this.symbol = args.symbol; this.uri = args.uri; this.sellerFeeBasisPoints = args.sellerFeeBasisPoints; this.creators = args.creators; } } class Metadata { key: MetadataKey; updateAuthority: StringPublicKey; mint: StringPublicKey; data: Data; primarySaleHappened: boolean; isMutable: boolean; editionNonce: number | null; // set lazy masterEdition?: StringPublicKey; edition?: StringPublicKey; constructor(args: { updateAuthority: StringPublicKey; mint: StringPublicKey; data: Data; primarySaleHappened: boolean; isMutable: boolean; editionNonce: number | null; }) { this.key = MetadataKey.MetadataV1; this.updateAuthority = args.updateAuthority; this.mint = args.mint; this.data = args.data; this.primarySaleHappened = args.primarySaleHappened; this.isMutable = args.isMutable; this.editionNonce = args.editionNonce; } } // eslint-disable-next-line @typescript-eslint/no-explicit-any const METADATA_SCHEMA = new Map<any, any>([ [ Data, { kind: "struct", fields: [ ["name", "string"], ["symbol", "string"], ["uri", "string"], ["sellerFeeBasisPoints", "u16"], ["creators", { kind: "option", type: [Creator] }], ], }, ], [ Creator, { kind: "struct", fields: [ ["address", "pubkeyAsString"], ["verified", "u8"], ["share", "u8"], ], }, ], [ Metadata, { kind: "struct", fields: [ ["key", "u8"], ["updateAuthority", "pubkeyAsString"], ["mint", "pubkeyAsString"], ["data", Data], ["primarySaleHappened", "u8"], // bool ["isMutable", "u8"], // bool ], }, ], ]); // eslint-disable-next-line no-control-regex const METADATA_REPLACE = new RegExp("\u0000", "g"); export const decodeMetadata = (buffer: Buffer): Metadata => { const metadata = deserializeUnchecked( METADATA_SCHEMA, Metadata, buffer ) as Metadata; metadata.data.name = metadata.data.name.replace(METADATA_REPLACE, ""); metadata.data.uri = metadata.data.uri.replace(METADATA_REPLACE, ""); metadata.data.symbol = metadata.data.symbol.replace(METADATA_REPLACE, ""); return metadata; }; export async function parseMetadata( connection: Connection, metadataAccount: PublicKey // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Promise<any> { const metadataBuffer = await connection.getAccountInfo(metadataAccount, "confirmed"); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const metadata = decodeMetadata(metadataBuffer?.data); let json = {}; try { const parsed = await fetch(metadata.data.uri) json = await parsed.json(); } catch (e) { console.log(e); } return { ...metadata.data, parsed: json, }; }