> For the complete documentation index, see [llms.txt](https://help.tokenpocket.pro/developer-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.tokenpocket.pro/developer-cn/extension-wallet/api-reference/solana-provider-api.md).

# Solana Provider API

TokenPocket Extension 会在页面中注入 Solana Provider，开发者可通过传统 Provider 接口或 Wallet Standard 接入 Solana 钱包能力。

## Provider 注入

页面中可使用以下对象：

```ts
window.solana
window.tokenpocket.solana
```

同时，TokenPocket 也支持 Wallet Standard，可被标准钱包发现流程识别。

{% hint style="info" %}
推荐优先兼容 Wallet Standard。对于已经基于 `window.solana` 开发的 dApp，也可以继续使用传统 Provider 接口接入。
{% endhint %}

## 快速开始

### 连接钱包

```ts
const provider = window.solana;

const res = await provider.connect();

console.log(res.address);
console.log(res.publicKey.toBase58());
console.log(res.accounts);
```

### 签名消息

```ts
const message = new TextEncoder().encode('hello tokenpocket');
const res = await window.solana.signMessage(message);

console.log(res.signature);
console.log(res.publicKey.toBase58());
```

### 签名交易

```ts
const signedTx = await window.solana.signTransaction(transaction);
```

## API 列表

### connect

连接当前站点到 Solana 账户。

```ts
connect(options?: { silent?: boolean }): Promise<{
  accounts: WalletAccount[];
  publicKey: PublicKey;
  address: string;
}>
```

参数：

* `silent`：是否静默连接，默认 `false`

说明：

* `silent: true` 时，仅在钱包已解锁且当前站点已有授权地址时返回账户
* 未连接时会抛出错误

示例：

```ts
const { address, publicKey } = await window.solana.connect();
console.log(address);
console.log(publicKey.toBase58());
```

### disconnect

断开当前连接。

```ts
disconnect(): Promise<void>
```

说明：

* 调用后会清空当前账户状态
* 会触发 `disconnect` 和 `accountChanged` 事件

示例：

```ts
await window.solana.disconnect();
```

### signTransaction

对单笔交易进行签名。

```ts
signTransaction(
  transaction: Transaction | VersionedTransaction
): Promise<Transaction | VersionedTransaction>
```

说明：

* 支持 `Transaction`
* 兼容处理 `VersionedTransaction`
* 当前建议 dApp 按 `legacy` 交易使用
* 返回已附加签名的交易对象
* 若钱包返回了 `unitsConsumed` / `microLamports`，Provider 会自动补充 Compute Budget 指令

示例：

```ts
const signedTx = await window.solana.signTransaction(transaction);
```

### signAllTransactions

批量签名交易。

```ts
signAllTransactions(
  transactions: Array<Transaction | VersionedTransaction>
): Promise<Array<Transaction | VersionedTransaction>>
```

说明：

* 当前实现会逐笔调用 `signTransaction`

示例：

```ts
const signedTxs = await window.solana.signAllTransactions(transactions);
```

### signMessage

签名消息。

```ts
signMessage(
  message: Uint8Array | { message: Uint8Array }
): Promise<{
  signature: Uint8Array;
  publicKey: PublicKey;
}>
```

说明：

* 支持直接传入 `Uint8Array`
* 也兼容 `{ message }` 结构

示例：

```ts
const message = new TextEncoder().encode('hello tokenpocket');
const res = await window.solana.signMessage(message);

console.log(res.signature);
console.log(res.publicKey.toBase58());
```

### signAndSendTransaction

签名并发送交易。

```ts
signAndSendTransaction(params: {
  recentBlockhash?: string;
  feePayer?: string;
  instructions?: Array<{
    keys: Array<{
      pubkey: string;
      isSigner: boolean;
      isWritable: boolean;
    }>;
    programId: string;
    data: number[] | Uint8Array | Buffer;
  }>;
}): Promise<{
  signature: string;
  publicKey: string;
}>
```

说明：

* 会基于传入的 `instructions` 构造交易
* 返回的 `signature` 为 Base58 字符串
* 返回的 `publicKey` 为当前签名地址

示例：

```ts
const result = await window.solana.signAndSendTransaction({
  recentBlockhash,
  feePayer,
  instructions,
});

console.log(result.signature);
console.log(result.publicKey);
```

## 事件

Provider 支持事件订阅。

### connect

连接成功时触发。

```ts
window.solana.on('connect', (publicKey) => {
  console.log(publicKey?.toBase58?.());
});
```

### disconnect

断开连接时触发。

```ts
window.solana.on('disconnect', () => {
  console.log('disconnected');
});
```

### accountChanged

账户切换时触发。

```ts
window.solana.on('accountChanged', (publicKey) => {
  if (!publicKey) {
    console.log('account cleared');
    return;
  }

  console.log(publicKey.toBase58());
});
```

{% hint style="warning" %}
当用户断开连接或当前账户被清空时，`accountChanged` 可能收到 `null`，请在业务代码中做好判空处理。
{% endhint %}

## Wallet Standard

TokenPocket 支持以下 Wallet Standard 能力：

* `standard:connect`
* `standard:events`
* `solana:signTransaction`
* `solana:signAndSendTransaction`
* `solana:signMessage`

官方参考：

* [Wallet Standard 官方文档](https://wallet-standard.github.io/wallet-standard/)
* [Wallet Standard 扩展说明](https://github.com/wallet-standard/wallet-standard/blob/master/EXTENSIONS.md)
* [Solana Wallet Adapter（Solana 生态常用接入参考）](https://github.com/solana-labs/wallet-adapter)

链支持如下：

```ts
[
  'solana:mainnet',
  'solana:devnet',
  'solana:testnet',
  'solana:localnet',
]
```

说明：

* 当前声明的 `supportedTransactionVersions` 为 `['legacy']`
* 建议 dApp 以 `legacy` 交易能力为准进行接入

### Wallet Standard 示例

```ts
const accounts = await wallet.features['standard:connect'].connect();

const outputs =
  await wallet.features['solana:signTransaction'].signTransaction({
    account: accounts.accounts[0],
    chain: 'solana:mainnet',
    transaction,
  });
```

## 错误处理

建议所有 Provider 调用都使用 `try/catch`。

```ts
try {
  await window.solana.connect();
} catch (error) {
  console.error(error);
}
```

常见失败场景：

* 用户拒绝连接
* 用户拒绝签名
* 钱包未解锁
* 当前站点未授权
* 交易或消息格式不正确

## 最佳实践

* 优先兼容 Wallet Standard
* 传统 dApp 可直接使用 `window.solana`
* 交易版本建议按 `legacy` 处理
* 所有签名和连接操作都应做好异常捕获
* 对 `accountChanged` 事件的 `null` 值做好兼容

## 兼容性说明

* TokenPocket 同时暴露 `window.solana` 与 `window.tokenpocket.solana`
* 推荐新接入的 dApp 优先使用 Wallet Standard
* 若已有基于传统 Solana Provider 的接入逻辑，也可直接兼容
