简介
本文暂未未经过精细处理 本人手稿 先发布下 日后整理
对于NFT开发来说,一般遵守metaplex规范,我回顾下上架大概设计状态的流程
1: 先创建一个metaDataAccount账户
2: 基于metadata再创建token(nft)
3: metadata publickey就是nft通用的key
4: MasterEdition是追加上去的,里面包含maxSupply
下面数据是我们做pu on slae时候用得到的一些获取数据方式,官方mateplex代码不太行,是全网爬取 数据很慢的,下面是针对性上架需要的数据获取方式。
获取metadata数据
const account = await connection.getAccountInfo(
new PublicKey('FgErmGp6ZR9G72rUZhRPK7gJTzwPttq85zk9haDsefFT'),
);
console.log(decodeMetadata(account.data));
nft地址mint
获取master edition数据
Solana-web3库有点bug,无法直接获取json类型的数据,顾不得已使用下面方式,之后我会给web3提pr的。
const masterEditionAccount = await connection.getAccountInfo(
new PublicKey('JBRtQ3BabStLi1dJsGpmfwQTQEFvi4ZmRkJ2pNNzj8xu'),
);
if (masterEditionAccount) {
console.log('master edtion');
console.log(
decodeMasterEdition(masterEditionAccount.data),
masterEditionAccount,
);
}
使用metaDataAccount publickey 获取 master edition
export const getAccountInfo = (publicKey: string) => {
return axios.post(ENDPOINTS[0].endpoint, {
method: 'getAccountInfo',
jsonrpc: '2.0',
params: [publicKey, { encoding: 'jsonParsed' }],
// TODO
id: '5b5044f3-b12b-4904-8d79-a2affae6247b',
});
};
export const accountGetMasterEditionInfo = async ({publicKey, connection}: {publicKey: string, connection: Connection}) => {
const account = await connection.getAccountInfo(
new PublicKey(publicKey),
'confirmed',
);
if (account && account?.data) {
const nftInfo = await getAccountInfo(decodeMetadata(account.data).mint);
const masterKey: string =
nftInfo.data?.result.value.data.parsed.info.mintAuthority;
if (masterKey) {
const masterEditionAccount = await connection.getAccountInfo(
new PublicKey(masterKey),
);
if (masterEditionAccount) {
const masterEditionAccountData = decodeMasterEdition(
masterEditionAccount.data,
);
return {
masterEditionAccountData,
masterEditionAccount
}
}
}
}
}
exp
const masterEdition = await accountGetMasterEditionInfo({
publicKey: 'FgErmGp6ZR9G72rUZhRPK7gJTzwPttq85zk9haDsefFT',
connection,
});
console.log('---masterEdition-----> ', masterEdition);
MasterEdition 方式2
这里主要是优化速度,获取masterEdition地址是可以通过计算得到的,代码如下
export const getMasterEdition = async (mint: PublicKey): Promise<PublicKey> => {
return (
await PublicKey.findProgramAddress(
[
Buffer.from('metadata'),
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mint.toBuffer(),
Buffer.from('edition'),
],
TOKEN_METADATA_PROGRAM_ID,
)
)[0];
};
export const accountGetMasterEditionInfo = async ({
publicKey,
connection,
}: {
publicKey: string;
connection: Connection;
}) => {
const account = await connection.getAccountInfo(
new PublicKey(publicKey),
'confirmed',
);
if (account && account?.data) {
const masterKey = (
await getMasterEdition(new PublicKey(decodeMetadata(account.data).mint))
).toBase58();
if (masterKey) {
const masterEditionAccount = await connection.getAccountInfo(
new PublicKey(masterKey),
);
if (masterEditionAccount) {
const masterEditionAccountData = decodeMasterEdition(
masterEditionAccount.data,
);
// cache
localforage.setItem(
getDbTableStoreName(DB_TABLES.masterEditions, masterKey),
JSON.stringify(masterEditionAccountData),
);
return {
masterEditionAccountData,
masterEditionAccount,
masterKey,
};
}
}
}
};
edition
获取地址
export const accountGetEditionInfo = async ({
parentPubkey,
connection,
}: {
parentPubkey: string;
connection: Connection;
}) => {
const res = await getProgramAccounts(connection, METADATA_PROGRAM_ID, {
filters: [
{
memcmp: {
offset: 0,
bytes: base58.encode(new Uint8Array([MetadataKey.EditionV1])),
},
},
{
memcmp: {
offset: 1,
bytes: parentPubkey,
},
},
],
});
return res;
}
获取具体数据
creator
export const getCreators = async ({
connection,
}: {
connection: Connection;
}) => {
const _creators = await getProgramAccounts(connection, METAPLEX_ID, {
filters: [
{
dataSize: MAX_WHITELISTED_CREATOR_SIZE,
},
],
});
let creators: {
address: string;
account: ParsedAccount<WhitelistedCreator>;
}[] = [];
for (const creator of _creators) {
await processMetaplexAccounts(
creator,
(key, address, account) => {
creators.push({ address, account });
},
false,
);
}
return creators;
};
const creators = (await getCreators({ connection })).map(e => {
return {
...e,
accountData: decodeWhitelistedCreator(e.account.account.data),
};
});
console.log('---creators---');
console.log(creators);
这一块数据建议放redux里面,用的地方蛮多的,比如put on sale和admin都需要用。
const storeWhiteCreators = useSelector(
(state: RootState) => state.user.storeWhiteCreators,
);
console.log('storeWhiteCreators----->', storeWhiteCreators);