# Keyring Controller

### Create an instance

```typescript
const keyring = new KeyringController({ 
    baseUrl: 'http://localhost:8000',
    walletType: {
        embedded: true, // for external wallet it should be false
        supportAa: true, // false if dapp only wants EOA wallets
    },
    sentryDns, // string
    environment, // ENV
    sessionSignatures, //[OPTIONAL] SESSION SIG FROM litController.initSession
    currentAccount, //[OPTIONAL] fetch PKPs FROM litController.fetchPKPs
    customAuthMethod,
    accessToken,
    aa,
    selectedWallet,
} as TriaArgs);

export type TriaArgs = {
  baseUrl: string;
  sentryDns?: string;
  walletType?: WalletType;
  selectedChainName?: ChainName;
  environment?: ENV;
  currentAccount?: IRelayPKP;
  sessionSignatures?: string;
  customAuthMethod?: LitCustomAuthMethod;
  accessToken?: string;
  aa?: AaDetails;
  selectedWallet?: "EOA" | "AA";
};

export type ENV = 'testnet' | 'mainnet-staging' | 'mainnet';
```

{% hint style="info" %}
To maintain the integrity of the keyring object that stores decrypted vaults in memory, it is crucial to preserve its context. This implies that the keyring object should not be recreated, but rather instantiated only once.&#x20;
{% endhint %}

{% hint style="warning" %}
Recreating the keyring object would lead to the loss of critical in-memory data, consequently preventing the user from performing any transaction signing. Therefore, it is imperative to avoid the recreation of this object at all costs.
{% endhint %}

## Functions

### **Reconstruction of Vault**&#x20;

{% hint style="info" %}
The ideal moment to invoke this method is immediately after a successful user login. This timing ensures that we have access to the user's password and pin, which are essential for decrypting and reconstructing the vault.
{% endhint %}

{% hint style="info" %}
To ensure smooth functioning and optimal performance of the KeyringController, it is essential to call the following method as the first step before invoking any other methods. This method initializes the persist storage and in-memory data, laying the foundation for subsequent operations.

Additionally, it should be called only once during the application startup process. Repeated invocations of this method may result in unnecessary overhead, affecting efficiency.
{% endhint %}

```typescript
reconstruct(password: string, pin: string): Promise<ReconstructResponse>;
```

```typescript
// Example
const password = 'password';
const pin = '444444';
const data = await keyring.reconstruct(password, pin);
console.log(data);
```

```typescript
interface ReconstructResponse {
  success: boolean
}
```

### Social Login \[v2]

```typescript
async socialogin({
    triaName,
    password,
    platform,
    userId,
    isPasswordLess,
  }: {
    triaName: string;
    password: string;
    platform: string;
    userId: string;
    isPasswordLess: boolean;
  }): Promise<SocialLoginResponse>
```

```typescript
interface SocialLoginResponse {
  success: boolean;
  data: any;
}
```

### Create Account \[v2]

```typescript
async createAccount({ triaName, password }: { triaName: string; password: string }) 
```

### Get Vault \[v2]

```typescript
async getVault({ triaName, password, userId,}: { triaName?: string; password: string; userId?: string; })
```

### Add Wallet

```typescript
 addWallet(username: string, password: string, pin: string, chainName: string): Promise<AddWalletResponse>;
```

```typescript
// Example
await keyring.addWallet({username: "alex@tria", password:"password", pin:"444444", chainName:"ETH"});
```

```typescript
export interface AddWalletResponse {
  list: UpdatedWalletInfoList
  success: boolean
}

interface UpdatedWalletInfoList extends Array<WalletInfo> { }
interface WalletInfo {
  creationMethod: CreationMethod;
  addresses: AddressList;
}
interface AddressList extends Array<Address> { }
interface Address {
  subname: Nullable<string>;
  address: string;
  isDeleted: Nullable<boolean>;
  chain: string;
}
enum CreationMethod {
  Onboarding = 1, // start from 1 not from zero, because it is falsy
  ManualCreation = 2,
  ManualImport = 3
}
type Nullable<T> = T | undefined | null;
```

### Export Mnemonic

```typescript
async exportMnemonic(password: string, pin: string): Promise<exportMnemonicResponse>
```

```typescript
interface exportMnemonicResponse {
    success: boolean,
    mnemonic: string | null;
}
```

### Export Private Key

```typescript
async exportPrivateKey(triaName: string, password: string, pin: string, chainName: string): Promise<ExportPrivateKeyResponse>
```

```typescript
interface ExportPrivateKeyResponse {
    success: boolean,
    privateKey: string | null;
}
```

### Update SubName

```typescript
async updateSubName({ newSubName, oldSubName, password, pin }: UpdateSubNameArgs) : Promise<UpdateSubNameResponse> 
```

```typescript
interface UpdateSubNameArgs {
    password: string,
    pin: string,
    oldSubName: string,
    newSubName: string
}
```

```typescript
interface UpdateSubNameResponse {
    message: string,
    success: boolean,
    vault: UpdatedPublicVault | null
}
```

### Remove Address

```typescript
async removeAddress({ subname, password, pin }: RemoveAddressArgs) : Promise<RemoveAddressResponse>
```

```typescript
export interface RemoveAddressArgs {
    subname: string,
    password: string,
    pin: string
}
```

```typescript
interface RemoveAddressResponse {
    message: string,
    success: boolean,
    vault: UpdatedPublicVault | null
}
```

* For Choose Asset or Assets display
* filter - chainNames - makes sense only when sending to a subName i.e. only available on one chain
* triaName- for fetching userDoc (vault with public keys) from db
* Available now for -&#x20;

  ```typescript
  [
    'ETH',
    'POLYGON',
    'AVALANCHE',
    'ARBITRUM',
    'BINANCE',
    'OPTIMISM',
    'FANTOM',
    'MOONBEAM',
    'BITCOIN'
  ];
  ```

### Detect Logged in Account

```typescript
detectLoggedInAccount();
```

<details>

<summary>Example implementation</summary>

Add this in auth.tria.so/detect and open this as a invisible iframe in the onboarding SDK to send events to the SDK, and read events with `const {account} = useDetectAccount();`&#x20;

```javascript
import { KeyringController } from '@tria-sdk/web';
import React, { useEffect } from 'react';
// import { baseUrl, embeddedWalletType } from '../utils/constants';
import { eventTypes, Account } from '@tria-sdk/connect';

const baseUrl = 'https://staging.tria.so';
const walletType = { embedded: true };

const Detect = () => {
  const detectAccount = async () => {
    const keyring = new KeyringController({
      baseUrl,
      walletType,
    });
    await keyring.init({});
    keyring.detectLoggedInAccount();
  };
  useEffect(() => {
    detectAccount();
  }, []);
  return <div>Detect</div>;
};

export default Detect;

```

</details>


---

# 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-priv.tria.so/reference/onboarding-and-wallet-sdk/tria-sdk-web-internal/keyring-controller.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.
