---
title: "@vonvon-kit/electron"
description: "メインプロセス PKCE フロー、contextBridge プリロード、OS キーチェーントークンストレージ、ループバックまたはカスタムスキームコールバック戦略を備えた Electron SDK。"
locale: "ja"
---

> Documentation Index
> Fetch the relevant documentation index at: https://vonvon.id/ja/sdks/llms.txt
> Use this file to discover all available pages before exploring further.

# @vonvon-kit/electron

## 状態

Registry 状態: UNPUBLISHED。この SDK はリポジトリのソース checkout からのみインストールし、外部 package registry は使用しないでください。

パッケージステータス：**現行パッケージ**。メインプロセスアプリ、contextBridge プリロード、レンダラー側ブリッジが実装済みです。本番インフラでの実際の IdP ラウンドトリップはまだ手動検証待ちです。

## エントリーポイント

| エントリー | 目的 |
| --- | --- |
| `@vonvon-kit/electron` | デフォルトエクスポート：レンダラーサーフェスと型 |
| `@vonvon-kit/electron/main` | メインプロセス専用：VonvonElectronApp |
| `@vonvon-kit/electron/renderer` | レンダラープロセス：getVonvonBridge、VonvonClient |
| `@vonvon-kit/electron/preload` | window.vonvonBridge を公開する既製のプリロードスクリプト |

## メインプロセスセットアップ

```ts
// main.ts
import { app, ipcMain } from 'electron'
import { VonvonElectronApp } from '@vonvon-kit/electron/main'

const vonvonApp = new VonvonElectronApp({
  issuer: 'https://vonvon.id',
  clientId: 'client_abc123',
  // callbackStrategy: 'loopback' (default, RFC 8252 s.7.3) | 'custom-scheme'
})

app.whenReady().then(async () => {
  await vonvonApp.init(ipcMain)
  const win = new BrowserWindow({
webPreferences: {
  contextIsolation: true,
  preload: path.join(__dirname, 'preload.js'),
},
  })
  win.on('closed', () => vonvonApp.dispose(ipcMain))
})
```

## プリロードスクリプト

```ts
// preload.ts
import '@vonvon-kit/electron/preload'
// Exposes window.vonvonBridge with storage, signIn, signOut,
// getAccessToken, getSession, setTokenStorage
```

## レンダラープロセス

```ts
import { getVonvonBridge } from '@vonvon-kit/electron/renderer'

const bridge = getVonvonBridge()

// Opens system browser, waits for loopback callback, exchanges code.
const accessToken = await bridge.signIn()

// Get the current unexpired access token. Expiry requires a new sign-in.
const token = await bridge.getAccessToken() // null when signed out or expired

// Get the current unexpired session (accessToken + expiresAt in epoch seconds).
const session = await bridge.getSession()

// Clear local tokens. No refresh or revoke request is sent.
await bridge.signOut()
```

## カスタムスキーム（ループバックの代替）

```ts
// main.ts
import { app } from 'electron'
import { VonvonElectronApp } from '@vonvon-kit/electron/main'

app.setAsDefaultProtocolClient('myapp')

const vonvonApp = new VonvonElectronApp({
  issuer: 'https://vonvon.id',
  clientId: 'client_abc123',
  callbackStrategy: 'custom-scheme',
  customScheme: 'myapp',  // redirect_uri = myapp://callback
})

vonvonApp.registerDeepLinkHandler(app)
```

## トークンストレージ

- トークンは `safeStorage.encryptString()`（OS キーチェーン）で暗号化され、デフォルトで `app.getPath('userData')/vonvon-tokens/` にバイナリファイルとして保存されます。
- `safeStorage.isEncryptionAvailable()` が `false`（キーリングのないヘッドレス Linux）を返す場合、`setItem()` は平文を黙って書き込む代わりにコード `encryption_unavailable` の `ElectronStorageError` をスローします。
- `VonvonElectronMainOptions` の `storageDir` でストレージディレクトリを上書きします。

## 共有ネイティブコントラクト

| 方式 | 説明 |
| --- | --- |
| `signIn(options?)` | システムブラウザを開き、コードを交換してトークンを保存します |
| `signOut()` | ローカルトークンをクリアします |
| `getAccessToken()` | refresh を行わずに、現在の有効期限内の access token を返します。有効期限切れのローカル state を消去した場合は null を返します。DPoP が実装されるまで SDK は offline\_access を拒否します。 |
| `getSession()` | 現在の有効期限内の accessToken と expiresAt、または null を返します |

Source: https://vonvon.id/ja/sdks/electron/index.mdx
