metaplex-foundation / js

A JavaScript SDK for interacting with Metaplex's programs
357 stars 182 forks source link

Direct sell method fails for auction houses that require sign off even when passing the authority keypair #337

Closed gabspeck closed 1 year ago

gabspeck commented 2 years ago

Hello!

I tried to use the newly available direct sell method, however it seems it is ignoring the authority keypair parameter, making it throw the Cannot take this action without auction house signing too error. Below is some reproduction code with private keys removed:

import {
    AuctionHouse,
    keypairIdentity,
    Metaplex,
    sol,
    toBigNumber,
    token,
    WRAPPED_SOL_MINT,
} from "@metaplex-foundation/js";
import {clusterApiUrl, Connection, Keypair, LAMPORTS_PER_SOL} from "@solana/web3.js";
import bs58 from "bs58";

const connection = new Connection(clusterApiUrl('devnet'))
const metaplex = Metaplex.make(connection)

const ahKey = bs58.decode('auction house authority key here')
const ownerKey = bs58.decode('token seller key here')
const bidderKey = bs58.decode('token bidder key here')

const ahKeypair = Keypair.fromSecretKey(ahKey)
const ownerKeypair = Keypair.fromSecretKey(ownerKey)
const bidderKeypair = Keypair.fromSecretKey(bidderKey)

const price = sol(1)

console.log('finding auction house...')
let auctionHouse: AuctionHouse
try {
    auctionHouse = await metaplex.auctionHouse().findByCreatorAndMint({
        creator: ahKeypair.publicKey,
        treasuryMint: WRAPPED_SOL_MINT
    }).run()
} catch (e){
    console.log('error finding auction house, will try to create')
    ;({auctionHouse} = await metaplex.use(keypairIdentity(ahKeypair)).auctionHouse().create({
        requiresSignOff: true,
        sellerFeeBasisPoints: 250
    }).run())
    console.log('funding fee payer')
    await metaplex.connection.requestAirdrop(auctionHouse.feeAccountAddress, LAMPORTS_PER_SOL)
}

const mint = Keypair.generate()
console.log(`minting token ${mint.publicKey.toBase58()}...`)
const {mintAddress} = await metaplex.use(keypairIdentity(ownerKeypair)).nfts().create({
    tokenOwner: ownerKeypair.publicKey,
    useNewMint: mint,
    name: 'Test Token',
    uri: 'http://example.com',
    isMutable: true,
    maxSupply: toBigNumber(0),
    sellerFeeBasisPoints: 500
}).run()

console.log('placing bid...')
const {bid} = await metaplex.use(keypairIdentity(bidderKeypair)).auctionHouse().bid({
    auctionHouse,
    authority: ahKeypair,
    mintAccount: mintAddress,
    tokens: token(1),
    seller: ownerKeypair.publicKey,
    price,
}).run()

console.log('selling...')
// @ts-ignore
const executionResult = await metaplex.use(keypairIdentity(ownerKeypair)).auctionHouse().sell({
    auctionHouse,
    authority: ahKeypair,
    bid
}).run()

console.log({executionResult})
gabspeck commented 2 years ago

I got it working by swapping the keypairIdentity and seller/authority parameters. That is, I changed it from this:

console.log('selling...')
// @ts-ignore
const executionResult = await metaplex.use(keypairIdentity(ownerKeypair)).auctionHouse().sell({
    auctionHouse,
    authority: ahKeypair,
    bid
}).run()

to the code below, passing the authority's private key to the keypairIdentity plugin and the token owner's keypair as the seller argument:

const executionResult = await metaplex
    .use(keypairIdentity(ahKeypair))
    .auctionHouse()
    //@ts-ignore
    .sell({
        auctionHouse,
        seller: ownerKeypair,
        bid
    }).run()

Not sure if that's intended design but it's a bit confusing, I thought the two ways of calling were interchangeable.

lorisleiva commented 1 year ago

Hi there,

Sorry for the late reply.

I'm not sure if this is the issue but when running metaplex.use(keypairIdentity(ownerKeypair)), you're telling the entire SDK that this is the new wallet they should use for everything by default which could create some unexpected behaviour if you change them frequently.

I'm going to close this for now because the Auction House module is not 100% ready yet but this is great feedback for us to have right now. Thank you.