Editions

Decent's most versatile token standard.

NFT drop utilizing the gas-optimized ERC721A which allows minting multiple NFTs for nearly the cost of one. This contract includes several methods including an option to create Soulbound NFTs, conduct allowlisted releases, create token gates, and more.

Getting Started
Module Methods
Smart Contract Methods

Getting Started

To begin we'll import the DecentSDK, chain configurations, and the Edition module.

Then we'll setup our signer (via wagmi/ethers) and create a new instance of the DecentSDK.

// Import SDK, chain configurations, and the Edition module
import { DecentSDK, chain, edition } from "@decent.xyz/sdk";

// Get the signer via wagmi or configure using ethers
// Setup the SDK with the desired chain and signer
const sdk = new DecentSDK(chain.goerli, signer);

Module Methods

deploy
Deploy a minimal proxy clone of the Edition implementation contract.

getContract
Get an ethers contract instance of a previously deployed Edition contract.

deploy

Deploy a minimal proxy clone of the Edition implementation contract.

const myNFT = await edition.deploy(
  sdk,
  name,
  symbol,
  hasAdjustableCap,
  isSoulbound,
  maxTokens,
  tokenPrice,
  maxTokenPurchase,
  presaleMerkleRoot,
  presaleStart,
  presaleEnd,
  saleStart,
  saleEnd,
  royaltyBPS,
  payoutAddress,
  contractURI,
  metadataURI,
  metadataRendererInit,
  tokenGateConfig,
  onTxPending,
  onTxReceipt,
  parentIP
);

console.log("Edition deployed to: ", myNFT.address);

sdk (SDK)
An instance of the DecentSDK, configured with a chain and signer.

name (string)
The name of the NFT collection.

symbol (string)
The symbol of the NFT collection.

hasAdjustableCap (boolean)
Include the ability to change maxTokens at a date after deployment.

isSoulBound (boolean)
Implementation of Soulbound NFTs so that tokens in this collection are non-transferrable. Best set to true if NFTs are intended to be used as a credential or another purely non-financial use case.

maxTokens (number)
The total number of tokens allowed to be minted from the collection.

tokenPrice (BigNumber)
The price (in Wei) to mint a token from the collection.

maxTokenPurchase (number)
The maximum number of tokens allowed per mint.

presaleMerkleRoot (number | BigNumber)
A merkle root representation of the allowlisted accounts, and their relative max purchase and price per token.

import { MerkleTree } from 'merkletreejs';
import { ethers } from 'ethers';

const createMerkleRoot = (allowlist: Allowed[]) => {
  const leaves = allowlist.map((leaf) => {
    const address = leaf[0];
    const maxQuantity = leaf[1];
    const pricePerToken = ethers.utils.parseEther(leaf[2].toString());
    return ethers.utils.solidityKeccak256(
      ["address", "uint256", "uint256"],
      [address, maxQuantity, pricePerToken]
    );
  });
  const tree = new MerkleTree(leaves, ethers.utils.keccak256, { sortPairs: true });
  return tree.getHexRoot();
}

const presaleMerkleRoot = createMerkleRoot([
  ['0xce90a7949bb78892f159f428d0dc23a8e3584d75', 1, 0.1],
  ['0xab5801a7d398351b8be11c439e05c5b3259aec9b', 1, 0.1],
]);

presaleStart (number | BigNumber)
Unix time presale ends.

presaleEnd (number | BigNumber)
Unix time presale ends.

saleStart (number | BigNumber)
Unix time general sale starts. General sale applies to contracts deployed with and without an allowlist.

saleEnd (number | BigNumber)
Unix time general sale ends.

royaltyBPS (number)
Percentage of secondary sales for the contract creator.

payoutAddress (string)
An alternate address for withdrawals and royalty payments may be used. Use zero address as the default setting for owner payouts.

contractURI (string)
The URI for contract level metadata.

metadataURI (string)
The base URI for the collection metadata.

metadataRendererInit (MetadataRendererInit)
An object containing metadata to initialize with the on-chain metadata renderer.

type MetadataRendererInit = {
  description: string;
  imageURI: string;
  animationURI: string;
}

tokenGateConfig (TokenGateConfig) optional
The configuration for a token gate, an NFT contract from wich users must have a minimum balance to mint. Think of this as a more dynamic allowlist or light anti-sybil mechanism.

 type TokenGateConfig = {
  tokenAddress: string;
  minBalance: number;
  saleType: number;
}

enum SaleType {
  ALL = 0,
  PRESALE = 1,
  PRIMARY = 2
}

onTxPending (Function) - optional
A callback function executed upon submission of the deploy transaction.

onTxReceipt (Function) - optional
A callback function executed upon receipt of the deploy transaction.

parentIP (string) - optional
Implementation of EIP 5553 to assign token metadata to the address of another NFT with registered IP.

getContract

Get an ethers contract instance of a previously deployed Edition contract.

const myNFT = await edition.getContract(sdk, address);

sdk (SDK)
An instance of the DecentSDK, configured with a chain and signer.

address (string)
The contract address of a previously deployed Edition contract.

Smart Contract Methods

mint
Mints the specified number of tokens to msg.sender.

mintAirdrop
Mints the specified number of tokens to msg.sender.

flipSaleState
Toggles whether to allow minting.

withdraw
Allows the owner to withdraw the contract balance.

setBaseURI
Allows the owner to update the base URI for token metadata.

mint

Mints the specified number of tokens to msg.sender

const to = '0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B';
const qty = 1;
const myNFT = await edition.getContract(sdk, address);
await myNFT.mint(to, qty, { value: ethers.utils.parseEther('0.1') });

to (address)
The address of the account which will recieve the minted tokens.

numberOfTokens (uint256)
The number of tokens to be minted.

mintAirdrop

Mints a token to an array of recipient addresses.

const recipients = [
  '0xce90a7949bb78892f159f428d0dc23a8e3584d75',
  '0xab5801a7d398351b8be11c439e05c5b3259aec9b'
];
const myNFT = await edition.getContract(sdk, address);
await myNFT.mintAirdrop(recipients);

recipients (address[])
The address of the account which will recieve the minted tokens.

flipSaleState

Toggles whether to allow minting.

const myNFT = await edition.getContract(sdk, address);
await myNFT.flipSaleState();

withdraw

Allows the owner to withdraw the contract balance.

const myNFT = await edition.getContract(sdk, address);
await myNFT.withdraw();

setBaseURI

Allows the owner to update the base URI for token metadata.

const myNFT = await edition.getContract(sdk, address);
await myNFT.setBaseURI('https://nft.example/metadata/');

uri (uint256)
The base URI serving metadata for the NFT collection.


What’s Next