> 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/zh/keyring-pro/open-source.md).

# 是开源的

## KEYRING PRO 是开源的

[**查看公开的 KEYRING PRO 代码仓库**](https://github.com/bacoor-hb/KEYRINGPRO)

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

对于非托管钱包而言，信任始于透明度。

KEYRING PRO 让用户完全掌控自己的私钥和资产。由于钱包会处理高度敏感的信息，我们认为，用户需要的不应只是安全方面的声明。用户还应当能够确信，保护其资产的技术可以由第三方进行独立审查和验证。

通过将 KEYRING PRO 开源，我们允许开发者、安全专家、审计人员和组织检查钱包的运行方式。他们可以查看私钥如何生成和加密、私钥存储在哪里、钱包访问如何受到保护、备份文件如何受到保护，以及交易如何完成签名。

大多数用户可能永远不需要亲自阅读源代码。但是，公开实现代码能够让用户更加确信，KEYRING PRO 是基于透明且可验证的安全原则构建的。

开源也体现了我们对责任与可验证性的承诺。KEYRING PRO 所描述的安全保护措施，可以直接与实现这些功能的代码进行对照。用户无需依赖隐藏的系统或缺乏依据的承诺。

公开源代码不会暴露用户的私钥、密码、备份文件、余额或其他个人钱包信息。这些信息仅会在用户实际使用钱包时产生，并与公开源代码相互独立。生产环境凭证和服务密钥也不会包含在公开代码仓库中。

对于 KEYRING PRO 而言，开源不仅仅是公开代码。它代表着我们通过透明度、责任机制和可独立验证的安全性，构建一款能够让用户更加放心使用的钱包。

> <mark style="color:pink;">**安全不应建立在盲目信任之上。它应当透明、可验证，并能够为用户带来信心。**</mark>

## KEYRING PRO 如何保护您的资产

KEYRING PRO 的私钥保护遵循清晰的流程：

* 使用安全的密码学随机性创建私钥。
* 使用由用户密码派生出的密钥对私钥进行加密。
* 受保护的私钥会存储在用户设备本地。
* 只有在钱包解锁后，私钥才会被读取和解密。
* 交易会在钱包内部完成签名。
* 只有已签名的交易才会发送至区块链网络。

由于源代码是公开的，因此可以直接审查这一流程中的每一个环节。

### 私钥存储在设备本地

启用密码保护后，KEYRING PRO 会在保存私钥之前对其进行加密：

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

受保护的数据随后会按照钱包地址进行保存：

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

`storeDataToSecureStorage()` 会将受保护的数据写入用户设备上应用程序内部的 MMKV 存储区域：

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

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

MMKV 存储区域本身也需要使用加密密钥才能打开。在正常设置过程中，应用程序会通过设备操作系统的钥匙串获取该存储密钥。

这些函数执行的是本地存储操作。其中不包含将私钥上传至 KEYRING PRO 服务器的网络请求。

> <mark style="color:green;">**您的私钥会存储在您自己设备上的受保护应用程序存储区域中。KEYRING PRO 不会为了管理您的钱包而在服务器端保存私钥副本。**</mark>
>
> <mark style="color:green;">**这使私钥始终由您的设备控制，而不是交由 KEYRING PRO 或其他服务保管。**</mark>

### 安全的私钥生成

选择“自动生成私钥”时，KEYRING PRO 会使用从 Viem 账户库导入的两个方法：

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

私钥会被生成并转换为 Ethereum 和 EVM 账户：

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

`generatePrivateKey()` 会创建一个新的随机私钥。`privateKeyToAccount()` 随后会根据该私钥派生出对应的 Ethereum 和 EVM 钱包地址。

Viem 使用专注于安全性的 `@noble/curves` 密码学库中的 secp256k1 实现来生成私钥。secp256k1 是 Ethereum 账户密钥所使用的椭圆曲线。

KEYRING PRO 还会加载 `react-native-get-random-values`，为 React Native 环境提供密码学安全的系统随机数。这不同于一般应用程序功能所使用的普通随机函数。

> <mark style="color:green;">**自动生成的私钥来自安全的系统随机性，并遵循 Ethereum 和 EVM 网络所使用的密码学模型。它并非基于简单或可预测的规律，因此其他人几乎不可能猜出或重新生成相同的私钥。**</mark>
>
> <mark style="color:green;">**这使私钥极难被猜测，从而帮助保护您的钱包免受未经授权的访问。**</mark>

KEYRING PRO 也支持手动生成私钥，让用户在创建钱包账户时拥有更高的灵活性和直接控制权。

使用该选项时，用户可以输入由数字 0–9 和字母 A–F 组成的 64 个有效十六进制字符，创建个性化私钥。

为了获得最高级别的保护，请使用只有您本人知道、独一无二且难以猜测的组合。

### 使用密码保护私钥

KEYRING PRO 不会直接将用户密码作为加密密钥使用。

相反，它使用由 `react-native-quick-crypto` 库提供的密码学方法：

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

密码处理和加密设置如下：

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

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

密码会通过 PBKDF2-SHA512 处理 900,000 次。这会生成一个适合保护敏感钱包数据的 256 位加密密钥。

PBKDF2 会在生成最终加密密钥之前，反复处理密码。每个钱包还会使用一个称为 salt 的随机值，因此，即使使用相同密码，不同数据也不会自动产生相同的加密结果。

随后，生成的加密密钥会用于 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 会将私钥转换为无法直接读取的加密数据。它还会创建一个认证标签，使钱包能够验证加密信息是否被修改或损坏。

以下情况会导致解密失败：

* 密码生成了错误的加密密钥。
* 加密数据已被修改。
* 认证标签不匹配。
* 存储的数据已经损坏。

> <mark style="color:green;">**启用密码保护后，您的私钥不会以可读文本形式存储。只有使用正确密码派生出的密钥才能完成解密，经过修改或已经损坏的加密数据也无法通过安全验证。**</mark>
>
> <mark style="color:green;">**这使私钥在没有正确密码的情况下无法被读取，同时还能检测加密数据是否被修改或损坏。**</mark>

使用强大且唯一的密码仍然非常重要。加密能够显著增加密码猜测的难度，但无法让容易猜测的密码变得绝对安全。

### 私钥与普通账户数据分开保存

账户创建或导入后，KEYRING PRO 会将其私钥移动至专用的私钥存储区域，并从普通账户对象中删除私钥：

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

钱包地址、账户名称、已选择的网络和其他常规信息，仍可继续用于普通钱包页面。私钥则会与这些账户信息分开保存。

KEYRING PRO 无需在应用程序的每个部分都保留私钥，也可以显示钱包地址、余额和交易信息。这减少了对钱包中最敏感信息的不必要访问。

> <mark style="color:green;">**您的私钥会从普通账户数据中删除，并单独存储在受保护的专用私钥存储区域中。**</mark>
>
> <mark style="color:green;">**这将私钥访问限制在真正需要使用私钥的钱包功能之中。**</mark>

### 只有在需要时才会读取私钥

当 KEYRING PRO 需要使用私钥执行已授权的操作时，它会首先从本地安全存储中读取受保护的记录：

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

如果该记录已加密，KEYRING PRO 会检查密钥库是否已解锁：

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

如果钱包处于锁定状态，私钥不会被返回。用户必须先完成解锁流程。

KEYRING PRO 不会让解密后的私钥始终保持可用状态。只有在受保护的钱包操作确实需要私钥，并且钱包已成功解锁时，才会读取并解密私钥。

> <mark style="color:green;">**只有在钱包成功解锁后，才能读取加密的私钥。如果钱包处于锁定状态或解密失败，系统不会返回私钥。**</mark>
>
> <mark style="color:green;">**这使私钥只在真正需要时才被访问，从而减少不必要的暴露。**</mark>

### 当前有效的密钥库密钥是临时的

输入正确密码后，KEYRING PRO 会暂时将派生出的密钥库密钥保存在应用程序的活动状态中：

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

当钱包处于解锁状态时，该密钥库密钥允许执行经过授权的私钥操作。该模块不会将这个密钥作为永久数据保存。

钱包锁定后，当前活动的引用会被清除：

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

同一个模块还会在密钥库锁定时阻止加密操作：

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

解密操作也受到相同条件的保护：

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

这可以防止密钥库锁定后，受保护的私钥操作仍然通过正常的钱包流程继续执行。

> <mark style="color:green;">**只有在钱包正确解锁期间，才能访问加密私钥。钱包锁定后，当前有效的密钥库密钥会被清除，并且需要重新完成身份验证。**</mark>
>
> <mark style="color:green;">**这可以防止钱包锁定后，受保护的钱包功能仍然保持可访问状态。**</mark>

### 交易在钱包内部完成签名

当用户批准一笔交易时，KEYRING PRO 会使用应用程序内部的私钥创建已签名交易：

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

私钥会在本地授权交易。私钥本身不会被添加到交易数据中。

完成的已签名交易随后会被发送至广播流程：

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

这意味着私钥用于创建账户所有者已经批准交易的密码学证明，但私钥本身无需离开钱包。

> <mark style="color:green;">**您的私钥仅在设备本地用于授权交易。它不会作为签名过程的一部分发送至区块链服务。**</mark>
>
> <mark style="color:green;">**这使您能够在不将私钥发送到钱包外部的情况下批准交易。**</mark>

### 只有已签名的交易会被广播

完成本地签名后，KEYRING PRO 会将序列化的已签名交易发送至 RPC 服务：

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

RPC 服务使用已签名交易将操作广播至区块链。它不需要创建签名的私钥。

> <mark style="color:green;">**区块链基础设施接收到的是已签名交易，而不是控制您钱包账户的私钥。**</mark>
>
> <mark style="color:green;">**这使区块链能够在不接收私钥的情况下处理您的交易。**</mark>

### 可以通过源代码验证的非托管机制

公开代码展示了完整的私钥处理流程：

**安全随机性 → 私钥生成 → 基于密码的加密 → 设备本地存储 → 身份验证后的解密 → 本地交易签名 → 已签名交易广播**

KEYRING PRO 无需在服务器端持有私钥副本，即可创建账户、存储私钥、解锁钱包或广播交易。

公开的钱包地址、已签名交易以及区块链服务所需的请求，可能会作为正常钱包操作的一部分离开设备。私钥本身会保留在本地存储中，并且不会包含在发送至 RPC 服务的已签名交易中。

> <mark style="color:green;">**您的私钥始终由您本人控制并保存在设备上。KEYRING PRO 只会在本地使用私钥授权钱包操作，而不会托管您的私钥。**</mark>
>
> <mark style="color:green;">**这确保只有您本人能够控制钱包账户和资产的访问权限。**</mark>

由于 KEYRING PRO 不会在服务器上保留私钥恢复副本，因此 KEYRING 团队无法访问账户、批准交易，也无法为用户恢复已经遗失的私钥。

用户必须安全保管自己的私钥和备份文件。如果两者均无法访问，可能会永久失去对钱包账户的访问权限。

## 其他安全功能

### 钱包自动锁定

当应用程序在后台停留的时间超过用户选择的自动锁定时间时，KEYRING PRO 可以自动锁定钱包。

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

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

选择的时间到期后，KEYRING PRO 会清除当前有效的密钥库访问权限，并让应用程序返回解锁流程。

> <mark style="color:green;">**即使您离开应用程序或设备，钱包也不会持续保持解锁状态。超过所选的自动锁定时间后，必须重新完成身份验证。**</mark>
>
> <mark style="color:green;">**这有助于防止设备无人看管时发生未经授权的访问。**</mark>

### 防止连续尝试密码

KEYRING PRO 会限制连续输入错误密码的次数：

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

连续五次输入错误密码后，钱包会被锁定一小时。

错误尝试次数会存储在加密的安全存储中：

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

达到最大失败次数后，KEYRING PRO 会保存锁定结束的时间：

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

错误尝试次数和锁定期限会存储在加密的安全存储中，因此重新启动应用程序不会立即解除限制。

这会中断通过普通应用程序界面持续猜测密码的行为。

> <mark style="color:green;">**即使有人能够访问您的设备，也无法通过应用程序无限次尝试密码。连续失败会暂时阻止进一步尝试。**</mark>
>
> <mark style="color:green;">**这会增加反复猜测密码的难度。**</mark>

该保护功能不能取代使用强密码的必要性。

### 加密的备份文件

KEYRING PRO 备份可能包含多个账户和钱包设置。在保存备份文件之前，钱包数据会先被加密。

系统会生成一个新的随机 salt，并使用它根据备份密码派生出加密密钥：

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

随后，钱包数据会使用 AES-256-GCM 进行加密：

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

每次创建备份文件时，KEYRING PRO 都会执行以下操作：

* 生成一个新的随机 salt。
* 使用 PBKDF2-SHA512 处理备份密码。
* 为该备份创建专用加密密钥。
* 使用 AES-256-GCM 加密钱包数据。
* 将加密后的数据与恢复所需的信息一同保存。

由于每次创建备份都会生成新的随机 salt，因此每个备份文件都拥有独立的、基于密码的加密关系。

> <mark style="color:green;">**仅持有备份文件不足以恢复您的钱包。必须同时拥有正确的备份文件，以及为该文件设置的密码。**</mark>
>
> <mark style="color:green;">**这可以防止他人仅凭备份文件副本恢复您的钱包。**</mark>

输入错误密码会生成错误的加密密钥。经过修改、损坏或破损的加密数据也无法通过 AES-GCM 身份验证检查。

每个新备份文件都必须使用密码保护。用户应安全保存备份文件及其密码。

### 生物识别和设备密码保护

启用生物识别解锁后，KEYRING PRO 会通过操作系统钥匙串保护所保存的钱包密码副本：

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

根据设备不同，身份验证可能使用：

* Face ID
* Touch ID
* 指纹识别
* 设备密码

保存受保护的凭证后，KEYRING PRO 会立即通过操作系统身份验证提示尝试读取该凭证。如果身份验证失败、被取消，或无法验证保存的数据，已保存的记录将被删除。

生物识别解锁并不仅仅是应用程序中的视觉确认。对受保护钱包凭证的访问由 iOS 或 Android 所提供的安全功能控制。

> <mark style="color:green;">**生物识别身份验证不会直接显示私钥。它会授权访问受保护的钱包密码，然后使用该密码解锁加密的私钥密钥库。**</mark>
>
> <mark style="color:green;">**这会在钱包解锁之前增加设备级别的安全保护。**</mark>

## 可验证的 KEYRING PRO 功能

开源不仅可以展示安全设置，还允许审查人员查看 KEYRING PRO 的主要钱包功能是如何实现的。

### 账户创建和导入

KEYRING PRO 支持：

* 自动生成的私钥
* 手动输入的私钥
* 从其他兼容钱包导入的私钥

代码会将私钥转换为 EVM 账户，并派生出对应的钱包地址：

```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
  }
}
```

无效私钥不会返回账户。KEYRING PRO 还会在添加账户之前检查是否存在重复的钱包地址，然后将私钥移动至专用存储区域。

> <mark style="color:green;">**无论创建新账户还是导入现有账户，KEYRING PRO 都会应用相同的账户验证和私钥存储流程。**</mark>
>
> <mark style="color:green;">**这为新创建和导入的账户提供一致的保护。**</mark>

### 热账户、NFC KeyCard 账户和仅查看账户

KEYRING PRO 支持三种账户类型：

* **热账户：** 私钥在设备上生成或导入。
* **NFC KeyCard 账户：** 加密的私钥数据存储在受支持的 NFC 卡中。
* **仅查看账户：** 只注册公开钱包地址。

对于仅查看账户，KEYRING PRO 会创建一个不包含私钥导入或存储的账户记录：

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

由于仅查看账户没有需要保存的私钥，因此该功能不会访问私钥存储区域。

仅查看账户可以查看余额和活动，但无法签署交易，因为 KEYRING PRO 并不持有该账户的私钥。

> <mark style="color:green;">**仅查看账户允许您在不导入或保存私钥的情况下查看钱包地址。**</mark>
>
> <mark style="color:green;">**这使您能够监控账户，而不会暴露控制该账户的私钥。**</mark>

对于 NFC KeyCard 账户，KEYRING PRO 不会在普通账户对象中保存私钥：

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

该账户会被单独识别为冷账户：

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

对于 NFC KeyCard 账户，KEYRING PRO 使用 PBKDF2 和 AES-256-GCM 加密卡片数据。读取卡片时，它还会检查卡片数据中的地址是否与钱包中所选账户匹配。如果不匹配，私钥将被拒绝。

> <mark style="color:green;">**存储在 NFC KeyCard 中的私钥数据会受到基于密码的加密保护。在使用私钥之前，KEYRING PRO 还会确认卡片地址与所选钱包账户一致。**</mark>
>
> <mark style="color:green;">**这有助于防止 NFC KeyCard 被未经授权地使用，并避免其被用于错误的账户。**</mark>

### 支持多个 EVM 网络

KEYRING PRO 内置了 20 个 Ethereum 和 EVM 兼容网络的配置：

```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]
```

配置中包含以下信息：

* Chain ID
* 网络名称
* 原生货币
* RPC 连接
* 区块浏览器
* 交易和代币链接

代码仓库中定义的内置网络包括：

Ethereum、Optimism、BNB Chain、Base、Arbitrum、Avalanche、Polygon、Unichain、Plasma、HyperEVM、Stable、Mantle、Celo、MegaETH、Gnosis、Katana、Monad、Ink、Tempo、Robinhood

还可以添加其他兼容的 EVM 网络。

> <mark style="color:green;">**您可以在受支持的 Ethereum 和 EVM 兼容网络中使用同一个钱包账户，无需为每个网络安装不同的钱包。**</mark>
>
> <mark style="color:green;">**这使您能够通过一个钱包管理多个 EVM 网络上的资产。**</mark>

### WalletConnect 连接

KEYRING PRO 使用 WalletConnect v2 将用户选择的钱包账户连接至受支持的 Web3 应用程序。

批准连接之前，KEYRING PRO 会使用所选账户、已批准网络、请求的方法和请求的事件准备会话：

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

随后创建已批准的命名空间：

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

WalletConnect 会话会使用该命名空间获得批准：

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

批准之前，KEYRING PRO 会使用以下信息准备会话：

* 用户选择的账户
* 已批准的 EVM 网络
* dApp 请求的方法
* dApp 请求的事件

会话随后会与所选账户地址绑定。如果账户或请求的网络不可用，钱包中也包含拒绝连接的处理流程。

> <mark style="color:green;">**您可以自行选择需要连接的账户，而不是自动共享 KEYRING PRO 中存储的所有账户。**</mark>
>
> <mark style="color:green;">**这使您能够更加精确地控制与 Web3 应用程序共享的账户和网络。**</mark>

WalletConnect 连接并不保证 dApp 一定安全。在批准连接请求、消息或交易之前，请务必仔细检查相关内容。

### 代币兑换和跨链桥

KEYRING PRO 为兑换和跨链桥服务提供商使用统一的服务结构：

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

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

公开源代码中包含 Relay 和 deBridge 的服务适配器。

该服务结构会处理以下操作：

* 选择服务提供商
* 请求报价
* 检查代币授权
* 准备交易
* 执行兑换或跨链桥操作
* 跟踪交易进度

> <mark style="color:green;">**您可以通过统一的钱包界面执行受支持的同链兑换和跨链转移，无需针对每个服务提供商使用不同的应用程序。**</mark>
>
> <mark style="color:green;">**这使在受支持网络之间兑换和转移资产更加便捷。**</mark>

### 内置 AI 助手

公开代码仓库中包含一个专用的 AI 助手界面，支持选择钱包账户和网络。

该助手旨在帮助用户理解钱包信息并准备受支持的钱包操作。代码仓库中描述的示例包括，在获得用户批准的前提下准备代币转账或受支持的流动性操作。

敏感操作仍然必须遵循钱包正常的检查、批准和交易签名流程。

> <mark style="color:green;">**AI 助手可以帮助解释或准备钱包操作，但最终操作仍需要由您亲自检查并批准。**</mark>
>
> <mark style="color:green;">**这在提供辅助功能的同时，确保所有钱包操作的最终控制权始终掌握在您手中。**</mark>

## 开源为何重要

钱包可以声明自己会加密私钥、保护备份，或在本地签署交易。

开源允许具备相关专业能力的审查人员确认，这些声明是否真实反映在实际实现中。

KEYRING PRO 代码仓库允许审查人员查看：

* 私钥如何生成
* 哪个库负责生成私钥
* 使用哪一种密码学曲线
* 密码如何转换为加密密钥
* 哪种加密算法用于保护私钥
* 私钥存储在哪里
* 私钥如何被读取
* 钱包锁定时会发生什么
* 如何限制连续密码尝试
* 备份文件如何加密和恢复
* 生物识别身份验证如何控制访问
* 交易是否在广播前完成签名
* RPC 请求中是否包含私钥
* 热账户、NFC KeyCard 账户和仅查看账户如何运行
* WalletConnect 会话如何获得批准
* 网络、兑换、跨链桥和其他功能如何实现

相比“私钥已经加密”这样的笼统声明，这能够提供更高程度的可信度。审查人员可以查看支持该声明的实际方法、库、安全设置和存储流程。

开发者还可以编译应用程序、研究其设计、提出改进建议，并按照适用的开源许可证创建新的钱包软件。

> <mark style="color:pink;">**开源并不意味着每位用户都必须理解每一行代码。其目的是公开实现方式，使第三方能够进行独立审查。**</mark>

## 通过透明度实现安全

KEYRING PRO 并不要求每位用户都理解密码学源代码。

相反，我们公开代码，让开发者、审计人员、安全专家和组织能够检查私钥、密码、备份、钱包访问和交易是如何受到保护的。

对于非托管钱包而言，用户不应被要求盲目信任安全声明。

> <mark style="color:pink;">**负责保护用户资产的软件，应当能够接受第三方的独立验证。**</mark>

## 开源允许创建独立的钱包版本

由于 KEYRING PRO 是开源的，因此开发者可以根据 GPL-3.0 许可证研究、修改和编译代码，创建可运行的钱包，或将其作为其他钱包项目的基础。

这是开源的目的之一。开发者可以学习现有实现，并基于透明代码创建新的钱包解决方案。

但是，使用 KEYRING PRO 源代码创建的钱包，并不会自动成为官方 KEYRING PRO 产品。

第三方开发者可能会：

* 修改私钥保护系统
* 将钱包连接至不同服务
* 添加或删除安全功能
* 更改钱包数据的处理方式
* 使用不同名称发布应用程序
* 创建外观与 KEYRING PRO 相似，但运行方式不同的应用程序

因此，在执行以下操作之前，用户应始终通过 KEYRING 官方渠道下载 KEYRING PRO，并确认应用程序由正确的开发者发布：

* 创建钱包
* 输入密码
* 导入私钥
* 扫描 NFC KeyCard
* 恢复备份文件
* 批准交易

开源意味着所有人都可以访问代码，但只有官方 KEYRING PRO 应用程序由 Bacoor 开发、发布、维护和提供支持。

Bacoor 无法审查或控制独立第三方所做的修改。因此，对于非官方分支、修改后的版本、克隆应用程序或冒充 KEYRING PRO 的应用程序，Bacoor 无法进行验证、提供支持或承担责任。

> <mark style="color:pink;">**在输入任何敏感的钱包信息之前，请始终确认您使用的是官方 KEYRING PRO Wallet。**</mark>
