Skip to content

Commit 99f692f

Browse files
authored
Merge pull request #51 from metaplex-foundation/fix/cm-add-config-lines
Fix/cm add config lines
2 parents 52ae33f + aef9d18 commit 99f692f

File tree

5 files changed

+55
-36
lines changed

5 files changed

+55
-36
lines changed

asset-cache.json

Lines changed: 0 additions & 22 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@metaplex-foundation/cli",
33
"description": "Metaplex CLI",
4-
"version": "0.0.7",
4+
"version": "0.0.8",
55
"author": "Metaplex <[email protected]>",
66
"bin": {
77
"mplx": "./bin/run.js"

src/commands/cm/fetch.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import { fetchCandyGuard, fetchCandyMachine, findCandyGuardPda } from '@metaplex-foundation/mpl-core-candy-machine'
1+
import { CandyGuard, fetchCandyGuard, fetchCandyMachine } from '@metaplex-foundation/mpl-core-candy-machine'
22
import { publicKey } from '@metaplex-foundation/umi'
33
import { Args, Flags } from '@oclif/core'
4-
import fs from 'node:fs'
5-
import path from 'node:path'
4+
import { readCmConfig } from '../../lib/cm/cm-utils.js'
65
import { jsonStringify } from '../../lib/util.js'
76
import { TransactionCommand } from '../../TransactionCommand.js'
8-
import { readCmConfig } from '../../lib/cm/cm-utils.js'
97

108
export default class CmFetch extends TransactionCommand<typeof CmFetch> {
119
static override description = `Fetch candy machine and guard data from the blockchain`
1210

1311
static override examples = [
1412
'$ mplx cm fetch',
1513
'$ mplx cm fetch <address>',
14+
'$ mplx cm fetch --items',
15+
'$ mplx cm fetch <address> --items',
1616
]
1717

1818
static override usage = 'cm fetch [FLAGS] [ARGS]'
@@ -47,12 +47,33 @@ export default class CmFetch extends TransactionCommand<typeof CmFetch> {
4747
this.error('No address provided and no config file found with candy machine address');
4848
}
4949

50+
51+
let candyGuard: CandyGuard | undefined = undefined;
52+
let authorityOnlyMinting: boolean = false;
53+
5054
const { items, ...candyMachine } = await fetchCandyMachine(umi, publicKey(address));
51-
const candyGuardPda = findCandyGuardPda(umi, { base: candyMachine.publicKey });
52-
const candyGuard = await fetchCandyGuard(umi, candyGuardPda);
55+
const mintAuthority = candyMachine.mintAuthority;
56+
if (mintAuthority === candyMachine.authority) {
57+
authorityOnlyMinting = true;
58+
} else {
59+
this.log(`Checking if mint authority is a Candy Guard...`);
60+
candyGuard = await fetchCandyGuard(umi, candyMachine.mintAuthority)
61+
.then(guard => guard)
62+
.catch(error => {
63+
this.log(`Failed to fetch candy guard: ${error instanceof Error ? error.message : String(error)}`);
64+
this.log(`The mint authority address ${candyMachine.mintAuthority} doesn't appear to be a valid candy guard, may be a custom program`);
65+
return undefined;
66+
});
67+
}
5368

5469
this.log(jsonStringify(candyMachine, 2));
55-
this.log(jsonStringify(candyGuard, 2));
70+
if (candyGuard) {
71+
this.log(jsonStringify(candyGuard, 2));
72+
} else if (authorityOnlyMinting) {
73+
this.log(`No candy guard - using authority-only minting`);
74+
} else {
75+
this.log(`No candy guard found - mint authority may be a custom program`);
76+
}
5677

5778
if (flags.items) {
5879
this.log(jsonStringify(items, 2));

src/commands/toolbox/token/create.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
import { Flags } from '@oclif/core'
21
import { createFungible } from '@metaplex-foundation/mpl-token-metadata'
32
import { createTokenIfMissing, findAssociatedTokenPda, mintTokensTo } from '@metaplex-foundation/mpl-toolbox'
43
import { generateSigner, percentAmount, Umi } from '@metaplex-foundation/umi'
5-
import { base58 } from '@metaplex-foundation/umi/serializers'
4+
import { Flags } from '@oclif/core'
65
import ora from 'ora'
76
import { TransactionCommand } from '../../../TransactionCommand.js'
87
import { ExplorerType, generateExplorerUrl } from '../../../explorers.js'
98
import umiSendAndConfirmTransaction from '../../../lib/umi/sendAndConfirm.js'
109
import imageUploader from '../../../lib/uploader/imageUploader.js'
1110
import uploadJson from '../../../lib/uploader/uploadJson.js'
11+
import { RpcChain, txSignatureToString } from '../../../lib/util.js'
1212
import { validateMintAmount, validateTokenName, validateTokenSymbol } from '../../../lib/validations.js'
1313
import createTokenPrompt from '../../../prompts/createTokenPrompt.js'
14-
import { RpcChain, txSignatureToString } from '../../../lib/util.js'
1514

1615
/*
1716
Create Possibilities:

src/lib/cm/insertItems.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ const insertItems = async (umi: Umi, candyMachineConfig: CandyMachineConfig, ass
5757
let maxNameLength = 0
5858

5959
for (const item of Object.values(assetCache.assetItems)) {
60-
if (item.imageUri?.length && item.imageUri.length > maxUriLength) {
61-
maxUriLength = item.imageUri.length
60+
if (item.jsonUri?.length && item.jsonUri.length > maxUriLength) {
61+
maxUriLength = item.jsonUri.length
6262
}
6363
if (item.name && item.name.length > maxNameLength) {
6464
maxNameLength = item.name.length
@@ -106,9 +106,30 @@ const insertItems = async (umi: Umi, candyMachineConfig: CandyMachineConfig, ass
106106
}
107107

108108
// else we need to add the config lines to the transaction
109+
// Validate all items have required fields before building configLines
110+
for (let i = 0; i < configLineGroup.assetItems.length; i++) {
111+
const item = configLineGroup.assetItems[i];
112+
const itemIndex = configLineGroup.startingIndex + i;
113+
114+
if (!item.name || item.name.trim() === '') {
115+
throw new Error(
116+
`Item at index ${itemIndex} is missing required field 'name'. ` +
117+
`Item details: ${JSON.stringify({ jsonUri: item.jsonUri, imageUri: item.imageUri })}`
118+
);
119+
}
120+
121+
if (!item.jsonUri || item.jsonUri.trim() === '') {
122+
throw new Error(
123+
`Item at index ${itemIndex} is missing required field 'jsonUri'. ` +
124+
`Item details: ${JSON.stringify({ name: item.name, imageUri: item.imageUri })}`
125+
);
126+
}
127+
}
128+
129+
// Build configLines with validated values (type assertion safe after validation)
109130
const configLines = configLineGroup.assetItems.map(item => ({
110131
name: item.name,
111-
uri: item.imageUri!,
132+
uri: item.jsonUri as string,
112133
}))
113134

114135
const transaction = addConfigLines(umi, {

0 commit comments

Comments
 (0)