# 工具程式

`@arcblock/did-connect-react` 函式庫匯出了一系列工具函式，旨在簡化與身份驗證流程、資料處理和 API 通訊相關的常見任務。雖然核心元件和掛鉤（hooks）處理了大多數使用情境，但這些工具程式為進階整合或自訂實作提供了精細的控制。

## API 客戶端

### createAxios

此函式是一個用於建立預先設定的 `axios` 實例的工廠。它會自動包含必要的標頭，如 `x-did-connect-version` 和 `x-blocklet-visitor-id`，以確保與基於 Blocklet 的服務正常通訊。這是您應用程式中建立 API 客戶端的建議方法。

**參數**

<x-field-group>
  <x-field data-name="options" data-type="object" data-required="false" data-desc="標準的 Axios 設定物件。"></x-field>
  <x-field data-name="lazyOptions" data-type="object" data-required="false" data-desc="延遲發送的設定。">
    <x-field data-name="lazy" data-type="boolean" data-default="false" data-desc="是否啟用延遲發送。"></x-field>
    <x-field data-name="lazyTime" data-type="number" data-default="300" data-desc="延遲發送的去抖動時間（毫秒）。"></x-field>
  </x-field>
</x-field-group>

**回傳值**

<x-field data-name="axiosInstance" data-type="AxiosInstance" data-desc="一個已設定的 Axios 實例。"></x-field>

**範例**

```javascript apiClient.js icon=logos:javascript
import { createAxios } from '@arcblock/did-connect-react/lib/utils';

const apiClient = createAxios({
  baseURL: '/api',
});

export default apiClient;
```

## URL 和彈出視窗處理

這些函式有助於管理在 DID Connect 身份驗證過程中使用的 URL 和彈出視窗。

| 函式 | 說明 |
| :--- | :--- |
| `encodeConnectUrl(url)` | 將 URL 編碼，以便安全地作為 `__connect_url__` 查詢參數傳遞。 |
| `decodeConnectUrl(encoded)` | 解碼由 `encodeConnectUrl` 編碼的 URL。 |
| `parseTokenFromConnectUrl(connectUrl)` | 從 DID Connect URL 中提取會話權杖 (`_t_`)。 |
| `openPopup(url, options)` | 開啟一個新的、置中的彈出視窗。`DidConnect` 元件內部使用它來顯示錢包連接介面。如果彈出視窗被阻擋，則會拋出 `NotOpenError`。 |
| `runPopup(config)` | 一個基於 promise 的包裝器，用於管理由 `openPopup` 建立的彈出視窗的生命週期。它監聽來自彈出視窗的 `message` 事件，處理超時，並在身份驗證流程完成時解析。 |
| `decodeUrlParams()` | 從當前視窗的 URL 中解析自訂的 `__did-connect__` 參數。 |

**範例：自訂彈出視窗流程**

```javascript customAuthButton.js icon=logos:javascript
import { openPopup, runPopup } from '@arcblock/did-connect-react/lib/utils';

const handleCustomLogin = async () => {
  const authUrl = 'https://your-auth-service.com/connect';
  try {
    const popup = openPopup(authUrl);
    const result = await runPopup({ popup, timeoutInSeconds: 600 });
    console.log('Authentication successful:', result);
    // Handle successful login
  } catch (error) {
    console.error('Authentication failed:', error.message);
    // Handle popup closed or timeout
  }
};
```

## 會話和 Cookie 管理

這些輔助函式用於將使用者連接資訊讀寫到 Cookie，從而實現跨頁面載入的會話持久性。

| 函式 | 說明 |
| :--- | :--- |
| `getConnectedInfo(data)` | 將來自連接請求的原始回應資料格式化為適合 Cookie 儲存的標準化物件。 |
| `updateConnectedInfo(info, parsed)` | 在成功連接後設定必要的 Cookie (`connected_did`, `connected_pk`, `connected_app`)。這讓函式庫可以優化後續的身份驗證檢查。 |
| `getVisitorId()` | 從 Cookie 中檢索唯一訪客 ID。 |
| `setVisitorId(id)` | 在 Cookie 中設定唯一訪客 ID。 |

**範例**

```javascript sessionManager.js icon=logos:javascript
import { getConnectedInfo, updateConnectedInfo } from '@arcblock/did-connect-react/lib/utils';

// Assuming 'authResponse' is the object returned from your login API
function persistSession(authResponse) {
  const connectedInfo = getConnectedInfo(authResponse);
  updateConnectedInfo(connectedInfo, true);
  console.log('Session info saved to cookies.');
}
```

## 加密工具

對於需要客戶端加密或解密的進階情境，該函式庫公開了包裝 `tweetnacl-sealedbox-js` 函式庫的輔助函式。

| 函式 | 說明 |
| :--- | :--- |
| `encodeKey(key)` | 將金鑰進行 Base64URL 編碼以便傳輸。 |
| `decodeKey(str)` | 將 Base64URL 字串解碼為 `Uint8Array` 金鑰。 |
| `encrypt(value, encryptKey)` | 使用公鑰加密字串值。 |
| `decrypt(value, encryptKey, decryptKey)` | 使用對應的公鑰和私鑰解密 base64 字串。 |

## 錯誤處理

為了向使用者提供更好的回饋，您可以使用這些函式將技術性錯誤物件解析為人類可讀的訊息。

| 函式 | 說明 |
| :--- | :--- |
| `getApiErrorMessage(err, defaultMessage)` | 從 `axios` 錯誤物件中提取使用者友善的錯誤訊息。 |
| `getWebAuthnErrorMessage(err, defaultMessage, t)` | 處理 WebAuthn/Passkey 特定錯誤（例如，使用者取消、瀏覽器不支援），並回傳本地化的、使用者友善的訊息。 |

**範例**

```javascript errorHandling.js icon=logos:javascript
import { getApiErrorMessage } from '@arcblock/did-connect-react/lib/utils';
import apiClient from './apiClient';

async function fetchData() {
  try {
    const response = await apiClient.get('/data');
    return response.data;
  } catch (error) {
    const message = getApiErrorMessage(error, 'Failed to fetch data.');
    alert(message);
  }
}
```

---

透過利用這些工具程式，您可以建立更複雜和自訂的身份驗證體驗。有關所有匯出成員及其類型的完整列表，請參閱 [API 參考](./api-reference.md)。