Skip to content

Commit

Permalink
feat: find many for auction/manager/metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
vecheslav committed Sep 24, 2021
1 parent 64add73 commit 3900594
Showing 6 changed files with 98 additions and 29 deletions.
30 changes: 26 additions & 4 deletions api/src/programs/auction/accouns/Auction.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { AccountInfo, Connection, PublicKey } from '@solana/web3.js';
import BN from 'bn.js';
import { ERROR_INVALID_OWNER } from '@metaplex/errors';
import { AnyPublicKey, StringPublicKey } from '@metaplex/types';
import { Borsh } from '@metaplex/utils';
import { AccountInfo, Connection, PublicKey } from '@solana/web3.js';
import BN from 'bn.js';
import { Buffer } from 'buffer';
import { Account } from '../../../Account';
import { AuctionProgram } from '../AuctionProgram';
import { BidderMetadata } from './BidderMetadata';
import { BidderPot } from './BidderPot';
import { Buffer } from 'buffer';
import { Borsh } from '@metaplex/utils';

export enum AuctionState {
Created = 0,
@@ -183,6 +183,28 @@ export class Auction extends Account<AuctionData> {
]);
}

static async findMany(connection: Connection, filters: { authority?: AnyPublicKey }) {
return (
await AuctionProgram.getProgramAccounts(connection, {
filters: [
// Filter for assigned to authority
filters.authority && {
memcmp: {
offset: 0,
bytes: new PublicKey(filters.authority).toBase58(),
},
},
].filter(Boolean),
})
)
.map((account) => {
try {
return Auction.from(account);
} catch (err) {}
})
.filter(Boolean);
}

async getBidderPots(connection: Connection) {
return (
await AuctionProgram.getProgramAccounts(connection, {
40 changes: 18 additions & 22 deletions api/src/programs/metadata/accounts/Metadata.ts
Original file line number Diff line number Diff line change
@@ -124,7 +124,10 @@ export class Metadata extends Account<MetadataData> {
]);
}

static async getAll(connection: Connection) {
static async findMany(
connection: Connection,
filters: { mint?: AnyPublicKey; updateAuthority?: AnyPublicKey } = {},
) {
return (
await MetadataProgram.getProgramAccounts(connection, {
filters: [
@@ -135,38 +138,30 @@ export class Metadata extends Account<MetadataData> {
bytes: bs58.encode(Buffer.from([MetadataKey.MetadataV1])),
},
},
],
})
).map((account) => Metadata.from(account));
}

static async getByMint(connection: Connection, mint: AnyPublicKey) {
return (
await MetadataProgram.getProgramAccounts(connection, {
filters: [
// Filter for MetadataV1 by key
{
// Filter for assigned to update authority
filters.updateAuthority && {
memcmp: {
offset: 0,
bytes: bs58.encode(Buffer.from([MetadataKey.MetadataV1])),
offset: 1,
bytes: new PublicKey(filters.updateAuthority).toBase58(),
},
},
// Filter for assigned to mint
{
filters.mint && {
memcmp: {
offset: 33,
bytes: new PublicKey(mint).toBase58(),
bytes: new PublicKey(filters.mint).toBase58(),
},
},
],
].filter(Boolean),
})
).map((account) => Metadata.from(account));
}

static async getMetdataByOwner(connection: Connection, owner: AnyPublicKey) {
static async findByOwner(connection: Connection, owner: AnyPublicKey) {
const accounts = await TokenAccount.getTokenAccountsByOwner(connection, owner);
const accountMap = new Map(accounts.map(({ data }) => [data.mint.toString(), data]));
const allMetadata = await Metadata.getAll(connection);
// Slow method
const allMetadata = await Metadata.findMany(connection);

return allMetadata.filter(
(metadata) =>
@@ -175,15 +170,16 @@ export class Metadata extends Account<MetadataData> {
);
}

// TODO: lol
static async getMetdataByOwnerV2(connection: Connection, owner: AnyPublicKey) {
static async findByOwnerV2(connection: Connection, owner: AnyPublicKey) {
const accounts = await TokenAccount.getTokenAccountsByOwner(connection, owner);
const accountsWithAmount = accounts
.map(({ data }) => data)
.filter(({ amount }) => amount?.toNumber() > 0);

return (
await Promise.all(accountsWithAmount.map(({ mint }) => Metadata.getByMint(connection, mint)))
await Promise.all(
accountsWithAmount.map(({ mint }) => Metadata.findMany(connection, { mint })),
)
).flat();
}

33 changes: 33 additions & 0 deletions api/src/programs/metaplex/accounts/AuctionManager.ts
Original file line number Diff line number Diff line change
@@ -113,6 +113,39 @@ export class AuctionManager extends Account<AuctionManagerV2Data> {
]);
}

static async findMany(
connection: Connection,
filters: { store?: AnyPublicKey; authority?: AnyPublicKey } = {},
) {
return (
await MetaplexProgram.getProgramAccounts(connection, {
filters: [
// Filter for AuctionManagerV2 by key
{
memcmp: {
offset: 0,
bytes: bs58.encode(Buffer.from([MetaplexKey.AuctionManagerV2])),
},
},
// Filter for assigned to store
filters.store && {
memcmp: {
offset: 1,
bytes: new PublicKey(filters.store).toBase58(),
},
},
// Filter for assigned to authority
filters.authority && {
memcmp: {
offset: 33,
bytes: new PublicKey(filters.authority).toBase58(),
},
},
].filter(Boolean),
})
).map((account) => AuctionManager.from(account));
}

async getAuction(connection: Connection) {
return Auction.load(connection, this.data.auction);
}
12 changes: 11 additions & 1 deletion api/test/auction.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Auction, AuctionExtended, AuctionState, Connection } from '../src';
import { AUCTION_EXTENDED_PUBKEY, AUCTION_PUBKEY, VAULT_PUBKEY } from './utils';
import {
AUCTION_EXTENDED_PUBKEY,
AUCTION_MANAGER_PUBKEY,
AUCTION_PUBKEY,
VAULT_PUBKEY,
} from './utils';

describe('Auction', () => {
let connection: Connection;
@@ -16,6 +21,11 @@ describe('Auction', () => {
expect(auction.data.state).toEqual(AuctionState.Started);
});

test('findMany', async () => {
const auctions = await Auction.findMany(connection, { authority: AUCTION_MANAGER_PUBKEY });
expect(auctions[0].data.authority).toEqual(AUCTION_MANAGER_PUBKEY.toString());
});

test('getBidderPots', async () => {
const auction = await Auction.load(connection, AUCTION_PUBKEY);
const bidderPots = await auction.getBidderPots(connection);
8 changes: 8 additions & 0 deletions api/test/metaplex.test.ts
Original file line number Diff line number Diff line change
@@ -56,6 +56,14 @@ describe('Metaplex', () => {
expect(auctionManager.data.key).toEqual(MetaplexKey.AuctionManagerV2);
});

test('findMany', async () => {
const auctionManagers = await AuctionManager.findMany(connection, {
store: STORE_PUBKEY,
authority: STORE_OWNER_PUBKEY,
});
expect(auctionManagers[0].data.store).toEqual(STORE_PUBKEY.toString());
});

test('getAuction', async () => {
const auctionManager = await AuctionManager.load(connection, AUCTION_MANAGER_PUBKEY);
const auction = await auctionManager.getAuction(connection);
4 changes: 2 additions & 2 deletions examples/node/index.ts
Original file line number Diff line number Diff line change
@@ -15,12 +15,12 @@ const connection = new Connection('devnet');
const run = async () => {
// TODO: just waiting for layer service with combine
// console.time('ownedMetadata');
// const ownedMetadata = await Metadata.getMetdataByOwner(connection, payer.publicKey);
// const ownedMetadata = await Metadata.findByOwner(connection, payer.publicKey);
// console.log(ownedMetadata);
// console.timeEnd('ownedMetadata');

console.time('ownedMetadata v2');
const ownedMetadata = await Metadata.getMetdataByOwnerV2(connection, payer.publicKey);
const ownedMetadata = await Metadata.findByOwnerV2(connection, payer.publicKey);
console.log(ownedMetadata);
console.timeEnd('ownedMetadata v2');

0 comments on commit 3900594

Please sign in to comment.