Metadata Address |
@@ -203,7 +210,7 @@ export function SplTokenMetadataInterfaceCard({ mint }: { mint: string }) {
);
- }, [loading, metadata, metadataAuthority, metadataPointer, mint]);
+ }, [metadataAuthority, metadataPointer, metadataCard, programOwner]);
return card;
}
diff --git a/app/providers/accounts/index.tsx b/app/providers/accounts/index.tsx
index 4fa4e639..9da2abd5 100644
--- a/app/providers/accounts/index.tsx
+++ b/app/providers/accounts/index.tsx
@@ -62,7 +62,7 @@ export function isTokenProgramData(data: { program: string }): data is TokenProg
try {
assertIsTokenProgram(data.program);
return true;
- } catch(e) {
+ } catch (e) {
return false;
}
}
@@ -97,6 +97,17 @@ export type AddressLookupTableProgramData = {
parsed: ParsedAddressLookupTableAccount;
};
+type ExtensionRecord = Record & { extension: string };
+export type TokenMintExtensionData = {
+ program: 'spl-token-2022';
+ parsed: {
+ type: 'mint';
+ info: {
+ extensions: ExtensionRecord[];
+ };
+ };
+};
+
export type ParsedData =
| UpgradeableLoaderAccountData
| StakeProgramData
@@ -105,7 +116,8 @@ export type ParsedData =
| NonceProgramData
| SysvarProgramData
| ConfigProgramData
- | AddressLookupTableProgramData;
+ | AddressLookupTableProgramData
+ | TokenMintExtensionData;
export interface AccountData {
parsed?: ParsedData;
diff --git a/app/providers/accounts/metadata-extension.tsx b/app/providers/accounts/metadata-extension.tsx
new file mode 100644
index 00000000..5304a87e
--- /dev/null
+++ b/app/providers/accounts/metadata-extension.tsx
@@ -0,0 +1,44 @@
+import { base64 } from '@project-serum/anchor/dist/cjs/utils/bytes';
+import { createEmitInstruction, TokenMetadata, unpack as deserializeTokenMetadata } from '@solana/spl-token-metadata';
+import { useConnection } from '@solana/wallet-adapter-react';
+import { MessageV0, PublicKey, VersionedTransaction } from '@solana/web3.js';
+import { useEffect, useState } from 'react';
+
+export function useTokenMetadataExtension(programId: PublicKey | undefined, metadataPointer: PublicKey | undefined) {
+ const { connection } = useConnection();
+ const [tokenMetadata, setTokenMetadata] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ async function fetchTokenMetadata() {
+ if (!programId || !metadataPointer) {
+ return;
+ }
+ const ix = createEmitInstruction({ metadata: metadataPointer, programId });
+ const message = MessageV0.compile({
+ instructions: [ix],
+ payerKey: new PublicKey('86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY'),
+ recentBlockhash: (await connection.getLatestBlockhashAndContext()).value.blockhash,
+ });
+
+ const tx = new VersionedTransaction(message);
+ const result = await connection.simulateTransaction(tx, {
+ commitment: 'confirmed',
+ replaceRecentBlockhash: true,
+ sigVerify: false,
+ });
+
+ if (result.value.returnData) {
+ const buffer = base64.decode(result.value.returnData.data[0]);
+ console.log('Inner found metadata, setting');
+ setTokenMetadata(deserializeTokenMetadata(buffer));
+ }
+
+ setLoading(false);
+ }
+
+ fetchTokenMetadata();
+ }, [connection, programId, metadataPointer]);
+
+ return loading ? null : tokenMetadata;
+}
diff --git a/app/providers/accounts/utils/isT22NFT.ts b/app/providers/accounts/utils/isT22NFT.ts
new file mode 100644
index 00000000..80f667ee
--- /dev/null
+++ b/app/providers/accounts/utils/isT22NFT.ts
@@ -0,0 +1,10 @@
+import { ParsedData, TokenMintExtensionData } from '..';
+
+export default function isT22NFT(parsedData?: ParsedData): parsedData is TokenMintExtensionData {
+ return (
+ parsedData &&
+ parsedData.parsed.info &&
+ parsedData.parsed.info.extensions &&
+ (parsedData.parsed.info.extensions as Record[]).find(ext => ext.extension === 'metadataPointer')
+ );
+}
|