# BTC+ Oracle on Solana

Solana completely separates execution logic from data storage. Execution logic is stored in program accounts, and contract data is stored in data accounts.

The BTC+ vault account, managed by the Solv Program, has the address [B3ct2h3iCWKZmErPQ8PtZ51qBU98Zfci2TSnjvXNUbUa](https://explorer.solana.com/address/B3ct2h3iCWKZmErPQ8PtZ51qBU98Zfci2TSnjvXNUbUa). The terms "BTC+ vault," "BTC+ account," and "BTC+ vault account" all refer to the same concept unless otherwise specified.

<figure><img src="/files/0JBt4sBF6CISNwpk8Qei" alt=""><figcaption></figcaption></figure>

### GetNav

The nav info is stored in BTC+ vault. You can get nav through querying BTC+ Vault Account.&#x20;

#### Step1. Fetch Account Info

```typescript
import {Connection, PublicKey } from "@solana/web3.js";
import * as borsh from '@coral-xyz/borsh';

const vault = new PublicKey("B3ct2h3iCWKZmErPQ8PtZ51qBU98Zfci2TSnjvXNUbUa");
const connection = new Connection("https://api.mainnet-beta.solana.com	", "confirmed");

let vaultInfo = await connection.getAccountInfo(vault);

```

#### Step2. Deserialize Account Data

To deserialize account data, you must be familiar with the memory buffer layout of the accounts.\
Before defining the buffer layout, examine the structure of your account data within the contract.\
For BTC+ Vault, you can find it's structure in verified repo(<https://github.com/solv-finance/SolvBTC-Solana-Contract/blob/master/programs/solvbtc/src/state/vault.rs>)

```typescript
// Let's start by defining our typeScript interface for our account data
interface whitelistedToken {
    mint: PublicKey;
    depositFee: number;
}

interface Vault {
    discriminator: number[];
    admin: PublicKey;
    mint: PublicKey;
    feeReceiver: PublicKey;
    treasurer: PublicKey;
    depositCurrencies: whitelistedToken[];
    verifier: number[];
    oracleUpdated: bigint;
    oracleManager: PublicKey;
    nav: bigint;
    withdrawFee: number;
    bump: number;
}

// define buffer layout
const WhitelistedTokenLayout = borsh.struct<whitelistedToken>([
    borsh.publicKey('mint'),
    borsh.u16('depositFee'),
]);

const VaultLayout = borsh.struct<Vault>([
    borsh.array(borsh.u8(), 1, 'discriminator'),
    borsh.publicKey('admin'),
    borsh.publicKey('mint'),
    borsh.publicKey('feeReceiver'),
    borsh.publicKey('treasurer'),
    borsh.array(WhitelistedTokenLayout, 10, 'depositCurrencies'),
    borsh.array(borsh.u8(), 64, 'verifier'),
    borsh.i64('oracleUpdated'),
    borsh.publicKey('oracleManager'),
    borsh.u64('nav'),
    borsh.u16('withdrawFee'),
    borsh.u8('bump'),
]);

```

#### Step3. Decode Account Data and Get Nav

```typescript
const deserialize = VaultLayout.decode(vaultInfo?.data)
console.log(deserialize);
consoole.log("Current Nav", Number(deserialize.nav))
```

You can run ts-node \<your\_script\_name> from your ./src folder, and will get a result similar to the following:

```shellscript
{
  discriminator: [ 1 ],
  admin: PublicKey [PublicKey(BsF2mR9brTd7u7wGWrejksQzsdrGFNcddRSYeNpHZixM)] {
    _bn: <BN: a173c62453a369b2bbbf5290d7071a720f6d474eed749b030ae17fb54b99a66e>
  },
  mint: PublicKey [PublicKey(SoLvHDFVstC74Jr9eNLTDoG4goSUsn1RENmjNtFKZvW)] {
    _bn: <BN: 69bebc05aa95ec929fdd48c9d90c6c8c961589e86aefbf8dc1ce588c5206b6f>
  },
  feeReceiver: PublicKey [PublicKey(BThzBKuJeExUxDAWzmBteAk8VH6UgnaosBuybtdy14Jj)] {
    _bn: <BN: 9b6c5028d5fca099ab1d559c072055dc7879126cfc9682fe17fdb736c23e4d30>
  },
  treasurer: PublicKey [PublicKey(4aW1UQgHYz3VKu6QUyst3SPe1YoaBvPy1DmozVf3WFUS)] {
    _bn: <BN: 352806efbaec22bef2a1d849976758da9ac727640d24587af8b3b0830946a017>
  },
  ...
  oracleUpdated: <BN: 69047365>,
  oracleManager: PublicKey [PublicKey(72hthmBVybLZTTM1qQYAk39ZrJtFW8aWtssYNe29cEKT)] {
    _bn: <BN: 5995f03e5c3d703235ee9ac4c4b5d442002971f37e634fe8fd25b2b10d12075a>
  },
  nav: <BN: 5f5e100>,
  withdrawFee: 0,
  bump: 254
}
Current Nav 100000000
```

### Nav Decimals

The NAV decimal is 8 for Solv Solana program, and this value is hardcoded. This can be verified in the repository mentioned previously

#### Full Code

Take a look at the full code for deserialize.ts here:

```typescript
import { Connection, PublicKey } from "@solana/web3.js";
import * as borsh from '@coral-xyz/borsh';


async function main() {
    const vault = new PublicKey("B3ct2h3iCWKZmErPQ8PtZ51qBU98Zfci2TSnjvXNUbUa");
    const connection = new Connection("https://api.mainnet-beta.solana.com	", "confirmed");

    let vaultInfo = await connection.getAccountInfo(vault);

    // Let's start by defining our TypeScript interface for our account data
    interface whitelistedToken {
        mint: PublicKey;
        depositFee: number;
    }

    interface Vault {
        discriminator: number[];
        admin: PublicKey;
        mint: PublicKey;
        feeReceiver: PublicKey;
        treasurer: PublicKey;
        depositCurrencies: whitelistedToken[];
        verifier: number[];
        oracleUpdated: bigint;
        oracleManager: PublicKey;
        nav: bigint;
        withdrawFee: number;
        bump: number;
    }

    // define buffer layout
    const WhitelistedTokenLayout = borsh.struct<whitelistedToken>([
        borsh.publicKey('mint'),
        borsh.u16('depositFee'),
    ]);

    const VaultLayout = borsh.struct<Vault>([
        borsh.array(borsh.u8(), 1, 'discriminator'),
        borsh.publicKey('admin'),
        borsh.publicKey('mint'),
        borsh.publicKey('feeReceiver'),
        borsh.publicKey('treasurer'),
        borsh.array(WhitelistedTokenLayout, 10, 'depositCurrencies'),
        borsh.array(borsh.u8(), 64, 'verifier'),
        borsh.i64('oracleUpdated'),
        borsh.publicKey('oracleManager'),
        borsh.u64('nav'),
        borsh.u16('withdrawFee'),
        borsh.u8('bump'),
    ]);

    const deserialize = VaultLayout.decode(vaultInfo?.data)
    console.log(deserialize);
    console.log("Current Nav", Number(deserialize.nav));

}

main().catch(console.error);

```

## Conclusion

With the Vault account data on Solana now deserialized, you can apply these same principles to other Vault on Solana by simply substituting the vault account address . Use similar research methods to determine the program's data structure for the given data. Always ensure you check the source code of the program you wish to deserialize data from, and adapt these methods to your specific needs.

\ <br>

<br>


---

# 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.solv.finance/developer-guide/oracle-mechanism/btc+-oracle-on-solana.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.
