diff --git a/packages/common/src/actions/auction.ts b/packages/common/src/actions/auction.ts index 9d07210..fddeff1 100644 --- a/packages/common/src/actions/auction.ts +++ b/packages/common/src/actions/auction.ts @@ -142,27 +142,30 @@ export class WinnerLimit { class CreateAuctionArgs { instruction: number = 0; /// How many winners are allowed for this auction. See AuctionData. - winners: WinnerLimit; + winnerType: number; + winnerAmount: BN | null; /// The resource being auctioned. See AuctionData. resource: PublicKey; /// End time is the cut-off point that the auction is forced to end by. See AuctionData. - endAuctionAt?: BN; + endAuctionAt: BN | null; /// Gap time is how much time after the previous bid where the auction ends. See AuctionData. - endAuctionGap?: BN; + endAuctionGap: BN | null; /// Token mint for the SPL token used for bidding. tokenMint: PublicKey; /// Authority authority: PublicKey; constructor(args: { - winners: WinnerLimit; + winnerType: number; + winnerAmount: BN | null; resource: PublicKey; - endAuctionAt?: BN; - endAuctionGap?: BN; + endAuctionAt: BN | null; + endAuctionGap: BN | null; tokenMint: PublicKey; authority: PublicKey; }) { - this.winners = args.winners; + this.winnerType = args.winnerType; + this.winnerAmount = args.winnerAmount; this.resource = args.resource; this.endAuctionAt = args.endAuctionAt; this.endAuctionGap = args.endAuctionGap; @@ -198,8 +201,8 @@ export const AUCTION_SCHEMA = new Map([ kind: 'struct', fields: [ ['instruction', 'u8'], - ['winnerLimitType', 'u8'], - ['usize', { kind: 'option', type: 'u64' }], + ['winnerType', 'u8'], + ['winnerAmount', { kind: 'option', type: 'u64' }], ['resource', 'pubkey'], ['endAuctionAt', { kind: 'option', type: 'u64' }], ['endAuctionGap', { kind: 'option', type: 'u64' }], @@ -296,8 +299,8 @@ export const decodeAuctionData = (buffer: Buffer) => { export async function createAuction( winners: WinnerLimit, resource: PublicKey, - endAuctionAt: BN | undefined, - endAuctionGap: BN | undefined, + endAuctionAt: BN | null, + endAuctionGap: BN | null, tokenMint: PublicKey, authority: PublicKey, creator: PublicKey, @@ -309,7 +312,8 @@ export async function createAuction( serialize( AUCTION_SCHEMA, new CreateAuctionArgs({ - winners, + winnerType: winners.type, + winnerAmount: winners.usize == undefined ? null : winners.usize, resource, endAuctionAt, endAuctionGap, @@ -319,6 +323,10 @@ export async function createAuction( ), ); + console.log('Winner', winners); + + console.log('Data', data); + const auctionKey: PublicKey = ( await PublicKey.findProgramAddress( [ diff --git a/packages/common/src/actions/metadata.ts b/packages/common/src/actions/metadata.ts index 7fdfac2..7771d86 100644 --- a/packages/common/src/actions/metadata.ts +++ b/packages/common/src/actions/metadata.ts @@ -529,7 +529,7 @@ export async function createMasterEdition( const metadataAccount = ( await PublicKey.findProgramAddress( [ - Buffer.from('metadata'), + Buffer.from(METADATA_PREFIX), metadataProgramId.toBuffer(), mintKey.toBuffer(), ], @@ -540,7 +540,7 @@ export async function createMasterEdition( const nameSymbolAccount = ( await PublicKey.findProgramAddress( [ - Buffer.from('metadata'), + Buffer.from(METADATA_PREFIX), metadataProgramId.toBuffer(), Buffer.from(name), Buffer.from(symbol), @@ -552,10 +552,10 @@ export async function createMasterEdition( const editionAccount = ( await PublicKey.findProgramAddress( [ - Buffer.from('metadata'), + Buffer.from(METADATA_PREFIX), metadataProgramId.toBuffer(), mintKey.toBuffer(), - Buffer.from('edition'), + Buffer.from(EDITION), ], metadataProgramId, ) diff --git a/packages/common/src/actions/vault.ts b/packages/common/src/actions/vault.ts index f67cb7b..f837bd7 100644 --- a/packages/common/src/actions/vault.ts +++ b/packages/common/src/actions/vault.ts @@ -204,10 +204,7 @@ export const VAULT_SCHEMA = new Map([ kind: 'struct', fields: [ ['instruction', 'u8'], - ['key', 'u8'], - ['pricePerShare', 'u64'], - ['priceMint', 'pubkey'], - ['allowToCombine', 'u8'], + ['externalPriceAccount', ExternalPriceAccount], ], }, ], @@ -251,7 +248,7 @@ export const VAULT_SCHEMA = new Map([ ['key', 'u8'], ['pricePerShare', 'u64'], ['priceMint', 'pubkey'], - ['allowToCombine', 'u8'], + ['allowedToCombine', 'u8'], ], }, ], @@ -671,6 +668,7 @@ export async function updateExternalPriceAccount( const value = new UpdateExternalPriceAccountArgs({ externalPriceAccount }); const data = Buffer.from(serialize(VAULT_SCHEMA, value)); + console.log('Data', data); const keys = [ { diff --git a/packages/common/src/contexts/connection.tsx b/packages/common/src/contexts/connection.tsx index 079149e..8fbebe3 100644 --- a/packages/common/src/contexts/connection.tsx +++ b/packages/common/src/contexts/connection.tsx @@ -487,6 +487,11 @@ export async function sendSignedTransaction({ true, ); + if (confirmation.err) { + console.error(confirmation.err); + throw new Error('Transaction failed: Custom instruction error'); + } + slot = confirmation?.slot || 0; } catch (err) { if (err.timeout) { @@ -580,8 +585,10 @@ async function awaitTransactionSignatureConfirmation( confirmations: 0, }; if (result.err) { + console.log('Rejected via websocket', result.err); reject(result.err); } else { + console.log('Resolved via websocket', result); resolve(result); } }, @@ -624,7 +631,7 @@ async function awaitTransactionSignatureConfirmation( } })(); }) - .catch(_ => { + .catch(err => { //@ts-ignore if (connection._signatureSubscriptions[subId]) connection.removeSignatureListener(subId); diff --git a/packages/metavinci/src/actions/addTokensToVault.tsx b/packages/metavinci/src/actions/addTokensToVault.ts similarity index 100% rename from packages/metavinci/src/actions/addTokensToVault.tsx rename to packages/metavinci/src/actions/addTokensToVault.ts diff --git a/packages/metavinci/src/actions/closeVault.tsx b/packages/metavinci/src/actions/closeVault.ts similarity index 90% rename from packages/metavinci/src/actions/closeVault.tsx rename to packages/metavinci/src/actions/closeVault.ts index 95993d3..20d78da 100644 --- a/packages/metavinci/src/actions/closeVault.tsx +++ b/packages/metavinci/src/actions/closeVault.ts @@ -40,12 +40,6 @@ export async function closeVault( ); let signers: Account[] = []; let instructions: TransactionInstruction[] = []; - const vaultAuthority = ( - await PublicKey.findProgramAddress( - [Buffer.from(VAULT_PREFIX), PROGRAM_IDS.vault.toBuffer()], - PROGRAM_IDS.vault, - ) - )[0]; const auctionKey: PublicKey = ( await PublicKey.findProgramAddress( @@ -70,7 +64,7 @@ export async function closeVault( vault, fractionMint, fractionTreasury, - vaultAuthority, + wallet.publicKey, instructions, ); @@ -92,14 +86,30 @@ export async function closeVault( signers, ); + let transferAuthority = new Account(); + // Shouldn't need to pay anything since we activated vault with 0 shares, but we still // need this setup anyway. - const transferAuthority = approve( + approve( instructions, [], payingTokenAccount, wallet.publicKey, 0, + false, + undefined, + transferAuthority, + ); + + approve( + instructions, + [], + outstandingShareAccount, + wallet.publicKey, + 0, + false, + undefined, + transferAuthority, ); signers.push(transferAuthority); diff --git a/packages/metavinci/src/actions/createAuctionManager.tsx b/packages/metavinci/src/actions/createAuctionManager.ts similarity index 90% rename from packages/metavinci/src/actions/createAuctionManager.tsx rename to packages/metavinci/src/actions/createAuctionManager.ts index b4e1a29..c873e0c 100644 --- a/packages/metavinci/src/actions/createAuctionManager.tsx +++ b/packages/metavinci/src/actions/createAuctionManager.ts @@ -31,6 +31,7 @@ import { createVault } from './createVault'; import { closeVault } from './closeVault'; import { addTokensToVault } from './addTokensToVault'; import { makeAuction } from './makeAuction'; +import { createExternalPriceAccount } from './createExternalPriceAccount'; const { createTokenAccount } = actions; interface normalPattern { @@ -51,6 +52,7 @@ interface byType { makeAuction: normalPattern; initAuctionManager: normalPattern; startAuction: normalPattern; + externalPriceAccount: normalPattern; } export interface SafetyDepositDraft { @@ -77,16 +79,21 @@ export async function createAuctionManager( auction: PublicKey; auctionManager: PublicKey; }> { + const { + externalPriceAccount, + priceMint, + instructions: epaInstructions, + signers: epaSigners, + } = await createExternalPriceAccount(connection, wallet); + const { instructions: createVaultInstructions, signers: createVaultSigners, vault, - externalPriceAccount, fractionalMint, redeemTreasury, fractionTreasury, - priceMint, - } = await createVault(connection, wallet); + } = await createVault(connection, wallet, priceMint, externalPriceAccount); const { instructions: makeAuctionInstructions, @@ -131,6 +138,10 @@ export async function createAuctionManager( } = await addTokensToVault(connection, wallet, vault, nftConfigs); let lookup: byType = { + externalPriceAccount: { + instructions: epaInstructions, + signers: epaSigners, + }, createVault: { instructions: createVaultInstructions, signers: createVaultSigners, @@ -159,6 +170,7 @@ export async function createAuctionManager( }; let signers: Account[][] = [ + lookup.externalPriceAccount.signers, lookup.createVault.signers, ...lookup.addTokens.signers, lookup.closeVault.signers, @@ -168,6 +180,7 @@ export async function createAuctionManager( lookup.startAuction.signers, ]; let instructions: TransactionInstruction[][] = [ + lookup.externalPriceAccount.instructions, lookup.createVault.instructions, ...lookup.addTokens.instructions, lookup.closeVault.instructions, @@ -225,13 +238,13 @@ async function setupAuctionManagerInstructions( vault, openEditionSafetyDeposit?.metadata.pubkey, openEditionSafetyDeposit?.nameSymbol?.pubkey, - wallet.pubkey, + wallet.publicKey, openEditionSafetyDeposit?.masterEdition?.pubkey, openEditionSafetyDeposit?.metadata.info.mint, openEditionSafetyDeposit?.masterEdition?.info.masterMint, - wallet.pubkey, - wallet.pubkey, - wallet.pubkey, + wallet.publicKey, + wallet.publicKey, + wallet.publicKey, acceptPayment, settings, instructions, @@ -282,12 +295,12 @@ async function validateBoxes( safetyDepositBox, stores[i], safetyDeposits[i].metadata.info.mint, - wallet.pubkey, - wallet.pubkey, - wallet.pubkey, + wallet.publicKey, + wallet.publicKey, + wallet.publicKey, tokenInstructions, safetyDeposits[i].masterEdition?.info.masterMint, - safetyDeposits[i].masterEdition ? wallet.pubkey : undefined, + safetyDeposits[i].masterEdition ? wallet.publicKey : undefined, ); signers.push(tokenSigners); diff --git a/packages/metavinci/src/actions/createExternalPriceAccount.ts b/packages/metavinci/src/actions/createExternalPriceAccount.ts new file mode 100644 index 0000000..430cf90 --- /dev/null +++ b/packages/metavinci/src/actions/createExternalPriceAccount.ts @@ -0,0 +1,81 @@ +import { + Account, + Connection, + PublicKey, + SystemProgram, + TransactionInstruction, +} from '@solana/web3.js'; +import { utils, actions, createMint, VAULT_SCHEMA } from '@oyster/common'; + +import { MintLayout } from '@solana/spl-token'; +import BN from 'bn.js'; +const { + updateExternalPriceAccount, + ExternalPriceAccount, + MAX_EXTERNAL_ACCOUNT_SIZE, +} = actions; + +// This command creates the external pricing oracle +export async function createExternalPriceAccount( + connection: Connection, + wallet: any, +): Promise<{ + priceMint: PublicKey; + externalPriceAccount: PublicKey; + instructions: TransactionInstruction[]; + signers: Account[]; +}> { + const PROGRAM_IDS = utils.programIds(); + + let signers: Account[] = []; + let instructions: TransactionInstruction[] = []; + + const mintRentExempt = await connection.getMinimumBalanceForRentExemption( + MintLayout.span, + ); + + const epaRentExempt = await connection.getMinimumBalanceForRentExemption( + MAX_EXTERNAL_ACCOUNT_SIZE, + ); + + let externalPriceAccount = new Account(); + + const priceMint = createMint( + instructions, + wallet.publicKey, + mintRentExempt, + 0, + wallet.publicKey, + wallet.publicKey, + signers, + ); + + let epaStruct = new ExternalPriceAccount({ + pricePerShare: new BN(0), + priceMint: priceMint, + allowedToCombine: true, + }); + + const uninitializedEPA = SystemProgram.createAccount({ + fromPubkey: wallet.publicKey, + newAccountPubkey: externalPriceAccount.publicKey, + lamports: epaRentExempt, + space: MAX_EXTERNAL_ACCOUNT_SIZE, + programId: PROGRAM_IDS.vault, + }); + instructions.push(uninitializedEPA); + signers.push(externalPriceAccount); + + await updateExternalPriceAccount( + externalPriceAccount.publicKey, + epaStruct, + instructions, + ); + + return { + externalPriceAccount: externalPriceAccount.publicKey, + priceMint, + instructions, + signers, + }; +} diff --git a/packages/metavinci/src/actions/createVault.ts b/packages/metavinci/src/actions/createVault.ts index 01ef522..8a28bfb 100644 --- a/packages/metavinci/src/actions/createVault.ts +++ b/packages/metavinci/src/actions/createVault.ts @@ -5,32 +5,23 @@ import { SystemProgram, TransactionInstruction, } from '@solana/web3.js'; -import { contexts, utils, actions, createMint } from '@oyster/common'; +import { utils, actions, createMint } from '@oyster/common'; import { AccountLayout, MintLayout } from '@solana/spl-token'; -import BN from 'bn.js'; -const { - createTokenAccount, - initVault, - updateExternalPriceAccount, - ExternalPriceAccount, - MAX_VAULT_SIZE, - VAULT_PREFIX, - MAX_EXTERNAL_ACCOUNT_SIZE, -} = actions; +const { createTokenAccount, initVault, MAX_VAULT_SIZE, VAULT_PREFIX } = actions; // 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: any, + priceMint: PublicKey, + externalPriceAccount: PublicKey, ): Promise<{ vault: PublicKey; - externalPriceAccount: PublicKey; fractionalMint: PublicKey; redeemTreasury: PublicKey; fractionTreasury: PublicKey; - priceMint: PublicKey; instructions: TransactionInstruction[]; signers: Account[]; }> { @@ -51,12 +42,7 @@ export async function createVault( MAX_VAULT_SIZE, ); - const epaRentExempt = await connection.getMinimumBalanceForRentExemption( - MAX_EXTERNAL_ACCOUNT_SIZE, - ); - let vault = new Account(); - let externalPriceAccount = new Account(); const vaultAuthority = ( await PublicKey.findProgramAddress( @@ -74,21 +60,6 @@ export async function createVault( vaultAuthority, signers, ); - const priceMint = createMint( - instructions, - wallet.publicKey, - mintRentExempt, - 0, - vaultAuthority, - vaultAuthority, - signers, - ); - - let epaStruct = new ExternalPriceAccount({ - pricePerShare: new BN(0), - priceMint: priceMint, - allowedToCombine: true, - }); const redeemTreasury = createTokenAccount( instructions, @@ -115,23 +86,8 @@ export async function createVault( space: MAX_VAULT_SIZE, programId: PROGRAM_IDS.vault, }); - const uninitializedEPA = SystemProgram.createAccount({ - fromPubkey: wallet.publicKey, - newAccountPubkey: vault.publicKey, - lamports: epaRentExempt, - space: MAX_EXTERNAL_ACCOUNT_SIZE, - programId: PROGRAM_IDS.vault, - }); instructions.push(uninitializedVault); - instructions.push(uninitializedEPA); signers.push(vault); - signers.push(externalPriceAccount); - - await updateExternalPriceAccount( - externalPriceAccount.publicKey, - epaStruct, - instructions, - ); await initVault( true, @@ -140,17 +96,15 @@ export async function createVault( fractionTreasury, vault.publicKey, wallet.publicKey, - externalPriceAccount.publicKey, + externalPriceAccount, instructions, ); return { vault: vault.publicKey, - externalPriceAccount: externalPriceAccount.publicKey, fractionalMint, redeemTreasury, fractionTreasury, - priceMint, signers, instructions, }; diff --git a/packages/metavinci/src/actions/makeAuction.tsx b/packages/metavinci/src/actions/makeAuction.ts similarity index 100% rename from packages/metavinci/src/actions/makeAuction.tsx rename to packages/metavinci/src/actions/makeAuction.ts diff --git a/packages/metavinci/src/hooks/useUserArts.tsx b/packages/metavinci/src/hooks/useUserArts.tsx index cfff151..1ec723c 100644 --- a/packages/metavinci/src/hooks/useUserArts.tsx +++ b/packages/metavinci/src/hooks/useUserArts.tsx @@ -10,8 +10,11 @@ export const useUserArts = (): SafetyDepositDraft[] => { return prev; }, new Map()); - const ownedMetadata = metadata.filter(m => - accountByMint.has(m.info.mint.toBase58()), + const ownedMetadata = metadata.filter( + m => + accountByMint.has(m.info.mint.toBase58()) && + (accountByMint?.get(m.info.mint.toBase58())?.info?.amount?.toNumber() || + 0) > 0, ); const possibleNameSymbols = ownedMetadata.map(m => diff --git a/packages/metavinci/src/models/metaplex/index.ts b/packages/metavinci/src/models/metaplex/index.ts index 9b49821..76ec495 100644 --- a/packages/metavinci/src/models/metaplex/index.ts +++ b/packages/metavinci/src/models/metaplex/index.ts @@ -65,7 +65,7 @@ export class AuctionManager { export class InitAuctionManagerArgs { instruction = 0; - settings?: AuctionManagerSettings; + settings: AuctionManagerSettings; constructor(args: { settings: AuctionManagerSettings }) { this.settings = args.settings; @@ -102,8 +102,8 @@ export class AuctionManagerSettings { openEditionNonWinningConstraint: NonWinningConstraint = NonWinningConstraint.GivenForFixedPrice; winningConfigs: WinningConfig[] = []; - openEditionConfig?: number = 0; - openEditionFixedPrice?: number = 0; + openEditionConfig: number | null = 0; + openEditionFixedPrice: number | null = 0; constructor(args?: AuctionManagerSettings) { Object.assign(this, args); @@ -196,8 +196,8 @@ export const SCHEMA = new Map([ ['tokenMetadataProgram', 'pubkey'], ['tokenProgram', 'pubkey'], ['acceptPayment', 'pubkey'], - ['state', 'AuctionManagerState'], - ['settings', 'AuctionManagerSettings'], + ['state', AuctionManagerState], + ['settings', AuctionManagerSettings], ], }, ], @@ -265,7 +265,7 @@ export const SCHEMA = new Map([ kind: 'struct', fields: [ ['instruction', 'u8'], - ['manager', 'AuctionManagerSettings'], + ['settings', AuctionManagerSettings], ], }, ], diff --git a/packages/metavinci/src/models/metaplex/initAuctionManager.ts b/packages/metavinci/src/models/metaplex/initAuctionManager.ts index 1e90aa1..37d65e1 100644 --- a/packages/metavinci/src/models/metaplex/initAuctionManager.ts +++ b/packages/metavinci/src/models/metaplex/initAuctionManager.ts @@ -1,4 +1,4 @@ -import { programIds, VAULT_SCHEMA } from '@oyster/common'; +import { programIds } from '@oyster/common'; import { PublicKey, SystemProgram, @@ -11,6 +11,7 @@ import { AuctionManagerSettings, getAuctionKeys, InitAuctionManagerArgs, + SCHEMA, } from '.'; export async function initAuctionManager( @@ -35,7 +36,16 @@ export async function initAuctionManager( settings, }); - const data = Buffer.from(serialize(VAULT_SCHEMA, value)); + const data = Buffer.from(serialize(SCHEMA, value)); + console.log( + 'Auction', + auctionManagerKey, + vault, + auctionKey, + auctionManagerAuthority, + payer, + acceptPaymentAccount, + ); const keys = [ { pubkey: auctionManagerKey, diff --git a/packages/metavinci/src/models/metaplex/redeemBid.ts b/packages/metavinci/src/models/metaplex/redeemBid.ts index a607747..a99834d 100644 --- a/packages/metavinci/src/models/metaplex/redeemBid.ts +++ b/packages/metavinci/src/models/metaplex/redeemBid.ts @@ -1,4 +1,4 @@ -import { programIds, VAULT_SCHEMA, VAULT_PREFIX } from '@oyster/common'; +import { programIds, VAULT_PREFIX } from '@oyster/common'; import { PublicKey, SystemProgram, @@ -8,7 +8,7 @@ import { } from '@solana/web3.js'; import { serialize } from 'borsh'; -import { getAuctionKeys, getBidderKeys, RedeemBidArgs } from '.'; +import { getAuctionKeys, getBidderKeys, RedeemBidArgs, SCHEMA } from '.'; export async function redeemBid( vault: PublicKey, @@ -37,7 +37,7 @@ export async function redeemBid( )[0]; const value = new RedeemBidArgs(); - const data = Buffer.from(serialize(VAULT_SCHEMA, value)); + const data = Buffer.from(serialize(SCHEMA, value)); const keys = [ { pubkey: auctionManagerKey, diff --git a/packages/metavinci/src/models/metaplex/redeemLimitedEditionBid.ts b/packages/metavinci/src/models/metaplex/redeemLimitedEditionBid.ts index e8f546f..154d71f 100644 --- a/packages/metavinci/src/models/metaplex/redeemLimitedEditionBid.ts +++ b/packages/metavinci/src/models/metaplex/redeemLimitedEditionBid.ts @@ -1,4 +1,4 @@ -import { getEdition, programIds, VAULT_SCHEMA } from '@oyster/common'; +import { getEdition, programIds } from '@oyster/common'; import { PublicKey, SystemProgram, @@ -14,6 +14,7 @@ import { getMetadata, getOriginalAuthority, RedeemLimitedEditionBidArgs, + SCHEMA, } from '.'; export async function redeemLimitedEditionBid( @@ -50,7 +51,7 @@ export async function redeemLimitedEditionBid( ); const value = new RedeemLimitedEditionBidArgs(); - const data = Buffer.from(serialize(VAULT_SCHEMA, value)); + const data = Buffer.from(serialize(SCHEMA, value)); const keys = [ { pubkey: auctionManagerKey, diff --git a/packages/metavinci/src/models/metaplex/redeemMasterEditionBid.ts b/packages/metavinci/src/models/metaplex/redeemMasterEditionBid.ts index 562529d..89825a2 100644 --- a/packages/metavinci/src/models/metaplex/redeemMasterEditionBid.ts +++ b/packages/metavinci/src/models/metaplex/redeemMasterEditionBid.ts @@ -1,4 +1,4 @@ -import { programIds, VAULT_SCHEMA, VAULT_PREFIX } from '@oyster/common'; +import { programIds, VAULT_PREFIX } from '@oyster/common'; import { PublicKey, SystemProgram, @@ -13,6 +13,7 @@ import { getBidderKeys, getMetadata, RedeemMasterEditionBidArgs, + SCHEMA, } from '.'; export async function redeemMasterEditionBid( @@ -45,7 +46,7 @@ export async function redeemMasterEditionBid( )[0]; const value = new RedeemMasterEditionBidArgs(); - const data = Buffer.from(serialize(VAULT_SCHEMA, value)); + const data = Buffer.from(serialize(SCHEMA, value)); const keys = [ { pubkey: auctionManagerKey, diff --git a/packages/metavinci/src/models/metaplex/redeemOpenEditionBid.ts b/packages/metavinci/src/models/metaplex/redeemOpenEditionBid.ts index 43cd368..aa64329 100644 --- a/packages/metavinci/src/models/metaplex/redeemOpenEditionBid.ts +++ b/packages/metavinci/src/models/metaplex/redeemOpenEditionBid.ts @@ -1,4 +1,4 @@ -import { getEdition, programIds, VAULT_SCHEMA } from '@oyster/common'; +import { getEdition, programIds } from '@oyster/common'; import { PublicKey, SystemProgram, @@ -13,6 +13,7 @@ import { getBidderKeys, getMetadata, RedeemOpenEditionBidArgs, + SCHEMA, } from '.'; export async function redeemOpenEditionBid( @@ -43,7 +44,7 @@ export async function redeemOpenEditionBid( const masterEdition: PublicKey = await getEdition(tokenMint); const value = new RedeemOpenEditionBidArgs(); - const data = Buffer.from(serialize(VAULT_SCHEMA, value)); + const data = Buffer.from(serialize(SCHEMA, value)); const keys = [ { pubkey: auctionManagerKey, diff --git a/packages/metavinci/src/models/metaplex/startAuction.ts b/packages/metavinci/src/models/metaplex/startAuction.ts index 206a0fd..a8820ae 100644 --- a/packages/metavinci/src/models/metaplex/startAuction.ts +++ b/packages/metavinci/src/models/metaplex/startAuction.ts @@ -1,4 +1,4 @@ -import { programIds, VAULT_SCHEMA } from '@oyster/common'; +import { programIds } from '@oyster/common'; import { PublicKey, SYSVAR_CLOCK_PUBKEY, @@ -6,7 +6,7 @@ import { } from '@solana/web3.js'; import { serialize } from 'borsh'; -import { getAuctionKeys, StartAuctionArgs } from '.'; +import { getAuctionKeys, SCHEMA, StartAuctionArgs } from '.'; export async function startAuction( vault: PublicKey, @@ -18,7 +18,7 @@ export async function startAuction( const { auctionKey, auctionManagerKey } = await getAuctionKeys(vault); const value = new StartAuctionArgs(); - const data = Buffer.from(serialize(VAULT_SCHEMA, value)); + const data = Buffer.from(serialize(SCHEMA, value)); const keys = [ { diff --git a/packages/metavinci/src/models/metaplex/validateSafetyDepositBox.ts b/packages/metavinci/src/models/metaplex/validateSafetyDepositBox.ts index 1af2e29..f29a3eb 100644 --- a/packages/metavinci/src/models/metaplex/validateSafetyDepositBox.ts +++ b/packages/metavinci/src/models/metaplex/validateSafetyDepositBox.ts @@ -1,10 +1,4 @@ -import { - programIds, - VAULT_SCHEMA, - METADATA_PREFIX, - EDITION, - getEdition, -} from '@oyster/common'; +import { programIds, getEdition } from '@oyster/common'; import { PublicKey, SystemProgram, @@ -16,7 +10,7 @@ import { serialize } from 'borsh'; import { getAuctionKeys, getOriginalAuthority, - METAPLEX_PREFIX, + SCHEMA, ValidateSafetyDepositBoxArgs, } from '.'; @@ -46,7 +40,7 @@ export async function validateSafetyDepositBox( const edition: PublicKey = await getEdition(tokenMint); const value = new ValidateSafetyDepositBoxArgs(); - const data = Buffer.from(serialize(VAULT_SCHEMA, value)); + const data = Buffer.from(serialize(SCHEMA, value)); const keys = [ { pubkey: auctionManagerKey, diff --git a/packages/metavinci/src/views/auctionCreate/index.tsx b/packages/metavinci/src/views/auctionCreate/index.tsx index ab016c5..1796c52 100644 --- a/packages/metavinci/src/views/auctionCreate/index.tsx +++ b/packages/metavinci/src/views/auctionCreate/index.tsx @@ -31,6 +31,8 @@ import { Metadata, ParsedAccount, deserializeBorsh, + WinnerLimit, + WinnerLimitType, } from '@oyster/common'; import { getAssetCostToStore, LAMPORT_MULTIPLIER } from '../../utils/assets'; import { Connection, ParsedAccountData, PublicKey } from '@solana/web3.js'; @@ -44,12 +46,17 @@ import { AuctionManagerSettings, AuctionManagerState, AuctionManagerStatus, + EditionType, NonWinningConstraint, SCHEMA, WinningConstraint, } from '../../models/metaplex'; import { serialize } from 'borsh'; -import { SafetyDepositDraft } from '../../actions/createAuctionManager'; +import { + createAuctionManager, + SafetyDepositDraft, +} from '../../actions/createAuctionManager'; +import BN from 'bn.js'; const { Step } = Steps; const { Option } = Select; @@ -76,9 +83,6 @@ export interface AuctionState { // listed NFTs items: SafetyDepositDraft[]; - - settings: AuctionManagerSettings; - // number of editions for this auction (only applicable to limited edition) editions?: number; @@ -111,6 +115,7 @@ export interface AuctionState { export const AuctionCreateView = () => { const connection = useConnection(); const { env } = useConnectionConfig(); + const items = useUserArts(); const { wallet, connected } = useWallet(); const { step_param }: { step_param: string } = useParams(); const history = useHistory(); @@ -123,13 +128,6 @@ export const AuctionCreateView = () => { items: [], category: AuctionCategory.Open, saleType: 'auction', - settings: { - openEditionWinnerConstraint: WinningConstraint.NoOpenEdition, - openEditionNonWinningConstraint: NonWinningConstraint.NoOpenEdition, - winningConfigs: [], - openEditionConfig: undefined, - openEditionFixedPrice: undefined, - }, }); useEffect(() => { @@ -143,7 +141,53 @@ export const AuctionCreateView = () => { }; const createAuction = async () => { - // TODO: .... + let settings: AuctionManagerSettings; + let winnerLimit: WinnerLimit; + if (attributes.category == AuctionCategory.Open) { + settings = new AuctionManagerSettings({ + openEditionWinnerConstraint: WinningConstraint.OpenEditionGiven, + openEditionNonWinningConstraint: NonWinningConstraint.GivenForBidPrice, + winningConfigs: [], + openEditionConfig: 0, + openEditionFixedPrice: null, + }); + + winnerLimit = new WinnerLimit({ type: WinnerLimitType.Unlimited }); + } else if (attributes.category == AuctionCategory.Single) { + settings = new AuctionManagerSettings({ + openEditionWinnerConstraint: WinningConstraint.NoOpenEdition, + openEditionNonWinningConstraint: NonWinningConstraint.NoOpenEdition, + winningConfigs: [ + { + safetyDepositBoxIndex: 0, + amount: 1, + hasAuthority: false, + editionType: items[0].masterEdition + ? EditionType.MasterEdition + : EditionType.NA, + }, + ], + openEditionConfig: null, + openEditionFixedPrice: null, + }); + winnerLimit = new WinnerLimit({ + type: WinnerLimitType.Capped, + usize: new BN(1), + }); + } else { + throw new Error('Not supported'); + } + + await createAuctionManager( + connection, + wallet, + settings, + winnerLimit, + new BN((attributes.auctionDuration || 1) * 60), + new BN((attributes.gapTime || 1) * 60), + [items[0]], + new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'), + ); }; const categoryStep = ( @@ -255,6 +299,7 @@ export const AuctionCreateView = () => { ], [AuctionCategory.Single]: [ ['Category', categoryStep], + ['Copies', copiesStep], ['Price', priceStep], ['Initial Phase', initialStep], ['Ending Phase', endingStep], @@ -422,21 +467,6 @@ const CopiesStep = (props: { ); } - const [selectedItems, setSelectedItems] = useState>( - new Set( - props.attributes.items.map(item => item.metadata.pubkey.toBase58()), - ), - ); - - useEffect(() => { - props.setAttributes({ - ...props.attributes, - items: eligibleItems.filter((item: SafetyDepositDraft) => - selectedItems.has(item.metadata.pubkey.toBase58()), - ), - }); - }, [selectedItems]); - return ( <> @@ -448,14 +478,10 @@ const CopiesStep = (props: { - selectedItems.has(item.metadata.pubkey.toBase58()), - )} - setSelected={items => - setSelectedItems( - new Set(items.map(item => item.metadata.pubkey.toBase58())), - ) - } + selected={props.attributes.items} + setSelected={items => { + props.setAttributes({ ...props.attributes, items }); + }} allowMultiple={false} > Select NFT