# Pontis Frontend SDK

### Installation

To install the Pontis Bridge Frontend SDK, run:

```bash
npm install @pontis/core-sdk
```

### Supported Cross-Chain Assets

The first SDK version supports the following assets:

* **BTC**
* **Runes**

### Workflow

#### 1. Authorization

Authorize using an extension wallet or a private key (for wallet integration) to sign the authorization message.

**Supported Wallets:**

* **Bitcoin**: Xverse, Leather, Unisat, Asigna Multisig
* **Stacks**: Xverse, Leather
* **EVM**: Metamask

**Fields Required for Authorization:**

* `publicKey` (not required for EVM)
* `address`
* `signature`: A signature from the connected wallet for the message:\
  \&#xNAN;*"Welcome to Pontis!"*

#### 2. Authorize via Pontis API

Each network requires separate authentication.\
The authorization request returns a **JWT token** for each chain. *(See the API documentation for more details.)*

#### 3. Load History

Use the following function to fetch the transaction history for the specified chain:

```javascript
getTransaction('active' | 'completed');
```

The chain is determined by the **JWT token** obtained during the authorization step.

#### 4. Create Bridge Transactions

Create bridge transactions for different chains. Refer to the detailed guides below.

### Bitcoin Blockchain Actions

#### Hook: `useBitcoinBlockchainActions`

**1. `createSendBtc`**

Send BTC via the bridge.

**Parameters:**

* `amount`: The amount of BTC to send.
* `feeRate`: The fee rate for the bridge transaction.
* `recipientAddress`: The recipient’s address.
* `destinationChain`: The target blockchain.
* `doSignAndBroadcastPsbt`: Function to sign and broadcast the generated PSBT.

**Example:**

```javascript
async (psbt) => {
  const txId = await signAndBroadcastPsbtXverse(psbt);
  return txId;
};
```

**2. `doSignMessage`**

Function to sign the bridge message (a required step for Bitcoin transactions).

**Example:**

```javascript
async (message) => {
  const signature = await signCustomMessage(message);
  return signature;
};
```

***

**3. `createSendRune`**

Send Rune assets via the Bitcoin chain.

**Parameters:**

The parameters are the same as `createSendBtc` with one additional field:

* `rune`: The Rune to send.

### Pending Transactions

For Bitcoin, the bridge transaction process involves two steps:

1. The bridge transaction is created.
2. The message with the `txId` and destination parameters is signed by the sender's wallet.

{% hint style="info" %}
Developers should account for the users that accidentally closes the sign message window.
{% endhint %}

* Unsigned transactions are stored in `localStorage` under the key: `pending_transactions`.

#### Hook: `usePendingTransactions`

This hook:

* Returns stored transactions.
* Provides functions to handle the state of stored data.

By default, the stored data is managed within the library.

#### Signing Pending Transactions: `signMessageForTx`

**Parameters:**

* `txId`: The transaction ID.
* `async doSignMessage(message: string)`: The message signing handler.
* `onFinish(claim: Claim)`: A callback triggered when the transaction is created on the backend.

**Example:**

```javascript
const { txs, signMessageForTx } = usePendingTransactions();

{txs.length > 0 && (
  <div
    onClick={() => {
      signMessageForTx(
        txs[0].txId,
        async (message: string) => {
          return await signMessage(message) as string;
        },
        () => {
          navigate('history');
        }
      );
    }}
  >
    Pending
  </div>
)}
```

### Stacks Blockchain Actions

#### Hook: `useStxBlockchainActions`

**Supported Properties**

* **`whitelistedRunes`**: A list of [supported-runes](https://pontis.gitbook.io/about/introduction/supported-runes "mention").
* **`unlockBtcUnsignedCall`**

**Parameters:**

* **`publicKey`**: Signer’s public key.
* **`amount`**: Amount to transfer.
* **`recipientAddress`**: Destination address.
* **`targetChain`**: Target blockchain.
* **`stacksNetwork`**: `"testnet"` or `"mainnet"`.
* **`doSignAndBroadcast`**: Function to sign and broadcast the generated `StacksTransaction`. Returns `txId`.

**Example:**

```javascript
async (stacksTransaction) => {
  const txId = await openSignTransaction({
    txHex: bytesToHex(stacksTransaction.serialize()),
  });
  return txId;
};
```

**`unlockRunesUnsignedCall`**

Send Rune assets on the Stacks chain.

**Parameters:**

The parameters are the same as `unlockBtcUnsignedCall` with one additional field:

* **`rune`**: Rune to send.

**`unlockBtc` and `unlockRunes`**

These are helper functions to sign and broadcast transactions using the wallet.

### Supported EVM Chains

The SDK supports the following EVM testnets:

* **Sepolia (SEP)**
* **Merlin Testnet (MERL)**

### EVM Blockchain Actions

#### Hook: `useEvmBlockchainActions`

If permission hasn’t been granted yet, the `approve` **token contract** function will be called automatically.

**`createBridgeOutBTC`**

Send BTC via the EVM chain.

**Parameters:**

* **`amount`**: The amount to send.
* **`recipientAddress`**: The destination address.
* **`sourceChain`**: `SEP` (Sepolia) or `MERL` (Merlin Network).
* **`targetChain`**: The target blockchain.
* **`serviceValue`**: The service fee.

**`createSendRune`**

Send Rune assets via the EVM chain.

**Parameters:**

The parameters are the same as `createBridgeOutBTC` with one additional field:

* **`rune`**: Rune to send.

### Pontis API

#### Axios Instance: `pontisAxiosInstance`

This is an Axios instance used to interact with the Pontis API.

#### Authorization

**Functions:**

* **`evmLoginRequest`**
* **`stacksLoginRequest`**
* **`bitcoinLoginRequest`**

These functions return a **JWT token** for their respective chains.

#### Bitcoin Multisig Authentication

Used for integration with [**Asigna Multisig**](https://btc.asigna.io/).<br>

Connect to your dApp using the **`@asigna/btc-connect`** package.

Pass the information from the **`useAsignaSafeInfo()`** hook or **`connectToExtension()`** function to **`bitcoinLoginRequestMultisig()`**.

**Parameters:**

* **`finalSignature`**: Signature from the multisig owners.
* **`multiSigType`**: The multisig type.
* **`multisigAddress`**: The multisig address.
* **`ownersPublicKeys`**: Public keys of the multisig owners.
* **`ownersAddresses`**: Addresses of the multisig owners.
* **`threshold`**: Multisig threshold.

**Integration Example:**

```javascript
import { useAsignaExtension, validateMessage } from '@asigna/btc-connect';

const { openSignMessage } = useAsignaExtension();
const { asignaSafeInfo } = useAsignaSafeInfo();

const info = await connectToExtension();
const signature = await openSignMessage('Welcome to Pontis');

bitcoinLoginRequestMultisig({
  finalSignature: signature,
  multiSigType: info.multisigType,
  multisigAddress: info.address,
  ownersPublicKeys: info.users.map(user => user.publicKey || ''),
  ownersAddresses: info.users.map(user => user.address),
  threshold: info.threshold,
});
```

### Get Transactions

Use the following function to load created bridge transactions:

```javascript
getTransactions('active' | 'completed');
```

***

### Configuration

Bridge settings for supported chains:

* **`config.evm`**: EVM contracts.
* **`config.btc`**: Multisig address and fee contract to retrieve service fees.
* **`config.stx`**: Stacks contracts for bridging and loading fees.

### Utilities

#### Load Service Fees After Authorization

**Hook: `useEvmFees`**

\
Gets fees for `MERL` or `SEP` chains.

* **`loadFees(targetChain)`**: Returns the minimum limit for BTC asset transfers and service fees for Runes and BTC.
* **`loadMinFeesForRunes(runeId)`**: Returns the minimum limit for a specified Rune.

**Example:**

```javascript
const { loadFees, loadMinFeesForRunes } = useEvmFees(ChainType.MERL);

const fees = await loadFees(ChainType.BTC);
const minRunes = await loadMinFeesForRunes('runeId');
```

***

**Hook: `useFees`**\
\
Get fees for `BTC` and `STX` chains.

* **`getFeesForBridge`**: Returns the minimum limit for BTC asset transfers and service fees for Runes and BTC.
  * `sourceChain`: `'BTC' | 'STX'`
  * `targetChain`: `ChainType`
* **`getMinRunes(runeId)`**: Returns the minimum limit for a specified Rune.
  * `sourceChain`: `'BTC' | 'STX'`
  * `runeContractName`: The Rune contract name.
  * `runeContractAddress`: The Rune contract address.

**Example:**

```javascript
const runeContractAddress = 'ST3DGSTWQZ80CXTFBKE2RMC02MGXCXEPQCXY528VS';
const runeContractName = 'pontis-bridge-i-need-test-runes::bridge-token';

const { getFeesForBridge, getMinRunes } = useFees('testnet');

const fees = await getFeesForBridge(ChainType.BTC, ChainType.STX);
const minRune = await getMinRunes(ChainType.BTC, runeContractAddress, runeContractName);
```

***

#### Pending Transactions

**Created Transactions Without Signed Messages**

For Bitcoin, transactions without signed messages are stored in **localStorage** under the key: `pending_transactions`.

***

**Hook: `usePendingTransactions`**

* Returns stored transactions.
* Provides functions to handle the state of stored transaction data.

By default, stored data is managed within the library.

***

**Signing Pending Transactions: `signMessageForTx`**

**Parameters:**

* **`txId`**: Transaction ID.
* **`async doSignMessage(message: string)`**: The message signing handler.
* **`onFinish(claim: Claim)`**: A callback triggered when the transaction is created on the backend.

**Example:**

```javascript
const { txs, signMessageForTx } = usePendingTransactions();

{txs.length > 0 && (
  <div
    onClick={() => {
      signMessageForTx(
        txs[0].txId,
        async (message: string) => {
          return await signMessage(message) as string;
        },
        () => {
          navigate('history');
        }
      );
    }}
  >
    Pending
  </div>
)}

```


---

# 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://pontis.gitbook.io/about/developers/pontis-frontend-sdk.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.
