# Babylon

## Getting Started <a href="#getting-started" id="getting-started"></a>

You can use this library or API to implement Babylon staking for Everstake validator.

{% hint style="info" %}
Be carefully! This library may have compatibility issues with other versions of the libraries.
{% endhint %}

As an example we use:

* node: v22.11.0
* bitcoinjs-lib: ^6.1.5
* ecpair: ^2.1.0
* tiny-secp256k1: ^2.2.3
* @everstake/wallet-sdk: v0.\*

#### Step. 1: Installing the Library <a href="#step-1-installing-the-library" id="step-1-installing-the-library"></a>

Install the npm library or yarn by copying the code below.

{% tabs %}
{% tab title="npm" %}

```sh
$ npm install @everstake/wallet-sdk
```

{% endtab %}

{% tab title="yarn" %}

```sh
$ yarn add @everstake/wallet-sdk
```

{% endtab %}
{% endtabs %}

#### Step. 2: Import Wallet SDK <a href="#step-2-import-wallet-sdk" id="step-2-import-wallet-sdk"></a>

After installing the app, you can import module of needed blockchain (Ethereum, Aptos, Solana, Cosmos, Polygon are available) and use the SDK:

**Import ES6**

```javascript
// or you can also use
import * as Babylon from '@everstake/wallet-sdk/babylon';
// import needed class
import { Babylon } from '@everstake/wallet-sdk/babylon';
```

**Import ES5**

```javascript
// import module
const { Babylon } = require("@everstake/wallet-sdk");
// or you can also use
const { Babylon } = require("@everstake/wallet-sdk/babylon");
```

#### Step. 3: Create Auth Token <a href="#step-3-create-auth-token" id="step-3-create-auth-token"></a>

In order to access all the features of the Wallet SDK, it's necessary for you to generate an authentication token. This token will be required in all of the methods you use.

```javascript
// import
const { CreateToken } = require("@everstake/wallet-sdk");

// Project name
const name = 'Everstake Wallet SDK';
// wallet | Dapp | Other
const type = 'SDK';

// Create Token - return token ID
const token = await CreateToken(name, type);
console.log(token); // 3155f389-d943-4966-8e18-f159c2a6ef66
```

#### Step. 4: Create Babylon instance <a href="#step-4-create-babylon-instance" id="step-4-create-babylon-instance"></a>

```javascript
const { Babylon, signetNetwork } = require("@everstake/wallet-sdk/babylon");

// public key from KeyPair. Buffer type
const publicKey = Buffer.from(keyPair.publicKey)

const babylon = new Babylon(signetNetwork, publicKey, 'YOUR_TOKEN');
```

**Example of using keyPair to get public key and address (signet)**

```javascript
const {payments, initEccLib, networks} = require('bitcoinjs-lib');
const ecc = require('tiny-secp256k1');  // For elliptic curve operations
const {ECPairFactory} = require('ecpair')
const ECPair = ECPairFactory(ecc);
const bs58 = require('bs58');

// Taproot requires tiny-secp256k1 for ECC operations
bitcoin.initEccLib(ecc);

const privateKey = 'XXXXXXXXXXXXqdUAXbpr92hF7M28kTsXXXXXXXXXXXXX'
const keyPair = ECPair.fromWIF(privateKey, networks.testnet)

// Taproot address generation (using single public key)
const { address } = bitcoin.payments.p2tr({
    internalPubkey: keyPair.publicKey.slice(1, 33),  // Remove prefix byte
    network: signetNetwork,
});
console.log('address:', address);
console.log('public key:', bs58.encode(keyPair.publicKey));
```

**Example of using PSBT API**

```javascript
// decode PSBT that have been got from API response
const resultFromAPI = "012.....0123"
const decodedTx = Psbt.fromHex(resultFromAPI)

// sign tx
const signedTx = decodedTx.signInput(0, keyPair);
signedTx.finalizeAllInputs()

// send to network
const tx = Psbt.fromHex(signedTx.toHex()).extractTransaction();
fetch('https://mempool.space/signet/api/tx', {
    method: 'POST',
    headers: { 'Content-Type': 'text/plain' },
    body: tx.toHex()
})
    .then(response => response.text())
    .then(txid => {
        console.log('Broadcasted Transaction ID:', txid);
    })
    .catch(error => {
        console.error('Failed to broadcast transaction:', error);
    });
```

## Stake <a href="#stake-babylon" id="stake-babylon"></a>

The <mark style="color:yellow;">stake</mark> method creates unsigned transaction for stake/delegation

* <mark style="color:yellow;">`stake(amount, feeRate = 1)`</mark>: Stake bitcoin stats from and for specific address. Min. stake is 0.0005 BTC

```javascript
const { Babylon, signetNetwork } = require("@everstake/wallet-sdk/babylon");
const {crypto, Psbt} = require('bitcoinjs-lib');

// Token ID.
const token = process.env.TOKEN; // 3155f389-d943-4966-8e18-f159c2a6ef66

// create instance of Babylon class
const babylon = new Babylon(signetNetwork, Buffer.from(keyPair.publicKey), token);

// amount of stake (sats)
const amount = 50000;

// get unsigned stake tx
const unsignedStakeTx = await babylon.stake(amount);

// sign tx
const tweakedChildNode = keyPair.tweak(
    crypto.taggedHash('TapTweak', keyPair.publicKey.slice(1, 33)),
);
const signedTx = unsignedStakeTx.psbt.signInput(0, tweakedChildNode);
signedTx.finalizeAllInputs()

// extract and sent to network
const stakingTx = Psbt.fromHex(signedTx.toHex()).extractTransaction();
fetch('https://mempool.space/signet/api/tx', {
    method: 'POST',
    headers: { 'Content-Type': 'text/plain' },
    body: stakingTx.toHex()
})
    .then(response => response.text())
    .then(txid => {
        console.log('Broadcasted Transaction ID:', txid);
    })
    .catch(error => {
        console.error('Failed to broadcast transaction:', error);
    });
```

## Unstake <a href="#unbonding-babylon" id="unbonding-babylon"></a>

The <mark style="color:yellow;">`unbonding`</mark> method creates unsigned transaction for unbonding (undelegation which need to withdraw then)

* <mark style="color:yellow;">`unbonding(stakingTxHash)`</mark>: Unbond stake from specific staking Tx.

```javascript
const { Babylon, signetNetwork } = require("@everstake/wallet-sdk/babylon");
const { Psbt } = require('bitcoinjs-lib');

// Token ID.
const token = process.env.TOKEN; // 3155f389-d943-4966-8e18-f159c2a6ef66

// create instance of Babylon class
const babylon = new Babylon(signetNetwork, Buffer.from(keyPair.publicKey), token);

// stake tx hash which need to unbond
const stakeTxHash = '00000000000000000000000000000000000000'

// get unsigned tx
const unsignedUnbondingTx = await babylon.unbonding(stakeTxHash);

// sign tx
const signedTx = unsignedUnbondingTx.psbt.signInput(0, keyPair);
signedTx.finalizeAllInputs();
const tx = Psbt.fromHex(signedTx.toHex()).extractTransaction();

// collect data and send it to Babylon API
const stakerSignature = tx.ins[0].witness[0].toString('hex')
const unbondingTxHex = tx.toHex()
await babylon.sendUnbondingTx({
    staker_signed_signature_hex: stakerSignature,
    staking_tx_hash_hex: stakeTxHash,
    unbonding_tx_hash_hex: tx.getId(),
    unbonding_tx_hex: unbondingTxHex,
})
```

#### Unbonding using API <a href="#unbonding-using-api" id="unbonding-using-api"></a>

At first, you need use <mark style="color:yellow;">`/babylon/unbonding`</mark> endpoint to create unbonding tx, then you need to sign this transaction and make a payload which need to send to another endpoint <mark style="color:yellow;">`/babylon/unbonding/send`</mark> to make order for unbonding.

## Withdraw <a href="#withdrawing-babylon" id="withdrawing-babylon"></a>

#### There are at least two types of withdrawing: <a href="#there-are-at-least-two-types-of-withdrawing" id="there-are-at-least-two-types-of-withdrawing"></a>

* <mark style="color:yellow;">`withdrawEarlyUnbonded(stakingTxHash, feeRate = 1)`</mark>: withdraw your stake after unbonding
* <mark style="color:yellow;">`withdrawTimelockUnbonded(stakingTxHash, feeRate = 1)`</mark>: withdraw your stake after your stake period is expired. No need to make unbonding before

```javascript
const { Babylon, signetNetwork } = require("@everstake/wallet-sdk/babylon");
const { Psbt } = require('bitcoinjs-lib');

// Token ID.
const token = process.env.TOKEN; // 3155f389-d943-4966-8e18-f159c2a6ef66

// create instance of Babylon class
const babylon = new Babylon(signetNetwork, Buffer.from(keyPair.publicKey), token);

// stake tx hash which need to withdraw
const stakeTxHash = '00000000000000000000000000000000000000'

// get unsigned tx
const unsignedWithdrawalTx = await babylon.withdrawEarlyUnbonded(stakeTxHash);
// or you should use withdrawTimelockUnbonded instead of withdrawEarlyUnbonded, it depends on conditions

// sign tx
const signedTx = unsignedWithdrawalTx.psbt.signInput(0, keyPair);
signedTx.finalizeAllInputs();
const tx = Psbt.fromHex(signedTx.toHex()).extractTransaction();

// sent to network
fetch('https://mempool.space/signet/api/tx', {
    method: 'POST',
    headers: { 'Content-Type': 'text/plain' },
    body: tx.toHex()
})
    .then(response => response.text())
    .then(txid => {
        console.log('Broadcasted Transaction ID:', txid);
    })
    .catch(error => {
        console.error('Failed to broadcast transaction:', error);
    });
```

## Getting Info <a href="#getting-info-babylon" id="getting-info-babylon"></a>

* <mark style="color:yellow;">`getDelegations()`</mark>: Gets all user's delegations using the current public key.
* <mark style="color:yellow;">`getGlobalParamsVersions()`</mark>: Gets all versions of global params.

```javascript
const { Babylon, signetNetwork } = require("@everstake/wallet-sdk/babylon");

// Token ID.
const token = process.env.TOKEN; // 3155f389-d943-4966-8e18-f159c2a6ef66

// create instance of Babylon class
const babylon = new Babylon(signetNetwork, keyPair.publicKey, token);

console.log(await babylon.getDelegations()); // list of delegations
```


---

# 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.everstake.one/integrations/everstake-products/wallet-sdk/protocols/babylon.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.
