Skip to content

Commit

Permalink
Add update candy machine
Browse files Browse the repository at this point in the history
  • Loading branch information
mordonez-me committed Jun 8, 2023
1 parent 2551d3d commit c587cab
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 5 deletions.
Binary file modified .DS_Store
Binary file not shown.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ distribution_list.txt
*.jpg
yarn.lock
*.success
*.error
*.error
*.json
6 changes: 5 additions & 1 deletion args/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import commandLineUsage from 'command-line-usage'
import commandLineArgs from 'command-line-args'
import runCreateCollection from './create'
import runCreateCandyMachine from './candy-machine'
import runUpdateCandyMachine from './update-candy-machine'
import runAirdrop from './airdrop'
import _ from 'lodash'

Expand Down Expand Up @@ -37,9 +38,10 @@ const argv = mainOptions._unknown || []

const CREATE_COLLECTION = 'create-collection'
const CREATE_CANDY_MACHINE = 'create-candy-machine'
const UPDATE_CANDY_MACHINE = 'update-candy-machine'
const AIRDROP = 'airdrop'

const allowedCommands = [CREATE_CANDY_MACHINE, CREATE_COLLECTION, AIRDROP]
const allowedCommands = [CREATE_CANDY_MACHINE, UPDATE_CANDY_MACHINE, CREATE_COLLECTION, AIRDROP]

const commandDetected = _.filter(_.map(
allowedCommands, command => mainOptions.command == command
Expand All @@ -54,6 +56,8 @@ if (mainOptions.command === CREATE_COLLECTION) {
runCreateCollection(argv)
} else if (mainOptions.command === CREATE_CANDY_MACHINE) {
runCreateCandyMachine(argv)
} else if (mainOptions.command === UPDATE_CANDY_MACHINE) {
runUpdateCandyMachine(argv)
} else if (mainOptions.command === AIRDROP) {
runAirdrop(argv)
}
118 changes: 118 additions & 0 deletions args/update-candy-machine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import commandLineUsage from 'command-line-usage'
import commandLineArgs from 'command-line-args'
import { checkRequiredKeys, clusterCommandLine, convertOptionsToCamelCase, privateKeyCommandLine, validateFilesExistenceFromKeys } from './utils'
import _ from 'lodash'
import chalk from 'chalk'
import { UpdateCandyMachineParams, init } from '../src/update-candy-machine'

export default (argv: any) => {
const createCollectionOptionList = [
privateKeyCommandLine,
clusterCommandLine,
{
name: 'candy-machine-address',
alias: 'm',
type: String,
description: 'Candy nacgube address.',
typeLabel: '{underline string}',
group: 'required'
},
{
name: 'collection-address',
alias: 'a',
type: String,
description: 'Collection address.',
typeLabel: '{underline string}',
group: 'required'
},
{
name: 'quantity',
alias: 'q',
type: Number,
description: 'Quantity of items in the candy machine (items to be minted).',
typeLabel: '{underline number}',
group: 'required'
},
{
name: 'item-name',
alias: 'n',
type: String,
description: 'Name for the NFT to mint (uses autoincrement automatically).',
typeLabel: '{underline string}',
group: 'required'
},
{
name: 'image-path',
alias: 'P',
type: String,
description: 'NFT image path',
typeLabel: '{underline file}',
group: 'required'
},
{
name: 'image-name',
alias: 'N',
type: String,
defaultValue: '',
description: 'NFT image name. Defaults to \'\'',
typeLabel: '{underline string}'
},
{
name: 'image-description',
alias: 'D',
type: String,
defaultValue: '',
description: 'NFT image description. Defaults to \'\'',
typeLabel: '{underline string}'
},
{
name: 'attributes',
alias: 'A',
type: String,
defaultValue: '',
description: 'NFT attributes with json format. Defaults to null',
typeLabel: '{underline string}'
},
]
const createCollectionOptions = commandLineArgs(createCollectionOptionList, { argv })

const createCollectionDefinitions = [
{
header: 'NFT Candy Machine for POAPs',
content: 'Updates a candy machine.'
},
{
header: 'Required options',
optionList: createCollectionOptionList,
group: ['required']
},
{
header: 'Optional (with default values)',
optionList: createCollectionOptionList,
group: ['_none']
}
]

const requiredKeysPresent = checkRequiredKeys(createCollectionOptionList, createCollectionOptions.required)

if (!requiredKeysPresent) {
console.log(commandLineUsage(createCollectionDefinitions))
} else {

const filesExistResult = validateFilesExistenceFromKeys(
['private-key', 'image-path'],
createCollectionOptions._all
)

if (filesExistResult.length > 0) {
_.forEach(filesExistResult, x => {
console.log(chalk.red(chalk.bold(`ERROR ====> ${x}`)))
})
return
}

const data = convertOptionsToCamelCase(createCollectionOptions._all)

init(data as UpdateCandyMachineParams)
}
}
5 changes: 2 additions & 3 deletions src/candy-machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ const createCandyMachine = async (metaplex: Metaplex, keypair: Keypair, collecti
updateAuthority: keypair
},
authority: keypair,
price: sol(0)
price: sol(0),
// guards: {
// startDate: { date: toDateTime(startDate) },
// endDate: { date: toDateTime(endDate) },
// mintLimit: { id: 1, limit: 5 },
// }
};
const { candyMachine } = await metaplex.candyMachines().create(candyMachineSettings, { commitment: 'finalized' });
Expand Down
111 changes: 111 additions & 0 deletions src/update-candy-machine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { CandyMachine, CandyMachineConfigLineSettings, DefaultCandyGuardMintSettings, Metaplex, PublicKey, sol, toBigNumber } from "@metaplex-foundation/js";
import { nameLength, prefixUri, prefixUriLength } from "../settings"
import { getKeypair, initializeMetaplex, uploadMetadata } from "./utils"
import { Keypair } from "@solana/web3.js";
import chalk from "chalk";

const fs = require('fs')

const updateCandyMachine = async (metaplex: Metaplex, keypair: Keypair, collectionMintPubkey: PublicKey, candyMachine: CandyMachine, itemName: string, quantity: number) => {
const itemSettings: CandyMachineConfigLineSettings = {
type: 'configLines',
prefixName: itemName + ' #$ID+1$',
nameLength: nameLength,
prefixUri: prefixUri,
uriLength: prefixUriLength,
isSequential: true,
}
const candyMachineSettings =
{
candyMachine: candyMachine,
itemsAvailable: toBigNumber(quantity),
itemSettings,
sellerFeeBasisPoints: 0,
maxEditionSupply: toBigNumber(0),
isMutable: true,
creators: [
{ address: keypair.publicKey, share: 100, verified: true },
],
collection: {
address: collectionMintPubkey,
updateAuthority: keypair
},
authority: keypair,
price: sol(0),
// guards: {
// mintLimit: { id: 1, limit: 5 },
// }
};

const updateCandyMachineOutput = await metaplex.candyMachines().update(candyMachineSettings, { commitment: 'finalized' });
return updateCandyMachineOutput.response.signature
}

const addNFTItems = async (metaplex: Metaplex, candyMachinePubkey: PublicKey, uri: string, quantity: number) => {
const candyMachine = await metaplex
.candyMachines()
.findByAddress({ address: candyMachinePubkey });
const piecesUri = uri.split('/')
const uriId = piecesUri[piecesUri.length - 1]
const items: any[] = [];
for (let i = 0; i < quantity; i++) {
items.push({
name: '',
index: i,
uri: uriId
})
}
const { response } = await metaplex.candyMachines().insertItems({
candyMachine,
items: items,
}, { commitment: 'finalized' });

// console.log(`✅ - Items added to Candy Machine: ${candyMachinePubkey.toBase58()}`);
// console.log(` https://explorer.solana.com/tx/${response.signature}`);

}

export interface UpdateCandyMachineParams {
privateKey: string;
cluster: string;
collectionAddress: string;
candyMachineAddress: string;
quantity: number;
itemName: string;
imagePath: string;
imageName: string;
imageDescription: string;
attributes?: string;
}


export const init = async (params: UpdateCandyMachineParams) => {
const { privateKey, cluster, collectionAddress, candyMachineAddress, quantity, itemName, imagePath, imageName, imageDescription, attributes } = params

const keypair = getKeypair(privateKey)
const metaplex = initializeMetaplex(cluster, keypair)

const candyMachineAddressPublicKey = new PublicKey(candyMachineAddress)

const candyMachine = await metaplex
.candyMachines()
.findByAddress({ address: candyMachineAddressPublicKey });


candyMachine

await updateCandyMachine(
metaplex, keypair, new PublicKey(collectionAddress), candyMachine, itemName, quantity)

const uriImage = await uploadMetadata(
metaplex,
fs.readFileSync(imagePath),
imageName,
imageDescription,
attributes ? JSON.parse(attributes) : []
)
await addNFTItems(metaplex, candyMachineAddressPublicKey, uriImage, quantity)

console.log('✅ - ' + chalk.green(`Candy Machine Address: ${candyMachineAddress}`));
console.log('✅ - ' + chalk.green(`Candy Machine Address: ${candyMachineAddressPublicKey.toBase58()}`));
}

0 comments on commit c587cab

Please sign in to comment.