# Wrapped BTC Contract

This page explains how to create a simple wrapped Bitcoin implementation using the Glittr SDK. The example demonstrates creating a contract that allows users to mint wrapped BTC tokens at a 1:1 ratio.

### 1. Setup and Configuration

```typescript
import {
  Account,
  addFeeToTx,
  BitcoinUTXO,
  BlockTxTuple,
  electrumFetchNonGlittrUtxos,
  GlittrSDK,
  OpReturnMessage,
  Output,
  txBuilder
} from "@glittr-sdk/sdk";

const NETWORK = "regtest";
const client = new GlittrSDK({
  network: NETWORK,
  apiKey: <your api key here>,
  glittrApi: "https://devnet-core-api.glittr.fi",
  electrumApi: "https://devnet-electrum.glittr.fi"
});
```

First, we import the necessary components from the Glittr SDK and initialize the client with the appropriate network settings. In this case, we're using the `regtest` network for development purposes.

### 2. Account Setup

```typescript
// Create two accounts: creator and minter
const creatorAccount = new Account({
  wif: "...",
  network: NETWORK,
});
const minterAccount = new Account({
  wif: "...",
  network: NETWORK,
});
```

We create two accounts:

* `creatorAccount`: The account that will create and manage the contract
* `minterAccount`: The account that will mint wrapped BTC tokens

### 3. Creating the Contract

{% code fullWidth="false" %}

```typescript
async function deployWbtcContract() {
  const tx: OpReturnMessage = {
    contract_creation: {
      contract_type: {
        moa: {
          divisibility: 8,
          live_time: 0,
          supply_cap: 21000000n.toString(),
          mint_mechanism: {
            purchase: {
              input_asset: 'raw_btc',
              ratio: { fixed: { ratio: [1, 1] } } // 1:1 ratio
            }
          }
        }
      }
    }
  }

  const address = creatorAccount.p2pkh().address
  const utxos = await electrumFetchNonGlittrUtxos(client.electrumApi, client.apiKey, address)
  const nonFeeInputs: BitcoinUTXO[] = []
  const nonFeeOutputs: Output[] = [
    { script: txBuilder.compile(tx), value: 0 }, // Output #0 should always be OP_RETURN
    { address: address, value: 546 }
  ]

  const { inputs, outputs } = await addFeeToTx(NETWORK, address, utxos, nonFeeInputs, nonFeeOutputs)

  const txid = await client.createAndBroadcastRawTx({
    account: creatorAccount.p2pkh(),
    inputs,
    outputs
  })

  console.log(`TX: https://explorer.glittr.fi/tx/${txid}`);
}
```

{% endcode %}

The contract creation function sets up:

* A maximum supply of 21 million (matching Bitcoin's cap)
* 8 decimal places of divisibility (matching Bitcoin)
* A 1:1 exchange ratio between BTC and the wrapped token
* No time restrictions on minting/burning

### 4. Minting Wrapped BTC

```typescript
async function mint() {
  // Change this to your deployWbtcContract() result
  const contract: BlockTxTuple = [101869, 1]; // https://explorer.glittr.fi/tx/688cbe5f4c147e46ef3ed2bbf448291c2041a7ab14ee9032ce1153b1ce89ed6e

  const tx: OpReturnMessage = {
    contract_call: {
      contract,
      call_type: {
        mint: {
          pointer: 1 // Points to the mint receiver's index in Output array 
        }
      }
    }
  }

  const address = minterAccount.p2pkh().address
  const utxos = await electrumFetchNonGlittrUtxos(client.electrumApi, client.apiKey, address)
  const nonFeeInputs: BitcoinUTXO[] = []
  const nonFeeOutputs: Output[] = [
    { script: txBuilder.compile(tx), value: 0 }, // Output #0 should always be OP_RETURN
    { address: address, value: 546 },
    { address: creatorAccount.p2pkh().address, value: 1000 } // Mint 1000 sats
  ]

  const { inputs, outputs } = await addFeeToTx(NETWORK, address, utxos, nonFeeInputs, nonFeeOutputs)

  const txid = await client.createAndBroadcastRawTx({
    account: minterAccount.p2pkh(),
    inputs,
    outputs
  })

  console.log(`TX: https://explorer.glittr.fi/tx/${txid}`);
}
```

The minting function:

* References the existing contract
* Creates a mint transaction
* Sends Bitcoin to the creator's address
* Receives wrapped BTC tokens in return

### 5. Checking Asset Details

```typescript
async function _checkingAsset() {
  const mintTxid =
    "a320545261eb503ba305ebaf3e7bcaa7534c905b91b03a51759cf8e8128808de";
  const mintVout = 0;
  const result = await fetch(
    `https://devnet-core-api.glittr.fi/assets/${mintTxid}/${mintVout}`
  );

  console.log(await result.text());
}
```

This utility function allows you to check the details of an asset by its transaction ID and output index.

### Key Concepts

1. **1:1 Backing**: Each wrapped BTC token is backed by an equivalent amount of Bitcoin.
2. **Supply Cap**: The contract matches Bitcoin's supply cap of 21 million.
3. **Divisibility**: The wrapped token maintains the same 8 decimal places as Bitcoin.
4. **Purchase/Burn**: Users can mint tokens by sending BTC and burn tokens to receive BTC back.

This implementation provides a simple way to create wrapped Bitcoin tokens that maintain a 1:1 peg with actual Bitcoin, allowing for easier integration with other Glittr contracts and applications.

### Usage Flow

1. **Initialize the SDK and accounts**

   ```typescript
   const client = new GlittrSDK({...});
   const creatorAccount = new Account({...});
   const minterAccount = new Account({...});
   ```
2. **Create the wrapped BTC contract**

   ```typescript
   await deployWbtcContract();
   ```
3. **Mint wrapped BTC tokens**

   ```typescript
   await mint();
   ```
4. **Check asset details**

   ```typescript
   await _checkingAsset();
   ```

### Full Code Example

```typescript
import {
  Account,
  addFeeToTx,
  BitcoinUTXO,
  BlockTxTuple,
  electrumFetchNonGlittrUtxos,
  GlittrSDK,
  OpReturnMessage,
  Output,
  txBuilder
} from "@glittr-sdk/sdk";

const NETWORK = "regtest";
const client = new GlittrSDK({
  network: NETWORK,
  apiKey: <your api key here>,
  glittrApi: "https://devnet-core-api.glittr.fi", // devnet
  electrumApi: "https://devnet-electrum.glittr.fi" // devnet
});

const creatorAccount = new Account({
  wif: "...",
  network: NETWORK,
});

const minterAccount = new Account({
  wif: "...",
  network: NETWORK,
});

console.log(`Creator account ${creatorAccount.p2pkh().address}`);
console.log(`Minter account ${minterAccount.p2pkh().address}`);


async function deployWbtcContract() {
  const tx: OpReturnMessage = {
    contract_creation: {
      contract_type: {
        moa: {
          divisibility: 8,
          live_time: 0,
          supply_cap: 21000000n.toString(),
          mint_mechanism: {
            purchase: {
              input_asset: 'raw_btc',
              ratio: { fixed: { ratio: [1, 1] } } // 1:1 ratio
            }
          }
        }
      }
    }
  }

  const address = creatorAccount.p2pkh().address
  const utxos = await electrumFetchNonGlittrUtxos(client.electrumApi, client.apiKey, address)
  const nonFeeInputs: BitcoinUTXO[] = []
  const nonFeeOutputs: Output[] = [
    { script: txBuilder.compile(tx), value: 0 }, // Output #0 should always be OP_RETURN
    { address: address, value: 546 }
  ]

  const { inputs, outputs } = await addFeeToTx(NETWORK, address, utxos, nonFeeInputs, nonFeeOutputs)

  const txid = await client.createAndBroadcastRawTx({
    account: creatorAccount.p2pkh(),
    inputs,
    outputs
  })

  console.log(`TXID : ${txid}`)
}

async function mint() {
  // Change this to your deployWbtcContract() result
  const contract: BlockTxTuple = [101869, 1]; // https://explorer.glittr.fi/tx/688cbe5f4c147e46ef3ed2bbf448291c2041a7ab14ee9032ce1153b1ce89ed6e

  const tx: OpReturnMessage = {
    contract_call: {
      contract,
      call_type: {
        mint: {
          pointer: 1 // Points to the mint receiver's index in Output array 
        }
      }
    }
  }

  const address = minterAccount.p2pkh().address
  const utxos = await electrumFetchNonGlittrUtxos(client.electrumApi, client.apiKey, address)
  const nonFeeInputs: BitcoinUTXO[] = []
  const nonFeeOutputs: Output[] = [
    { script: txBuilder.compile(tx), value: 0 }, // Output #0 should always be OP_RETURN
    { address: address, value: 546 },
    { address: creatorAccount.p2pkh().address, value: 1000 } // Mint 1000 sats
  ]

  const { inputs, outputs } = await addFeeToTx(NETWORK, address, utxos, nonFeeInputs, nonFeeOutputs)

  const txid = await client.createAndBroadcastRawTx({
    account: minterAccount.p2pkh(),
    inputs,
    outputs
  })

  console.log(`TXID : ${txid}`)
}

/**
 * Call deployWbtcContract() function first
 * wait for confirmation and indexing
 * then call the mint() function
 */
deployWbtcContract()



/**
 * Function to check asset after mint
 * change the mintTxId and mintVout
 * with your vestedMint() and freeMint() result
 */
async function _checkingAsset() {
  const mintTxid =
    "a320545261eb503ba305ebaf3e7bcaa7534c905b91b03a51759cf8e8128808de";
  const mintVout = 0;
  const result = await fetch(
    `https://devnet-core-api.glittr.fi/assets/${mintTxid}/${mintVout}`
  );

  console.log(await result.text());
}
```
