EthereumApp クラスは、Ethereum
のアドレス取得、メッセージ署名、トランザクション署名、EIP-712 Typed Data
署名、EIP-7702 Authorization 署名を提供します。
import {
EthereumApp,
DEFAULT_ETH_PATH,
type SignatureResult,
} from '@openloop/sdk-core'const eth = new EthereumApp(transport)transport は ITransport
インターフェースを実装する任意の Transport インスタンスです。
| メソッド | 説明 |
|---|---|
getAddress(path) |
アドレスと公開鍵を取得 |
signPersonalMessage(path, message, chainId?) |
EIP-191 personal_sign |
signTransaction(path, rawTx) |
RLP エンコード済みトランザクションに署名 |
signTypedData(path, domainHash, msgHash, chainId?) |
EIP-712 Typed Data に署名 |
signAuthorization(path, authorizationRlp) |
EIP-7702 Authorization に署名 |
デバイスから Ethereum アドレスと公開鍵を取得します。
async getAddress(path: string): Promise<{
publicKey: string // 非圧縮公開鍵 (hex, 65 bytes)
address: string // チェックサム付きアドレス ("0x...")
}>| 名前 | 型 | 説明 |
|---|---|---|
path |
string |
BIP44 パス(例: "44'/60'/0'/0/0") |
import { DEFAULT_ETH_PATH } from '@openloop/sdk-core'
const { address, publicKey } = await eth.getAddress(DEFAULT_ETH_PATH)
// address: "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18"
// publicKey: "04a1b2c3d4..."DEFAULT_ETH_PATH = "44'/60'/0'/0/0"
EIP-191 personal_sign でメッセージに署名します。チェーン ID を認識する Openloop 独自の拡張プロトコルを使用します。
async signPersonalMessage(
path: string,
message: string,
chainId?: number
): Promise<SignatureResult>| 名前 | 型 | デフォルト | 説明 |
|---|---|---|---|
path |
string |
— | BIP44 パス |
message |
string |
— | メッセージ(UTF-8 文字列または 0x プレフィックス付き
hex) |
chainId |
number |
1 |
EVM チェーン ID |
SignatureResult| フィールド | 型 | 説明 |
|---|---|---|
v |
number |
リカバリー ID (27 or 28) |
r |
string |
R 値 (32 bytes hex, 0x なし) |
s |
string |
S 値 (32 bytes hex, 0x なし) |
const sig = await eth.signPersonalMessage(
DEFAULT_ETH_PATH,
'Hello, Openloop!',
1
)
// sig.v = 27
// sig.r = "a1b2c3..."
// sig.s = "d4e5f6..."注意: 長いメッセージは自動的にチャンク分割されてデバイスに送信されます(最初のチャンク 150 バイト、以降 255 バイトずつ)。
RLP エンコード済みの Ethereum トランザクションに署名します。
async signTransaction(
path: string,
rawTx: string
): Promise<SignatureResult>| 名前 | 型 | 説明 |
|---|---|---|
path |
string |
BIP44 パス |
rawTx |
string |
RLP エンコード済みトランザクション (hex, 0x
プレフィックスあり/なし) |
const sig = await eth.signTransaction(
DEFAULT_ETH_PATH,
'f86c0a8502540be400825208...'
)EIP-712 Typed Data に署名します。事前にハッシュ化された domainSeparator と message を渡します。
async signTypedData(
path: string,
domainSeparatorHash: string,
messageHash: string,
chainId?: number
): Promise<SignatureResult>| 名前 | 型 | デフォルト | 説明 |
|---|---|---|---|
path |
string |
— | BIP44 パス |
domainSeparatorHash |
string |
— | EIP-712 domain separator ハッシュ (32 bytes hex) |
messageHash |
string |
— | EIP-712 message ハッシュ (32 bytes hex) |
chainId |
number |
1 |
EVM チェーン ID |
const sig = await eth.signTypedData(
DEFAULT_ETH_PATH,
'aabbccddee...', // domainSeparatorHash
'1122334455...', // messageHash
1
)EIP-7702 Authorization(EOA に対する Set Code)に署名します。
async signAuthorization(
path: string,
authorizationRlp: string
): Promise<SignatureResult>| 名前 | 型 | 説明 |
|---|---|---|
path |
string |
BIP44 パス |
authorizationRlp |
string |
RLP([chain_id, address, nonce]) の hex |
const sig = await eth.signAuthorization(
DEFAULT_ETH_PATH,
'c3010a...' // RLP([1, "0x...", 0])
)import { ethers } from 'ethers'
import { EthereumApp, DEFAULT_ETH_PATH } from '@openloop/sdk-core'
import { WebHidTransport } from '@openloop/transport-webhid'
const transport = await WebHidTransport.connect()
const eth = new EthereumApp(transport)
// アドレス取得
const { address } = await eth.getAddress(DEFAULT_ETH_PATH)
// トランザクション作成
const tx = {
to: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
value: ethers.parseEther('0.01'),
gasLimit: 21000n,
gasPrice: (await provider.getFeeData()).gasPrice,
nonce: await provider.getTransactionCount(address),
chainId: 1n,
}
// RLP エンコードして署名
const unsignedTx = ethers.Transaction.from(tx).unsignedSerialized
const sig = await eth.signTransaction(DEFAULT_ETH_PATH, unsignedTx)
// 署名済みトランザクションを構築
const signedTx = ethers.Transaction.from({
...tx,
signature: {
v: sig.v,
r: '0x' + sig.r,
s: '0x' + sig.s,
},
})
// ブロードキャスト
const txResponse = await provider.broadcastTransaction(signedTx.serialized)import { createPublicClient, http, parseEther } from 'viem'
import { mainnet } from 'viem/chains'
import { EthereumApp, DEFAULT_ETH_PATH } from '@openloop/sdk-core'
import { WebHidTransport } from '@openloop/transport-webhid'
const transport = await WebHidTransport.connect()
const eth = new EthereumApp(transport)
const { address } = await eth.getAddress(DEFAULT_ETH_PATH)
// personal_sign
const sig = await eth.signPersonalMessage(
DEFAULT_ETH_PATH,
'Hello from viem!',
1
)
// viem の署名フォーマットに変換
const signature = `0x${sig.r}${sig.s}${sig.v.toString(16)}` as `0x${string}`