# User Guide: Pre-Inscribed Launchpad API

This document provides detailed instructions for implementing the Pre-Inscribed Launchpad API, covering the steps required to create a launchpad and make offers.

## 1. Creating a Pre-Inscribed Launchpad

### Overview

The Pre-Inscribed Launchpad API enables you to create and manage pre-inscribed launchpads for pre inscribed inscriptions.\
\
Here is a sequence of API calls for creating a Launchpad:

<figure><img src="https://796103842-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FO24IAeCgrVaXB6ds99Ew%2Fuploads%2FA6oEDNxNOUyPEoGvMBPu%2Fcreate-launchpad.png?alt=media&#x26;token=d8a99145-ec92-46ed-9c06-f9ad543fd64b" alt=""><figcaption></figcaption></figure>

### Implementation Steps

#### Step 1: Create Launchpad

Make an API call to create a new Pre-Inscribed Launchpad:

```
POST https://api.ordinalsbot.com/marketplace/launchpads/create
```

Request body:

```json
{
  "slug": "satoshibles-the-ordinals",
  "makerPaymentAddress": "2N6ZePLQrKtix9bJBfznsykxKX1XtirnbKL",
  "makerPaymentPublicKey": "033528dc4c9fd062e63d2a8d5f8b2e3c3b8312ae7c1d3c4a41a9dc4eefa4205c05",
  "makerOrdinalAddress": "bc1q...",
  "makerOrdinalPublicKey": "e581edf3a948470930171a3e676490a8f7953a3698044c14b4d75ffeabc88a26",
  "data": [
    {
      "id": "8e7ba76e0c06ff5f43f50371bce849ae4e88dd36e1c0629e1a6f4383d1b0e679i0",
      "meta": {
        "attributes": [
          {
            "trait_type": "background",
            "value": "orange"
          }
        ],
        "name": "Satoshibles: The Ordinals #1"
      }
    }
  ],
  "meta": {
    "description": "Satoshi has come home to Bitcoin! The Ordinals collection by OG NFT project Satoshibles are a limited edition collection of 100 ordinals, featuring all new traits from the original artist Ayyoub Bouzerda. This collection is a tribute to Satoshi and the enduring legacy of Bitcoin. Don't miss your chance to own a piece of history!",
    "discord_link": "https://discord.com/invite/7Wm9Jg8MkW",
    "icon": "https://turbo.ordinalswallet.com/inscription/preview/3542f12dbe5fe3bd7fd622d1bb54994432e9a9184d24ff62ceb83234383b558ei0",
    "inscription_icon": "https://example.com/icon.png",
    "name": "Satoshibles: The Ordinals",
    "slug": "satoshibles-the-ordinals",
    "twitter_link": "https://twitter.com/satoshibles",
    "website_link": "https://satoshibles.com",
    "banner_image": "https://example.com/banner.png"
  },
  "phases": [
    {
      "name": "Whitelist Sale",
      "startDate": 1712044800,
      "endDate": 1712131200,
      "price": 100000,
      "isPublic": false,
      "allowList": [
        {
          "address": "bc1q...",
          "allocation": 5
        }
      ]
    }
  ]
}
```

Response:

```json
{
  "launchpadId": 123
}
```

#### Step 2: Monitor Launchpad Status by calling launchpad info endpoint /launchpads/{id}

Poll the Launchpad info API until the launchpad status changes:

* **"initializing"**: Lanchpad creation has started and still in progress
* **"pending\_psbt\_signature"**: All inscriptions processed and all PSBTs ready for requires signature
* **"active"**: No pending PSBTs to sign
* **"failed"**: Creation process failed failed\_reason will have reason for failure

```
GET https://api.ordinalsbot.com/marketplace/launchpads/{id}
```

Response:

```json
{
  "id": 99,
  "marketplace_id": "string",
  "status": "string",
  "failed_reason": "string",
  "total_inscriptions": 1000,
  "remaining_inscriptions": 1000,
  "meta_data": "string",
  "phases": [
    {
      "id": 0,
      "launchpad_id": 0,
      "name": "string",
      "phase_number": 0,
      "start_date": 1729621800,
      "end_date": 1729621810,
      "status": "string",
      "is_public": true,
      "price": 0,
      "psbts": [
        {
          "id": 207,
          "status": "unsigned",
          "phase_id": 132,
          "batch_number": 1,
          "inscription_count": 500
        },
        {
          "id": 208,
          "status": "unsigned",
          "phase_id": 132,
          "batch_number": 2,
          "inscription_count": 500
        }
      ]
    }
  ]
}
```

#### Step 3: Poll launchpad info&#x20;

Poll launchpad info till the status changes to "pending\_psbt\_signature", this indicates that all inscriptions have been processed. A set of PSBTs have been created and need to be signed.

#### Step 4: Fetch PSBT Details

Use the psbt id for each PSBT object from launchpad if. Call the `/marketplace/launchpads/psbt/{id}` API endpoint to fetch PSBT details for each psbt id:

```
GET https://api.ordinalsbot.com/marketplace/launchpads/psbt/{id}
```

Response:

```json
{
  "id": 207,
  "phase_id": 132,
  "batch_number": 1,
  "status": "unsigned",
  "inscription_count": 500,
  "psbt": "cHNi.....ZUEAAA=="
}
```

#### Step 5: Sign the PSBT

The PSBT needs to be signed by the inscription owner address on the frontend. Configure seller input and sign the transaction:

```js
try {
  // Configure seller inputs for the seller's wallet to sign
  const sellerInput = {
    address: ordinalsAddress, // Seller's ordinal wallet address
    signingIndexes: [0 to inscription_count], // Some walle api require this others done
    sigHash: bitcoin.Transaction.SIGHASH_SINGLE | bitcoin.Transaction.SIGHASH_ANYONECANPAY, // Specify sigHash type
  };
  
  // Prepare signing payload
  const payload = {
    network: { type: "Mainnet" },
    message: "Sign Seller Transaction",
    psbtBase64: psbt, // PSBT returned by the /marketplace/launchpads/psbt/{id} API
    broadcast: false,
    inputsToSign: [sellerInput],
  };
  
  // Sign transaction
  await signTransaction({
    payload,
    onFinish: async ({ psbtBase64 }) => {
      // Step 6: Call the confirm endpoint with the signed PSBT
    },
    onCancel: () => {
      console.error("User canceled the signing request");
    },
  });
} catch (error) {
  console.error("Error creating listing:", error);
}
```

#### Step 6: Confirm Signed PSBT

Call the `/marketplace/launchpads/psbt/{id}/confirm` endpoint to update with the signed PSBT:

```
PUT https://api.ordinalsbot.com/marketplace/launchpads/psbt/{id}/confirm
```

Request body:

```json
{
  "signedPSBT": "cHNi.....ZUEAAA=="
}
```

Response:

```json
{
  "message": "Signed PSBT is updated successfully"
}
```

#### Step 7: Complete Process

Repeat steps 2-6 until all required PSBTs are signed and the launchpad status becomes "active".

## 2. Creating a Pre-Inscribed Launchpad Offer

### Overview

This process allows users to buy(mint) from a pre-inscribed launchpad.

Here is a sequence of API calls for buying from a Launchpad:

<figure><img src="https://796103842-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FO24IAeCgrVaXB6ds99Ew%2Fuploads%2FL3KVvpm3KmiDMXlfTtff%2Fcreate-launchpad-offer.png?alt=media&#x26;token=d82bc4c6-f7a5-4545-a775-7fe6674a6854" alt=""><figcaption></figcaption></figure>

### Implementation Steps

#### Step 1: Set Up Padding Outputs

if padding outputs dont exist in the buyers payment address then padding outputs will need to be created by calling:

Call the Setup Padding Output API:

```
POST https://api.ordinalsbot.com/marketplace/launchpads/offers/setup-padding
```

Request body:

```json
{
  "launchpadId": 123,
  "paymentAddress": "2N6ZePLQrKtix9bJBfznsykxKX1XtirnbKL",
  "paymentPublicKey": "033528dc4c9fd062e63d2a8d5f8b2e3c3b8312ae7c1d3c4a41a9dc4eefa4205c05"
}
```

Response:

```json
{
  "psbt": "cHNi.....ZUEAAA==",
  "inputIndices": [0, 1]
}
```

Sign the padding output transaction:

```js
try {
  const setupPaddingPayload = {
    network: {
      type: "Mainnet",
    },
    message: 'Sign Padding Outputs Transaction',
    psbtBase64: psbt, // PSBT returned by the Setup Padding Output API
    broadcast: true,
    inputsToSign: [{
      address: paymentAddress,
      signingIndexes: inputIndices, // Payment input indices returned by the Setup Padding Output API
    }],
  };
  
  await signTransaction({
    payload: setupPaddingPayload,
    onFinish: async ({ txId }) => {
      console.log("Signed Padding Outputs Transaction: " + txId);
    },
    onCancel: () => {
      console.error("User canceled the transaction");
    },
  });
} catch (error) {
  console.error("Error:", error);
}
```

Wait for transaction confirmation before making a purchase

#### Step 2: Create the Offer

Call the `/marketplace/launchpads/offers` API:

```
POST https://api.ordinalsbot.com/marketplace/launchpads/offers
```

Request body:

```json
{
  "launchpadId": 123,
  "items": [1, 2],
  "paymentAddress": "2N6ZePLQrKtix9bJBfznsykxKX1XtirnbKL",
  "paymentPublicKey": "033528dc4c9fd062e63d2a8d5f8b2e3c3b8312ae7c1d3c4a41a9dc4eefa4205c05",
  "ordinalAddress": "tb1q..."
}
```

Response:

```json
{
  "offerId": 456,
  "psbt": "cHNi.....ZUEAAA==",
  "inputIndices": [0, 1]
}
```

#### Step 3: Sign the Offer Transaction

```js
try {
  const createOfferPayload = {
    network: {
      type: "Mainnet",
    },
    message: 'Sign Create Offer Transaction',
    psbtBase64: psbt, // PSBT returned by the Create Offer API
    broadcast: false,
    inputsToSign: [{
      address: paymentAddress,
      signingIndexes: inputIndices, // Payment input indices returned by the Create Offer API
    }],
  };
  
  await signTransaction({
    payload: createOfferPayload,
    onFinish: async ({ psbtBase64 }) => {
      // Step 4: Submit the signed offer
    },
    onCancel: () => {
      console.error("User canceled the transaction");
    },
  });
} catch (error) {
  console.error("Error:", error);
}
```

#### Step 4: Submit the Offer

Call the `/marketplace/launchpads/offers/{id}/submit` API to complete the purchase and broadcast the transaction:

```
PUT https://api.ordinalsbot.com/marketplace/launchpads/offers/{id}/submit
```

Request body:

```json
{
  "signedPSBT": "cHNi.....ZUEAAA=="
}
```

Response:

```json
{
  "txId": "aa1c27........2767",

}
```

*
