Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/heavy-ties-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@thirdweb-dev/solana": patch
---

Fixes for dashboard integration
3 changes: 2 additions & 1 deletion packages/solana/src/classes/deployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "../types/contracts";
import {
NFTDropConditionsOutputSchema,
NFTDropContractInput,
NFTDropMetadataInput,
} from "../types/contracts/nft-drop";
import { enforceCreator } from "./helpers/creators-helper";
Expand Down Expand Up @@ -100,7 +101,7 @@ export class Deployer {
return collectionNft.mint.address.toBase58();
}

async createNftDrop(metadata: NFTDropMetadataInput): Promise<string> {
async createNftDrop(metadata: NFTDropContractInput): Promise<string> {
const collectionInfo = NFTCollectionMetadataInputSchema.parse(metadata);
const candyMachineInfo = NFTDropConditionsOutputSchema.parse(metadata);
const uri = await this.storage.uploadMetadata(collectionInfo);
Expand Down
6 changes: 3 additions & 3 deletions packages/solana/src/classes/helpers/nft-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,17 @@ export class NFTHelper {
};
}

async balanceOf(walletAddress: string, mintAddress: string): Promise<bigint> {
async balanceOf(walletAddress: string, mintAddress: string): Promise<number> {
const address = await getAssociatedTokenAddress(
new PublicKey(mintAddress),
new PublicKey(walletAddress),
);

try {
const account = await getAccount(this.connection, address);
return account.amount;
return Number(account.amount);
} catch (e) {
return BigInt(0);
return 0;
}
}

Expand Down
14 changes: 9 additions & 5 deletions packages/solana/src/contracts/nft-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ export class NFTCollection {
return this.nft.get(mintAddress);
}

async getAll(): Promise<string[]> {
async getAll(): Promise<NFTMetadata[]> {
const addresses = await this.getAllNFTAddresses();
return await Promise.all(addresses.map((a) => this.get(a)));
}

async getAllNFTAddresses(): Promise<string[]> {
const allSignatures: ConfirmedSignatureInfo[] = [];
// This returns the first 1000, so we need to loop through until we run out of signatures to get.
let signatures = await this.metaplex.connection.getSignaturesForAddress(
Expand Down Expand Up @@ -132,12 +137,12 @@ export class NFTCollection {
return Array.from(mintAddresses);
}

async balance(mintAddress: string): Promise<bigint> {
async balance(mintAddress: string): Promise<number> {
const address = this.metaplex.identity().publicKey.toBase58();
return this.balanceOf(address, mintAddress);
}

async balanceOf(walletAddress: string, mintAddress: string): Promise<bigint> {
async balanceOf(walletAddress: string, mintAddress: string): Promise<number> {
return this.nft.balanceOf(walletAddress, mintAddress);
}

Expand Down Expand Up @@ -210,8 +215,7 @@ export class NFTCollection {
const { nft } = await this.metaplex
.nfts()
.create({
// useExistingMint: newMint,
name: metadata.name || "",
name: metadata.name?.toString() || "",
uri,
sellerFeeBasisPoints: 0,
collection: this.publicKey,
Expand Down
25 changes: 12 additions & 13 deletions packages/solana/src/contracts/nft-drop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ export class NFTDrop {
// TODO: Add pagination to get NFT functions
async getAll(): Promise<NFTMetadata[]> {
const info = await this.getCandyMachine();
const nfts = await Promise.all(
// TODO merge with getAllClaimed()
return await Promise.all(
info.items.map(async (item) => {
const metadata = await this.storage.get(item.uri);
return { uri: item.uri, ...metadata };
}),
);

return nfts;
}

async getAllClaimed(): Promise<NFTMetadata[]> {
Expand All @@ -61,29 +60,29 @@ export class NFTDrop {
.findMintedNfts({ candyMachine: this.publicKey })
.run();

const metadatas = nfts.map((nft) => this.nft.toNFTMetadata(nft));
return metadatas;
return nfts.map((nft) => this.nft.toNFTMetadata(nft));
}

async balance(mintAddress: string): Promise<bigint> {
async balance(mintAddress: string): Promise<number> {
const address = this.metaplex.identity().publicKey.toBase58();
return this.balanceOf(address, mintAddress);
}

async balanceOf(walletAddress: string, mintAddress: string): Promise<bigint> {
async balanceOf(walletAddress: string, mintAddress: string): Promise<number> {
return this.nft.balanceOf(walletAddress, mintAddress);
}

async totalUnclaimedSupply(): Promise<bigint> {
async totalUnclaimedSupply(): Promise<number> {
const info = await this.getCandyMachine();
return BigInt(
Math.min(info.itemsLoaded.toNumber(), info.itemsRemaining.toNumber()),
return Math.min(
info.itemsLoaded.toNumber(),
info.itemsRemaining.toNumber(),
);
}

async totalClaimedSupply(): Promise<bigint> {
async totalClaimedSupply(): Promise<number> {
const info = await this.getCandyMachine();
return BigInt(info.itemsMinted.toNumber());
return info.itemsMinted.toNumber();
}

async transfer(
Expand All @@ -99,7 +98,7 @@ export class NFTDrop {
);
const upload = await this.storage.uploadMetadataBatch(parsedMetadatas);
const items = upload.uris.map((uri, i) => ({
name: parsedMetadatas[i].name || "",
name: parsedMetadatas[i].name?.toString() || "",
uri,
}));

Expand Down
8 changes: 7 additions & 1 deletion packages/solana/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ import { IpfsStorage, IStorage, PinataUploader } from "@thirdweb-dev/storage";

export class ThirdwebSDK {
static fromNetwork(network: Network, storage?: IStorage): ThirdwebSDK {
return new ThirdwebSDK(new Connection(getUrlForNetwork(network)), storage);
return new ThirdwebSDK(
new Connection(getUrlForNetwork(network), {
disableRetryOnRateLimit: true,
commitment: "confirmed",
}),
storage,
);
}

private connection: Connection;
Expand Down
10 changes: 5 additions & 5 deletions packages/solana/src/types/contracts/nft-drop.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NFTCollectionMetadataInputSchema } from ".";
import { AmountSchema } from "../common";
import { sol, toBigNumber, toDateTime } from "@metaplex-foundation/js";
import { PublicKey } from "@solana/web3.js";
import { z } from "zod";
Expand All @@ -8,9 +9,9 @@ import { z } from "zod";
*/
// TODO: Handle allow lists and end times
export const NFTDropConditionsInputSchema = z.object({
itemsAvailable: AmountSchema,
price: z.number().default(0),
sellerFeeBasisPoints: z.number().default(0),
itemsAvailable: z.number().default(0),
goLiveDate: z.date().optional(),
splToken: z.string().optional(),
solTreasuryAccount: z.string().optional(),
Expand All @@ -23,10 +24,7 @@ export const NFTDropConditionsOutputSchema = z.object({
.transform((p) => sol(p))
.optional(),
sellerFeeBasisPoints: z.number().optional(),
itemsAvailable: z
.number()
.transform((bn) => toBigNumber(bn))
.optional(),
itemsAvailable: AmountSchema.transform((bn) => toBigNumber(bn)).optional(),
goLiveDate: z
.date()
.transform((d) => toDateTime(d))
Expand All @@ -48,4 +46,6 @@ export const NFTDropConditionsOutputSchema = z.object({
export const NFTDropContractInputSchema =
NFTCollectionMetadataInputSchema.merge(NFTDropConditionsInputSchema);

export type NFTDropContractInput = z.input<typeof NFTDropContractInputSchema>;

export type NFTDropMetadataInput = z.input<typeof NFTDropConditionsInputSchema>;
3 changes: 2 additions & 1 deletion packages/solana/src/types/nft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { z } from "zod";
*/
export const CommonTokenInput = z
.object({
name: z.string().optional(),
name: z.union([z.string(), z.number()]).optional(),
symbol: z.string().optional(),
description: z.string().nullable().optional(),
image: FileBufferOrStringSchema.nullable().optional(),
Expand All @@ -32,6 +32,7 @@ export const CommonNFTInput = CommonTokenInput.extend({
animation_url: FileBufferOrStringSchema.optional(),
background_color: HexColor.optional(),
properties: OptionalPropertiesInput,
attributes: OptionalPropertiesInput,
});

/**
Expand Down
21 changes: 10 additions & 11 deletions packages/solana/test/nft-collection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,32 @@ describe("NFTCollection", async () => {
it("should fetch NFTs", async () => {
const all = await collection.getAll();
expect(all.length).to.eq(1);
const single = await collection.get(all[0]);
expect(single.name).to.eq("Test NFT");
expect(all[0].name).to.eq("Test NFT");
});

it("should fetch balance of NFTs", async () => {
const all = await collection.getAll();
const balance = await collection.balanceOf(
sdk.wallet.getAddress() || "",
all[0],
all[0].id,
);
expect(balance).to.eq(1n);
expect(balance).to.eq(1);
});

it("should transfer NFTs", async () => {
const all = await collection.getAll();
const wallet = Keypair.generate();
await collection.transfer(wallet.publicKey.toBase58() || "", all[0]);
await collection.transfer(wallet.publicKey.toBase58() || "", all[0].id);
const balance = await collection.balanceOf(
wallet.publicKey.toBase58() || "",
all[0],
all[0].id,
);
expect(balance).to.eq(1n);
expect(balance).to.eq(1);
const balance2 = await collection.balanceOf(
sdk.wallet.getAddress() || "",
all[0],
all[0].id,
);
expect(balance2).to.eq(0n);
expect(balance2).to.eq(0);
});

it("should mint additional supply", async () => {
Expand All @@ -63,9 +62,9 @@ describe("NFTCollection", async () => {
});
const printed = await collection.mintAdditionalSupply(mint);
let balance = await collection.balance(mint);
expect(balance).to.equal(1n);
expect(balance).to.equal(1);
balance = await collection.balance(printed);
expect(balance).to.equal(1n);
expect(balance).to.equal(1);
});

it("test supply of", async () => {
Expand Down
14 changes: 7 additions & 7 deletions packages/solana/test/nft-drop.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe("NFTDrop", async () => {

it("should lazy mint NFTs", async () => {
let supply = await drop.totalUnclaimedSupply();
expect(supply).to.equal(0n);
expect(supply).to.equal(0);

await drop.lazyMint([
{ name: "NFT #1", description: "This is the #1 NFT" },
Expand All @@ -29,24 +29,24 @@ describe("NFTDrop", async () => {
]);

supply = await drop.totalUnclaimedSupply();
expect(supply).to.equal(5n);
expect(supply).to.equal(5);
});

it("should claim free drop", async () => {
let unclaimed = await drop.totalUnclaimedSupply();
let claimed = await drop.totalClaimedSupply();
expect(unclaimed).to.equal(5n);
expect(claimed).to.equal(0n);
expect(unclaimed).to.equal(5);
expect(claimed).to.equal(0);

const address = await drop.claim();

unclaimed = await drop.totalUnclaimedSupply();
claimed = await drop.totalClaimedSupply();
expect(unclaimed).to.equal(4n);
expect(claimed).to.equal(1n);
expect(unclaimed).to.equal(4);
expect(claimed).to.equal(1);

const balance = await drop.balance(address);
expect(balance).to.equal(1n);
expect(balance).to.equal(1);
});

it("should get all nfts", async () => {
Expand Down