# 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

```rust
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

```typescript
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

```typescript
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

```typescript
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
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sns.id/dev/sns-sdk/sales-and-listings/p2p-offers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
