跳至主要内容

二维码扫描

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;

参数:

参数类型描述
datastring二维码扫描得到的原始字符串数据。

返回值: 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>
);
}

下一步