metaplex-foundation / mpl-candy-machine Goto Github PK
View Code? Open in Web Editor NEWMint your NFT collection on Solana
Home Page: https://developers.metaplex.com/candy-machine
License: Other
Mint your NFT collection on Solana
Home Page: https://developers.metaplex.com/candy-machine
License: Other
Is there a plan for rate limiting guard?
Not sure if needed , since the bot tax has been quite successful in reducing spam.
If it's needed , I can open a PR.
Plan is, having a PDA used as a mini blockchain.
As in, client reads PDA data and pass that to minting instruction.
The program will compare PDA data to client input and hash this data with a nonce from client or clock time, and update the PDA.
This means that only one can mint until the network propagates the new state and clients can pass the correct PDA info again.
Can also be expanded to store an array of size X if a higher throughput is desired.
Hello,
I'm encountering a persistent issue when trying to initialize a candy machine using the create
function provided by '@metaplex-foundation/mpl-candy-machine'. Despite ensuring that all objects (signers, public keys, etc.) are properly initialized and logged (see attached logs), I receive a TypeError indicating an undefined publicKey
.
Here are the details of my setup:
import {
mplTokenMetadata,
mplCandyMachine,
create as candyMachineCreate,
route,
getMerkleProof,
getMerkleRoot,
mintV2
} from '@metaplex-foundation/mpl-candy-machine'
useEffect(() => {
async function initializeCandyMachine() {
if (!umi) {
console.error('UMI client not initialized');
return;
}
if (!projectOwnerSigner || !projectOwnerSigner.publicKey) {
console.error('Project owner signer is not properly initialized.');
return;
}
try {
console.log('Initializing signer identity...');
umi.use(signerIdentity(projectOwnerSigner));
} catch (error) {
console.error('Error initializing signer identity:', error);
return;
}
try {
console.log('Attempting to use public keys...');
const solTreasuryPublicKey = new PublicKey(solTreasury);
const projectOwnerSignerPublicKey = new PublicKey(projectOwnerSigner.publicKey);
console.log('Treasury Public Key:', solTreasuryPublicKey.toString());
console.log('Owner Signer Public Key:', projectOwnerSignerPublicKey.toString());
console.log('Project Owner Signer:', projectOwnerSigner);
console.log('UMI Configuration:', umi);
try {
console.log('Creating Candy Machine...');
const result = await candyMachineCreate(umi, {
guards: {
botTax: some({ lamports: sol(0.05), lastInstruction: true }),
solPayment: some({ lamports: sol(0.05), destination: solTreasuryPublicKey }),
},
});
console.log("Candy Machine initialization successful", result);
setMintProgressStep(MintingStep.Success);
} catch (internalError) {
console.error("Error during Candy Machine creation:", internalError);
setMintProgressStep(MintingStep.Error);
}
} catch (error) {
console.error("Error preparing or using public keys:", error);
setMintProgressStep(MintingStep.Error);
}
}
initializeCandyMachine();
}, [umi, projectOwnerSigner]);
BUNDLE ./index.js
LOG projectOwnerSigner initialized {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}
LOG Initializing signer identity...
LOG Treasury Public Key: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
LOG Owner Signer Public Key: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
LOG Fetching balance for: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
ERROR Error during Candy Machine creation: [TypeError: Cannot read property 'publicKey' of undefined]
LOG Balance fetched: 13889948440
LOG projectOwnerSigner initialized {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}
LOG Initializing signer identity...
LOG Attempting to use public keys...
LOG Treasury Public Key: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
LOG Owner Signer Public Key: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
LOG Project Owner Signer: {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}
LOG UMI Configuration: {"downloader": {"download": [Function download], "downloadJson": [Function downloadJson]}, "eddsa": {"createKeypairFromSecretKey": [Function createKeypairFromSecretKey], "createKeypairFromSeed": [Function createKeypairFromSeed], "findPda": [Function findPda], "generateKeypair": [Function generateKeypair], "isOnCurve": [Function isOnCurve], "sign": [Function sign], "verify": [Function verify]}, "guards": {"manifests": Map {"botTax" => [Object], "solPayment" => [Object], "tokenPayment" => [Object], "startDate" => [Object], "thirdPartySigner" => [Object], "tokenGate" => [Object], "gatekeeper" => [Object], "endDate" => [Object], "allowList" => [Object], "mintLimit" => [Object], "nftPayment" => [Object], "redeemedAmount" => [Object], "addressGate" => [Object], "nftGate" => [Object], "nftBurn" => [Object], "tokenBurn" => [Object], "freezeSolPayment" => [Object], "freezeTokenPayment" => [Object], "programGate" => [Object], "allocation" => [Object], "token2022Payment" => [Object]}}, "http": {"send": [Function send]}, "identity": {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}, "payer": {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}, "programs": {"add": [Function add], "all": [Function all], "bind": [Function bind], "clone": [Function clone], "get": [Function get], "getPublicKey": [Function getPublicKey], "has": [Function has], "resolveError": [Function resolveError], "unbind": [Function unbind]}, "rpc": {"accountExists": [Function accountExists], "airdrop": [Function airdrop], "call": [Function call], "confirmTransaction": [Function confirmTransaction], "connection": {"_blockhashInfo": [Object], "_commitment": undefined, "_confirmTransactionInitialTimeout": undefined, "_disableBlockhashCaching": false, "_nextClientSubscriptionId": 0, "_pollingBlockhash": false, "_rpcBatchRequest": [Function anonymous], "_rpcClient": [ClientBrowser], "_rpcEndpoint": "https://api.devnet.solana.com", "_rpcRequest": [Function anonymous], "_rpcWebSocket": [RpcWebSocketClient], "_rpcWebSocketConnected": false, "_rpcWebSocketGeneration": 0, "_rpcWebSocketHeartbeat": null, "_rpcWebSocketIdleTimeout": null, "_rpcWsEndpoint": "wss://api.devnet.solana.com", "_subscriptionCallbacksByServerSubscriptionId": [Object], "_subscriptionDisposeFunctionsByClientSubscriptionId": [Object], "_subscriptionHashByClientSubscriptionId": [Object], "_subscriptionStateChangeCallbacksByHash": [Object], "_subscriptionsAutoDisposedByRpc": [Set], "_subscriptionsByHash": [Object], "getBlockHeight": [Function anonymous]}, "getAccount": [Function getAccount], "getAccounts": [Function getAccounts], "getBalance": [Function getBalance], "getBlockTime": [Function getBlockTime], "getCluster": [Function getCluster], "getEndpoint": [Function getEndpoint], "getLatestBlockhash": [Function getLatestBlockhash], "getProgramAccounts": [Function getProgramAccounts], "getRent": [Function getRent], "getSignatureStatuses": [Function getSignatureStatuses], "getSlot": [Function getSlot], "getTransaction": [Function getTransaction], "sendTransaction": [Function sendTransaction]}, "serializer": {"array": [Function array], "bool": [Function bool], "bytes": [Function bytes], "dataEnum": [Function dataEnum], "enum": [Function scalarEnum], "f32": [Function f32], "f64": [Function f64], "i128": [Function i128], "i16": [Function i16], "i32": [Function i32], "i64": [Function i64], "i8": [Function i8], "map": [Function map], "nullable": [Function nullable], "option": [Function option], "publicKey": [Function publicKey], "set": [Function set], "string": [Function string], "struct": [Function struct], "tuple": [Function tuple], "u128": [Function u128], "u16": [Function u16], "u32": [Function u32], "u64": [Function u64], "u8": [Function u8], "unit": [Function unit]}, "transactions": {"create": [Function create], "deserialize": [Function deserialize], "deserializeMessage": [Function deserializeMessage], "serialize": [Function serialize], "serializeMessage": [Function serializeMessage]}, "uploader": {"getUploadPrice": [Function errorHandler], "upload": [Function errorHandler], "uploadJson": [Function errorHandler]}, "use": [Function use]}
LOG Creating Candy Machine...
LOG Fetching balance for: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
ERROR Error during Candy Machine creation: [TypeError: Cannot read property 'publicKey' of undefined]
LOG Balance fetched: 13889948440
π Error running command (re-run needed): unable to confirm transaction. This can happen in situations such as transaction expiration and insufficient fee-payer funds % sugar withdraw --candy-machine J3RZuYxgsGeZmwqrafb9ghYDtmqXAMWz6DHDANxyDw7j --keypair /Users/jiawababa/keys___/id.json
[1/2] π₯ Initializing connection
βͺβͺβͺβͺβͺ Connected
[2/2] π§ Retrieving funds
π Error running command (re-run needed): unable to confirm transaction. This can happen in situations such as transaction expiration and insufficient fee-payer funds
getRent % sugar withdraw --candy-machine J3RZuYxgsGeZmwqrafb9ghYDtmqXAMWz6DHDANxyDw7j --keypair /Users/jiawababa/keys___/id.json
[1/2] π₯ Initializing connection
βͺβͺβͺβͺβͺ Connected
[2/2] π§ Retrieving funds
π Error running command (re-run needed): unable to confirm transaction. This can happen in situations such as transaction expiration and insufficient fee-payer funds
getRent % sugar withdraw --candy-machine J3RZuYxgsGeZmwqrafb9ghYDtmqXAMWz6DHDANxyDw7j --keypair /Users/jiawababa/keys___/id.json
[1/2] π₯ Initializing connection
βͺβͺβͺβͺβͺ Connected
[2/2] π§ Retrieving funds
π Error running command (re-run needed): unable to confirm transaction. This can happen in situations such as transaction expiration and insufficient fee-payer funds
getRent %
My understanding of safe*
functions was that they return null
when the account does not exist. However, it actually throws an UnexpectedAccountError
on the empty buffer.
UnexpectedAccountError: The account at the provided address [3ix9kizh1uKa7PEYhWUHLseMRVMtqgu5eSUTZ6LT3Ezt] is not of the expected type [CandyGuard].
Source: SDK
Caused By: DeserializingEmptyBufferError: Serializer [i8] cannot deserialize empty buffers.
at deserializeAccount (Account.ts:63:11)
at deserializeCandyGuard (candyGuard.ts:90:10)
at safeFetchCandyGuard (candyGuard.ts:125:7)
@metaplex-foundation/mpl-candy-machine
v6.0.0
have followed all steps in this guide https://docs.metaplex.com/developer-tools/sugar/tutorials/my-first-candy-machine
but get this error everytime i run sugar deploy
Error running command (re-run needed): Missing collection item in cache
this is what my config looks like :
in the cache file there are 6 items from 0 to 5 similar to what the example in the guide looks like.
Any ideas what can be happening? thanks
Getting compatibility errors when using anchor_lang = "0.27.0"
and mpl-candy-machine-core = {version = "1.0.2", features = ["no-entrypoint"]}
which use anchor_lang = "0.26.0"
[...]
| pub candy_machine: Account<'info, CandyMachine>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `anchor_lang::AccountDeserialize` is not implemented for `CandyMachine`
|
help: trait impl with same name found
= note: perhaps two different versions of crate `anchor_lang` are being used?
= help: the following other types implement trait `anchor_lang::AccountDeserialize`:
[...]
Downgrading to anchor_lang = "0.26.0"
temporarily bypass the issue
Does Phantom wallet no longer allow developers to build their own NFT mint dApps?
I plan to setup a candy machine to distribute NFTs, but for the setting of payment, I'd like to set a dynamic price (by fetching price via oracles or fetching a pool state).
Is it possible to do? Thanks.
Hi!
I was hoping to make a feature for updating spl-token metadata on frontend. I'm using the latest version of packages. But as soon as i import them I start receiving this error:
Class extends value undefined is not a constructor or null
TypeError: Class extends value undefined is not a constructor or null
my imports:
import { percentAmount, generateSigner, signerIdentity, createSignerFromKeypair } from '@metaplex-foundation/umi';
import { createAndMint, TokenStandard } from '@metaplex-foundation/mpl-token-metadata';
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { mplCandyMachine } from '@metaplex-foundation/mpl-candy-machine';
Please let me know if it's possible to fix if someone knows. Thank you
how can i add a small time-lock customisation when minting spl tokens with candy machine?
I would like to lock tokens of new holders for 1 day as an experiment. please guide me. let me know the best way to achieve this. or if it is not possible.
I want to limit the number of mint per wallet which can be dynamic.
e.g. wallet1 has 5, wallet2 has 7, wallet3 has 10
to achieve this scenario, I have left the default guard empty and set 3 groups with the following settings.
groups
which works just fine.
the problem starts when I specify 50 groups, the length of the transaction would be ~2500 bytes, which exceeded the hard limit of 1232 bytes. and I can not do a partial update, as it needs all data to update Candy Guard.
Is there any trick that executes this transaction OR is there any other combination of guards that can achieve the above scenario
Does phantom block all organizations or individual dapp developers who do not apply?
Hi! I am following this guide, adding the code to my create-react-app
project:
https://docs.metaplex.com/programs/candy-machine/getting-started
But as soon as I include mpl-candy-machine
I get the following runtime error from its depencency mpl-token-metadata
:
ERROR Class extends value undefined is not a constructor or null TypeError: Class extends value undefined is not a constructor or null at ./node_modules/@metaplex-foundation/mpl-token-metadata/dist/src/errors.js (http://localhost:3000/static/js/bundle.js:8513:40) at options.factory (http://localhost:3000/static/js/bundle.js:110628:31) at __webpack_require__ (http://localhost:3000/static/js/bundle.js:110051:33) at fn (http://localhost:3000/static/js/bundle.js:110285:21) at ./node_modules/@metaplex-foundation/mpl-token-metadata/dist/src/hooked/metadataDelegateRoleSeed.js (http://localhost:3000/static/js/bundle.js:22151:18) at options.factory (http://localhost:3000/static/js/bundle.js:110628:31) at __webpack_require__ (http://localhost:3000/static/js/bundle.js:110051:33) at fn (http://localhost:3000/static/js/bundle.js:110285:21) at ./node_modules/@metaplex-foundation/mpl-token-metadata/dist/src/hooked/index.js (http://localhost:3000/static/js/bundle.js:22132:14) at options.factory (http://localhost:3000/static/js/bundle.js:110628:31)
I have checked the errors.js file of mpl-token-metadata
and it is extending the UmiError
class that is indeed being exported from the umi interface, so I'm not sure what is wrong here:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenMetadataError = void 0;
const {UmiError} = require("@metaplex-foundation/umi");
class TokenMetadataError extends umi_1.UmiError {
constructor(message, cause) {
super(message, 'plugin', 'Token Metadata', cause);
this.name = 'TokenMetadataError';
}
}
exports.TokenMetadataError = TokenMetadataError;
//# sourceMappingURL=errors.js.map
'Program 11111111111111111111111111111111 invoke [1]', 'Program CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR invoke [1]', 'Program log: Instruction: InitializeV2', 'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s invoke [2]', 'Program log: IX: Delegate', 'Program log: Incorrect account owner', 'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s consumed 8216 of 774536 compute units', 'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s failed: custom program error: 0x39', 'Program CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR consumed 33530 of 799850 compute units', 'Program CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR failed: custom program error: 0x39'
/// Author: Oguntunde Caleb Fiyinfoluwa <[email protected]>
import {
addConfigLines,
CandyGuard,
CandyMachine,
ConfigLine,
updateCandyGuard,
DefaultGuardSetArgs,
} from "@metaplex-foundation/mpl-candy-machine";
import {
createNft,
TokenStandard,
} from "@metaplex-foundation/mpl-token-metadata";
import { create } from "@metaplex-foundation/mpl-candy-machine";
import { generateSigner, some } from "@metaplex-foundation/umi";
import { publicKey } from "@metaplex-foundation/umi";
import BaseDaddyInuImpl from "./impl";
type NFTInput = Omit<Parameters<typeof createNft>[1], "mint" | "authority">;
type CreateInput = Omit<
Parameters<typeof create>[1],
| "candyMachine"
| "collectionMint"
| "tokenStandard"
| "collectionUpdateAuthority"
>;
export default class DaddyInu extends BaseDaddyInuImpl {
async createNFT(nftInput: NFTInput) {
const mint = generateSigner(this.umi);
const authority = generateSigner(this.umi);
await createNft(this.umi, {
mint,
authority,
...nftInput,
}).sendAndConfirm(this.umi);
return [mint, authority];
}
async createCandyMachine(
[mint, authority]: Awaited<ReturnType<typeof this.createNFT>>,
createInput: CreateInput
) {
const candyMachine = generateSigner(this.umi);
await (
await create(this.umi, {
candyMachine,
collectionMint: mint.publicKey,
collectionUpdateAuthority: authority,
tokenStandard: TokenStandard.NonFungible,
...createInput,
creators: [
{
address: this.umi.identity.publicKey,
verified: true,
percentageShare: 10,
},
...createInput.creators,
],
configLineSettings: some({
prefixName: "",
prefixUri: "",
nameLength: 8,
uriLength: 32,
isSequential: true,
...createInput.configLineSettings,
}),
})
)
.sendAndConfirm(this.umi);
return candyMachine;
}
insertNFTItems(
candyMachine: CandyMachine,
items: ConfigLine[],
index?: number
) {
return addConfigLines(this.umi, {
candyMachine: publicKey(candyMachine.publicKey),
index: index ?? candyMachine.itemsLoaded,
configLines: items,
}).sendAndConfirm(this.umi);
}
updateCandyGuards(
candyGuard: CandyGuard,
guards: Partial<DefaultGuardSetArgs>
) {
return updateCandyGuard(this.umi, {
candyGuard: candyGuard.publicKey,
guards: {
...candyGuard.guards,
...guards,
},
groups: candyGuard.groups,
});
}
}
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
import { publicKey, Umi } from "@metaplex-foundation/umi";
import {
fetchCandyMachine,
fetchCandyGuard,
mplCandyMachine,
CandyGuard,
CandyMachine,
} from "@metaplex-foundation/mpl-candy-machine";
export default class BaseDaddyInuImpl {
public readonly umi: Umi;
constructor(endpoint: string | Umi) {
if (typeof endpoint === "string") this.umi = createUmi(endpoint);
else this.umi = endpoint;
this.umi.use(mplCandyMachine()).use(mplCandyMachine());
}
async fetchCandyMachineAndGuard(
candyMachineAddress: string
): Promise<[CandyMachine, CandyGuard]> {
const candyMachine = await fetchCandyMachine(
this.umi,
publicKey(candyMachineAddress)
);
const candyGuard = await fetchCandyGuard(
this.umi,
candyMachine.mintAuthority
);
return [candyMachine, candyGuard];
}
}
import { percentAmount, keypairIdentity, some } from "@metaplex-foundation/umi";
import secret from "./keypair.json";
import DaddyInu from "../src/daddy_inu";
export default async function main() {
const daddyInu = new DaddyInu("https://api.devnet.solana.com");
const keypair = daddyInu.umi.eddsa.createKeypairFromSecretKey(
Uint8Array.from(secret)
);
daddyInu.umi.use(keypairIdentity(keypair));
const signers = await daddyInu.createNFT({
name: "Big Daddy Pass",
symbol: "BDP",
uri: "https://www.daddyinu.com/pass/dinu.jpg",
sellerFeeBasisPoints: percentAmount(10),
isCollection: true,
});
const nftAddress = signers.map((signer) => signer.publicKey);
console.log(`Mint & Authority: ${nftAddress.join(", ")}`);
const [mintAddress, _authorityAddress] = nftAddress;
console.log(
`https://explorer.solana.com/address/${mintAddress}?cluster=devnet`
);
await sleep(5);
const candyMachine = await daddyInu.createCandyMachine(signers, {
creators: [],
symbol: "BDB",
sellerFeeBasisPoints: percentAmount(10),
itemsAvailable: 5000,
});
console.log(`Candy Machine: ${candyMachine.publicKey}`);
}
main().catch((error) => {
console.log(error);
});
async function sleep(seconds: number) {
return new Promise((resolve) => {
setTimeout(() => {
return resolve(void 0);
}, seconds * 1000);
});
}
Allow multiple nftPayments / nftBurns per mint.
No
Simple solution is to extend the current gates to allow an "amount" as a part of the configuration. Then during the mint process it burns/ transfers multiple NFTs at once from the given collection.
No response
No response
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.