二维码扫描
ONE SDK 提供了 parseQRCode 工具函数,用于将二维码数据解析为结构化结果。它支持 EIP-681 支付 URI、WalletConnect URI 和纯钱包地址。
React Native 入口
parseQRCode 工具函数从 React Native 入口(@one_deploy/sdk/react-native)导出。它是一个无 UI 依赖的纯函数,可以与任何二维码扫描库配合使用。
parseQRCode
将原始二维码字符串数据解析为类型化结果。
import { parseQRCode } from '@one_deploy/sdk/react-native';
const result = parseQRCode('ethereum:0x1234...abcd@8453?value=1e17');
console.log(result.type); // 'payment'
console.log(result.address); // '0x1234...abcd'
console.log(result.chainId); // 8453
console.log(result.value); // '0.1'
函数签名
function parseQRCode(data: string): QRScanResult;
参数:
| 参数 | 类型 | 描述 |
|---|---|---|
data | string | 二维码扫描得到的原始字符串数据。 |
返回值: QRScanResult
QRScanResult 类型
结果是一个基于 type 字段的可辨识联合类型。
type QRScanResult =
| QRPaymentResult
| QRAddressResult
| QRWalletConnectResult
| QRUnknownResult;
interface QRPaymentResult {
type: 'payment';
/** 收款方钱包地址。 */
address: string;
/** 从 URI 解析的链 ID,未指定时为 null。 */
chainId: number | null;
/** 支付金额,以十进制字符串表示,未指定时为 null。 */
value: string | null;
/** 代币符号或 ERC-20 转账的合约地址。 */
token: string | null;
/** ERC-20 转账时的代币合约地址。 */
contractAddress: string | null;
/** URI 中的附加函数参数。 */
params: Record<string, string>;
/** 原始输入字符串。 */
raw: string;
}
interface QRAddressResult {
type: 'address';
/** 解析后的钱包地址。 */
address: string;
/** 原始输入字符串。 */
raw: string;
}
interface QRWalletConnectResult {
type: 'walletconnect';
/** 用于会话配对的 WalletConnect URI。 */
uri: string;
/** WalletConnect 协议版本(1 或 2)。 */
version: 1 | 2;
/** 原始输入字符串。 */
raw: string;
}
interface QRUnknownResult {
type: 'unknown';
/** 无法解析的原始输入字符串。 */
raw: string;
}
EIP-681 支付 URI 解析
EIP-681 定义了以太坊兼容链上支付 URI 的标准格式。parseQRCode 函数完全支持此标准。
原生代币支付
import { parseQRCode } from '@one_deploy/sdk/react-native';
// ethereum:0x1234...abcd@8453?value=1e17
const result = parseQRCode('ethereum:0x1234567890abcdef1234567890abcdef12345678@8453?value=1e17');
if (result.type === 'payment') {
console.log(result.address); // '0x1234567890abcdef1234567890abcdef12345678'
console.log(result.chainId); // 8453
console.log(result.value); // '0.1'(从 1e17 wei 转换)
console.log(result.token); // null(原生代币)
console.log(result.contractAddress); // null
}
ERC-20 代币转账
import { parseQRCode } from '@one_deploy/sdk/react-native';
// EIP-681 ERC-20 转账 URI
const uri = 'ethereum:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913@8453/transfer?address=0xRecipient&uint256=50000000';
const result = parseQRCode(uri);
if (result.type === 'payment') {
console.log(result.contractAddress); // '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
console.log(result.token); // 'USDC'(从已知合约解析)
console.log(result.value); // '50.0'(使用 6 位小数转换)
console.log(result.chainId); // 8453
console.log(result.params.address); // '0xRecipient'
}
纯地址
import { parseQRCode } from '@one_deploy/sdk/react-native';
const result = parseQRCode('0x1234567890abcdef1234567890abcdef12345678');
if (result.type === 'address') {
console.log(result.address); // '0x1234567890abcdef1234567890abcdef12345678'
}
WalletConnect URI 支持
parseQRCode 函数可检测 WalletConnect 配对 URI(v1 和 v2 均支持)。
WalletConnect v2
import { parseQRCode } from '@one_deploy/sdk/react-native';
const wcUri = 'wc:a]b1c2d3e4f5@2?relay-protocol=irn&symKey=abc123...';
const result = parseQRCode(wcUri);
if (result.type === 'walletconnect') {
console.log(result.version); // 2
console.log(result.uri); // 用于会话配对的完整 WC URI
}
WalletConnect v1
import { parseQRCode } from '@one_deploy/sdk/react-native';
const wcUri = 'wc:sessionId@1?bridge=https://bridge.example.com&key=abc123';
const result = parseQRCode(wcUri);
if (result.type === 'walletconnect') {
console.log(result.version); // 1
console.log(result.uri); // 完整的 WC URI
}
集成示例
一个完整的示例,展示如何将 parseQRCode 与基于摄像头的二维码扫描器集成,并根据结果路由到相应的操作。
import { useState } from 'react';
import { parseQRCode } from '@one_deploy/sdk/react-native';
import { useOneClient, CHAIN_IDS } from '@one_deploy/sdk';
import type { QRScanResult } from '@one_deploy/sdk';
function QRScanHandler() {
const { engineClient } = useOneClient();
const [scanResult, setScanResult] = useState<QRScanResult | null>(null);
// 当二维码扫描库检测到二维码时调用
const handleScan = (rawData: string) => {
const result = parseQRCode(rawData);
setScanResult(result);
routeResult(result);
};
const routeResult = async (result: QRScanResult) => {
switch (result.type) {
case 'payment': {
// 导航到发送页面并预填数据
console.log('Payment request detected');
console.log('To:', result.address);
console.log('Amount:', result.value);
console.log('Chain:', result.chainId);
if (result.value && result.chainId) {
const tx = await engineClient.sendTransaction({
fromAddress: '0xMyWallet...',
toAddress: result.address,
chainId: result.chainId,
value: result.value,
currency: result.token ?? 'ETH',
contractAddress: result.contractAddress ?? undefined,
});
console.log('Sent:', tx.transactionHash);
}
break;
}
case 'address': {
// 导航到发送页面,仅预填地址
console.log('Address scanned:', result.address);
break;
}
case 'walletconnect': {
// 发起 WalletConnect 会话配对
console.log('WalletConnect v' + result.version);
console.log('URI:', result.uri);
break;
}
case 'unknown': {
console.warn('Unrecognized QR code:', result.raw);
break;
}
}
};
return (
<div>
{/* 你的二维码扫描组件放在这里 */}
{/* <QRScanner onScan={handleScan} /> */}
{scanResult && (
<div>
<p>Scanned: {scanResult.type}</p>
<pre>{JSON.stringify(scanResult, null, 2)}</pre>
</div>
)}
</div>
);
}