> For the complete documentation index, see [llms.txt](https://help.keyring.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.keyring.app/keyring-pro/open-source.md).

# Open Source

## KEYRING PRO Is Open Source

[**View the public KEYRING PRO repository**](https://github.com/bacoor-hb/KEYRINGPRO)&#x20;

{% embed url="<https://github.com/bacoor-hb/KEYRINGPRO>" %}

Trust begins with transparency.

<mark style="color:$success;">**KEYRING PRO is a non-custodial wallet**</mark> that gives users full control over their private keys and assets. Because the wallet handles highly sensitive information, we believe users deserve more than security claims. They deserve the confidence that the technology protecting their assets can be independently reviewed and verified.

By making KEYRING PRO open source, we allow developers, security professionals, auditors, and organizations to examine how the wallet works. They can review how private keys are generated and encrypted, where they are stored, how wallet access is protected, how backup files are secured, and how transactions are signed.

Most users may never need to read the source code themselves. However, knowing that the implementation is publicly available provides greater confidence that KEYRING PRO is built on transparent and verifiable security principles.

Open source also reflects our commitment to accountability. The protections described by KEYRING PRO can be compared directly with the code that implements them. Users do not need to rely on hidden systems or unsupported promises.

Publishing the source code does not expose users’ private keys, passwords, backup files, balances, or other personal wallet information. This information is created during actual use and remains separate from the public source code. Production credentials and service keys are also not included in the public repository.

For KEYRING PRO, open source is more than making code publicly available. It is our commitment to building a wallet that users can trust with greater confidence through transparency, accountability, and independently verifiable security.

> <mark style="color:pink;">**Security should not rely on blind trust. It should be transparent, verifiable, and built to give users confidence.**</mark>

## How KEYRING PRO Protects Your Assets

Private key protection in KEYRING PRO follows a clear process:

* A private key is created using secure cryptographic randomness.
* The private key is encrypted using a key derived from the user’s password.
* The protected private key is stored locally on the user’s device.
* It is retrieved and decrypted only when the wallet is unlocked.
* Transactions are signed inside the wallet.
* Only the signed transaction is sent to the blockchain network.

Because the source code is public, each part of this process can be reviewed directly.

### <mark style="color:red;">Non-Custodial. Private Keys Are Stored Locally on the Device</mark>

When password protection is active, KEYRING PRO encrypts the private key before saving it:

```js
let value = privateKey
if (vaultHasPassword()) {
  if (!vaultIsUnlocked()) {
    vaultRequestUnlock()
    return false
  }
  value = vaultEncryptPrivateKey(privateKey)
}
```

The protected value is then stored by wallet address:

```js
listPrivateKeyByAddress[lowerCase(address)] = value
storeDataToSecureStorage(KEYSTORE.LIST_PRIVATE_KEY_BY_ADDRESS, listPrivateKeyByAddress)
```

`storeDataToSecureStorage()` writes the protected data into an MMKV storage area inside the application on the user’s device:

```js
secureStorage = new MMKV({
  id: Config.SECURE_STORAGE_ID,
  encryptionKey
})
```

```js
secureStorage.set(key, JSON.stringify(value))
```

The MMKV storage area is itself opened with an encryption key. During the normal setup process, the application obtains this storage key through the device’s operating-system keychain.

These functions perform local storage operations. They do not contain a network request that uploads the private key to a KEYRING PRO server.

> <mark style="color:green;">**Your private key is stored in protected application storage on your own device. KEYRING PRO does not keep a server-side copy of the private key to manage your wallet.**</mark>
>
> <mark style="color:green;">**This keeps control of your private key on your device instead of placing it in the hands of KEYRING PRO or another service.**</mark>

### Secure Private Key Generation

When Automatic Private Key Generation is selected, KEYRING PRO uses two methods imported from the **Viem account library**:

```js
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
```

The private key is generated and converted into an Ethereum and EVM account:

```js
const privateKey = generatePrivateKey()
const account = privateKeyToAccount(privateKey)
```

`generatePrivateKey()` creates a new random private key. `privateKeyToAccount()` then derives the matching Ethereum and EVM wallet address from that private key.

Viem generates the private key using the secp256k1 implementation from the security-focused `@noble/curves` cryptography library. secp256k1 is the elliptic curve used for Ethereum account keys.

KEYRING PRO also loads `react-native-get-random-values`, which provides cryptographically secure system randomness in the React Native environment. This is different from an ordinary random function used for simple application behavior.

> <mark style="color:green;">**Your automatically generated private key is created from secure system randomness and follows the cryptographic model used by Ethereum and EVM networks. It is not based on a simple or predictable pattern, making it extremely difficult for another person to guess or reproduce.**</mark>
>
> <mark style="color:green;">**This helps protect your wallet from unauthorized access by making the private key extremely difficult to guess.**</mark>

KEYRING PRO also supports Manual Private Key Generation, giving users greater flexibility and direct control when creating a wallet account.

With this option, users can create a personalized private key by entering 64 valid HEX characters using numbers 0–9 and letters A–F.

For the highest level of protection, use a unique and difficult-to-guess combination that is known only to you.

### Password Protection for Private Keys

KEYRING PRO does not use the user’s password directly as an encryption key.

Instead, it uses cryptographic methods provided by the `react-native-quick-crypto` library:

```js
import QuickCrypto from 'react-native-quick-crypto'
```

The password-processing and encryption settings are:

```js
export const PBKDF2_ITERATIONS_DEFAULT = 900000
export const KEY_LENGTH = 32
```

```js
export const DIGEST = 'sha512'
export const CIPHER_ALGO = 'aes-256-gcm'
```

The password is processed using PBKDF2-SHA512 with 900,000 iterations. This produces a 256-bit encryption key suitable for protecting sensitive wallet data.

PBKDF2 repeatedly processes the password before creating the final encryption key. Each wallet also uses a random value called a salt, so the same password does not automatically produce the same encryption result for different data.

The resulting encryption key is then used with AES-256-GCM:

```js
const cipher = QuickCrypto.createCipheriv(CIPHER_ALGO, key, iv)
const ciphertext = Buffer.concat([cipher.update(Buffer.from(plaintext, 'utf8')), cipher.final()])
const tag = cipher.getAuthTag()
```

AES-256-GCM changes the private key into unreadable encrypted data. It also creates an authentication tag that allows the wallet to verify that the encrypted information has not been changed or damaged.

Decryption will fail when:

* The password produces the wrong encryption key.
* The encrypted data has been modified.
* The authentication tag does not match.
* The stored data has become corrupted.

> <mark style="color:green;">**When password protection is active, your private key is not stored as readable text. The correct password-derived key is required to decrypt it, and altered or corrupted encrypted data will fail the security check.**</mark>
>
> <mark style="color:green;">**This keeps your private key unreadable without the correct password and detects altered or corrupted encrypted data.**</mark>

A strong and unique password remains important. Encryption makes password guessing significantly more difficult, but it cannot make an easy-to-guess password completely safe.

### Private Keys Are Kept Separate from Normal Account Data

After an account is created or imported, KEYRING PRO moves its private key into dedicated private key storage and removes it from the normal account object:

```js
// store private key to secure storage
storePrivateKeyByAddress(evmAccount.address, evmAccount.privateKey)
// remove private key from object
delete evmAccount.privateKey
```

The wallet address, account name, selected networks, and other general information can continue to be used by normal wallet screens. The private key is kept separately from that account information.

KEYRING PRO can display your wallet address, balances, and transaction information without keeping your private key inside every part of the application. This reduces unnecessary access to the most sensitive information in your wallet.

> <mark style="color:green;">**Your private key is removed from normal account data and stored separately in protected private key storage.**</mark>
>
> <mark style="color:green;">**This limits private key access to only the parts of the wallet that need it.**</mark>

### Private Keys Are Retrieved Only When Required

When KEYRING PRO needs a private key for an authorized operation, it first reads the protected entry from local secure storage:

```js
const listPrivateKeyByAddress = getDataFromSecureStorage(KEYSTORE.LIST_PRIVATE_KEY_BY_ADDRESS, {})
const entry = listPrivateKeyByAddress?.[lowerCase(address)]
```

If the entry is encrypted, KEYRING PRO checks whether the vault is unlocked:

```js
if (isEncryptedEntry(entry)) {
  if (!vaultIsUnlocked()) {
    vaultRequestUnlock()
    return ''
  }
  try {
    privateKey = vaultDecryptPrivateKey(entry)
  } catch (e) {
    return ''
  }
}
```

If the wallet is locked, the private key is not returned. The user must first complete the unlock process.

KEYRING PRO does not keep the decrypted private key permanently available. It retrieves and decrypts the private key only when a protected wallet operation requires it and the wallet has been successfully unlocked.

> <mark style="color:green;">**The encrypted private key can only be retrieved after the wallet has been successfully unlocked. If the wallet is locked or decryption fails, no private key is returned.**</mark>
>
> <mark style="color:green;">**This reduces unnecessary exposure by accessing the private key only when it is needed.**</mark>

### The Active Vault Key Is Temporary

After the correct password is entered, KEYRING PRO temporarily keeps the derived vault key in the active application state:

```js
// RAM-only. Never persisted.
let vaultEncryptionKey = null
```

The vault key allows authorized private key operations while the wallet is unlocked. The module does not save this key as a permanent value.

When the wallet is locked, the active reference is cleared:

```js
export const clearVault = () => {
  vaultEncryptionKey = null
}
```

The same module blocks encryption while the vault is locked:

```js
export const encryptPrivateKey = (plainPk) => {
  if (!vaultEncryptionKey) throw new Error('Vault is locked')
  return encryptWithKey(plainPk, vaultEncryptionKey)
}
```

Decryption is protected by the same requirement:

```js
export const decryptPrivateKey = (entry) => {
  if (!vaultEncryptionKey) throw new Error('Vault is locked')
  return decryptWithKey(entry, vaultEncryptionKey)
}
```

This prevents protected private key operations from continuing through the normal wallet process after the vault has been locked.

> <mark style="color:green;">**Access to your encrypted private keys is available only while the wallet is properly unlocked. After the wallet is locked, the active vault key is cleared and authentication is required again.**</mark>
>
> <mark style="color:green;">**This prevents protected wallet functions from remaining accessible after the wallet is locked.**</mark>

### Transactions Are Signed Inside the Wallet

When the user approves a transaction, KEYRING PRO uses the private key inside the application to create a signed transaction:

```js
const signedTransaction = await ethWallet.signTransaction(rawTransaction)
```

The private key authorizes the transaction locally. It is not added to the transaction data.

The completed signed transaction is then sent to the broadcasting process:

```js
this.sendSignedTransactionWithRetry(chainTypeOrChainId, signedTransaction, isWaitDone, callback)
  .then(result => resolve(result))
  .catch(err => reject(err))
```

This means the private key is used to create cryptographic proof that the account owner approved the transaction, but the private key itself does not need to leave the wallet.

> <mark style="color:green;">**Your private key is used locally to authorize transactions. It is not sent to the blockchain service as part of the signing process.**</mark>
>
> <mark style="color:green;">**This allows you to approve transactions without sending your private key outside the wallet.**</mark>

### Only the Signed Transaction Is Broadcast

After local signing is complete, KEYRING PRO sends the serialized signed transaction to the RPC service:

```js
const hash = await client.sendRawTransaction({ serializedTransaction: signedTransaction })
```

The RPC service uses the signed transaction to broadcast the operation to the blockchain. It does not require the private key that created the signature.

> <mark style="color:green;">**Blockchain infrastructure receives the signed transaction, but it does not receive the private key that controls your wallet account.**</mark>
>
> <mark style="color:green;">**This allows the blockchain to process your transaction without receiving your private key.**</mark>

### Self-Custody Verified Through Source Code

The published code shows the complete private key flow:

**Secure randomness → Private key generation → Password-based encryption → Local device storage → Decryption after authentication → Local transaction signing → Signed transaction broadcasting**

KEYRING PRO does not need to hold a server-side copy of the private key to create an account, store it, unlock it, or broadcast a transaction.

Public wallet addresses, signed transactions, and requests required for blockchain services may leave the device as part of normal wallet operation. The private key itself remains locally stored and is not included in the signed transaction sent to RPC services.

> <mark style="color:green;">**Your private key remains under your control on your device. KEYRING PRO uses it locally to authorize wallet operations without taking custody of it.**</mark>
>
> <mark style="color:green;">**This ensures that only you control access to your wallet account and assets.**</mark>

Because KEYRING PRO does not keep a recovery copy of the private key on its servers, the KEYRING team cannot access the account, approve transactions, or recover a lost private key for the user.

Users must securely keep their private key and backup file. Losing access to both may result in permanent loss of access to the wallet account.

## Additional Security Features

### Automatic Wallet Locking

KEYRING PRO can automatically lock the wallet after the application remains in the background longer than the selected Auto-Lock period.

```js
const elapsedMs = Date.now() - enteredAt
const thresholdMs = Math.max(0, minutes) * 60 * 1000

if (elapsedMs >= thresholdMs) {
  clearVault()
  requestUnlock()
}
```

When the selected period has passed, KEYRING PRO clears active vault access and returns the application to the unlock process.

> <mark style="color:green;">**If you leave the application or your device unattended, the wallet will not remain continuously unlocked. Authentication is required again after the selected Auto-Lock period.**</mark>
>
> <mark style="color:green;">**This helps prevent unauthorized access when your device is left unattended.**</mark>

### Protection Against Repeated Password Attempts

KEYRING PRO limits repeated incorrect password attempts:

```js
export const MAX_FAILED_ATTEMPTS = 5
export const LOCK_DURATION_MS = 60 * 60 * 1000 // 1 hour
```

After five consecutive incorrect attempts, the wallet applies a one-hour lockout.

The failed-attempt count is stored in encrypted secure storage:

```js
const failedAttempts = current.failedAttempts + 1
storeDataToSecureStorage(KEYSTORE.LOCKOUT_FAILED_ATTEMPTS, failedAttempts)
```

When the maximum number of failed attempts is reached, KEYRING PRO stores the time when the lockout will end:

```js
if (failedAttempts >= MAX_FAILED_ATTEMPTS) {
  const lockUntil = Date.now() + LOCK_DURATION_MS
  storeDataToSecureStorage(KEYSTORE.LOCKOUT_UNTIL, lockUntil)
  return buildState(failedAttempts, lockUntil)
}
```

The failed-attempt count and lockout period are stored in encrypted secure storage, so restarting the application does not immediately remove the restriction.

This interrupts repeated password guessing through the normal application interface.

> <mark style="color:green;">**Someone with access to your device cannot make unlimited password guesses through the application. Repeated failures temporarily stop further attempts.**</mark>
>
> <mark style="color:green;">**This makes repeated password-guessing attempts more difficult.**</mark>

This protection does not replace the need for a strong password.

### Encrypted Backup Files

A KEYRING PRO backup may contain multiple accounts and wallet settings. The wallet payload is encrypted before the backup file is saved.

A new random salt is generated and used to derive an encryption key from the backup password:

```js
const salt = randomBytes(SALT_LENGTH)
const key = await derivePbkdf2(password, salt, PBKDF2_ITERATIONS_DEFAULT)
```

The wallet payload is then encrypted with AES-256-GCM:

```js
const { iv, tag, ciphertext } = encryptAesGcm(JSON.stringify(payload), key)
```

Each time a backup file is created, KEYRING PRO:

* Generates a new random salt.
* Processes the backup password with PBKDF2-SHA512.
* Creates an encryption key for that backup.
* Encrypts the wallet payload with AES-256-GCM.
* Saves the encrypted payload with the information needed for restoration.

Each backup file has its own password-based encryption relationship because a new random salt is created for every backup.

> <mark style="color:green;">**Having the backup file alone is not enough to restore your wallet. The correct backup file and the password set for that specific file are both required.**</mark>
>
> <mark style="color:green;">**This prevents someone from restoring your wallet using only a copy of the backup file.**</mark>

An incorrect password produces the wrong encryption key. Modified, corrupted, or damaged encrypted data will also fail the AES-GCM authentication check.

Every new backup file must be protected with a password. Users should securely store both the backup file and its password.

### Biometric and Device Passcode Protection

When biometric unlock is enabled, KEYRING PRO protects a saved copy of the wallet password through the operating-system keychain:

```js
const saved = await Keychain.setInternetCredentials(
  VAULT_USER_PASSWORD,
  VAULT_USER_PASSWORD_ACCOUNT,
  wrapped,
  { accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY_OR_DEVICE_PASSCODE }
)
```

Depending on the device, authentication may use:

* Face ID
* Touch ID
* Fingerprint authentication
* The device passcode

After saving the protected credential, KEYRING PRO immediately attempts to read it through an operating-system authentication prompt. If authentication fails, is cancelled, or the stored value cannot be verified, the saved entry is removed.

Biometric unlock is not only a visual confirmation inside the application. Access to the protected wallet credential is controlled through the security functions provided by iOS or Android.

> <mark style="color:green;">**Biometric authentication does not directly reveal the private key. It authorizes access to the protected wallet password, which is then used to unlock the encrypted private key vault.**</mark>
>
> <mark style="color:green;">**This adds device-level protection before the wallet can be unlocked.**</mark>

## KEYRING PRO Features That Can Be Verified

Open source does more than show security settings. It also allows reviewers to examine how KEYRING PRO’s main wallet features are implemented.

### Account Creation and Import

KEYRING PRO supports:

* Automatically generated private keys
* Manually entered private keys
* Private keys imported from another compatible wallet

The code converts a private key into an EVM account and derives its wallet address:

```js
export const generateEvmAccountFromPrivateKeyEvm = (privateKey, isFromKeyCard = false, addressProps) => {
  try {
    const wallet = privateKeyToAccount(add0xToPrivateKey(privateKey))
    return { chain: STANDARD_CHAIN.Evm, address: addressProps || lowerCase(wallet.address), privateKey: isFromKeyCard ? '' : remove0xFromPrivateKey(privateKey) }
  } catch (error) {
    return null
  }
}
```

Invalid private keys return no account. KEYRING PRO also checks for duplicate wallet addresses before adding an account and then moves the private key into dedicated storage.

> <mark style="color:green;">**You can create a new account or import an existing one while KEYRING PRO applies the same account validation and private key storage process.**</mark>
>
> <mark style="color:green;">**This provides consistent protection for both newly created and imported accounts.**</mark>

### Hot, NFC KeyCard, and View-Only Accounts

KEYRING PRO supports three account types:

* **Hot account:** The private key is generated or imported on the device.
* **NFC KeyCard account:** Encrypted private key data is stored on a supported NFC card.
* **View-only account:** Only the public wallet address is registered.

For a view-only account, KEYRING PRO creates an account entry without importing or storing a private key:

```js
const accountData = {
  chain: STANDARD_CHAIN.Evm,
  address: addressLower,
  name: accountName,
  status: true,
  accountType: ACCOUNT_TYPE.VIEW_ONLY
}
```

The view-only function does not touch private key storage because there is no private key to store.

A view-only account can monitor balances and activity but cannot sign transactions because KEYRING PRO does not hold its private key.

> <mark style="color:green;">**A view-only account lets you monitor a wallet address without importing or storing its private key.**</mark>
>
> <mark style="color:green;">**This allows you to monitor an account without exposing the private key controlling it.**</mark>

For an NFC KeyCard account, KEYRING PRO does not keep the private key in the normal account object:

```js
return { chain: STANDARD_CHAIN.Evm, address: addressProps || lowerCase(wallet.address), privateKey: isFromKeyCard ? '' : remove0xFromPrivateKey(privateKey) }
```

The account is identified separately as a cold account:

```js
accountType: isFromKeyCard ? ACCOUNT_TYPE.COLD : ACCOUNT_TYPE.HOT
```

For an NFC KeyCard account, KEYRING PRO encrypts the card payload with PBKDF2 and AES-256-GCM. When reading the card, it also checks that the address stored in the card data matches the account selected in the wallet. A mismatch causes the private key to be rejected.

> <mark style="color:green;">**Private key data stored on an NFC KeyCard is protected with password-based encryption. KEYRING PRO also checks that the card address matches the selected wallet account before using the private key.**</mark>
>
> <mark style="color:green;">**This helps protect the NFC KeyCard from unauthorized use and prevents it from being used with the wrong account.**</mark>

### Multi-Chain EVM Support

KEYRING PRO includes built-in configuration for 20 Ethereum and EVM-compatible networks:

```js
export const LIST_DEFAULT_CHAIN_ID = [1, 10, 56, 8453, 42161, 43114, 137, 130, 9745, 999, 988, 5000, 42220, 4326, 100, 747474, 143, 57073, 4217, 4663]
```

The configuration defines information such as:

* Chain ID
* Network name
* Native currency
* RPC connection
* Block explorer
* Transaction and token links

The repository identifies the built-in networks as: Ethereum, Optimism, BNB Chain, Base, Arbitrum, Avalanche, Polygon, Unichain, Plasma, HyperEVM, Stable, Mantle, Celo, MegaETH, Gnosis, Katana, Monad, Ink, Tempo, Robinhood.

Other compatible EVM networks can also be added.

> <mark style="color:green;">**You can use the same wallet account across supported Ethereum and EVM-compatible networks without installing a different wallet for each network.**</mark>
>
> <mark style="color:green;">**This allows you to manage assets across multiple EVM networks from one wallet.**</mark>

### WalletConnect Connections

KEYRING PRO uses WalletConnect v2 to connect selected wallet accounts to supported Web3 applications.

Before approval, KEYRING PRO prepares the session using the selected account, approved networks, requested methods, and requested events:

```js
const namespacesParams = {
  proposal: proposal.params,
  supportedNamespaces: {
    eip155: { chains: chainsArr, accounts: accountArr, methods, events }
  }
}
```

The approved namespace is then created:

```js
const approvedNamespaces = buildApprovedNamespaces(namespacesParams)
```

The WalletConnect session is approved using that namespace:

```js
const session = await connectorV2.approveSession({
  id: proposal.id,
  namespaces: approvedNamespaces
})
```

Before approval, KEYRING PRO prepares the session using:

* The account selected by the user
* The approved EVM networks
* The methods requested by the dApp
* The events requested by the dApp

The session is then bound to the selected account address. The wallet also contains a rejection process when the account or requested networks are unavailable.

> <mark style="color:green;">**You can choose which account is connected instead of automatically sharing every account stored in KEYRING PRO.**</mark>
>
> <mark style="color:green;">**This gives you greater control over which account and networks are shared with a Web3 application.**</mark>

A WalletConnect connection does not guarantee that a dApp is safe. Always review connection requests, messages, and transactions before approving them.

### Token Swap and Cross-Chain Bridge

KEYRING PRO uses a shared service structure for swap and bridge providers:

```js
switch (providerName) {
  case 'debridge':
    return new DebridgeAdapter(config)
  case 'relay':
    return new RelayAdapter(config)

  default:
    return new DebridgeAdapter(config)
}
```

The published source includes service adapters for Relay and deBridge.

The service structure handles operations such as:

* Selecting a provider
* Requesting a quote
* Checking token approval
* Preparing the transaction
* Executing the swap or bridge
* Tracking transaction progress

> <mark style="color:green;">**You can perform supported same-chain swaps and cross-chain transfers through one consistent wallet interface instead of using a separate application for each provider.**</mark>
>
> <mark style="color:green;">**This makes swapping and transferring assets across supported networks more convenient.**</mark>

### Built-In AI Assistant

The public repository includes a dedicated AI assistant interface with wallet account and network selection.

The assistant is designed to help users understand wallet information and prepare supported wallet operations. The repository describes examples such as preparing token transfers or supported liquidity actions with user approval.

Sensitive operations must still follow the wallet’s normal review, approval, and transaction-signing process.

> <mark style="color:green;">**The AI assistant can help explain or prepare wallet actions, but you remain responsible for reviewing and approving the final operation.**</mark>
>
> <mark style="color:green;">**This provides helpful guidance while keeping final control of every wallet action in your hands.**</mark>

## Why Open Source Matters

A wallet can state that it encrypts private keys, protects backups, or signs transactions locally. Open source allows qualified reviewers to check whether those statements are reflected in the actual implementation.

The KEYRING PRO repository allows reviewers to examine:

* How private keys are generated
* Which library creates private keys
* Which cryptographic curve is used
* How passwords are converted into encryption keys
* Which encryption algorithm protects private keys
* Where private keys are stored
* How private keys are retrieved
* What happens when the wallet locks
* How repeated password attempts are limited
* How backup files are encrypted and restored
* How biometric authentication controls access
* Whether transactions are signed before broadcasting
* Whether the private key is included in RPC requests
* How hot, NFC KeyCard, and view-only accounts work
* How WalletConnect sessions are approved
* How networks, swaps, bridges, and other features are implemented

This provides more assurance than a general statement such as “private keys are encrypted.” Reviewers can inspect the actual methods, libraries, security settings, and storage flow behind that statement.

Developers can also compile the application, study its design, propose improvements, and create new wallet software under the applicable open-source license.

> <mark style="color:pink;">**Open source does not mean that users must understand every line of code. Its purpose is to make the implementation visible and available for independent examination.**</mark>

## Security Through Transparency

KEYRING PRO does not expect every user to understand cryptographic source code.

Instead, it publishes the code so developers, auditors, security professionals, and organizations can examine how private keys, passwords, backups, wallet access, and transactions are protected.

For a self-custodial wallet, users should not be required to trust security claims blindly.

> <mark style="color:pink;">**The software responsible for protecting user assets should be open to independent verification.**</mark>

## Open Source Allows Independent Wallet Versions

Because KEYRING PRO is open source, developers can study the code, modify it, compile a functional wallet, or use it as the foundation for another wallet project under the GPL-3.0 license.

This is one of the purposes of open source. It allows developers to learn from the implementation and create new wallet solutions based on transparent code.

However, a wallet created from the KEYRING PRO source code is not automatically an official KEYRING PRO product.

A third-party developer may:

* Change the private key protection system
* Connect the wallet to different services
* Add or remove security functions
* Change how wallet data is handled
* Distribute the application under a different name
* Create an application that looks similar to KEYRING PRO but operates differently

For this reason, users should always download KEYRING PRO through official KEYRING channels and confirm that the application is published by the correct developer before:

* Creating a wallet
* Entering a password
* Importing a private key
* Scanning an NFC KeyCard
* Restoring a backup file
* Approving a transaction

Open source makes the code available to everyone, but only the official KEYRING PRO application is developed, distributed, maintained, and supported by Bacoor.

Bacoor cannot review or control changes made by independent third parties. Therefore, Bacoor cannot verify, support, or accept responsibility for unofficial forks, modified builds, cloned applications, or applications that impersonate KEYRING PRO.

> <mark style="color:pink;">**Always make sure that you are using the official KEYRING PRO Wallet before entering any sensitive wallet information.**</mark>
