Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow Master Edition max supply to be 0 #147

Merged
merged 3 commits into from
Jan 17, 2022
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
6 changes: 3 additions & 3 deletions src/actions/mintNFT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ import { sendTransaction } from './transactions';
import { lookup } from '../utils/metadata';
import { prepareTokenAccountAndMintTxs } from './shared';

interface MintNFTParams {
export interface MintNFTParams {
connection: Connection;
wallet: Wallet;
uri: string;
maxSupply?: number;
}

interface MintNFTResponse {
export interface MintNFTResponse {
txId: string;
mint: PublicKey;
metadata: PublicKey;
Expand Down Expand Up @@ -90,7 +90,7 @@ export const mintNFT = async ({
updateAuthority: wallet.publicKey,
mint: mint.publicKey,
mintAuthority: wallet.publicKey,
maxSupply: maxSupply ? new BN(maxSupply) : null,
maxSupply: maxSupply || maxSupply === 0 ? new BN(maxSupply) : null,
},
);

Expand Down
6 changes: 3 additions & 3 deletions test/actions/createMetadataAndME.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import BN from 'bn.js';
import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
import { Connection, NodeWallet } from '../../src';
import { FEE_PAYER, NETWORK, pause } from '../utils';
import { FEE_PAYER, NETWORK, sleep } from '../utils';
import {
Creator,
MasterEdition,
Expand Down Expand Up @@ -51,7 +51,7 @@ describe('creatomg metadata and master edition PDAs', () => {
metadataData,
});

await pause(20000);
await sleep(20000);

const metadata = await Metadata.getPDA(mint.publicKey);
const metadataInfo = await Account.getInfo(connection, metadata);
Expand All @@ -66,7 +66,7 @@ describe('creatomg metadata and master edition PDAs', () => {
});

// had to increase to 25s, or it was failing
await pause(25000);
await sleep(25000);

const edition = await MasterEdition.getPDA(mint.publicKey);
const editionInfo = await Account.getInfo(connection, edition);
Expand Down
4 changes: 2 additions & 2 deletions test/actions/mintEditionFromMaster.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Connection, NodeWallet } from '../../src';
import { mintNFT } from '../../src/actions';
import { FEE_PAYER, NETWORK, pause } from '../utils';
import { FEE_PAYER, NETWORK, sleep } from '../utils';
import { MasterEdition, Metadata } from '@metaplex-foundation/mpl-token-metadata';
import { mintEditionFromMaster } from '../../src/actions/mintEditionFromMaster';
import { mockAxios200, uri } from './shared';
Expand All @@ -26,7 +26,7 @@ describe('minting a limited edition from master', () => {

// unfortunately it takes some time for the master mint to propagate
// empirically, I found anything below 20s to be unreliable
await pause(20000);
await sleep(20000);

const editionMintResponse = await mintEditionFromMaster({
connection,
Expand Down
86 changes: 52 additions & 34 deletions test/actions/mintNFT.test.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,75 @@
import { Keypair } from '@solana/web3.js';
import { Connection, NodeWallet } from '../../src';
import { mintNFT } from '../../src/actions';
import { FEE_PAYER, NETWORK } from '../utils';
import { mintNFT, MintNFTParams } from '../../src/actions';
import { sleep } from '../utils';
import { MasterEdition, Metadata } from '@metaplex-foundation/mpl-token-metadata';
import { mockAxios200, mockAxios404, uri } from './shared';
import { uri, generateConnectionAndWallet, mockAxios200, mockAxios404 } from './shared';
import { airdrop } from '@metaplex-foundation/amman';

jest.mock('axios');

describe('minting an NFT', () => {
const connection = new Connection(NETWORK);
const wallet = new NodeWallet(FEE_PAYER);
let mint: Keypair;
let connection: Connection;
let wallet: NodeWallet;
let payer: Keypair;

beforeAll(() => {
jest
.spyOn(connection, 'sendRawTransaction')
.mockResolvedValue(
'64Tpr1DNj9UWg1P89Zss5Y4Mh2gGyRUMYZPNenZKY2hiNjsotrCDMBriDrsvhg5BJt3mY4hH6jcparNHCZGhAwf6',
);
});
beforeAll(async () => {
const result = await generateConnectionAndWallet();
connection = result.connection;
wallet = result.wallet;
payer = result.payer;

beforeEach(() => {
mint = Keypair.generate();
jest.spyOn(Keypair, 'generate').mockReturnValue(mint);
await airdrop(connection, payer.publicKey, 2);
});

describe('when can find metadata json', () => {
beforeEach(() => {
mockAxios200(wallet);
describe('when metadata json is found', () => {
beforeAll(async () => {
mockAxios200(wallet); // metadata json found
});

test('generates a unique mint and creates metadata plus master edition from metadata URL and max supply', async () => {
const mintResponse = await mintNFT({
connection,
wallet,
uri,
maxSupply: 0,
});
const values = [0, 3, undefined];
for (const maxSupply of values) {
describe(`when max supply is "${maxSupply}"`, () => {
test('generates a unique mint, metadata & master editions from metadata URL', async () => {
const arg: MintNFTParams = {
connection,
wallet,
uri,
};

if (maxSupply !== undefined) {
arg.maxSupply = maxSupply;
}

const mintResponse = await mintNFT(arg);
const { mint } = mintResponse;

const metadata = await Metadata.getPDA(mint.publicKey);
const edition = await MasterEdition.getPDA(mint.publicKey);
const metadata = await Metadata.getPDA(mint);
const edition = await MasterEdition.getPDA(mint);

expect(mintResponse).toMatchObject({
metadata,
edition,
mint: mint.publicKey,
expect(mintResponse).toMatchObject({
metadata,
edition,
});

await sleep(2000); // HACK

const metadataEdition = (await Metadata.getEdition(connection, mint)) as MasterEdition;
expect(metadataEdition.data?.maxSupply?.toNumber()).toBe(maxSupply);
});
});
});
}
});

describe('when metadata json not found', () => {
beforeEach(() => {
mockAxios404();

jest
.spyOn(connection, 'sendRawTransaction')
.mockResolvedValue(
'64Tpr1DNj9UWg1P89Zss5Y4Mh2gGyRUMYZPNenZKY2hiNjsotrCDMBriDrsvhg5BJt3mY4hH6jcparNHCZGhAwf6',
);
});

test('exits the action and throws an error', async () => {
Expand All @@ -63,7 +81,7 @@ describe('minting an NFT', () => {
maxSupply: 0,
});
} catch (e) {
expect(e).not.toBeNull();
expect(e.message).toMatch(/unable to get metadata/);
}
});
});
Expand Down
6 changes: 3 additions & 3 deletions test/actions/signMetadata.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Keypair } from '@solana/web3.js';
import { Connection, NodeWallet } from '../../src';
import { mintNFT } from '../../src/actions';
import { FEE_PAYER, NETWORK, pause } from '../utils';
import { FEE_PAYER, NETWORK, sleep } from '../utils';
import { Metadata } from '@metaplex-foundation/mpl-token-metadata';
import { signMetadata } from '../../src/actions/signMetadata';
import { mockAxios200, uri } from './shared';
Expand Down Expand Up @@ -30,7 +30,7 @@ describe('signing metadata on a master edition', () => {

// unfortunately it takes some time for the master mint to propagate
// empirically, I found anything below 20s to be unreliable
await pause(20000);
await sleep(20000);

// before signing
const metadata = await Metadata.getPDA(masterMintResponse.mint);
Expand All @@ -45,7 +45,7 @@ describe('signing metadata on a master edition', () => {
signer: secondSigner,
});

await pause(20000);
await sleep(20000);

//after signing
info = await Account.getInfo(connection, metadata);
Expand Down
6 changes: 3 additions & 3 deletions test/actions/updateMetadata.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Keypair } from '@solana/web3.js';
import { Connection, NodeWallet } from '../../src';
import { mintNFT } from '../../src/actions';
import { FEE_PAYER, NETWORK, pause } from '../utils';
import { FEE_PAYER, NETWORK, sleep } from '../utils';
import { Creator, Metadata, MetadataDataData } from '@metaplex-foundation/mpl-token-metadata';
import { updateMetadata } from '../../src/actions/updateMetadata';
import { mockAxios200, uri } from './shared';
Expand Down Expand Up @@ -44,7 +44,7 @@ describe('updating metadata on a master edition', () => {

// unfortunately it takes some time for the master mint to propagate
// empirically, I found anything below 20s to be unreliable
await pause(20000);
await sleep(20000);

// before update
const metadata = await Metadata.getPDA(masterMintResponse.mint);
Expand All @@ -63,7 +63,7 @@ describe('updating metadata on a master edition', () => {
primarySaleHappened: true,
});

await pause(20000);
await sleep(20000);

//after update
info = await Account.getInfo(connection, metadata);
Expand Down
6 changes: 3 additions & 3 deletions test/actions/utility/closeVault.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NATIVE_MINT } from '@solana/spl-token';
import { Vault, VaultState } from '@metaplex-foundation/mpl-token-vault';

import { pause } from '../../utils';
import { sleep } from '../../utils';
import { generateConnectionAndWallet } from '../shared';
import { closeVault, createVault, createExternalPriceAccount } from '../../../src/actions/utility';

Expand All @@ -19,7 +19,7 @@ describe('closing a Vault', () => {
...externalPriceAccountData,
});

await pause(1000);
await sleep(1000);

vault = await Vault.load(connection, vaultResponse.vault);
expect(vault).toHaveProperty('data');
Expand All @@ -32,7 +32,7 @@ describe('closing a Vault', () => {
priceMint: NATIVE_MINT,
});

await pause(1000);
await sleep(1000);

vault = await Vault.load(connection, vaultResponse.vault);
expect(vault).toHaveProperty('data');
Expand Down
4 changes: 2 additions & 2 deletions test/actions/utility/createVault.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Vault, VaultState } from '@metaplex-foundation/mpl-token-vault';

import { pause } from '../../utils';
import { sleep } from '../../utils';
import { createVault, createExternalPriceAccount } from '../../../src/actions/utility';
import { generateConnectionAndWallet } from '../shared';

Expand All @@ -17,7 +17,7 @@ describe('creating a Vault', () => {
...externalPriceAccountData,
});

await pause(1000);
await sleep(1000);
const vault = await Vault.load(connection, vaultResponse.vault);
expect(vault).toHaveProperty('data');
expect(vault.data.state).toEqual(VaultState.Inactive);
Expand Down
4 changes: 2 additions & 2 deletions test/actions/utility/initAuction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
WinnerLimitType,
} from '@metaplex-foundation/mpl-auction';

import { pause } from '../../utils';
import { sleep } from '../../utils';
import { generateConnectionAndWallet } from '../shared';
import { createExternalPriceAccount, createVault, initAuction } from '../../../src/actions/utility';

Expand Down Expand Up @@ -45,7 +45,7 @@ describe('initAuction action', () => {
auctionSettings,
});

await pause(1000);
await sleep(1000);

const auctionInstance = await Auction.load(connection, auction);

Expand Down
8 changes: 2 additions & 6 deletions test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,8 @@ export const projectRoot = path.resolve(__dirname, '..', '..');
export const tmpTestDir = path.resolve(tmpdir(), 'test');

export const serializeConfig = { verifySignatures: false, requireAllSignatures: false };
export async function pause(ms: number) {
await new Promise((response) =>
setTimeout(() => {
response(0);
}, ms),
);
export async function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

export function getUserKeypairFromFile(keypairPath) {
Expand Down