@solana/spl-token#MintLayout TypeScript Examples
The following examples show how to use
@solana/spl-token#MintLayout.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts From zo-client with Apache License 2.0 | 6 votes |
export async function createMintIxs(
mint: Keypair,
provider: Provider,
authority: PublicKey,
decimals: number,
freezeAuthority?: PublicKey,
): Promise<TransactionInstruction[]> {
return [
SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: mint.publicKey,
space: MintLayout.span,
lamports: await Token.getMinBalanceRentForExemptMint(provider.connection),
programId: TOKEN_PROGRAM_ID,
}),
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
decimals,
authority,
freezeAuthority ?? null,
),
];
}
Example #2
Source File: instructions.ts From serum-ts with Apache License 2.0 | 6 votes |
deserializeMint = (data: Buffer): MintInfo => {
if (data.length !== MintLayout.span) {
throw new Error('Not a valid Mint');
}
const mintInfo = MintLayout.decode(data);
if (mintInfo.mintAuthorityOption === 0) {
mintInfo.mintAuthority = null;
} else {
mintInfo.mintAuthority = new PublicKey(mintInfo.mintAuthority);
}
mintInfo.supply = u64.fromBuffer(mintInfo.supply);
mintInfo.isInitialized = mintInfo.isInitialized !== 0;
if (mintInfo.freezeAuthorityOption === 0) {
mintInfo.freezeAuthority = null;
} else {
mintInfo.freezeAuthority = new PublicKey(mintInfo.freezeAuthority);
}
return mintInfo as MintInfo;
}
Example #3
Source File: getNewMint.ts From metaplex with Apache License 2.0 | 6 votes |
export async function getNewMint(
wallet: WalletContextState,
connection: Connection,
): Promise<Response> {
const instructions: TransactionInstruction[] = [];
const signers: Keypair[] = [];
if (!wallet.publicKey) {
throw new Error('Wallet pubKey is not provided');
}
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
const newMint = await createMintAndAccountWithOne(
wallet,
wallet.publicKey.toString(),
mintRentExempt,
instructions,
signers,
);
return { ...newMint, instructions, signers };
}
Example #4
Source File: accounts.ts From metaplex with Apache License 2.0 | 6 votes |
getMintInfo = async (
connection: Connection,
mint: string,
): Promise<{ key: PublicKey; info: MintInfo }> => {
let mintKey: PublicKey;
try {
mintKey = new PublicKey(mint);
} catch (err) {
throw new Error(`Invalid mint key ${err}`);
}
const mintAccount = await connection.getAccountInfo(mintKey);
if (mintAccount === null) {
throw new Error(`Could not fetch mint`);
}
if (!mintAccount.owner.equals(TOKEN_PROGRAM_ID)) {
const mintOwner = mintAccount.owner.toBase58();
throw new Error(`Invalid mint owner ${mintOwner}`);
}
if (mintAccount.data.length !== MintLayout.span) {
throw new Error(`Invalid mint size ${mintAccount.data.length}`);
}
const mintInfo = MintLayout.decode(Buffer.from(mintAccount.data));
return {
key: mintKey,
info: mintInfo,
};
}
Example #5
Source File: deserialize.ts From metaplex with Apache License 2.0 | 6 votes |
deserializeMint = (data: Buffer) => {
if (data.length !== MintLayout.span) {
throw new Error('Not a valid Mint');
}
const mintInfo = MintLayout.decode(data);
if (mintInfo.mintAuthorityOption === 0) {
mintInfo.mintAuthority = null;
} else {
mintInfo.mintAuthority = new PublicKey(mintInfo.mintAuthority);
}
mintInfo.supply = u64.fromBuffer(mintInfo.supply);
mintInfo.isInitialized = mintInfo.isInitialized !== 0;
if (mintInfo.freezeAuthorityOption === 0) {
mintInfo.freezeAuthority = null;
} else {
mintInfo.freezeAuthority = new PublicKey(mintInfo.freezeAuthority);
}
return mintInfo as MintInfo;
}
Example #6
Source File: account.ts From metaplex with Apache License 2.0 | 6 votes |
export function createUninitializedMint(
instructions: TransactionInstruction[],
payer: PublicKey,
amount: number,
signers: Keypair[],
) {
const account = Keypair.generate();
instructions.push(
SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: account.publicKey,
lamports: amount,
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
}),
);
signers.push(account);
return account.publicKey;
}
Example #7
Source File: accountParser.ts From jet-engine with GNU Affero General Public License v3.0 | 6 votes |
parseMintAccount = (info: AccountInfo<Buffer>, address: PublicKey): Mint => {
if (!info) throw new TokenAccountNotFoundError()
if (!info.owner.equals(TOKEN_PROGRAM_ID)) throw new TokenInvalidAccountOwnerError()
if (info.data.length != MINT_SIZE) throw new TokenInvalidAccountSizeError()
const rawMint = MintLayout.decode(info.data)
return {
address,
mintAuthority: rawMint.mintAuthorityOption ? rawMint.mintAuthority : null,
supply: rawMint.supply,
decimals: rawMint.decimals,
isInitialized: rawMint.isInitialized,
freezeAuthority: rawMint.freezeAuthorityOption ? rawMint.freezeAuthority : null
}
}
Example #8
Source File: mockAccounts.ts From protocol-v1 with Apache License 2.0 | 6 votes |
export async function mockUSDCMint(provider: Provider): Promise<Keypair> {
const fakeUSDCMint = anchor.web3.Keypair.generate();
const createUSDCMintAccountIx = SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: fakeUSDCMint.publicKey,
lamports: await Token.getMinBalanceRentForExemptMint(provider.connection),
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
});
const initCollateralMintIx = Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
fakeUSDCMint.publicKey,
6,
provider.wallet.publicKey,
null
);
const fakeUSDCTx = new Transaction();
fakeUSDCTx.add(createUSDCMintAccountIx);
fakeUSDCTx.add(initCollateralMintIx);
const _fakeUSDCTxResult = await sendAndConfirmTransaction(
provider.connection,
fakeUSDCTx,
// @ts-ignore
[provider.wallet.payer, fakeUSDCMint],
{
skipPreflight: false,
commitment: 'recent',
preflightCommitment: 'recent',
}
);
return fakeUSDCMint;
}
Example #9
Source File: index.ts From zo-client with Apache License 2.0 | 6 votes |
export async function getMintInfo(
provider: Provider,
pubkey: PublicKey,
): Promise<MintInfo> {
const data = (await provider.connection.getAccountInfo(pubkey))?.data;
if (!data) throw Error(`Couldn't load mint data for ${pubkey.toBase58()}`);
const m = MintLayout.decode(data);
return {
mintAuthority: new PublicKey(m.mintAuthority),
supply: u64.fromBuffer(m.supply),
decimals: m.decimals,
isInitialized: !!m.isInitialized,
freezeAuthority: new PublicKey(m.freezeAuthority),
};
}
Example #10
Source File: testHelpers.ts From protocol-v1 with Apache License 2.0 | 6 votes |
export async function mockUSDCMint(provider: Provider): Promise<Keypair> {
const fakeUSDCMint = anchor.web3.Keypair.generate();
const createUSDCMintAccountIx = SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: fakeUSDCMint.publicKey,
lamports: await Token.getMinBalanceRentForExemptMint(provider.connection),
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
});
const initCollateralMintIx = Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
fakeUSDCMint.publicKey,
6,
provider.wallet.publicKey,
null
);
const fakeUSDCTx = new Transaction();
fakeUSDCTx.add(createUSDCMintAccountIx);
fakeUSDCTx.add(initCollateralMintIx);
await sendAndConfirmTransaction(
provider.connection,
fakeUSDCTx,
// @ts-ignore
[provider.wallet.payer, fakeUSDCMint],
{
skipPreflight: false,
commitment: 'recent',
preflightCommitment: 'recent',
}
);
return fakeUSDCMint;
}
Example #11
Source File: index.tsx From metaplex with Apache License 2.0 | 5 votes |
async function calculateTotalCostOfRedeemingOtherPeoplesBids(
connection: Connection,
auctionView: AuctionView,
bids: ParsedAccount<BidderMetadata>[],
bidRedemptions: Record<string, ParsedAccount<BidRedemptionTicket>>,
): Promise<number> {
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
const metadataRentExempt = await connection.getMinimumBalanceForRentExemption(
MAX_METADATA_LEN,
);
const editionRentExempt = await connection.getMinimumBalanceForRentExemption(
MAX_EDITION_LEN,
);
const prizeTrackingTicketExempt =
await connection.getMinimumBalanceForRentExemption(
MAX_PRIZE_TRACKING_TICKET_SIZE,
);
const eligibleParticipations =
await findEligibleParticipationBidsForRedemption(
auctionView,
bids,
bidRedemptions,
);
const max = auctionView.auction.info.bidState.max.toNumber();
let totalWinnerItems = 0;
for (let i = 0; i < max; i++) {
const winner = auctionView.auction.info.bidState.getWinnerAt(i);
if (!winner) {
break;
} else {
const bid = bids.find(b => b.info.bidderPubkey === winner);
if (bid) {
for (
let j = 0;
j < auctionView.auctionManager.safetyDepositBoxesExpected.toNumber();
j++
) {
totalWinnerItems += auctionView.auctionManager
.getAmountForWinner(i, j)
.toNumber();
}
}
}
}
return (
(mintRentExempt +
accountRentExempt +
metadataRentExempt +
editionRentExempt +
prizeTrackingTicketExempt) *
(eligibleParticipations.length + totalWinnerItems)
);
}
Example #12
Source File: setupMintEditionIntoWalletInstructions.ts From metaplex with Apache License 2.0 | 5 votes |
export async function setupMintEditionIntoWalletInstructions(
art: Art,
wallet: WalletContextState,
connection: Connection,
mintTokenAccount: TokenAccount,
edition: BN,
instructions: any,
signers: any,
mintDestination: StringPublicKey,
) {
if (!art.mint) throw new Error('Art mint is not provided');
if (typeof art.supply === 'undefined') {
throw new Error('Art supply is not provided');
}
if (!wallet.publicKey) throw new Error('Wallet pubKey is not provided');
if (!mintTokenAccount) {
throw new Error('Art mint token account is not provided');
}
const walletPubKey = wallet.publicKey.toString();
const { mint: tokenMint } = art;
const { pubkey: mintTokenAccountPubKey } = mintTokenAccount;
const mintTokenAccountOwner = mintTokenAccount.info.owner.toString();
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
const { mint: newMint } = await createMintAndAccountWithOne(
wallet,
mintDestination,
mintRentExempt,
instructions,
signers,
);
await mintNewEditionFromMasterEditionViaToken(
newMint,
tokenMint,
walletPubKey,
walletPubKey,
mintTokenAccountOwner,
mintTokenAccountPubKey,
instructions,
walletPubKey,
edition,
);
}
Example #13
Source File: helpers.ts From psyoptions with Apache License 2.0 | 5 votes |
initNewTokenMint = async (
connection: Connection,
/** The owner for the new mint account */
owner: PublicKey,
wallet: Keypair
) => {
const mintAccount = new Keypair();
const transaction = new Transaction();
// Create the Option Mint Account with rent exemption
// Allocate memory for the account
const mintRentBalance = await connection.getMinimumBalanceForRentExemption(
MintLayout.span
);
transaction.add(
SystemProgram.createAccount({
fromPubkey: wallet.publicKey,
newAccountPubkey: mintAccount.publicKey,
lamports: mintRentBalance,
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
})
);
transaction.add(
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mintAccount.publicKey,
8,
owner,
null
)
);
await sendAndConfirmTransaction(
connection,
transaction,
[wallet, mintAccount],
{
commitment: "confirmed",
}
);
return {
mintAccount,
};
}
Example #14
Source File: mockUSDCFaucet.ts From protocol-v1 with Apache License 2.0 | 5 votes |
public async initialize(): Promise<TransactionSignature> {
const stateAccountRPCResponse = await this.connection.getParsedAccountInfo(
await this.getMockUSDCFaucetStatePublicKey()
);
if (stateAccountRPCResponse.value !== null) {
throw new Error('Faucet already initialized');
}
const fakeUSDCMint = anchor.web3.Keypair.generate();
const createUSDCMintAccountIx = SystemProgram.createAccount({
fromPubkey: this.wallet.publicKey,
newAccountPubkey: fakeUSDCMint.publicKey,
lamports: await Token.getMinBalanceRentForExemptMint(this.connection),
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
});
const [mintAuthority, _mintAuthorityNonce] =
await PublicKey.findProgramAddress(
[fakeUSDCMint.publicKey.toBuffer()],
this.program.programId
);
const initUSDCMintIx = Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
fakeUSDCMint.publicKey,
6,
mintAuthority,
null
);
const [mockUSDCFaucetStatePublicKey, mockUSDCFaucetStateNonce] =
await this.getMockUSDCFaucetStatePublicKeyAndNonce();
return await this.program.rpc.initialize(mockUSDCFaucetStateNonce, {
accounts: {
mockUsdcFaucetState: mockUSDCFaucetStatePublicKey,
admin: this.wallet.publicKey,
mintAccount: fakeUSDCMint.publicKey,
rent: SYSVAR_RENT_PUBKEY,
systemProgram: anchor.web3.SystemProgram.programId,
},
instructions: [createUSDCMintAccountIx, initUSDCMintIx],
signers: [fakeUSDCMint],
});
}
Example #15
Source File: fair-launch-cli.ts From metaplex with Apache License 2.0 | 5 votes |
program
.command('create_dummy_payment_mint')
.option(
'-e, --env <string>',
'Solana cluster env name',
'devnet', //mainnet-beta, testnet, devnet
)
.option(
'-k, --keypair <path>',
`Solana wallet location`,
'--keypair not provided',
)
.action(async (_, cmd) => {
const { env, keypair } = cmd.opts();
const walletKeyPair = loadWalletKey(keypair);
const anchorProgram = await loadFairLaunchProgram(walletKeyPair, env);
const mint = anchor.web3.Keypair.generate();
const token = (
await getAtaForMint(mint.publicKey, walletKeyPair.publicKey)
)[0];
const instructions: anchor.web3.TransactionInstruction[] = [
anchor.web3.SystemProgram.createAccount({
fromPubkey: walletKeyPair.publicKey,
newAccountPubkey: mint.publicKey,
space: MintLayout.span,
lamports:
await anchorProgram.provider.connection.getMinimumBalanceForRentExemption(
MintLayout.span,
),
programId: TOKEN_PROGRAM_ID,
}),
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
6,
walletKeyPair.publicKey,
walletKeyPair.publicKey,
),
createAssociatedTokenAccountInstruction(
token,
walletKeyPair.publicKey,
walletKeyPair.publicKey,
mint.publicKey,
),
];
const signers = [mint];
await sendTransactionWithRetryWithKeypair(
anchorProgram.provider.connection,
walletKeyPair,
instructions,
signers,
'single',
);
console.log(`create mint Done: ${mint.publicKey.toBase58()}.`);
});
Example #16
Source File: index.ts From serum-ts with Apache License 2.0 | 5 votes |
export function parseMintAccount(data: Buffer): MintInfo {
const m = MintLayout.decode(data);
m.mintAuthority = new PublicKey(m.mintAuthority);
m.supply = u64.fromBuffer(m.supply);
m.isInitialized = m.state !== 0;
return m;
}
Example #17
Source File: candy-machine.ts From metaplex with Apache License 2.0 | 5 votes |
createAccountsForMint = async (
candyMachine: CandyMachineAccount,
payer: anchor.web3.PublicKey,
): Promise<SetupState> => {
const mint = anchor.web3.Keypair.generate();
const userTokenAccountAddress = (
await getAtaForMint(mint.publicKey, payer)
)[0];
const signers: anchor.web3.Keypair[] = [mint];
const instructions = [
anchor.web3.SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: mint.publicKey,
space: MintLayout.span,
lamports:
await candyMachine.program.provider.connection.getMinimumBalanceForRentExemption(
MintLayout.span,
),
programId: TOKEN_PROGRAM_ID,
}),
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
0,
payer,
payer,
),
createAssociatedTokenAccountInstruction(
userTokenAccountAddress,
payer,
payer,
mint.publicKey,
),
Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
userTokenAccountAddress,
payer,
[],
1,
),
];
return {
mint: mint,
userTokenAccount: userTokenAccountAddress,
transaction: (
await sendTransactions(
candyMachine.program.provider.connection,
candyMachine.program.provider.wallet,
[instructions],
[signers],
SequenceType.StopOnFailure,
'singleGossip',
() => {},
() => false,
undefined,
[],
[],
)
).txs[0].txid,
};
}
Example #18
Source File: pools.ts From serum-ts with Apache License 2.0 | 4 votes |
/**
* Note: for seed param, this must be <= 32 characters for the txn to succeed
*/
static async makeInitializePoolTransaction<T extends PublicKey | Account>(
connection: Connection,
tokenSwapProgram: PublicKey,
owner: T,
componentMints: PublicKey[],
sourceTokenAccounts: {
mint: PublicKey;
tokenAccount: PublicKey;
amount: number; // note this is raw amount, not decimal
}[],
options: PoolConfig,
liquidityTokenPrecision = DEFAULT_LIQUIDITY_TOKEN_PRECISION,
accounts?: {
liquidityTokenMint?: Account;
tokenSwapPoolAddress?: Account;
},
seed?: string,
): Promise<{
initializeAccountsTransaction: Transaction;
initializeAccountsSigners: Account[];
initializePoolTransaction: Transaction;
initializePoolSigners: Account[];
}> {
// @ts-ignore
const ownerAddress: PublicKey = owner.publicKey ?? owner;
const initializeAccountsInstructions: TransactionInstruction[] = [];
const initializeAccountsSigners: Account[] = [];
const liquidityTokenMintAccount = accounts?.liquidityTokenMint
? accounts.liquidityTokenMint
: new Account();
initializeAccountsInstructions.push(
SystemProgram.createAccount({
fromPubkey: ownerAddress,
newAccountPubkey: liquidityTokenMintAccount.publicKey,
lamports: await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
),
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
}),
);
initializeAccountsSigners.push(liquidityTokenMintAccount);
let tokenSwapAccountPubkey;
let tokenSwapAccountSigner;
if (accounts?.tokenSwapPoolAddress) {
tokenSwapAccountPubkey = accounts.tokenSwapPoolAddress.publicKey;
tokenSwapAccountSigner = accounts.tokenSwapPoolAddress;
} else if (seed) {
// Only works when owner is of type Account
tokenSwapAccountSigner = owner;
tokenSwapAccountPubkey = await PublicKey.createWithSeed(ownerAddress, seed, tokenSwapProgram);
} else {
tokenSwapAccountSigner = new Account();
tokenSwapAccountPubkey = tokenSwapAccountSigner.pubkey;
}
const [authority, nonce] = await PublicKey.findProgramAddress(
[tokenSwapAccountPubkey.toBuffer()],
tokenSwapProgram,
);
// create mint for pool liquidity token
initializeAccountsInstructions.push(
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
liquidityTokenMintAccount.publicKey,
liquidityTokenPrecision,
// pass control of liquidity mint to swap program
authority,
// swap program can freeze liquidity token mint
null,
),
);
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const holdingAccounts: { [mint: string]: Account } = {};
componentMints.forEach(mint => {
const {
account,
instructions: createHoldingTokenAccountInstructions,
} = createTokenAccount(authority, ownerAddress, mint, accountRentExempt);
initializeAccountsInstructions.push(
...createHoldingTokenAccountInstructions,
);
initializeAccountsSigners.push(account);
holdingAccounts[mint.toBase58()] = account;
});
const {
account: depositorAccount,
instructions: createLPTokenAccountInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
liquidityTokenMintAccount.publicKey,
accountRentExempt,
);
initializeAccountsSigners.push(depositorAccount);
initializeAccountsInstructions.push(...createLPTokenAccountInstructions);
const {
account: feeAccount,
instructions: createFeeAccountInstructions,
} = createTokenAccount(
SWAP_PROGRAM_OWNER_FEE_ADDRESS,
ownerAddress,
liquidityTokenMintAccount.publicKey,
accountRentExempt,
);
initializeAccountsSigners.push(feeAccount);
initializeAccountsInstructions.push(...createFeeAccountInstructions);
const initializeAccountsTransaction = new Transaction();
initializeAccountsTransaction.add(...initializeAccountsInstructions);
// break up these into two transactions because it does not fit in a single transaction
const initializePoolSigners: Account[] = [];
const initializePoolInstructions: TransactionInstruction[] = [];
const cleanupInstructions: TransactionInstruction[] = [];
let initializeTokenSwapAccountInstruction;
if (seed) {
initializeTokenSwapAccountInstruction = SystemProgram.createAccountWithSeed({
fromPubkey: ownerAddress,
basePubkey: ownerAddress,
newAccountPubkey: tokenSwapAccountPubkey,
seed: seed,
lamports: await connection.getMinimumBalanceForRentExemption(
getLayoutForProgramId(tokenSwapProgram).span
),
space: getLayoutForProgramId(tokenSwapProgram).span,
programId: tokenSwapProgram,
});
} else {
initializeTokenSwapAccountInstruction = SystemProgram.createAccount({
fromPubkey: ownerAddress,
newAccountPubkey: tokenSwapAccountPubkey,
lamports: await connection.getMinimumBalanceForRentExemption(
getLayoutForProgramId(tokenSwapProgram).span,
),
space: getLayoutForProgramId(tokenSwapProgram).span,
programId: tokenSwapProgram,
})
}
initializePoolInstructions.push(initializeTokenSwapAccountInstruction);
sourceTokenAccounts.forEach(({ mint, tokenAccount, amount }) => {
let wrappedAccount: PublicKey;
if (mint.equals(WRAPPED_SOL_MINT)) {
const {
account,
instructions: createWrappedSolInstructions,
cleanUpInstructions: removeWrappedSolInstructions,
} = createTokenAccount(
ownerAddress,
ownerAddress,
WRAPPED_SOL_MINT,
amount + accountRentExempt,
);
wrappedAccount = account.publicKey;
initializePoolSigners.push(account);
initializePoolInstructions.push(...createWrappedSolInstructions);
cleanupInstructions.push(...removeWrappedSolInstructions);
} else {
wrappedAccount = tokenAccount;
}
initializePoolInstructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
wrappedAccount,
holdingAccounts[mint.toBase58()].publicKey,
ownerAddress,
[],
amount,
),
);
});
initializePoolInstructions.push(
createInitSwapInstruction(
tokenSwapAccountPubkey,
authority,
holdingAccounts[sourceTokenAccounts[0].mint.toBase58()].publicKey,
holdingAccounts[sourceTokenAccounts[1].mint.toBase58()].publicKey,
liquidityTokenMintAccount.publicKey,
feeAccount.publicKey,
depositorAccount.publicKey,
TOKEN_PROGRAM_ID,
tokenSwapProgram,
nonce,
options,
),
);
initializePoolSigners.push(tokenSwapAccountSigner);
const initializePoolTransaction = new Transaction();
initializePoolTransaction.add(
...initializePoolInstructions,
...cleanupInstructions,
);
return {
initializeAccountsTransaction,
initializeAccountsSigners,
initializePoolTransaction,
initializePoolSigners,
};
}
Example #19
Source File: Port.ts From port-sdk with MIT License | 4 votes |
public async createReserve({
provider,
reserveConfig,
transferAuthority,
sourceTokenWallet,
initialLiquidity,
oracle,
price,
}: {
provider: Provider;
reserveConfig: ReserveConfigProto;
transferAuthority: PublicKey;
sourceTokenWallet: PublicKey;
initialLiquidity: number | BN;
oracle?: PublicKey;
price?: BN;
}): Promise<[TransactionEnvelope[], PublicKey]> {
invariant(!!oracle !== !!price, "Oracle and price can't both be present");
const [createReserveAccountIx, reservePubKey] = await this.createAccount({
provider,
space: ReserveLayout.span,
owner: PORT_LENDING,
});
const [collateralMintIx, collateralMintPubKey] = await this.createAccount({
provider,
space: MintLayout.span,
owner: TOKEN_PROGRAM_ID,
});
const [liquiditySupplyIx, liquiditySupplyPubKey] = await this.createAccount(
{
provider,
space: AccountLayout.span,
owner: TOKEN_PROGRAM_ID,
}
);
const [collateralSupplyIx, collateralSupplyPubKey] =
await this.createAccount({
provider,
space: AccountLayout.span,
owner: TOKEN_PROGRAM_ID,
});
const [userCollateralIx, userCollateralPubKey] = await this.createAccount({
provider,
space: AccountLayout.span,
owner: TOKEN_PROGRAM_ID,
});
const [feeReceiverIx, feeReceiverPubkey] = await this.createAccount({
provider,
space: AccountLayout.span,
owner: TOKEN_PROGRAM_ID,
});
const tokenAccount = await getTokenAccount(provider, sourceTokenWallet);
const initReserveIx = initReserveInstruction(
initialLiquidity,
oracle ? 0 : 1, // price Option
price ?? new BN(1),
reserveConfig,
sourceTokenWallet,
collateralSupplyPubKey,
reservePubKey,
tokenAccount.mint,
liquiditySupplyPubKey,
feeReceiverPubkey,
oracle ?? Keypair.generate().publicKey,
collateralMintPubKey,
userCollateralPubKey,
this.lendingMarket,
(await this.getLendingMarketAuthority())[0],
provider.wallet.publicKey,
transferAuthority
);
let tx1 = new TransactionEnvelope(provider, []);
tx1 = tx1.combine(createReserveAccountIx);
tx1 = tx1.combine(collateralMintIx);
tx1 = tx1.combine(liquiditySupplyIx);
tx1 = tx1.combine(collateralSupplyIx);
tx1 = tx1.combine(userCollateralIx);
let tx2 = new TransactionEnvelope(provider, []);
tx2 = tx2.combine(feeReceiverIx);
tx2 = tx2.addInstructions(initReserveIx);
return [[tx1, tx2], reservePubKey];
}
Example #20
Source File: Dex.tsx From swap-ui with Apache License 2.0 | 4 votes |
export function DexContextProvider(props: any) {
const [ooAccounts, setOoAccounts] = useState<Map<string, Array<OpenOrders>>>(
new Map()
);
const swapClient = props.swapClient;
// Removes the given open orders from the context.
const closeOpenOrders = async (openOrder: OpenOrders) => {
const newOoAccounts = new Map(ooAccounts);
const openOrders = newOoAccounts
.get(openOrder.market.toString())
?.filter((oo: OpenOrders) => !oo.address.equals(openOrder.address));
if (openOrders && openOrders.length > 0) {
newOoAccounts.set(openOrder.market.toString(), openOrders);
} else {
newOoAccounts.delete(openOrder.market.toString());
}
setOoAccounts(newOoAccounts);
};
// Three operations:
//
// 1. Fetch all open orders accounts for the connected wallet.
// 2. Batch fetch all market accounts for those open orders.
// 3. Batch fetch all mints associated with the markets.
useEffect(() => {
if (!swapClient.program.provider.wallet.publicKey) {
setOoAccounts(new Map());
return;
}
OpenOrders.findForOwner(
swapClient.program.provider.connection,
swapClient.program.provider.wallet.publicKey,
DEX_PID
).then(async (openOrders) => {
const newOoAccounts = new Map();
let markets = new Set<string>();
openOrders.forEach((oo) => {
markets.add(oo.market.toString());
if (newOoAccounts.get(oo.market.toString())) {
newOoAccounts.get(oo.market.toString()).push(oo);
} else {
newOoAccounts.set(oo.market.toString(), [oo]);
}
});
if (markets.size > 100) {
// Punt request chunking until there's user demand.
throw new Error(
"Too many markets. Please file an issue to update this"
);
}
const multipleMarkets = await anchor.utils.rpc.getMultipleAccounts(
swapClient.program.provider.connection,
Array.from(markets.values()).map((m) => new PublicKey(m))
);
const marketClients = multipleMarkets.map((programAccount) => {
return {
publicKey: programAccount?.publicKey,
account: new Market(
Market.getLayout(DEX_PID).decode(programAccount?.account.data),
-1, // Set below so that we can batch fetch mints.
-1, // Set below so that we can batch fetch mints.
swapClient.program.provider.opts,
DEX_PID
),
};
});
setOoAccounts(newOoAccounts);
// Batch fetch all the mints, since we know we'll need them at some
// point.
const mintPubkeys = Array.from(
new Set<string>(
marketClients
.map((m) => [
m.account.baseMintAddress.toString(),
m.account.quoteMintAddress.toString(),
])
.flat()
).values()
).map((pk) => new PublicKey(pk));
if (mintPubkeys.length > 100) {
// Punt request chunking until there's user demand.
throw new Error("Too many mints. Please file an issue to update this");
}
const mints = await anchor.utils.rpc.getMultipleAccounts(
swapClient.program.provider.connection,
mintPubkeys
);
const mintInfos = mints.map((mint) => {
const mintInfo = MintLayout.decode(mint!.account.data);
setMintCache(mint!.publicKey, mintInfo);
return { publicKey: mint!.publicKey, mintInfo };
});
marketClients.forEach((m) => {
const baseMintInfo = mintInfos.filter((mint) =>
mint.publicKey.equals(m.account.baseMintAddress)
)[0];
const quoteMintInfo = mintInfos.filter((mint) =>
mint.publicKey.equals(m.account.quoteMintAddress)
)[0];
assert.ok(baseMintInfo && quoteMintInfo);
// @ts-ignore
m.account._baseSplTokenDecimals = baseMintInfo.mintInfo.decimals;
// @ts-ignore
m.account._quoteSplTokenDecimals = quoteMintInfo.mintInfo.decimals;
_MARKET_CACHE.set(
m.publicKey!.toString(),
new Promise<Market>((resolve) => resolve(m.account))
);
});
});
}, [
swapClient.program.provider.connection,
swapClient.program.provider.wallet.publicKey,
swapClient.program.provider.opts,
]);
return (
<_DexContext.Provider
value={{
openOrders: ooAccounts,
closeOpenOrders,
swapClient,
}}
>
{props.children}
</_DexContext.Provider>
);
}
Example #21
Source File: mint.ts From sdk with MIT License | 4 votes |
export async function getMintNftInstructions(
connection: Connection,
signer: IWalletSigner,
params: {
metadataLink: string,
//mutableMetadata: boolean,
collection: PublicKey | null,
maxSupply: number,
verifyCreators: boolean,
use?: Uses,
}
): Promise<ITransactionPreparedInstructions & { mint: PublicKey }> {
// Retrieve metadata
const data = await createMetadata(
params.metadataLink,
params.collection,
params.verifyCreators ? { [signer.publicKey.toString()]: true } : undefined,
params.use,
)
if (!data) {
throw new Error("Empty metadata")
}
// Allocate memory for the account
const mintRent = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
)
// Generate a mint
const mint = SolanaKeypairWallet.generate()
const instructions: TransactionInstruction[] = []
const signers: IWalletSigner[] = [mint, signer]
instructions.push(
SystemProgram.createAccount({
fromPubkey: signer.publicKey,
// eslint-disable-next-line unicorn/no-keyword-prefix
newAccountPubkey: mint.publicKey,
lamports: mintRent,
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
}),
)
instructions.push(
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
0,
signer.publicKey,
signer.publicKey,
),
)
const userTokenAccoutAddress = await getTokenWallet(
signer.publicKey,
mint.publicKey,
)
instructions.push(
createAssociatedTokenAccountInstruction(
userTokenAccoutAddress,
signer.publicKey,
signer.publicKey,
mint.publicKey,
),
)
// Create metadata
const metadataAccount = await getMetadata(mint.publicKey)
instructions.push(
...new CreateMetadataV2(
{ feePayer: signer.publicKey },
{
metadata: metadataAccount,
metadataData: data,
updateAuthority: signer.publicKey,
mint: mint.publicKey,
mintAuthority: signer.publicKey,
},
).instructions,
)
instructions.push(
Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
userTokenAccoutAddress,
signer.publicKey,
[],
1,
),
)
// Create master edition
const editionAccount = await getMasterEdition(mint.publicKey)
instructions.push(
...new CreateMasterEditionV3(
{
feePayer: signer.publicKey,
},
{
edition: editionAccount,
metadata: metadataAccount,
mint: mint.publicKey,
mintAuthority: signer.publicKey,
updateAuthority: signer.publicKey,
maxSupply: new BN(params.maxSupply),
},
).instructions,
)
/*
// not working with current mpl-token-metadata version
if (params.mutableMetadata === false) {
instructions.push(
...new UpdateMetadataV2(
{},
{
metadata: metadataAccount,
metadataData: data,
updateAuthority: signer.publicKey,
primarySaleHappened: null,
isMutable: false,
},
).instructions,
)
}*/
return { instructions, signers, mint: mint.publicKey }
}
Example #22
Source File: mint.ts From candy-machine-v2 with MIT License | 4 votes |
mintOneToken = async (
candyMachine: CandyMachineAccount,
payer: anchor.web3.PublicKey,
mint: anchor.web3.Keypair
): Promise<(string | undefined)[]> => {
// const mint = anchor.web3.Keypair.generate();
console.log(mint.publicKey);
const userTokenAccountAddress = (
await getAtaForMint(mint.publicKey, payer)
)[0];
const userPayingAccountAddress = candyMachine.state.tokenMint
? (await getAtaForMint(candyMachine.state.tokenMint, payer))[0]
: payer;
const candyMachineAddress = candyMachine.id;
const remainingAccounts = [];
const signers: anchor.web3.Keypair[] = [mint];
const cleanupInstructions = [];
const metadataAddress = await getMetadata(mint.publicKey);
const masterEdition = await getMasterEdition(mint.publicKey);
const [candyMachineCreator, creatorBump] = await getCandyMachineCreator(
candyMachineAddress
);
const instructions = [
anchor.web3.SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: mint.publicKey,
space: MintLayout.span,
lamports:
await candyMachine.program.provider.connection.getMinimumBalanceForRentExemption(
MintLayout.span
),
programId: TOKEN_PROGRAM_ID,
}),
Token.createInitMintInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
0,
payer,
payer
),
createAssociatedTokenAccountInstruction(
userTokenAccountAddress,
payer,
payer,
mint.publicKey
),
Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
mint.publicKey,
userTokenAccountAddress,
payer,
[],
1
),
];
if (candyMachine.state.whitelistMintSettings) {
const mint = new anchor.web3.PublicKey(
candyMachine.state.whitelistMintSettings.mint
);
const whitelistToken = (await getAtaForMint(mint, payer))[0];
remainingAccounts.push({
pubkey: whitelistToken,
isWritable: true,
isSigner: false,
});
if (candyMachine.state.whitelistMintSettings.mode.burnEveryTime) {
const whitelistBurnAuthority = anchor.web3.Keypair.generate();
remainingAccounts.push({
pubkey: mint,
isWritable: true,
isSigner: false,
});
remainingAccounts.push({
pubkey: whitelistBurnAuthority.publicKey,
isWritable: false,
isSigner: true,
});
signers.push(whitelistBurnAuthority);
const exists =
await candyMachine.program.provider.connection.getAccountInfo(
whitelistToken
);
if (exists) {
instructions.push(
Token.createApproveInstruction(
TOKEN_PROGRAM_ID,
whitelistToken,
whitelistBurnAuthority.publicKey,
payer,
[],
1
)
);
cleanupInstructions.push(
Token.createRevokeInstruction(
TOKEN_PROGRAM_ID,
whitelistToken,
payer,
[]
)
);
}
}
}
if (candyMachine.state.tokenMint) {
const transferAuthority = anchor.web3.Keypair.generate();
signers.push(transferAuthority);
remainingAccounts.push({
pubkey: userPayingAccountAddress,
isWritable: true,
isSigner: false,
});
remainingAccounts.push({
pubkey: transferAuthority.publicKey,
isWritable: false,
isSigner: true,
});
instructions.push(
Token.createApproveInstruction(
TOKEN_PROGRAM_ID,
userPayingAccountAddress,
transferAuthority.publicKey,
payer,
[],
candyMachine.state.price.toNumber()
)
);
cleanupInstructions.push(
Token.createRevokeInstruction(
TOKEN_PROGRAM_ID,
userPayingAccountAddress,
payer,
[]
)
);
}
instructions.push(
await candyMachine.program.instruction.mintNft(creatorBump, {
accounts: {
candyMachine: candyMachineAddress,
candyMachineCreator,
payer: payer,
wallet: candyMachine.state.treasury,
mint: mint.publicKey,
metadata: metadataAddress,
masterEdition,
mintAuthority: payer,
updateAuthority: payer,
tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
tokenProgram: TOKEN_PROGRAM_ID,
systemProgram: SystemProgram.programId,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
recentBlockhashes: anchor.web3.SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
instructionSysvarAccount: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY,
},
remainingAccounts:
remainingAccounts.length > 0 ? remainingAccounts : undefined,
})
);
try {
return (
await sendTransactions(
candyMachine.program.provider.connection,
candyMachine.program.provider.wallet,
[instructions, cleanupInstructions],
[signers, []]
)
).txs.map((t) => t.txid);
} catch (e) {
console.log(e);
}
return [];
}
Example #23
Source File: index.tsx From metaplex with Apache License 2.0 | 4 votes |
ReviewStep = (props: {
confirm: () => void;
attributes: AuctionState;
setAttributes: Function;
connection: Connection;
}) => {
const [showFundsIssueModal, setShowFundsIssueModal] = useState(false);
const [cost, setCost] = useState(0);
const { account } = useNativeAccount();
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const rentCall = Promise.all([
props.connection.getMinimumBalanceForRentExemption(MintLayout.span),
props.connection.getMinimumBalanceForRentExemption(MAX_METADATA_LEN),
]);
// TODO: add
}, [setCost]);
const balance = (account?.lamports || 0) / LAMPORTS_PER_SOL;
const item = props.attributes.items?.[0];
const handleConfirm = () => {
props.setAttributes({
...props.attributes,
startListTS: props.attributes.startListTS || moment().unix(),
startSaleTS: props.attributes.startSaleTS || moment().unix(),
});
props.confirm();
};
return (
<>
<Row className="call-to-action">
<h2>Review and list</h2>
<p>Review your listing before publishing.</p>
</Row>
<Row className="content-action">
<Col xl={12}>
{item?.metadata.info && (
<ArtCard pubkey={item.metadata.pubkey} small={true} />
)}
</Col>
<Col className="section" xl={12}>
<Statistic
className="create-statistic"
title="Copies"
value={
props.attributes.editions === undefined
? 'Unique'
: props.attributes.editions
}
/>
{cost ? (
<AmountLabel
title="Cost to Create"
amount={cost}
tokenInfo={useTokenList().tokenMap.get(
WRAPPED_SOL_MINT.toString(),
)}
/>
) : (
<Spin />
)}
</Col>
</Row>
<Row style={{ display: 'block' }}>
<Divider />
<Statistic
className="create-statistic"
title="Start date"
value={
props.attributes.startSaleTS
? moment
.unix(props.attributes.startSaleTS as number)
.format('dddd, MMMM Do YYYY, h:mm a')
: 'Right after successfully published'
}
/>
<br />
{props.attributes.startListTS && (
<Statistic
className="create-statistic"
title="Listing go live date"
value={moment
.unix(props.attributes.startListTS as number)
.format('dddd, MMMM Do YYYY, h:mm a')}
/>
)}
<Divider />
<Statistic
className="create-statistic"
title="Sale ends"
value={
props.attributes.endTS
? moment
.unix(props.attributes.endTS as number)
.format('dddd, MMMM Do YYYY, h:mm a')
: 'Until sold'
}
/>
</Row>
<Row>
<Button
type="primary"
size="large"
onClick={() => {
if (balance < MINIMUM_SAFE_FEE_AUCTION_CREATION) {
setShowFundsIssueModal(true);
} else {
handleConfirm();
}
}}
className="action-btn"
>
{props.attributes.category === AuctionCategory.InstantSale
? 'List for Sale'
: 'Publish Auction'}
</Button>
<FundsIssueModal
message={'Estimated Minimum Fee'}
minimumFunds={MINIMUM_SAFE_FEE_AUCTION_CREATION}
currentFunds={balance}
isModalVisible={showFundsIssueModal}
onClose={() => setShowFundsIssueModal(false)}
/>
</Row>
</>
);
}
Example #24
Source File: index.tsx From metaplex with Apache License 2.0 | 4 votes |
LaunchStep = (props: {
confirm: () => void;
attributes: IMetadataExtension;
files: File[];
connection: Connection;
}) => {
const [cost, setCost] = useState(0);
const { image } = useArtworkFiles(props.files, props.attributes);
const files = props.files;
const metadata = props.attributes;
useEffect(() => {
const rentCall = Promise.all([
props.connection.getMinimumBalanceForRentExemption(MintLayout.span),
props.connection.getMinimumBalanceForRentExemption(MAX_METADATA_LEN),
]);
if (files.length)
getAssetCostToStore([
...files,
new File([JSON.stringify(metadata)], 'metadata.json'),
]).then(async lamports => {
const sol = lamports / LAMPORT_MULTIPLIER;
// TODO: cache this and batch in one call
const [mintRent, metadataRent] = await rentCall;
// const uriStr = 'x';
// let uriBuilder = '';
// for (let i = 0; i < MAX_URI_LENGTH; i++) {
// uriBuilder += uriStr;
// }
const additionalSol = (metadataRent + mintRent) / LAMPORT_MULTIPLIER;
// TODO: add fees based on number of transactions and signers
setCost(sol + additionalSol);
});
}, [files, metadata, setCost]);
return (
<>
<Row className="call-to-action">
<h2>Launch your creation</h2>
<p>
Provide detailed description of your creative process to engage with
your audience.
</p>
</Row>
<Row className="content-action" justify="space-around">
<Col>
{props.attributes.image && (
<ArtCard
image={image}
animationURL={props.attributes.animation_url}
category={props.attributes.properties?.category}
name={props.attributes.name}
symbol={props.attributes.symbol}
small={true}
artView={props.files[1]?.type === 'unknown'}
className="art-create-card"
/>
)}
</Col>
<Col className="section" style={{ minWidth: 300 }}>
<Statistic
className="create-statistic"
title="Royalty Percentage"
value={props.attributes.seller_fee_basis_points / 100}
precision={2}
suffix="%"
/>
{cost ? (
<AmountLabel
title="Cost to Create"
amount={cost.toFixed(5)}
tokenInfo={useTokenList().tokenMap.get(
WRAPPED_SOL_MINT.toString(),
)}
/>
) : (
<Spin />
)}
</Col>
</Row>
<Row>
<Button
type="primary"
size="large"
onClick={props.confirm}
className="action-btn"
>
Pay with SOL
</Button>
<Button
disabled={true}
size="large"
onClick={props.confirm}
className="action-btn"
>
Pay with Credit Card
</Button>
</Row>
</>
);
}
Example #25
Source File: solana.tx.ts From tatum-js with MIT License | 4 votes |
mintNft = async (
body: MintSolanaNft,
web3: SolanaWeb3,
provider?: string,
feePayer?: string,
feePayerPrivateKey?: string,
) => {
const connection = web3.getClient(provider)
const from = new PublicKey(body.from)
const transaction = new Transaction({ feePayer: feePayer ? new PublicKey(feePayer) : from })
const mintRent = await connection.getMinimumBalanceForRentExemption(MintLayout.span)
const mint = Keypair.generate()
const instructions = []
instructions.push(
SystemProgram.createAccount({
fromPubkey: from,
newAccountPubkey: mint.publicKey,
lamports: mintRent,
space: MintLayout.span,
programId: TOKEN_PROGRAM_ID,
}),
createInitializeMintInstruction(mint.publicKey, 0, from, null, TOKEN_PROGRAM_ID),
)
const userTokenAccountAddress = (
await PublicKey.findProgramAddress(
[new PublicKey(body.to).toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.publicKey.toBuffer()],
SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
)
)[0]
instructions.push(
createAssociatedTokenAccountInstruction(
userTokenAccountAddress,
from,
new PublicKey(body.to),
mint.publicKey,
),
)
const metadataAccount = (
await PublicKey.findProgramAddress(
[Buffer.from('metadata'), TOKEN_METADATA_PROGRAM_ID.toBuffer(), mint.publicKey.toBuffer()],
TOKEN_METADATA_PROGRAM_ID,
)
)[0]
const metadata = new SolanaNftMetadata(
body.metadata.name,
body.metadata.symbol,
body.metadata.uri,
body.metadata.sellerFeeBasisPoints,
body.metadata.creators,
)
if (body.metadata.creators) {
metadata.creators = body.metadata.creators.map(
(c) => new SolanaNftMetadataCreator(c.address, c.verified, c.share),
)
}
const txnData = Buffer.from(
serialize(
METADATA_SCHEMA,
new CreateMetadataArgs({
data: metadata,
isMutable: true,
}),
),
)
instructions.push(
createMetadataInstruction(metadataAccount, mint.publicKey, from, from, from, txnData),
createMintToInstruction(mint.publicKey, userTokenAccountAddress, from, 1, [], TOKEN_PROGRAM_ID),
)
const editionAccount = (
await PublicKey.findProgramAddress(
[
Buffer.from('metadata'),
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mint.publicKey.toBuffer(),
Buffer.from('edition'),
],
TOKEN_METADATA_PROGRAM_ID,
)
)[0]
const masterEditionTxnData = Buffer.from(
serialize(METADATA_SCHEMA, new CreateMasterEditionArgs({ maxSupply: new BN(0) })),
)
instructions.push(
createMasterEditionInstruction(
metadataAccount,
editionAccount,
mint.publicKey,
from,
from,
from,
masterEditionTxnData,
),
)
transaction.add(...instructions)
if (body.signatureId) {
transaction.recentBlockhash = '7WyEshBZcZwEbJsvSeGgCkSNMxxxFAym3x7Cuj6UjAUE'
return {
txData: transaction.compileMessage().serialize().toString('hex'),
mintPK: Buffer.from(mint.secretKey).toString('hex'),
}
}
const wallet = web3.generateKeyPair(body.fromPrivateKey as string)
const signers = [mint, wallet]
if (feePayerPrivateKey) {
signers.push(web3.generateKeyPair(feePayerPrivateKey))
}
return {
txId: await connection.sendTransaction(transaction, [wallet, ...signers]),
nftAddress: mint.publicKey.toBase58(),
nftAccountAddress: userTokenAccountAddress.toBase58(),
}
}
Example #26
Source File: index.tsx From metaplex with Apache License 2.0 | 4 votes |
ArtMinting = ({ id, onMint }: ArtMintingProps) => {
const wallet = useWallet();
const connection = useConnection();
const { accountByMint } = useUserAccounts();
const [showMintModal, setShowMintModal] = useState<boolean>(false);
const [showCongrats, setShowCongrats] = useState<boolean>(false);
const [mintingDestination, setMintingDestination] = useState<string>('');
const [editions, setEditions] = useState<number>(1);
const [editionNumber, setEditionNumber] = useState<number | undefined>(
undefined,
);
const [totalCost, setTotalCost] = useState<number>(0);
const [isLoading, setIsLoading] = useState<boolean>(false);
const art = useArt(id);
const walletPubKey = wallet?.publicKey?.toString() || '';
const maxEditionsToMint = art.maxSupply! - art.supply!;
const isArtMasterEdition = art.type === ArtType.Master;
const artMintTokenAccount = accountByMint.get(art.mint!);
const isArtOwnedByUser =
((accountByMint.has(art.mint!) &&
artMintTokenAccount?.info.amount.toNumber()) ||
0) > 0;
const isMasterEditionV1 = artMintTokenAccount
? decodeMasterEdition(artMintTokenAccount.account.data).key ===
MetadataKey.MasterEditionV1
: false;
const renderMintEdition =
isArtMasterEdition &&
isArtOwnedByUser &&
!isMasterEditionV1 &&
maxEditionsToMint > 0;
const mintingDestinationErr = useMemo(() => {
if (!mintingDestination) return 'Required';
try {
new PublicKey(mintingDestination);
return '';
} catch (e) {
return 'Invalid address format';
}
}, [mintingDestination]);
const isMintingDisabled =
isLoading || editions < 1 || Boolean(mintingDestinationErr);
const debouncedEditionsChangeHandler = useCallback(
debounce(val => {
setEditions(val < 1 ? 1 : val);
}, 300),
[],
);
useEffect(() => {
if (editions < 1) return;
(async () => {
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
const accountRentExempt =
await connection.getMinimumBalanceForRentExemption(AccountLayout.span);
const metadataRentExempt =
await connection.getMinimumBalanceForRentExemption(MAX_METADATA_LEN);
const editionRentExempt =
await connection.getMinimumBalanceForRentExemption(MAX_EDITION_LEN);
const cost =
((mintRentExempt +
accountRentExempt +
metadataRentExempt +
editionRentExempt) *
editions) /
LAMPORTS_PER_SOL;
setTotalCost(cost);
})();
}, [connection, editions]);
useEffect(() => {
if (!walletPubKey) return;
setMintingDestination(walletPubKey);
}, [walletPubKey]);
useEffect(() => {
return debouncedEditionsChangeHandler.cancel();
}, []);
const onSuccessfulMint = () => {
setShowMintModal(false);
setMintingDestination(walletPubKey);
setEditions(1);
setShowCongrats(true);
};
const mint = async () => {
try {
setIsLoading(true);
await mintEditionsToWallet(
art,
wallet!,
connection,
artMintTokenAccount!,
editions,
mintingDestination,
editionNumber,
);
onSuccessfulMint();
} catch (e) {
console.error(e);
} finally {
setIsLoading(false);
}
};
return (
<>
{renderMintEdition && (
<div>
<Button
type="primary"
size="large"
className="action-btn"
style={{ marginTop: 20 }}
onClick={() => setShowMintModal(true)}
>
Mint
</Button>
<Modal
visible={showMintModal}
centered
okText="Mint"
closable={!isLoading}
okButtonProps={{
disabled: isMintingDisabled,
}}
cancelButtonProps={{ disabled: isLoading }}
onOk={mint}
onCancel={() => setShowMintModal(false)}
className="art-minting-modal"
>
<Form.Item
style={{
width: '100%',
flexDirection: 'column',
paddingTop: 30,
marginBottom: 4,
}}
label={<h3 style={{ color: 'white' }}>Mint to</h3>}
labelAlign="left"
colon={false}
validateStatus={mintingDestinationErr ? 'error' : 'success'}
help={mintingDestinationErr}
>
<Input
placeholder="Address to mint edition to"
value={mintingDestination}
onChange={e => {
setMintingDestination(e.target.value);
}}
/>
</Form.Item>
<Form.Item
style={{
width: '100%',
flexDirection: 'column',
paddingTop: 30,
}}
label={
<h3 style={{ color: 'white' }}>Number of editions to mint</h3>
}
labelAlign="left"
colon={false}
>
<InputNumber
type="number"
placeholder="1"
style={{ width: '100%' }}
min={1}
max={maxEditionsToMint}
value={editions}
precision={0}
onChange={debouncedEditionsChangeHandler}
/>
</Form.Item>
<Form.Item
style={{
width: '100%',
flexDirection: 'column',
paddingTop: 30,
}}
label={
<h3 style={{ color: 'white' }}>Edition Number (Optional)</h3>
}
labelAlign="left"
colon={false}
>
<InputNumber
type="number"
style={{ width: '100%' }}
min={1}
max={art.supply}
value={editionNumber}
precision={0}
onChange={setEditionNumber}
/>
</Form.Item>
<div>Total cost: {`◎${totalCost}`}</div>
</Modal>
<MetaplexOverlay visible={showCongrats}>
<Confetti />
<h1
className="title"
style={{
fontSize: '3rem',
marginBottom: 20,
}}
>
Congratulations
</h1>
<p
style={{
color: 'white',
textAlign: 'center',
fontSize: '2rem',
}}
>
New editions have been minted please view your NFTs in{' '}
<Link to="/artworks">My Items</Link>.
</p>
<Button
onClick={async () => {
await onMint();
setShowCongrats(false);
}}
className="overlay-btn"
>
Got it
</Button>
</MetaplexOverlay>
</div>
)}
</>
);
}
Example #27
Source File: sendRedeemBid.ts From metaplex with Apache License 2.0 | 4 votes |
export async function sendRedeemBid(
connection: Connection,
wallet: WalletSigner,
payingAccount: StringPublicKey,
auctionView: AuctionView,
accountsByMint: Map<string, TokenAccount>,
prizeTrackingTickets: Record<string, ParsedAccount<PrizeTrackingTicket>>,
bidRedemptions: Record<string, ParsedAccount<BidRedemptionTicket>>,
bids: ParsedAccount<BidderMetadata>[],
) {
if (!wallet.publicKey) throw new WalletNotConnectedError();
const signers: Array<Keypair[]> = [];
const instructions: Array<TransactionInstruction[]> = [];
if (
auctionView.auction.info.ended() &&
auctionView.auction.info.state !== AuctionState.Ended
) {
await setupPlaceBid(
connection,
wallet,
payingAccount,
auctionView,
accountsByMint,
0,
instructions,
signers,
);
}
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
let winnerIndex: number | null = null;
if (auctionView.myBidderPot?.pubkey)
winnerIndex = auctionView.auction.info.bidState.getWinnerIndex(
auctionView.myBidderPot?.info.bidderAct,
);
if (winnerIndex !== null) {
// items is a prebuilt array of arrays where each entry represents one
// winning spot, and each entry in it represents one type of item that can
// be received.
const winningSet = auctionView.items[winnerIndex];
for (let i = 0; i < winningSet.length; i++) {
const item = winningSet[i];
const safetyDeposit = item.safetyDeposit;
switch (item.winningConfigType) {
case WinningConfigType.PrintingV1:
console.log('Redeeming printing v1');
await deprecatedSetupRedeemPrintingV1Instructions(
auctionView,
accountsByMint,
accountRentExempt,
mintRentExempt,
wallet,
safetyDeposit,
item,
winnerIndex,
signers,
instructions,
);
break;
case WinningConfigType.PrintingV2:
console.log('Redeeming printing v2');
await setupRedeemPrintingV2Instructions(
connection,
auctionView,
mintRentExempt,
wallet,
wallet.publicKey.toBase58(),
safetyDeposit,
item,
signers,
instructions,
winnerIndex,
prizeTrackingTickets,
);
break;
case WinningConfigType.FullRightsTransfer:
console.log('Redeeming Full Rights');
await setupRedeemFullRightsTransferInstructions(
auctionView,
accountsByMint,
accountRentExempt,
wallet,
safetyDeposit,
item,
winnerIndex,
signers,
instructions,
);
break;
case WinningConfigType.TokenOnlyTransfer:
console.log('Redeeming Token only');
await setupRedeemInstructions(
auctionView,
accountsByMint,
accountRentExempt,
wallet,
safetyDeposit,
winnerIndex,
signers,
instructions,
);
break;
}
}
if (auctionView.myBidderMetadata && auctionView.myBidderPot) {
const claimSigners: Keypair[] = [];
const claimInstructions: TransactionInstruction[] = [];
instructions.push(claimInstructions);
signers.push(claimSigners);
console.log('Claimed');
await claimBid(
auctionView.auctionManager.acceptPayment,
auctionView.myBidderMetadata.info.bidderPubkey,
auctionView.myBidderPot?.info.bidderPot,
auctionView.vault.pubkey,
auctionView.auction.info.tokenMint,
claimInstructions,
);
}
} else {
// If you didnt win, you must have a bid we can refund before we check for open editions.
await setupCancelBid(
auctionView,
accountsByMint,
accountRentExempt,
wallet,
signers,
instructions,
connection,
);
}
if (
auctionView.participationItem &&
eligibleForParticipationPrizeGivenWinningIndex(
winnerIndex,
auctionView,
auctionView.myBidderMetadata,
auctionView.myBidRedemption,
)
) {
console.log('eligible for participation');
const item = auctionView.participationItem;
const safetyDeposit = item.safetyDeposit;
if (item.masterEdition?.info.key == MetadataKey.MasterEditionV1) {
await deprecatedSetupRedeemParticipationInstructions(
connection,
auctionView,
accountsByMint,
accountRentExempt,
mintRentExempt,
wallet,
safetyDeposit,
item,
signers,
instructions,
);
} else {
await setupRedeemParticipationInstructions(
connection,
auctionView,
accountsByMint,
accountRentExempt,
mintRentExempt,
wallet,
wallet.publicKey.toBase58(),
safetyDeposit,
auctionView.myBidRedemption,
auctionView.myBidderMetadata,
item,
signers,
instructions,
);
}
}
if (wallet.publicKey.toBase58() === auctionView.auctionManager.authority) {
await claimUnusedPrizes(
connection,
wallet,
auctionView,
accountsByMint,
bids,
bidRedemptions,
prizeTrackingTickets,
signers,
instructions,
);
}
await sendTransactionsWithManualRetry(
connection,
wallet,
instructions,
signers,
);
}
Example #28
Source File: nft.tsx From metaplex with Apache License 2.0 | 4 votes |
mintNFT = async (
connection: Connection,
wallet: WalletSigner | undefined,
endpoint: ENDPOINT_NAME,
files: File[],
metadata: {
name: string;
symbol: string;
description: string;
image: string | undefined;
animation_url: string | undefined;
attributes: Attribute[] | undefined;
external_url: string;
properties: any;
creators: Creator[] | null;
sellerFeeBasisPoints: number;
collection?: string;
uses?: Uses;
},
progressCallback: Dispatch<SetStateAction<number>>,
maxSupply?: number,
): Promise<{
metadataAccount: StringPublicKey;
} | void> => {
if (!wallet?.publicKey) return;
const metadataContent = {
name: metadata.name,
symbol: metadata.symbol,
description: metadata.description,
seller_fee_basis_points: metadata.sellerFeeBasisPoints,
image: metadata.image,
animation_url: metadata.animation_url,
attributes: metadata.attributes,
external_url: metadata.external_url,
properties: {
...metadata.properties,
creators: metadata.creators?.map(creator => {
return {
address: creator.address,
share: creator.share,
};
}),
},
collection: metadata.collection
? new PublicKey(metadata.collection).toBase58()
: null,
use: metadata.uses ? metadata.uses : null,
};
const realFiles: File[] = [
...files,
new File([JSON.stringify(metadataContent)], RESERVED_METADATA),
];
const { instructions: pushInstructions, signers: pushSigners } =
await prepPayForFilesTxn(wallet, realFiles);
progressCallback(1);
const TOKEN_PROGRAM_ID = programIds().token;
// Allocate memory for the account
const mintRent = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
// const accountRent = await connection.getMinimumBalanceForRentExemption(
// AccountLayout.span,
// );
// This owner is a temporary signer and owner of metadata we use to circumvent requesting signing
// twice post Arweave. We store in an account (payer) and use it post-Arweave to update MD with new link
// then give control back to the user.
// const payer = new Account();
const payerPublicKey = wallet.publicKey.toBase58();
const instructions: TransactionInstruction[] = [...pushInstructions];
const signers: Keypair[] = [...pushSigners];
// This is only temporarily owned by wallet...transferred to program by createMasterEdition below
const mintKey = createMint(
instructions,
wallet.publicKey,
mintRent,
0,
// Some weird bug with phantom where it's public key doesnt mesh with data encode wellff
toPublicKey(payerPublicKey),
toPublicKey(payerPublicKey),
signers,
).toBase58();
const recipientKey = (
await findProgramAddress(
[
wallet.publicKey.toBuffer(),
programIds().token.toBuffer(),
toPublicKey(mintKey).toBuffer(),
],
programIds().associatedToken,
)
)[0];
createAssociatedTokenAccountInstruction(
instructions,
toPublicKey(recipientKey),
wallet.publicKey,
wallet.publicKey,
toPublicKey(mintKey),
);
const metadataAccount = await createMetadataV2(
new DataV2({
symbol: metadata.symbol,
name: metadata.name,
uri: ' '.repeat(64), // size of url for arweave
sellerFeeBasisPoints: metadata.sellerFeeBasisPoints,
creators: metadata.creators,
collection: metadata.collection
? new Collection({
key: new PublicKey(metadata.collection).toBase58(),
verified: false,
})
: null,
uses: metadata.uses || null,
}),
payerPublicKey,
mintKey,
payerPublicKey,
instructions,
wallet.publicKey.toBase58(),
);
progressCallback(2);
// TODO: enable when using payer account to avoid 2nd popup
// const block = await connection.getRecentBlockhash('singleGossip');
// instructions.push(
// SystemProgram.transfer({
// fromPubkey: wallet.publicKey,
// toPubkey: payerPublicKey,
// lamports: 0.5 * LAMPORTS_PER_SOL // block.feeCalculator.lamportsPerSignature * 3 + mintRent, // TODO
// }),
// );
const { txid } = await sendTransactionWithRetry(
connection,
wallet,
instructions,
signers,
'single',
);
progressCallback(3);
try {
await connection.confirmTransaction(txid, 'max');
progressCallback(4);
} catch {
// ignore
}
// Force wait for max confirmations
// await connection.confirmTransaction(txid, 'max');
await connection.getParsedConfirmedTransaction(txid, 'confirmed');
progressCallback(5);
// this means we're done getting AR txn setup. Ship it off to ARWeave!
const data = new FormData();
data.append('transaction', txid);
data.append('env', endpoint);
const tags = realFiles.reduce(
(acc: Record<string, Array<{ name: string; value: string }>>, f) => {
acc[f.name] = [{ name: 'mint', value: mintKey }];
return acc;
},
{},
);
data.append('tags', JSON.stringify(tags));
realFiles.map(f => data.append('file[]', f));
// TODO: convert to absolute file name for image
const result: IArweaveResult = await uploadToArweave(data);
progressCallback(6);
const metadataFile = result.messages?.find(
m => m.filename === RESERVED_TXN_MANIFEST,
);
if (metadataFile?.transactionId && wallet.publicKey) {
const updateInstructions: TransactionInstruction[] = [];
const updateSigners: Keypair[] = [];
// TODO: connect to testnet arweave
const arweaveLink = `https://arweave.net/${metadataFile.transactionId}`;
await updateMetadataV2(
new DataV2({
symbol: metadata.symbol,
name: metadata.name,
uri: arweaveLink,
sellerFeeBasisPoints: metadata.sellerFeeBasisPoints,
creators: metadata.creators,
collection: metadata.collection
? new Collection({
key: new PublicKey(metadata.collection).toBase58(),
verified: false,
})
: null,
uses: metadata.uses || null,
}),
undefined,
undefined,
mintKey,
payerPublicKey,
updateInstructions,
metadataAccount,
);
updateInstructions.push(
Token.createMintToInstruction(
TOKEN_PROGRAM_ID,
toPublicKey(mintKey),
toPublicKey(recipientKey),
toPublicKey(payerPublicKey),
[],
1,
),
);
progressCallback(7);
// // In this instruction, mint authority will be removed from the main mint, while
// // minting authority will be maintained for the Printing mint (which we want.)
await createMasterEditionV3(
maxSupply !== undefined ? new BN(maxSupply) : undefined,
mintKey,
payerPublicKey,
payerPublicKey,
payerPublicKey,
updateInstructions,
);
// TODO: enable when using payer account to avoid 2nd popup
/* if (maxSupply !== undefined)
updateInstructions.push(
setAuthority({
target: authTokenAccount,
currentAuthority: payerPublicKey,
newAuthority: wallet.publicKey,
authorityType: 'AccountOwner',
}),
);
*/
// TODO: enable when using payer account to avoid 2nd popup
// Note with refactoring this needs to switch to the updateMetadataAccount command
// await transferUpdateAuthority(
// metadataAccount,
// payerPublicKey,
// wallet.publicKey,
// updateInstructions,
// );
progressCallback(8);
await sendTransactionWithRetry(
connection,
wallet,
updateInstructions,
updateSigners,
);
notify({
message: 'Art created on Solana',
description: (
<a href={arweaveLink} target="_blank" rel="noopener noreferrer">
Arweave Link
</a>
),
type: 'success',
});
// TODO: refund funds
// send transfer back to user
}
// TODO:
// 1. Jordan: --- upload file and metadata to storage API
// 2. pay for storage by hashing files and attaching memo for each file
return { metadataAccount };
}
Example #29
Source File: createVault.ts From metaplex with Apache License 2.0 | 4 votes |
// This command creates the external pricing oracle a vault
// This gets the vault ready for adding the tokens.
export async function createVault(
connection: Connection,
wallet: WalletSigner,
priceMint: StringPublicKey,
externalPriceAccount: StringPublicKey,
): Promise<{
vault: StringPublicKey;
fractionalMint: StringPublicKey;
redeemTreasury: StringPublicKey;
fractionTreasury: StringPublicKey;
instructions: TransactionInstruction[];
signers: Keypair[];
}> {
if (!wallet.publicKey) throw new WalletNotConnectedError();
const PROGRAM_IDS = utils.programIds();
const signers: Keypair[] = [];
const instructions: TransactionInstruction[] = [];
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
const vaultRentExempt = await connection.getMinimumBalanceForRentExemption(
MAX_VAULT_SIZE,
);
const vault = Keypair.generate();
const vaultAuthority = (
await findProgramAddress(
[
Buffer.from(VAULT_PREFIX),
toPublicKey(PROGRAM_IDS.vault).toBuffer(),
vault.publicKey.toBuffer(),
],
toPublicKey(PROGRAM_IDS.vault),
)
)[0];
const fractionalMint = createMint(
instructions,
wallet.publicKey,
mintRentExempt,
0,
toPublicKey(vaultAuthority),
toPublicKey(vaultAuthority),
signers,
).toBase58();
const redeemTreasury = createTokenAccount(
instructions,
wallet.publicKey,
accountRentExempt,
toPublicKey(priceMint),
toPublicKey(vaultAuthority),
signers,
).toBase58();
const fractionTreasury = createTokenAccount(
instructions,
wallet.publicKey,
accountRentExempt,
toPublicKey(fractionalMint),
toPublicKey(vaultAuthority),
signers,
).toBase58();
const uninitializedVault = SystemProgram.createAccount({
fromPubkey: wallet.publicKey,
newAccountPubkey: vault.publicKey,
lamports: vaultRentExempt,
space: MAX_VAULT_SIZE,
programId: toPublicKey(PROGRAM_IDS.vault),
});
instructions.push(uninitializedVault);
signers.push(vault);
await initVault(
true,
fractionalMint,
redeemTreasury,
fractionTreasury,
vault.publicKey.toBase58(),
wallet.publicKey.toBase58(),
externalPriceAccount,
instructions,
);
return {
vault: vault.publicKey.toBase58(),
fractionalMint,
redeemTreasury,
fractionTreasury,
signers,
instructions,
};
}