Ok, lot of rough draft work getting redemption action ready to go. Need to sleep now, test it in the morning.

This commit is contained in:
Jordan Prince 2021-04-27 02:25:10 -05:00
parent bb952ced4e
commit 0be625108f
11 changed files with 673 additions and 37 deletions

View File

@ -38,6 +38,11 @@ export class BidState {
bids?: Bid[];
max?: BN;
public getWinnerIndex(bidder: PublicKey): number | null {
if (!this.bids) return null;
return this.bids.findIndex(b => b.key.toBase58() == bidder.toBase58());
}
constructor(args: { type: BidStateType; bids?: Bid[]; max?: BN }) {
this.type = args.type;
this.bids = args.bids;

View File

@ -630,6 +630,107 @@ export async function createMasterEdition(
);
}
export async function mintNewEditionFromMasterEditionViaToken(
newMint: PublicKey,
tokenMint: PublicKey,
newMintAuthority: PublicKey,
masterMint: PublicKey,
authorizationTokenHoldingAccount: PublicKey,
burnAuthority: PublicKey,
updateAuthorityOfMaster: PublicKey,
instructions: TransactionInstruction[],
payer: PublicKey,
) {
const metadataProgramId = programIds().metadata;
const newMetadataKey = await getMetadata(newMint);
const masterMetadataKey = await getMetadata(tokenMint);
const newEdition = await getEdition(newMint);
const masterEdition = await getEdition(tokenMint);
const data = Buffer.from('5');
const keys = [
{
pubkey: newMetadataKey,
isSigner: false,
isWritable: true,
},
{
pubkey: newEdition,
isSigner: false,
isWritable: true,
},
{
pubkey: masterEdition,
isSigner: false,
isWritable: true,
},
{
pubkey: newMint,
isSigner: false,
isWritable: true,
},
{
pubkey: newMintAuthority,
isSigner: true,
isWritable: false,
},
{
pubkey: masterMint,
isSigner: false,
isWritable: true,
},
{
pubkey: authorizationTokenHoldingAccount,
isSigner: false,
isWritable: true,
},
{
pubkey: burnAuthority,
isSigner: true,
isWritable: false,
},
{
pubkey: payer,
isSigner: true,
isWritable: false,
},
{
pubkey: updateAuthorityOfMaster,
isSigner: false,
isWritable: false,
},
{
pubkey: masterMetadataKey,
isSigner: false,
isWritable: false,
},
{
pubkey: programIds().token,
isSigner: false,
isWritable: false,
},
{
pubkey: SystemProgram.programId,
isSigner: false,
isWritable: false,
},
{
pubkey: SYSVAR_RENT_PUBKEY,
isSigner: false,
isWritable: false,
},
];
instructions.push(
new TransactionInstruction({
keys,
programId: metadataProgramId,
data,
}),
);
}
export async function getNameSymbol(metadata: Metadata): Promise<PublicKey> {
const PROGRAM_IDS = programIds();
@ -662,3 +763,18 @@ export async function getEdition(tokenMint: PublicKey): Promise<PublicKey> {
)
)[0];
}
export async function getMetadata(tokenMint: PublicKey): Promise<PublicKey> {
const PROGRAM_IDS = programIds();
return (
await PublicKey.findProgramAddress(
[
Buffer.from(METADATA_PREFIX),
PROGRAM_IDS.metadata.toBuffer(),
tokenMint.toBuffer(),
],
PROGRAM_IDS.metadata,
)
)[0];
}

View File

@ -11,6 +11,7 @@ import {
WinnerLimit,
MasterEdition,
NameSymbolTuple,
getMetadata,
SequenceType,
sendTransactions,
getSafetyDepositBox,
@ -22,7 +23,6 @@ import BN from 'bn.js';
import {
AuctionManagerSettings,
getAuctionKeys,
getMetadata,
initAuctionManager,
startAuction,
validateSafetyDepositBox,

View File

@ -0,0 +1,448 @@
import {
Account,
Connection,
PublicKey,
TransactionInstruction,
} from '@solana/web3.js';
import {
actions,
ParsedAccount,
programIds,
models,
TokenAccount,
getNameSymbol,
createMint,
mintNewEditionFromMasterEditionViaToken,
SafetyDepositBox,
} from '@oyster/common';
import { AccountLayout, MintLayout, Token } from '@solana/spl-token';
import { AuctionView, AuctionViewItem } from '../hooks';
import {
EditionType,
getOriginalAuthority,
NonWinningConstraint,
redeemBid,
redeemLimitedEditionBid,
redeemMasterEditionBid,
redeemOpenEditionBid,
WinningConstraint,
} from '../models/metaplex';
const { createTokenAccount } = actions;
const { approve } = models;
export async function sendRedeemBid(
connection: Connection,
wallet: any,
auctionView: AuctionView,
accountsByMint: Map<string, TokenAccount>,
) {
let signers: Array<Account[]> = [];
let instructions: Array<TransactionInstruction[]> = [];
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
AccountLayout.span,
);
const mintRentExempt = await connection.getMinimumBalanceForRentExemption(
MintLayout.span,
);
let winnerIndex = null;
if (auctionView.myBidderMetadata?.info.bidderPubkey)
winnerIndex = auctionView.auction.info.bidState.getWinnerIndex(
auctionView.myBidderMetadata?.info.bidderPubkey,
);
if (winnerIndex != null) {
const winningConfig =
auctionView.auctionManager.info.settings.winningConfigs[winnerIndex];
const item = auctionView.items[winningConfig.safetyDepositBoxIndex];
const safetyDeposit = item.safetyDeposit;
let newTokenAccount: PublicKey | undefined;
switch (winningConfig.editionType) {
case EditionType.LimitedEdition:
await setupRedeemLimitedInstructions(
connection,
auctionView,
accountsByMint,
accountRentExempt,
mintRentExempt,
wallet,
safetyDeposit,
item,
signers,
instructions,
);
break;
case EditionType.MasterEdition:
await setupRedeemMasterInstructions(
auctionView,
accountsByMint,
accountRentExempt,
wallet,
safetyDeposit,
item,
signers,
instructions,
);
break;
case EditionType.NA:
await setupRedeemInstructions(
auctionView,
accountsByMint,
accountRentExempt,
wallet,
safetyDeposit,
signers,
instructions,
);
break;
}
}
const eligibleForOpenEdition =
(winnerIndex == null &&
auctionView.auctionManager.info.settings
.openEditionNonWinningConstraint !=
NonWinningConstraint.NoOpenEdition) ||
(winnerIndex != null &&
auctionView.auctionManager.info.settings.openEditionWinnerConstraint !=
WinningConstraint.NoOpenEdition);
if (auctionView.openEditionItem && eligibleForOpenEdition) {
const item = auctionView.openEditionItem;
const safetyDeposit = item.safetyDeposit;
await setupRedeemOpenInstructions(
auctionView,
accountsByMint,
accountRentExempt,
mintRentExempt,
wallet,
safetyDeposit,
item,
signers,
instructions,
);
}
}
async function setupRedeemInstructions(
auctionView: AuctionView,
accountsByMint: Map<string, TokenAccount>,
accountRentExempt: number,
wallet: any,
safetyDeposit: ParsedAccount<SafetyDepositBox>,
signers: Array<Account[]>,
instructions: Array<TransactionInstruction[]>,
) {
let winningPrizeSigner: Account[] = [];
let winningPrizeInstructions: TransactionInstruction[] = [];
signers.push(winningPrizeSigner);
instructions.push(winningPrizeInstructions);
if (auctionView.myBidderMetadata) {
let newTokenAccount = accountsByMint.get(
safetyDeposit.info.tokenMint.toBase58(),
)?.pubkey;
if (!newTokenAccount)
newTokenAccount = createTokenAccount(
winningPrizeInstructions,
wallet.publicKey,
accountRentExempt,
safetyDeposit.info.tokenMint,
wallet.publicKey,
winningPrizeSigner,
);
await redeemBid(
auctionView.auctionManager.info.vault,
safetyDeposit.info.store,
newTokenAccount,
safetyDeposit.pubkey,
auctionView.vault.info.fractionMint,
auctionView.myBidderMetadata.info.bidderPubkey,
wallet.publicKey,
winningPrizeInstructions,
);
}
}
async function setupRedeemMasterInstructions(
auctionView: AuctionView,
accountsByMint: Map<string, TokenAccount>,
accountRentExempt: number,
wallet: any,
safetyDeposit: ParsedAccount<SafetyDepositBox>,
item: AuctionViewItem,
signers: Array<Account[]>,
instructions: Array<TransactionInstruction[]>,
) {
let winningPrizeSigner: Account[] = [];
let winningPrizeInstructions: TransactionInstruction[] = [];
signers.push(winningPrizeSigner);
instructions.push(winningPrizeInstructions);
if (auctionView.myBidderMetadata) {
let newTokenAccount = accountsByMint.get(
safetyDeposit.info.tokenMint.toBase58(),
)?.pubkey;
if (!newTokenAccount)
newTokenAccount = createTokenAccount(
winningPrizeInstructions,
wallet.publicKey,
accountRentExempt,
safetyDeposit.info.tokenMint,
wallet.publicKey,
winningPrizeSigner,
);
await redeemMasterEditionBid(
auctionView.auctionManager.info.vault,
safetyDeposit.info.store,
newTokenAccount,
safetyDeposit.pubkey,
auctionView.vault.info.fractionMint,
auctionView.myBidderMetadata.info.bidderPubkey,
wallet.publicKey,
winningPrizeInstructions,
item.metadata.pubkey,
await getNameSymbol(item.metadata.info),
wallet.publicKey,
);
}
}
async function setupRedeemLimitedInstructions(
connection: Connection,
auctionView: AuctionView,
accountsByMint: Map<string, TokenAccount>,
accountRentExempt: number,
mintRentExempt: number,
wallet: any,
safetyDeposit: ParsedAccount<SafetyDepositBox>,
item: AuctionViewItem,
signers: Array<Account[]>,
instructions: Array<TransactionInstruction[]>,
) {
let winningPrizeSigner: Account[] = [];
let winningPrizeInstructions: TransactionInstruction[] = [];
signers.push(winningPrizeSigner);
instructions.push(winningPrizeInstructions);
const updateAuth =
item.metadata.info.nonUniqueSpecificUpdateAuthority ||
item.nameSymbol?.info.updateAuthority;
if (item.masterEdition && updateAuth && auctionView.myBidderMetadata) {
let newTokenAccount: PublicKey | undefined = accountsByMint.get(
item.masterEdition.info.masterMint.toBase58(),
)?.pubkey;
if (!newTokenAccount)
newTokenAccount = createTokenAccount(
winningPrizeInstructions,
wallet.publicKey,
accountRentExempt,
item.masterEdition.info.masterMint,
wallet.publicKey,
winningPrizeSigner,
);
const originalAuthorityAcct = await connection.getAccountInfo(
await getOriginalAuthority(
auctionView.auction.pubkey,
item.metadata.pubkey,
),
);
if (originalAuthorityAcct) {
const originalAuthority = new PublicKey(
originalAuthorityAcct.data.slice(1, 33),
);
await redeemLimitedEditionBid(
auctionView.auctionManager.info.vault,
safetyDeposit.info.store,
newTokenAccount,
safetyDeposit.pubkey,
auctionView.vault.info.fractionMint,
auctionView.myBidderMetadata.info.bidderPubkey,
wallet.publicKey,
winningPrizeInstructions,
originalAuthority,
item.metadata.info.mint,
item.masterEdition.info.masterMint,
);
let cashInLimitedPrizeAuthorizationTokenSigner: Account[] = [];
let cashInLimitedPrizeAuthorizationTokenInstruction: TransactionInstruction[] = [];
signers.push(cashInLimitedPrizeAuthorizationTokenSigner);
instructions.push(cashInLimitedPrizeAuthorizationTokenInstruction);
const newLimitedEditionMint = createMint(
cashInLimitedPrizeAuthorizationTokenInstruction,
wallet.publicKey,
mintRentExempt,
0,
wallet.publicKey,
wallet.publicKey,
cashInLimitedPrizeAuthorizationTokenSigner,
);
const newLimitedEdition = createTokenAccount(
cashInLimitedPrizeAuthorizationTokenInstruction,
wallet.publicKey,
accountRentExempt,
newLimitedEditionMint,
wallet.publicKey,
cashInLimitedPrizeAuthorizationTokenSigner,
);
cashInLimitedPrizeAuthorizationTokenInstruction.push(
Token.createMintToInstruction(
programIds().token,
newLimitedEditionMint,
newLimitedEdition,
wallet.publicKey,
[],
1,
),
);
const burnAuthority = approve(
cashInLimitedPrizeAuthorizationTokenInstruction,
[],
newTokenAccount,
wallet.publicKey,
1,
);
cashInLimitedPrizeAuthorizationTokenSigner.push(burnAuthority);
mintNewEditionFromMasterEditionViaToken(
newLimitedEditionMint,
item.metadata.info.mint,
wallet.publicKey,
item.masterEdition.info.masterMint,
newTokenAccount,
burnAuthority.publicKey,
updateAuth,
cashInLimitedPrizeAuthorizationTokenInstruction,
wallet.publicKey,
);
}
}
}
async function setupRedeemOpenInstructions(
auctionView: AuctionView,
accountsByMint: Map<string, TokenAccount>,
accountRentExempt: number,
mintRentExempt: number,
wallet: any,
safetyDeposit: ParsedAccount<SafetyDepositBox>,
item: AuctionViewItem,
signers: Array<Account[]>,
instructions: Array<TransactionInstruction[]>,
) {
let winningPrizeSigner: Account[] = [];
let winningPrizeInstructions: TransactionInstruction[] = [];
signers.push(winningPrizeSigner);
instructions.push(winningPrizeInstructions);
const updateAuth =
item.metadata.info.nonUniqueSpecificUpdateAuthority ||
item.nameSymbol?.info.updateAuthority;
if (item.masterEdition && updateAuth && auctionView.myBidderMetadata) {
let newTokenAccount: PublicKey | undefined = accountsByMint.get(
item.masterEdition.info.masterMint.toBase58(),
)?.pubkey;
if (!newTokenAccount)
newTokenAccount = createTokenAccount(
winningPrizeInstructions,
wallet.publicKey,
accountRentExempt,
item.masterEdition.info.masterMint,
wallet.publicKey,
winningPrizeSigner,
);
const transferAuthority = approve(
winningPrizeInstructions,
[],
auctionView.myBidderMetadata.info.bidderPubkey,
wallet.publicKey,
auctionView.auctionManager.info.settings.openEditionFixedPrice || 0,
);
winningPrizeSigner.push(transferAuthority);
await redeemOpenEditionBid(
auctionView.auctionManager.info.vault,
safetyDeposit.info.store,
newTokenAccount,
safetyDeposit.pubkey,
auctionView.vault.info.fractionMint,
auctionView.myBidderMetadata.info.bidderPubkey,
wallet.publicKey,
winningPrizeInstructions,
item.metadata.info.mint,
item.masterEdition.info.masterMint,
transferAuthority.publicKey,
auctionView.auctionManager.info.acceptPayment,
);
let cashInOpenPrizeAuthorizationTokenSigner: Account[] = [];
let cashInOpenPrizeAuthorizationTokenInstruction: TransactionInstruction[] = [];
signers.push(cashInOpenPrizeAuthorizationTokenSigner);
instructions.push(cashInOpenPrizeAuthorizationTokenInstruction);
const newOpenEditionMint = createMint(
cashInOpenPrizeAuthorizationTokenInstruction,
wallet.publicKey,
mintRentExempt,
0,
wallet.publicKey,
wallet.publicKey,
cashInOpenPrizeAuthorizationTokenSigner,
);
const newOpenEdition = createTokenAccount(
cashInOpenPrizeAuthorizationTokenInstruction,
wallet.publicKey,
accountRentExempt,
newOpenEditionMint,
wallet.publicKey,
cashInOpenPrizeAuthorizationTokenSigner,
);
cashInOpenPrizeAuthorizationTokenInstruction.push(
Token.createMintToInstruction(
programIds().token,
newOpenEditionMint,
newOpenEdition,
wallet.publicKey,
[],
1,
),
);
const burnAuthority = approve(
cashInOpenPrizeAuthorizationTokenInstruction,
[],
newTokenAccount,
wallet.publicKey,
1,
);
cashInOpenPrizeAuthorizationTokenSigner.push(burnAuthority);
mintNewEditionFromMasterEditionViaToken(
newOpenEditionMint,
item.metadata.info.mint,
wallet.publicKey,
item.masterEdition.info.masterMint,
newTokenAccount,
burnAuthority.publicKey,
updateAuth,
cashInOpenPrizeAuthorizationTokenInstruction,
wallet.publicKey,
);
}
}

View File

@ -26,6 +26,8 @@ import {
decodeBidderPot,
BIDDER_METADATA_LEN,
BIDDER_POT_LEN,
decodeVault,
Vault,
} from '@oyster/common';
import { MintInfo } from '@solana/spl-token';
import { Connection, PublicKey, PublicKeyAndAccount } from '@solana/web3.js';
@ -48,6 +50,7 @@ export interface MetaContextState {
masterEditions: Record<string, ParsedAccount<MasterEdition>>;
auctionManagers: Record<string, ParsedAccount<AuctionManager>>;
auctions: Record<string, ParsedAccount<AuctionData>>;
vaults: Record<string, ParsedAccount<Vault>>;
bidderMetadataByAuctionAndBidder: Record<
string,
ParsedAccount<BidderMetadata>
@ -67,6 +70,7 @@ const MetaContext = React.createContext<MetaContextState>({
editions: {},
auctionManagers: {},
auctions: {},
vaults: {},
bidderMetadataByAuctionAndBidder: {},
safetyDepositBoxesByVaultAndIndex: {},
bidderPotsByAuctionAndBidder: {},
@ -93,6 +97,9 @@ export function MetaProvider({ children = null as any }) {
const [auctions, setAuctions] = useState<
Record<string, ParsedAccount<AuctionData>>
>({});
const [vaults, setVaults] = useState<Record<string, ParsedAccount<Vault>>>(
{},
);
const [
bidderMetadataByAuctionAndBidder,
setBidderMetadataByAuctionAndBidder,
@ -204,7 +211,7 @@ export function MetaProvider({ children = null as any }) {
useEffect(() => {
let dispose = () => {};
(async () => {
const processSafetyDeposits = async (a: PublicKeyAndAccount<Buffer>) => {
const processVaultData = async (a: PublicKeyAndAccount<Buffer>) => {
try {
if (a.account.data[0] == VaultKey.SafetyDepositBoxV1) {
const safetyDeposit = await decodeSafetyDeposit(a.account.data);
@ -219,6 +226,17 @@ export function MetaProvider({ children = null as any }) {
'-' +
safetyDeposit.order]: account,
}));
} else if (a.account.data[0] == VaultKey.VaultV1) {
const vault = await decodeVault(a.account.data);
const account: ParsedAccount<Vault> = {
pubkey: a.pubkey,
account: a.account,
info: vault,
};
setVaults(e => ({
...e,
[a.pubkey.toBase58()]: account,
}));
}
} catch {
// ignore errors
@ -228,7 +246,7 @@ export function MetaProvider({ children = null as any }) {
const accounts = await connection.getProgramAccounts(programIds().vault);
for (let i = 0; i < accounts.length; i++) {
await processSafetyDeposits(accounts[i]);
await processVaultData(accounts[i]);
}
let subId = connection.onProgramAccountChange(
@ -238,7 +256,7 @@ export function MetaProvider({ children = null as any }) {
typeof info.accountId === 'string'
? new PublicKey((info.accountId as unknown) as string)
: info.accountId;
await processSafetyDeposits({
await processVaultData({
pubkey,
account: info.accountInfo,
});
@ -433,6 +451,7 @@ export function MetaProvider({ children = null as any }) {
safetyDepositBoxesByVaultAndIndex,
bidderMetadataByAuctionAndBidder,
bidderPotsByAuctionAndBidder,
vaults,
}}
>
{children}

View File

@ -25,6 +25,9 @@ export const useAuction = (id: string) => {
metadataByMint,
bidderMetadataByAuctionAndBidder,
bidderPotsByAuctionAndBidder,
masterEditions,
nameSymbolTuples,
vaults,
} = useMeta();
useEffect(() => {
@ -35,8 +38,11 @@ export const useAuction = (id: string) => {
auctionManagers,
safetyDepositBoxesByVaultAndIndex,
metadataByMint,
nameSymbolTuples,
bidderMetadataByAuctionAndBidder,
bidderPotsByAuctionAndBidder,
masterEditions,
vaults,
accountByMint,
clock,
undefined,
@ -52,6 +58,9 @@ export const useAuction = (id: string) => {
metadataByMint,
bidderMetadataByAuctionAndBidder,
bidderPotsByAuctionAndBidder,
vaults,
nameSymbolTuples,
masterEditions,
userAccounts,
]);
return existingAuctionView;

View File

@ -7,9 +7,11 @@ import {
AuctionState,
BidderMetadata,
BidderPot,
useWallet,
useUserAccounts,
TokenAccount,
Vault,
MasterEdition,
NameSymbolTuple,
} from '@oyster/common';
import { useEffect, useState } from 'react';
import { useMeta } from '../contexts';
@ -24,7 +26,9 @@ export enum AuctionViewState {
export interface AuctionViewItem {
metadata: ParsedAccount<Metadata>;
nameSymbol?: ParsedAccount<NameSymbolTuple>;
safetyDeposit: ParsedAccount<SafetyDepositBox>;
masterEdition?: ParsedAccount<MasterEdition>;
}
// Flattened surface item for easy display
@ -37,6 +41,7 @@ export interface AuctionView {
thumbnail: AuctionViewItem;
myBidderMetadata?: ParsedAccount<BidderMetadata>;
myBidderPot?: ParsedAccount<BidderPot>;
vault: ParsedAccount<Vault>;
totallyComplete: boolean;
}
@ -63,6 +68,9 @@ export const useAuctions = (state: AuctionViewState) => {
metadataByMint,
bidderMetadataByAuctionAndBidder,
bidderPotsByAuctionAndBidder,
vaults,
nameSymbolTuples,
masterEditions,
} = useMeta();
useEffect(() => {
@ -75,8 +83,11 @@ export const useAuctions = (state: AuctionViewState) => {
auctionManagers,
safetyDepositBoxesByVaultAndIndex,
metadataByMint,
nameSymbolTuples,
bidderMetadataByAuctionAndBidder,
bidderPotsByAuctionAndBidder,
masterEditions,
vaults,
accountByMint,
clock,
state,
@ -94,6 +105,9 @@ export const useAuctions = (state: AuctionViewState) => {
bidderMetadataByAuctionAndBidder,
bidderPotsByAuctionAndBidder,
userAccounts,
vaults,
nameSymbolTuples,
masterEditions,
]);
return Object.values(auctionViews).filter(v => v) as AuctionView[];
@ -107,11 +121,14 @@ export function processAccountsIntoAuctionView(
ParsedAccount<SafetyDepositBox>
>,
metadataByMint: Record<string, ParsedAccount<Metadata>>,
nameSymbolTuples: Record<string, ParsedAccount<NameSymbolTuple>>,
bidderMetadataByAuctionAndBidder: Record<
string,
ParsedAccount<BidderMetadata>
>,
bidderPotsByAuctionAndBidder: Record<string, ParsedAccount<BidderPot>>,
masterEditions: Record<string, ParsedAccount<MasterEdition>>,
vaults: Record<string, ParsedAccount<Vault>>,
accountByMint: Map<string, TokenAccount>,
clock: number,
desiredState: AuctionViewState | undefined,
@ -156,6 +173,34 @@ export function processAccountsIntoAuctionView(
// and only update the two things that could possibly change
existingAuctionView.myBidderPot = bidderPot;
existingAuctionView.myBidderMetadata = bidderMetadata;
for (let i = 0; i < existingAuctionView.items.length; i++) {
let curr = existingAuctionView.items[i];
if (!curr.metadata) {
let foundMetadata =
metadataByMint[curr.safetyDeposit.info.tokenMint.toBase58()];
curr.metadata = foundMetadata;
if (
curr.metadata &&
!curr.nameSymbol &&
curr.metadata.info.nameSymbolTuple
) {
let foundNS =
nameSymbolTuples[curr.metadata.info.nameSymbolTuple.toBase58()];
curr.nameSymbol = foundNS;
}
if (
curr.metadata &&
!curr.masterEdition &&
curr.metadata.info.masterEdition
) {
let foundMaster =
masterEditions[curr.metadata.info.masterEdition.toBase58()];
curr.masterEdition = foundMaster;
}
}
}
return existingAuctionView;
}
@ -183,13 +228,23 @@ export function processAccountsIntoAuctionView(
auction,
auctionManager,
state,
items: auctionManager.info.settings.winningConfigs.map(w => ({
metadata:
vault: vaults[auctionManager.info.vault.toBase58()],
items: auctionManager.info.settings.winningConfigs.map(w => {
let metadata =
metadataByMint[
boxes[w.safetyDepositBoxIndex].info.tokenMint.toBase58()
],
safetyDeposit: boxes[w.safetyDepositBoxIndex],
})),
];
return {
metadata,
nameSymbol: metadata?.info?.nameSymbolTuple
? nameSymbolTuples[metadata.info.nameSymbolTuple.toBase58()]
: undefined,
safetyDeposit: boxes[w.safetyDepositBoxIndex],
masterEdition: metadata?.info?.masterEdition
? masterEditions[metadata.info.masterEdition.toBase58()]
: undefined,
};
}),
openEditionItem:
auctionManager.info.settings.openEditionConfig != null
? {
@ -213,7 +268,8 @@ export function processAccountsIntoAuctionView(
boxesExpected == (view.items || []).length &&
(auctionManager.info.settings.openEditionConfig == null ||
(auctionManager.info.settings.openEditionConfig != null &&
view.openEditionItem))
view.openEditionItem)) &&
view.vault
);
if (!view.thumbnail || !view.thumbnail.metadata) return undefined;
return view as AuctionView;

View File

@ -18,6 +18,7 @@ export * from './startAuction';
export * from './validateSafetyDepositBox';
export const METAPLEX_PREFIX = 'metaplex';
export const ORIGINAL_AUTHORITY_LOOKUP_SIZE = 33;
export enum MetaplexKey {
AuctionManagerV1 = 0,
@ -111,14 +112,14 @@ export class AuctionManagerSettings {
}
export enum WinningConstraint {
NoOpenEdition,
OpenEditionGiven,
NoOpenEdition = 0,
OpenEditionGiven = 1,
}
export enum NonWinningConstraint {
NoOpenEdition,
GivenForFixedPrice,
GivenForBidPrice,
NoOpenEdition = 0,
GivenForFixedPrice = 1,
GivenForBidPrice = 2,
}
export enum EditionType {
@ -400,18 +401,3 @@ export async function getOriginalAuthority(
)
)[0];
}
export async function getMetadata(tokenMint: PublicKey): Promise<PublicKey> {
const PROGRAM_IDS = programIds();
return (
await PublicKey.findProgramAddress(
[
Buffer.from(METADATA_PREFIX),
PROGRAM_IDS.metadata.toBuffer(),
tokenMint.toBuffer(),
],
PROGRAM_IDS.metadata,
)
)[0];
}

View File

@ -1,4 +1,4 @@
import { getEdition, programIds } from '@oyster/common';
import { getEdition, programIds, getMetadata } from '@oyster/common';
import {
PublicKey,
SystemProgram,
@ -11,7 +11,6 @@ import { serialize } from 'borsh';
import {
getAuctionKeys,
getBidderKeys,
getMetadata,
getOriginalAuthority,
RedeemLimitedEditionBidArgs,
SCHEMA,

View File

@ -1,4 +1,4 @@
import { programIds, VAULT_PREFIX } from '@oyster/common';
import { programIds, VAULT_PREFIX, getMetadata } from '@oyster/common';
import {
PublicKey,
SystemProgram,
@ -11,7 +11,6 @@ import { serialize } from 'borsh';
import {
getAuctionKeys,
getBidderKeys,
getMetadata,
RedeemMasterEditionBidArgs,
SCHEMA,
} from '.';

View File

@ -1,4 +1,4 @@
import { getEdition, programIds } from '@oyster/common';
import { getEdition, programIds, getMetadata } from '@oyster/common';
import {
PublicKey,
SystemProgram,
@ -11,7 +11,6 @@ import { serialize } from 'borsh';
import {
getAuctionKeys,
getBidderKeys,
getMetadata,
RedeemOpenEditionBidArgs,
SCHEMA,
} from '.';