UNPKG

@gorbchain-xyz/chaindecode

Version:

GorbchainSDK V1.3+ - Complete Solana development toolkit with advanced cryptography, messaging, and collaboration features. Build secure applications with blockchain, DeFi, and end-to-end encryption.

573 lines (572 loc) 23.8 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { getGorbchainConfig } from '../utils/gorbchainConfig.js'; // Get Metaplex program ID from config function getMetaplexProgramId() { var _a, _b; const config = getGorbchainConfig(); return (_b = (_a = config.programIds) === null || _a === void 0 ? void 0 : _a.metaplex) !== null && _b !== void 0 ? _b : 'BvoSmPBF6mBRxBMY9FPguw1zUoUg3xrc5CaWf7y5ACkc'; } // Metaplex Instruction Types export var MetaplexInstruction; (function (MetaplexInstruction) { MetaplexInstruction[MetaplexInstruction["CreateMetadataAccount"] = 0] = "CreateMetadataAccount"; MetaplexInstruction[MetaplexInstruction["UpdateMetadataAccount"] = 1] = "UpdateMetadataAccount"; MetaplexInstruction[MetaplexInstruction["DeprecatedCreateMasterEdition"] = 2] = "DeprecatedCreateMasterEdition"; MetaplexInstruction[MetaplexInstruction["DeprecatedMintNewEditionFromMasterEditionViaPrintingToken"] = 3] = "DeprecatedMintNewEditionFromMasterEditionViaPrintingToken"; MetaplexInstruction[MetaplexInstruction["UpdatePrimarySaleHappenedViaToken"] = 4] = "UpdatePrimarySaleHappenedViaToken"; MetaplexInstruction[MetaplexInstruction["DeprecatedSetReservationList"] = 5] = "DeprecatedSetReservationList"; MetaplexInstruction[MetaplexInstruction["DeprecatedCreateReservationList"] = 6] = "DeprecatedCreateReservationList"; MetaplexInstruction[MetaplexInstruction["SignMetadata"] = 7] = "SignMetadata"; MetaplexInstruction[MetaplexInstruction["DeprecatedMintPrintingTokensViaToken"] = 8] = "DeprecatedMintPrintingTokensViaToken"; MetaplexInstruction[MetaplexInstruction["DeprecatedMintPrintingTokens"] = 9] = "DeprecatedMintPrintingTokens"; MetaplexInstruction[MetaplexInstruction["CreateMasterEdition"] = 10] = "CreateMasterEdition"; MetaplexInstruction[MetaplexInstruction["MintNewEditionFromMasterEditionViaToken"] = 11] = "MintNewEditionFromMasterEditionViaToken"; MetaplexInstruction[MetaplexInstruction["ConvertMasterEditionV1ToV2"] = 12] = "ConvertMasterEditionV1ToV2"; MetaplexInstruction[MetaplexInstruction["MintNewEditionFromMasterEditionViaVaultProxy"] = 13] = "MintNewEditionFromMasterEditionViaVaultProxy"; MetaplexInstruction[MetaplexInstruction["PuffMetadata"] = 14] = "PuffMetadata"; MetaplexInstruction[MetaplexInstruction["UpdateMetadataAccountV2"] = 15] = "UpdateMetadataAccountV2"; MetaplexInstruction[MetaplexInstruction["CreateMetadataAccountV2"] = 16] = "CreateMetadataAccountV2"; MetaplexInstruction[MetaplexInstruction["CreateMasterEditionV3"] = 17] = "CreateMasterEditionV3"; MetaplexInstruction[MetaplexInstruction["VerifyCollection"] = 18] = "VerifyCollection"; MetaplexInstruction[MetaplexInstruction["Utilize"] = 19] = "Utilize"; MetaplexInstruction[MetaplexInstruction["ApproveUseAuthority"] = 20] = "ApproveUseAuthority"; MetaplexInstruction[MetaplexInstruction["RevokeUseAuthority"] = 21] = "RevokeUseAuthority"; MetaplexInstruction[MetaplexInstruction["UnverifyCollection"] = 22] = "UnverifyCollection"; MetaplexInstruction[MetaplexInstruction["ApproveCollectionAuthority"] = 23] = "ApproveCollectionAuthority"; MetaplexInstruction[MetaplexInstruction["RevokeCollectionAuthority"] = 24] = "RevokeCollectionAuthority"; MetaplexInstruction[MetaplexInstruction["SetAndVerifyCollection"] = 25] = "SetAndVerifyCollection"; MetaplexInstruction[MetaplexInstruction["FreezeDelegatedAccount"] = 26] = "FreezeDelegatedAccount"; MetaplexInstruction[MetaplexInstruction["ThawDelegatedAccount"] = 27] = "ThawDelegatedAccount"; MetaplexInstruction[MetaplexInstruction["RemoveCreatorVerification"] = 28] = "RemoveCreatorVerification"; MetaplexInstruction[MetaplexInstruction["BurnNft"] = 29] = "BurnNft"; MetaplexInstruction[MetaplexInstruction["VerifyCreator"] = 30] = "VerifyCreator"; MetaplexInstruction[MetaplexInstruction["UnverifyCreator"] = 31] = "UnverifyCreator"; MetaplexInstruction[MetaplexInstruction["CreateMetadataAccountV3"] = 32] = "CreateMetadataAccountV3"; MetaplexInstruction[MetaplexInstruction["SetCollectionSize"] = 33] = "SetCollectionSize"; MetaplexInstruction[MetaplexInstruction["SetTokenStandard"] = 34] = "SetTokenStandard"; MetaplexInstruction[MetaplexInstruction["BubblegumSetCollectionSize"] = 35] = "BubblegumSetCollectionSize"; MetaplexInstruction[MetaplexInstruction["BurnEditionNft"] = 36] = "BurnEditionNft"; MetaplexInstruction[MetaplexInstruction["CreateEscrowAccount"] = 37] = "CreateEscrowAccount"; MetaplexInstruction[MetaplexInstruction["CloseEscrowAccount"] = 38] = "CloseEscrowAccount"; MetaplexInstruction[MetaplexInstruction["TransferOutOfEscrow"] = 39] = "TransferOutOfEscrow"; MetaplexInstruction[MetaplexInstruction["Burn"] = 40] = "Burn"; MetaplexInstruction[MetaplexInstruction["Create"] = 41] = "Create"; MetaplexInstruction[MetaplexInstruction["Mint"] = 42] = "Mint"; MetaplexInstruction[MetaplexInstruction["Delegate"] = 43] = "Delegate"; MetaplexInstruction[MetaplexInstruction["Revoke"] = 44] = "Revoke"; MetaplexInstruction[MetaplexInstruction["Lock"] = 45] = "Lock"; MetaplexInstruction[MetaplexInstruction["Unlock"] = 46] = "Unlock"; MetaplexInstruction[MetaplexInstruction["Migrate"] = 47] = "Migrate"; MetaplexInstruction[MetaplexInstruction["Transfer"] = 48] = "Transfer"; MetaplexInstruction[MetaplexInstruction["Update"] = 49] = "Update"; MetaplexInstruction[MetaplexInstruction["Use"] = 50] = "Use"; MetaplexInstruction[MetaplexInstruction["Verify"] = 51] = "Verify"; MetaplexInstruction[MetaplexInstruction["Unverify"] = 52] = "Unverify"; })(MetaplexInstruction || (MetaplexInstruction = {})); /** * Main NFT/Metaplex decoder function */ export function decodeNFTInstruction(instruction) { const data = instruction.data; if (!data || data.length === 0) { throw new Error('Invalid NFT instruction: no data'); } const instructionType = data[0]; const programId = getMetaplexProgramId(); switch (instructionType) { case MetaplexInstruction.CreateMetadataAccount: return decodeCreateMetadataAccount(instruction, programId); case MetaplexInstruction.UpdateMetadataAccount: return decodeUpdateMetadataAccount(instruction, programId); case MetaplexInstruction.CreateMasterEdition: return decodeCreateMasterEdition(instruction, programId); case MetaplexInstruction.MintNewEditionFromMasterEditionViaToken: return decodeMintNewEdition(instruction, programId); case MetaplexInstruction.UpdateMetadataAccountV2: return decodeUpdateMetadataAccountV2(instruction, programId); case MetaplexInstruction.CreateMetadataAccountV2: return decodeCreateMetadataAccountV2(instruction, programId); case MetaplexInstruction.CreateMasterEditionV3: return decodeCreateMasterEditionV3(instruction, programId); case MetaplexInstruction.VerifyCollection: return decodeVerifyCollection(instruction, programId); case MetaplexInstruction.UnverifyCollection: return decodeUnverifyCollection(instruction, programId); case MetaplexInstruction.VerifyCreator: return decodeVerifyCreator(instruction, programId); case MetaplexInstruction.UnverifyCreator: return decodeUnverifyCreator(instruction, programId); case MetaplexInstruction.BurnNft: return decodeBurnNft(instruction, programId); case MetaplexInstruction.CreateMetadataAccountV3: return decodeCreateMetadataAccountV3(instruction, programId); case MetaplexInstruction.SetCollectionSize: return decodeSetCollectionSize(instruction, programId); case MetaplexInstruction.SetTokenStandard: return decodeSetTokenStandard(instruction, programId); case MetaplexInstruction.Transfer: return decodeNFTTransfer(instruction, programId); case MetaplexInstruction.Mint: return decodeNFTMint(instruction, programId); case MetaplexInstruction.Burn: return decodeNFTBurn(instruction, programId); case MetaplexInstruction.Lock: return decodeNFTLock(instruction, programId); case MetaplexInstruction.Unlock: return decodeNFTUnlock(instruction, programId); default: return { type: 'nft-unknown', programId, data: { instructionType, error: `Unknown NFT instruction type: ${instructionType}` }, accounts: instruction.accounts, raw: instruction }; } } /** * Enhanced NFT instruction decoder with metadata extraction */ export function decodeNFTInstructionWithDetails(data) { if (data.length === 0) { return { type: 'nft-unknown', instruction: 'Unknown NFT instruction', accounts: [] }; } const instructionType = data[0]; switch (instructionType) { case 0: // CreateMetadataAccount return { type: 'nft-create-metadata', instruction: 'Create NFT metadata account', nftDetails: { isCollection: false, isMasterEdition: false }, accounts: [] }; case 10: // CreateMasterEdition return { type: 'nft-create-master-edition', instruction: 'Create NFT master edition', nftDetails: { isMasterEdition: true, isCollection: false }, accounts: [] }; case 16: // CreateMetadataAccountV2 return { type: 'nft-create-metadata-v2', instruction: 'Create NFT metadata account V2', nftDetails: { isCollection: false, isMasterEdition: false }, accounts: [] }; case 17: // CreateMasterEditionV3 return { type: 'nft-create-master-edition-v3', instruction: 'Create NFT master edition V3', nftDetails: { isMasterEdition: true, isCollection: false }, accounts: [] }; case 18: // VerifyCollection return { type: 'nft-verify-collection', instruction: 'Verify NFT collection', nftDetails: { isCollection: true, isMasterEdition: false }, accounts: [] }; case 29: // BurnNft return { type: 'nft-burn', instruction: 'Burn NFT', accounts: [] }; case 32: // CreateMetadataAccountV3 return { type: 'nft-create-metadata-v3', instruction: 'Create NFT metadata account V3', nftDetails: { isCollection: false, isMasterEdition: false }, accounts: [] }; case 48: // Transfer return { type: 'nft-transfer', instruction: 'Transfer NFT', accounts: [] }; case 42: // Mint return { type: 'nft-mint', instruction: 'Mint NFT', accounts: [] }; default: return { type: 'nft-unknown', instruction: `Unknown NFT instruction (type: ${instructionType})`, accounts: [] }; } } /** * Check if a token is an NFT based on its characteristics */ export function isNFTToken(tokenInfo) { // NFTs typically have: // - Supply of 1 // - 0 decimals // Note: We don't require mintAuthority to be null as many custom NFTs // may still have mint authority but are functionally NFTs const supply = BigInt(tokenInfo.supply); return (supply === BigInt(1) && tokenInfo.decimals === 0); } /** * Check if a token is a strict standard NFT (following Metaplex standards) */ export function isStandardNFT(tokenInfo) { // Standard NFTs have: // - Supply of 1 // - 0 decimals // - No mint authority (supply is fixed) const supply = BigInt(tokenInfo.supply); return (supply === BigInt(1) && tokenInfo.decimals === 0 && tokenInfo.mintAuthority === null); } /** * Get NFT metadata from URI */ export function fetchNFTMetadata(uri) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e; try { const response = yield fetch(uri); if (!response.ok) { return null; } const metadata = yield response.json(); return { name: (_a = metadata.name) !== null && _a !== void 0 ? _a : 'Unknown NFT', symbol: (_b = metadata.symbol) !== null && _b !== void 0 ? _b : '', uri, sellerFeeBasisPoints: (_c = metadata.seller_fee_basis_points) !== null && _c !== void 0 ? _c : 0, creators: (_e = (_d = metadata.properties) === null || _d === void 0 ? void 0 : _d.creators) !== null && _e !== void 0 ? _e : [], collection: metadata.collection, uses: metadata.uses }; } catch (error) { // eslint-disable-next-line no-console console.error('Failed to fetch NFT metadata:', error); return null; } }); } // Individual instruction decoders function decodeCreateMetadataAccount(instruction, programId) { var _a, _b, _c, _d, _e; return { type: 'nft-create-metadata', programId, data: { metadata: (_a = instruction.accounts[0]) !== null && _a !== void 0 ? _a : '', mint: (_b = instruction.accounts[1]) !== null && _b !== void 0 ? _b : '', mintAuthority: (_c = instruction.accounts[2]) !== null && _c !== void 0 ? _c : '', payer: (_d = instruction.accounts[3]) !== null && _d !== void 0 ? _d : '', updateAuthority: (_e = instruction.accounts[4]) !== null && _e !== void 0 ? _e : '' }, accounts: instruction.accounts }; } function decodeUpdateMetadataAccount(instruction, programId) { var _a, _b; return { type: 'nft-update-metadata', programId, data: { metadata: (_a = instruction.accounts[0]) !== null && _a !== void 0 ? _a : '', updateAuthority: (_b = instruction.accounts[1]) !== null && _b !== void 0 ? _b : '' }, accounts: instruction.accounts }; } function decodeCreateMasterEdition(instruction, programId) { var _a; return { type: 'nft-create-master-edition', programId, data: { edition: instruction.accounts[0], mint: instruction.accounts[1], updateAuthority: instruction.accounts[2], mintAuthority: instruction.accounts[3], payer: instruction.accounts[4], metadata: instruction.accounts[5] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeMintNewEdition(instruction, programId) { var _a; return { type: 'nft-mint-new-edition', programId, data: { metadata: instruction.accounts[0], edition: instruction.accounts[1], masterEdition: instruction.accounts[2], mint: instruction.accounts[3], mintAuthority: instruction.accounts[4] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeUpdateMetadataAccountV2(instruction, programId) { var _a; return { type: 'nft-update-metadata-v2', programId, data: { metadata: instruction.accounts[0], updateAuthority: instruction.accounts[1] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeCreateMetadataAccountV2(instruction, programId) { var _a; return { type: 'nft-create-metadata-v2', programId, data: { metadata: instruction.accounts[0], mint: instruction.accounts[1], mintAuthority: instruction.accounts[2], payer: instruction.accounts[3], updateAuthority: instruction.accounts[4] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeCreateMasterEditionV3(instruction, programId) { var _a; return { type: 'nft-create-master-edition-v3', programId, data: { edition: instruction.accounts[0], mint: instruction.accounts[1], updateAuthority: instruction.accounts[2], mintAuthority: instruction.accounts[3], payer: instruction.accounts[4], metadata: instruction.accounts[5] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeVerifyCollection(instruction, programId) { var _a; return { type: 'nft-verify-collection', programId, data: { metadata: instruction.accounts[0], collectionAuthority: instruction.accounts[1], payer: instruction.accounts[2], collectionMint: instruction.accounts[3], collection: instruction.accounts[4] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeUnverifyCollection(instruction, programId) { var _a; return { type: 'nft-unverify-collection', programId, data: { metadata: instruction.accounts[0], collectionAuthority: instruction.accounts[1], collectionMint: instruction.accounts[2], collection: instruction.accounts[3] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeVerifyCreator(instruction, programId) { var _a; return { type: 'nft-verify-creator', programId, data: { metadata: instruction.accounts[0], creator: instruction.accounts[1] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeUnverifyCreator(instruction, programId) { var _a; return { type: 'nft-unverify-creator', programId, data: { metadata: instruction.accounts[0], creator: instruction.accounts[1] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeBurnNft(instruction, programId) { var _a; return { type: 'nft-burn', programId, data: { metadata: instruction.accounts[0], owner: instruction.accounts[1], mint: instruction.accounts[2], tokenAccount: instruction.accounts[3] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeCreateMetadataAccountV3(instruction, programId) { var _a; return { type: 'nft-create-metadata-v3', programId, data: { metadata: instruction.accounts[0], mint: instruction.accounts[1], mintAuthority: instruction.accounts[2], payer: instruction.accounts[3], updateAuthority: instruction.accounts[4] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeSetCollectionSize(instruction, programId) { var _a; return { type: 'nft-set-collection-size', programId, data: { collectionMetadata: instruction.accounts[0], collectionAuthority: instruction.accounts[1], collectionMint: instruction.accounts[2] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeSetTokenStandard(instruction, programId) { var _a; return { type: 'nft-set-token-standard', programId, data: { metadata: instruction.accounts[0], updateAuthority: instruction.accounts[1], mint: instruction.accounts[2] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeNFTTransfer(instruction, programId) { var _a; return { type: 'nft-transfer', programId, data: { tokenAccount: instruction.accounts[0], tokenOwner: instruction.accounts[1], destinationTokenAccount: instruction.accounts[2], destinationOwner: instruction.accounts[3], mint: instruction.accounts[4] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeNFTMint(instruction, programId) { var _a; return { type: 'nft-mint', programId, data: { tokenAccount: instruction.accounts[0], tokenOwner: instruction.accounts[1], metadata: instruction.accounts[2], masterEdition: instruction.accounts[3], mint: instruction.accounts[4] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeNFTBurn(instruction, programId) { var _a; return { type: 'nft-burn', programId, data: { tokenAccount: instruction.accounts[0], mint: instruction.accounts[1], authority: instruction.accounts[2] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeNFTLock(instruction, programId) { var _a; return { type: 'nft-lock', programId, data: { authority: instruction.accounts[0], tokenOwner: instruction.accounts[1], tokenAccount: instruction.accounts[2], mint: instruction.accounts[3] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; } function decodeNFTUnlock(instruction, programId) { var _a; return { type: 'nft-unlock', programId, data: { authority: instruction.accounts[0], tokenOwner: instruction.accounts[1], tokenAccount: instruction.accounts[2], mint: instruction.accounts[3] }, accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [] }; }