# Core API

{% hint style="info" %}
The MetaID-TS-SDK source code has been released on GitHub. For the latest API and example code, please refer to the most recent GitHub page.

<https://github.com/metaid-developers/metaid>
{% endhint %}

#### Overview

The MetaID SDK currently targets the BTC chain, providing corresponding API methods from three dimensions: Wallet Layer, Connector Layer, and Entity Layer. Below is a detailed introduction to the relevant API methods.

Each layer's responsibilities and relationships are outlined.

#### Wallet Layer API

<pre class="language-jsx"><code class="lang-jsx">import { MetaletWalletForBtc } from '@metaid/metaid';
<strong>// Create a wallet object based on the currently logged-in wallet account
</strong>const _wallet = await MetaletWalletForBtc.create();

// Access the wallet object's public properties
const address = _wallet.address // Get address
const pubicKey = _wallet.pub // Get public key

// Access a series of methods provided by the wallet object (provided the wallet is connected, otherwise returns {status: 'not-connected' })
await _wallet.getAddress() // Get wallet address

await _wallet.getAddressType() // Get wallet address type

await _wallet.getPublicKey(path) // Get public key based on path

await _wallet.getBalance() // Get balance

await _wallet.signMessage(message) // Send signed message

await _wallet.signPsbt({
  psbtHex,
  options,
}: {
  psbtHex: string
  options?: { toSignInputs?: ToSignInput[]; autoFinalized: boolean }
}) // Sign the input psbtHex

// This is a low-level inscription API method; unless you have very customized inscription needs, it is not recommended to call it directly. 
// The connector layer has abstracted and encapsulated this method, along with related parameter descriptions.
await _wallet.inscribe({data, options} : \
  { data: InscriptionRequest, options: {noBroadcast : boolean }) 
</code></pre>

#### Notes on Wallet Method Parameters and Return Types:

1. Example return value for `getBalance`:

```jsx
{total: 97901828, confirmed: 97901828, unconfirmed: 0}
```

where `confirmed` and `unconfirmed` represent the confirmed and unconfirmed balances respectively (unit: satoshi).

2. Example return value for `getAddressType`:

```jsx
{name: 'Taproot', addressType: 'P2TR', path: "m/86'/0'/0'/0/0"}
```

BTC address types mainly include four types: Legacy (P2PKH), Nested SegWit (P2SH), Native SegWit (Bech32), and Taproot addresses.

3. Explanation of `inscribe` method parameters:

```jsx
export type Operation = 'init' | 'create' | 'modify' | 'revoke'
export type Encryption = '0' | '1' | '2'

export type MetaidData = {
  operation: Operation
  body?: string | Buffer
  path?: string
  contentType?: string
  encryption?: '0' | '1' | '2'
  version?: string
  encoding?: BufferEncoding
  revealAddr: string
}

export type InscriptionRequest = {
  feeRate: number;
  metaidDataList: MetaidData[];
  revealOutValue: number;
  changeAddress: string;
  minChangeValue?: number;
}
```

4. The `inscribe` method returns different transaction data formats depending on whether broadcasting is performed:

* If `noBroadcast` is set to `yes`, meaning no broadcasting, the return format is:

```jsx
{
  commitTxHex: string;
  revealTxsHex: string[];
  commitCost: string;
  revealCost: string;
}
```

* If `noBroadcast` is set to `no`, meaning broadcasting is performed, the return format is:

```jsx
{
  commitTxId: string;
  revealTxIds: string[];
  commitCost: string;
  revealCost: string;
}
```

Where, if not broadcasting, the transaction result is returned in `txHex` format; otherwise, the transaction result is returned as `txid`. The sum of `commitCost` and `revealCost` represents the estimated fee required for the current inscription transaction.

#### Connector Layer API

```jsx
import { btcConnect } from '@metaid/metaid';

// Create a new connector based on the wallet object
const _btcConnector: BtcConnector = await btcConnect({ wallet, network }: { wallet?: MetaIDWalletForBtc; network: BtcNetwork });

// If the wallet object is not empty, you can use the following method to check if the wallet has created a MetaID
_btcConnector.hasMetaid()

// The connector provides a series of methods for operating MetaID related data

type BtcNetwork = "testnet" | "regtest" | "livenet"

// Inscription method
type Operation = 'init' | 'create' | 'modify'
type InscribeOptions= {
  operation: Operation
  body?: string | Buffer
  path?: string
  contentType?: string
  encryption?: '0' | '1' | '2'
  version?: string
  encoding?: BufferEncoding
}
await _btcConnector.inscribe(inscribeOptions: InscribeOptions[], noBroadcast: 'yes' | 'no')
// The return type of this method is the same as the wallet inscribe method.

// Create MetaID, the parameter avatar is processed into Buffer in chunks from the native File type in JS, and then converted to a base64 string
const metaIdRes = await _btcConnector.createMetaid(body?: { network?: BtcNetwork, name?: string; avatar?: string })
// Return type: metaIdRes: { metaid:string }

// Get user information associated with MetaID
const user = await _btcConnector.getUser({ network, currentAddress }: { network: BtcNetwork; currentAddress?: string })

// Update user information associated with MetaID
const isUpdateSuccess = await _btcConnector.updateUserInfo(body: { name?: string; bio?: string; avatar?: string })

// Get MetaID
const currentMetaId = await _btcConnector.getMetaid()

// Check the current connector status (whether the wallet is connected)
const isConnected = await _btcConnector.isConnected()

// Disconnect the current wallet
await _btcConnector.disconnect()

// Create an Entity object, this method bridges the Connector layer and the Entity layer
await _btcConnector.use(entitySymbol: string)
```

#### Notes on Connector Layer API:

1. From the perspective of the MetaID Specification, issuing or modifying on-chain data involves sending a PIN, and the inscription interface handles this task. Whether it's creating a MetaID, updating user information, or calling the create method after generating an Entity object, it essentially sends a PIN to put the data on-chain.
2. For the `createMetaid` method of the connector object, if you pass in a complete `body` parameter including name, bio, and avatar, the SDK will sequentially perform the following actions: first initialize at the root path `/` (operation=init), then create corresponding information under the paths `/info/name`, `/info/bio`, and `/info/avatar` (operation=create).
3. Regarding data timeliness, when modifying on-chain data (operation=modify/revoke), there are relevant matters to note. Please refer to the second convention in the MetaID Specification regarding `modify`/`revoke` operations.

#### Entity Layer API

Once you create an entity through the connector, you can access a series of properties and methods provided by that entity.

> Currently, the MetaID SDK provides basic entity calls based on the on-chain microblog example application, including buzzEntity, fileEntity, and likeEntity. If developers have their own customization needs, they can create their data protocol on the MetaProtocols website, and the MetaID SDK will automatically create the corresponding entity for that protocol.

```jsx
// Example of creating a buzzEntity

type BtcNetwork = "testnet" | "regtest" | "livenet"

// Create a buzzEntity entity through the connector
const buzzEntity = await _btcConnector.use('buzz')

// Get all buzzes sent by the currently connected account in a paginated manner
const allBuzz = await buzzEntity.list({ page, limit, network }: { page: number; limit: number; network?: BtcNetwork })

// Get the details of a specific Pin by its pinId
const pid = 'XXXXXXXXX' 
const pinDetail = await buzzEntity.one({ pid, network }: { pid: string; network: BtcNetwork })

// Count the total number of Pins sent under the current entity (buzzEntity)
const pinTotal = await buzzEntity.total({ network }: { network?: BtcNetwork })

// Create a buzz
type CreateOptions = {
  body?: string | Buffer;
  contentType?: string;
  encryption?: "0" | "1" | "2";
  version?: string;
  encoding?: BufferEncoding;
}

// The return type of this method is the same as the wallet inscribe method.
const createRes = await buzzEntity.create({
  options,
  noBroadcast,
}: {
  options: CreateOptions[]
  noBroadcast: 'yes' | 'no'
})
```

#### Notes on the Entity's `create` Method:

1. According to the MetaID Specification, you can think of the create method as creating new files under a certain folder (file path), essentially calling the connector's inscribe method. The results vary depending on the broadcast parameter, and the specific data format can be found in the connector's inscribe method description.
2. Explanation of the `option` parameter corresponding to the MetaProtocols protocol:
   * The `body` parameter's specific fields should refer to the corresponding MetaProtocol protocol description for that entity (e.g., buzzEntity corresponds to the SimpleBuzz protocol).
   * The `contentType` field represents the data format, e.g., `text/plain`, `image/png`.
   * The `encryption` field indicates the encryption type of the content: `0` for no encryption, `1` for ECIES encryption, and `2` for ECDH negotiated key encryption.
   * The `version` field specifies the protocol version number of MetaProtocols.
   * The `encoding` field refers to the encoding format, which aligns with the global `BufferEncoding` parameter in TypeScript:

     ```typescript
     type BufferEncoding = 
         | "ascii"
         | "utf8"
         | "utf-8"
         | "utf16le"
         | "utf-16le"
         | "ucs2"
         | "ucs-2"
         | "base64"
         | "base64url"
         | "latin1"
         | "binary"
         | "hex";
     ```

     **Examples** for the `Option` Parameter

     (1) For the `buzz` entity, the `option` parameter should be:

     ```typescript
     {
         body: "buzz content"
     }
     ```

     (2) For the `file` entity, assuming you are passing an image file, the `option` parameter should be:

     ```typescript
     {
         body: Buffer.from('image raw hex string', "hex").toString("base64"),
         contentType: "image/jpeg",
         encoding: "base64"
     }
     ```

3\. Instructions for Batch Creation (Inscription): You may have noticed that the `CreateOptions` parameter is passed in as an array. This means you can create multiple pieces of data for a particular type of entity simultaneously. Here's a specific example: when you post a `buzz` with multiple image attachments, you only need to call the inscription interface twice. First, batch inscribe multiple images using the `fileEntity`. The generated transaction hash array is then passed into the `attachments` field of the `buzzEntity` create method for the second inscription.
