Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
jpbogle committed Apr 12, 2022
1 parent 4462867 commit aec6bf2
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 94 deletions.
1 change: 0 additions & 1 deletion actions/install-anchor/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ runs:
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
./target/
key: cargo-${{ runner.os }}-anchor-${{ hashFiles('**/Cargo.lock') }}
- name: Install anchor
if: steps.cache-anchor.outputs.cache-hit != 'true'
Expand Down
47 changes: 24 additions & 23 deletions api/common/tokenData.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
import {
AccountInfo,
ParsedAccountData,
PublicKey,
Connection,
} from "@solana/web3.js";
import * as anchor from "@project-serum/anchor";
import * as metaplex from "@metaplex-foundation/mpl-token-metadata";
import { findTokenManagerAddress } from "@cardinal/token-manager/dist/cjs/programs/tokenManager/pda";
import type { CertificateData } from "@cardinal/certificates";
import { certificateIdForMint, getCertificate } from "@cardinal/certificates";
import type { AccountData } from "@cardinal/token-manager";
import {
timeInvalidator,
tokenManager,
useInvalidator,
} from "@cardinal/token-manager/dist/cjs/programs";
import type { TimeInvalidatorData } from "@cardinal/token-manager/dist/cjs/programs/timeInvalidator";
import type { TokenManagerData } from "@cardinal/token-manager/dist/cjs/programs/tokenManager";
import { findTokenManagerAddress } from "@cardinal/token-manager/dist/cjs/programs/tokenManager/pda";
import type { UseInvalidatorData } from "@cardinal/token-manager/dist/cjs/programs/useInvalidator";
import * as metaplex from "@metaplex-foundation/mpl-token-metadata";
import * as anchor from "@project-serum/anchor";
import type {
AccountInfo,
Connection,
ParsedAccountData,
} from "@solana/web3.js";
import { PublicKey } from "@solana/web3.js";
import fetch from "node-fetch";
import { AccountData } from "@cardinal/token-manager";
import { TokenManagerData } from "@cardinal/token-manager/dist/cjs/programs/tokenManager";
import { TimeInvalidatorData } from "@cardinal/token-manager/dist/cjs/programs/timeInvalidator";
import { UseInvalidatorData } from "@cardinal/token-manager/dist/cjs/programs/useInvalidator";
import {
CertificateData,
certificateIdForMint,
getCertificate,
} from "@cardinal/certificates";

import type { NFTMetadata } from "../metadata-generator/generator";

export type TokenData = {
tokenAccount?: {
Expand All @@ -33,13 +32,13 @@ export type TokenData = {
useInvalidatorData?: AccountData<UseInvalidatorData> | null;
timeInvalidatorData?: AccountData<TimeInvalidatorData> | null;
certificateData?: AccountData<CertificateData> | null;
metadata?: any | null;
metadata?: { pubkey: PublicKey; data: NFTMetadata } | null;
};

export async function getTokenData(
connection: Connection,
mintId: PublicKey,
getMetadata: boolean = false
getMetadata = false
): Promise<TokenData> {
const [[metaplexId], [tokenManagerId], [certificateId]] = await Promise.all([
PublicKey.findProgramAddress(
Expand Down Expand Up @@ -94,16 +93,18 @@ export async function getTokenData(
}),
]);

let metadata: any | null = null;
let metadata: { pubkey: PublicKey; data: NFTMetadata } | null = null;
if (
metaplexData &&
getMetadata &&
!metaplexData.data.data.uri.includes("cardinal")
) {
try {
const json = await fetch(metaplexData.data.data.uri).then((r) =>
const uri = metaplexData.data.data.uri;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
const json = (await fetch(uri).then((r: Response) =>
r.json()
);
)) as NFTMetadata;
metadata = { pubkey: metaplexData.pubkey, data: json };
} catch (e) {
console.log("Failed to get metadata data", e);
Expand Down
5 changes: 3 additions & 2 deletions api/common/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Keypair, Connection, PublicKey } from "@solana/web3.js";
import { TOKEN_PROGRAM_ID, Token } from "@solana/spl-token";
import { Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";
import type { Connection } from "@solana/web3.js";
import { Keypair, PublicKey } from "@solana/web3.js";

export const getOwner = async (connection: Connection, mintId: string) => {
const mint = new PublicKey(mintId);
Expand Down
6 changes: 4 additions & 2 deletions api/metadata-generator/expired.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { NFTMetadata } from "./generator";

const burnURL = (cluster: string) => {
if (cluster === "devnet") {
return "https://dev.cardinal.so/burn";
}
return "https://main.cardinal.so/burn";
};

export const getExpiredMetadata = (cluster: string) => {
export const getExpiredMetadata = (cluster: string): NFTMetadata => {
const imageUrl = `https://api.cardinal.so/img/?text=EXPIRED`;
return {
name: "EXPIRED",
Expand All @@ -15,7 +17,7 @@ export const getExpiredMetadata = (cluster: string) => {
)}`,
seller_fee_basis_points: 0,
external_url: burnURL(cluster),
attributes: {},
attributes: [],
collection: {
name: "Expired Receipts",
family: "Expired Receipts",
Expand Down
151 changes: 87 additions & 64 deletions api/metadata-generator/generator.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unsafe-assignment*/
import * as namespaces from "@cardinal/namespaces";
import * as web3 from "@solana/web3.js";
import fetch from "node-fetch";
import { getTwitterMetadata } from "./twitter";
import { connectionFor, secondaryConnectionFor } from "../common/connection";
import { getOwner } from "../common/utils";
import { getTokenData, TokenData } from "../common/tokenData";
import {
InvalidationType,
TokenManagerState,
} from "@cardinal/token-manager/dist/cjs/programs/tokenManager";
import { getExpiredMetadata } from "./expired";
import type { Idl } from "@project-serum/anchor";
import { BorshAccountsCoder } from "@project-serum/anchor";
import * as web3 from "@solana/web3.js";
import fetch from "node-fetch";

import { connectionFor, secondaryConnectionFor } from "../common/connection";
import type { TokenData } from "../common/tokenData";
import { getTokenData } from "../common/tokenData";
import { getOwner } from "../common/utils";
import { getExpiredMetadata } from "./expired";
import { getTwitterMetadata } from "./twitter";

export type NFTMetadata = {
name?: string;
symbol?: string;
description?: string;
seller_fee_basis_points?: number;
external_url?: string;
attributes?: any[];
collection?: any;
properties?: any;
image?: string;
};

export async function getMetadata(
mintId: string,
Expand All @@ -19,7 +38,7 @@ export async function getMetadata(
imgParam: string,
attrs: string,
cluster: string
) {
): Promise<NFTMetadata> {
console.log(
`Getting metadata for mintId (${mintId}) uri (${metadataUri}) textParam (${textParam}) imgParam (${imgParam}) cluster (${cluster})`
);
Expand Down Expand Up @@ -68,8 +87,9 @@ export async function getMetadata(
new web3.PublicKey(address)
);
const programId = accountInfo?.owner!;
const IDL = await import(`../idls/${programId.toString()}.json`);
// `a` is imported and can be used here
const IDL = (await import(
`../idls/${programId.toString()}.json`
)) as Idl;
const coder = new BorshAccountsCoder(IDL);
const accountData = coder.decode(accountType, accountInfo?.data!);
const fields =
Expand All @@ -86,7 +106,7 @@ export async function getMetadata(
}
});
} catch (e) {
console.log("Failed to parse attribute: ", attributeConfigs[i], e);
console.log("Failed to parse attribute: ", attributeConfigs, e);
}
// }
} catch (e) {
Expand All @@ -100,7 +120,7 @@ export async function getMetadata(
originalTokenData = await getTokenData(connection, originalMint, true);
} catch (e) {
console.log(
`Error fetching metaplex metadata for original mint (${originalMint})`,
`Error fetching metaplex metadata for original mint (${originalMint.toString()})`,
e
);
}
Expand All @@ -110,7 +130,7 @@ export async function getMetadata(
originalTokenData?.metaplexData?.data.data.name ||
tokenData?.metaplexData?.data.data.name ||
textParam;
const [namespace, entryName] = namespaces.breakName(
const [namespace, _entryName] = namespaces.breakName(
fullName || textParam || ""
);
console.log(tokenData);
Expand All @@ -119,14 +139,15 @@ export async function getMetadata(
return getTwitterMetadata(fullName, mintId, owner.toString(), cluster);
}

let response: { attributes?: any; collection?: any; description?: string } = {
attributes: {},
let response: NFTMetadata = {
attributes: [],
};
if (originalTokenData?.metadata || metadataUri || tokenData.metadata) {
let metadata = originalTokenData?.metadata?.data || tokenData.metadata.data;
let metadata =
originalTokenData?.metadata?.data || tokenData.metadata?.data;
if (!metadata) {
try {
metadata = await fetch(metadataUri, {}).then((r) => r.json());
metadata = await fetch(metadataUri, {}).then((r: Response) => r.json());
} catch (e) {
console.log("Failed to get metadata URI");
}
Expand All @@ -147,9 +168,11 @@ export async function getMetadata(
response = {
...response,
...metadata,
image: `https://api.cardinal.so/img/${mintId}?uri=${metadata.image}${
textParam ? `&text=${textParam}` : ""
}${cluster ? `&cluster=${cluster}` : ""}`,
image: `https://api.cardinal.so/img/${mintId}?uri=${
metadata?.image || ""
}${textParam ? `&text=${textParam}` : ""}${
cluster ? `&cluster=${cluster}` : ""
}`,
};
}
}
Expand All @@ -158,7 +181,7 @@ export async function getMetadata(
response = {
...response,
attributes: [
...response.attributes,
...(response.attributes || []),
{
trait_type: "state",
value:
Expand All @@ -173,13 +196,13 @@ export async function getMetadata(
}

if (
tokenData.tokenManagerData?.parsed.invalidationType ==
tokenData.tokenManagerData?.parsed.invalidationType ===
InvalidationType.Return
) {
response = {
...response,
attributes: [
...response.attributes,
...(response.attributes || []),
{
trait_type: "type",
value: "RENTAL",
Expand All @@ -193,12 +216,12 @@ export async function getMetadata(
response = {
...response,
attributes: [
...response.attributes,
...(response.attributes || []),
{
trait_type: "used",
value: `(${tokenData.useInvalidatorData?.parsed.usages}${
value: `(${tokenData.useInvalidatorData?.parsed.usages.toNumber()}${
tokenData.useInvalidatorData?.parsed.maxUsages
? `/${tokenData.useInvalidatorData?.parsed.maxUsages}`
? `/${tokenData.useInvalidatorData?.parsed.maxUsages.toNumber()}`
: ""
})`,
display_type: "Used",
Expand All @@ -211,50 +234,50 @@ export async function getMetadata(
response = {
...response,
attributes: [
...response.attributes,
...(response.attributes || []),
{
trait_type: "expiration",
value: `${tokenData.timeInvalidatorData?.parsed.expiration}`,
value: `${tokenData.timeInvalidatorData?.parsed.expiration.toNumber()}`,
display_type: "Expiration",
},
],
};
}

// certificate
if (
tokenData.certificateData?.parsed.usages &&
tokenData.certificateData?.parsed.maxUsages
) {
response = {
...response,
attributes: [
...response.attributes,
{
trait_type: "used",
value: `(${tokenData.certificateData?.parsed.usages}${
tokenData.certificateData?.parsed.maxUsages
? `/${tokenData.certificateData?.parsed.maxUsages}`
: ""
})`,
display_type: "Used",
},
],
};
}
if (tokenData.certificateData?.parsed.expiration) {
response = {
...response,
attributes: [
...response.attributes,
{
trait_type: "expiration",
value: `${tokenData.certificateData?.parsed.expiration}`,
display_type: "Expiration",
},
],
};
}
// // certificate
// if (
// tokenData.certificateData?.parsed.usages &&
// tokenData.certificateData?.parsed.maxUsages
// ) {
// response = {
// ...response,
// attributes: [
// ...(response.attributes || []),
// {
// trait_type: "used",
// value: `(${tokenData.certificateData?.parsed.usages.toNumber()}${
// tokenData.certificateData?.parsed.maxUsages
// ? `/${tokenData.certificateData?.parsed.maxUsages.toNumber()}`
// : ""
// })`,
// display_type: "Used",
// },
// ],
// };
// }
// if (tokenData.certificateData?.parsed.expiration) {
// response = {
// ...response,
// attributes: [
// ...(response.attributes || []),
// {
// trait_type: "expiration",
// value: `${tokenData.certificateData?.parsed.expiration.toNumber()}`,
// display_type: "Expiration",
// },
// ],
// };
// }

// collection
if (tokenData?.metaplexData?.data.data.symbol === "$JAMB") {
Expand All @@ -265,7 +288,7 @@ export async function getMetadata(
family: "Jambomambo",
},
description:
textParam == "TRAINING"
textParam === "TRAINING"
? "This Origin Jambo is out training in Jambo Camp!"
: "This Origin Jambo is out hunting for loot around Jambo Camp!",
};
Expand All @@ -285,7 +308,7 @@ export async function getMetadata(
if (dynamicAttributes) {
response = {
...response,
attributes: [...response.attributes, ...dynamicAttributes],
attributes: [...(response.attributes || []), ...dynamicAttributes],
};
}

Expand Down
Loading

0 comments on commit aec6bf2

Please sign in to comment.