P2P Offers

P2P (Peer-to-Peer) Offers enable direct transactions between a buyer and a seller without listing the domain publicly. Sellers can create a P2P offer specifying the buyer's address, the SOL amount, the domain names involved and optionally set an expiration date to the offer.

Struct

pub struct P2pOffer {
    // Account tag
    pub tag: Tag,
    // Derivation nonce
    pub nonce: u8,
    // The owner of the p2p offer
    pub owner: Pubkey,
    // The counter party of the offer
    pub counter_party: Pubkey,
    // The domain(s) being traded
    pub domains: Vec<Pubkey>,
    // Domains against which the offer is priced
    pub quotes: Vec<Pubkey>,
    // Amount of SOL (in addition to the quote domains)
    pub amount: i64,
    // Expiry timestamp in seconds
    pub expiry_ts: u64,
}

Make P2P Offer

import { LAMPORTS_PER_SOL } from "@solana/web3.js";
import { NAME_OFFERS_ID, makeP2p } from "@bonfida/name-offers";

const amount = 10 * LAMPORTS_PER_SOL; // The SOL amount (in lamports) of the P2P offer (can be 0)
const owner = new PublicKey("..."); // The owner of the P2P offer (i.e creator)
const baseDomains: PublicKey[] = []; // The domains the owner wants to sell
const quoteDomains: PublicKey[] = []; // The domains the owner wants to buy (i.e the domains of the counter party)
const endDate: number | undefined = undefined; // The unix timestamp (in seconds) at which the P2P offer expires (optional)
const counterParty = new PublicKey("..."); // The counter party of the P2P offer

const ix = await makeP2p(
  amount,
  owner,
  baseDomains,
  quoteDomains,
  endDate,
  counterParty,
  NAME_OFFERS_ID
);

// ... sign and send instruction

Accept P2P Offer

import { useConnection } from "@solana/wallet-adapter-react";
import { PublicKey } from "@solana/web3.js";
import { useQuery } from "@tanstack/react-query";
import { getAllP2pOffersForOwner, acceptP2p } from "@bonfida/name-offers";


// Example hook to get P2P offers for an owner address
const useP2pOfferOwner = (address: string | null | undefined) => {
  const { connection } = useConnection();
  const fn = async () => {
    if (!address) return null;
    const res = await getAllP2pOffersForOwner(
      connection,
      new PublicKey(address),
    );
    res.sort((a, b) => a.pubkey.toBuffer().compare(b.pubkey.toBuffer()));
    return res;
  };
  return useQuery({ queryKey: ["useP2pOfferOwner", address], queryFn: fn });
};

const { data: p2pOffers } = useP2pOfferOwner(ownerPublicKey);

// This example arbitrarily selects the first P2P offer in the list. Filter offers based on your needs.
const p2pOfferKey = p2pOffers[0].pubkey;

const ix = await acceptP2p(connection, NAME_OFFERS_ID, p2pOfferKey);

// ... sign and send instruction

Cancel P2P Offer

import { cancelP2p } from "@bonfida/name-offers";

const ix = await cancelP2p(
          connection,
          NAME_OFFERS_ID,
          p2pKey, // See above for example of how to retrieve
          ownerPublicKey,
);

// ... sign and send instruction

Last updated