Reown walletKit 설치 및 초기설정 (React Native) 포스팅에서 이어지는 내용입니다.
HDNodeWallet
타입을 가지는 wallet을 사용하면 됩니다. buildApprovedNamespaces 함수를 사용하여 Namespace Builder를 생성합니다.// util params
{
proposal: ProposalTypes.Struct; // the proposal received by `.on("session_proposal")`
supportedNamespaces: Record< // your Wallet's supported namespaces
string, // the supported namespace key e.g. eip155
{
chains: string[]; // your supported chains in CAIP-2 format e.g. ["eip155:1", "eip155:2", ...]
methods: string[]; // your supported methods e.g. ["personal_sign", "eth_sendTransaction"]
events: string[]; // your supported events e.g. ["chainChanged", "accountsChanged"]
accounts: string[] // your user's accounts in CAIP-10 format e.g. ["eip155:1:0x453d506b1543dcA64f57Ce6e7Bb048466e85e228"]
}
>;
};
.on("session_proposal")
이벤트에서 받은 proposal.on("session_proposal")
이벤트에서 받은 proposal을 사용하면 됩니다..on("session_proposal")
이벤트에서 받은 proposal을 사용할 예정이고, supportedNamespaces는 사용자의 wallet이 지원하는 namespace 정보를 설정하면 됩니다.
여기서는 eip155 namespace를 사용하여 이더리움 메인넷과 폴리곤 메인넷을 지원하는 예시를 보여드리겠습니다. 체인 리스트는 reown-com: web-examples↗에서 확인할 수 있습니다. {
methods: [
"eth_accounts",
"eth_requestAccounts",
"eth_sendRawTransaction",
"eth_sign",
"eth_signTransaction",
"eth_signTypedData",
"eth_signTypedData_v3",
"eth_signTypedData_v4",
"eth_sendTransaction",
"personal_sign",
"wallet_switchEthereumChain",
"wallet_addEthereumChain",
"wallet_getPermissions",
"wallet_requestPermissions",
"wallet_registerOnboarding",
"wallet_watchAsset",
"wallet_scanQRCode",
"wallet_sendCalls",
"wallet_getCallsStatus",
"wallet_showCallsStatus",
"wallet_getCapabilities",
],
events: [
"chainChanged",
"accountsChanged",
"message",
"disconnect",
"connect",
]
}
// 추후 세션 제안을 받은 후 `.on("session_proposal")` 이벤트에서 받은
// proposal 파라미터를 사용할 예정이기 때문에 참고만 해 주세요.
import { buildApprovedNamespaces } from "@reown/walletkit";
// ...
const approvedNamespaces = buildApprovedNamespaces({
proposal: params,
supportedNamespaces: {
eip155: {
chains: ['eip155:1', 'eip155:137'],
methods: ['eth_sendTransaction', 'personal_sign'],
events: ['accountsChanged', 'chainChanged'],
accounts: [
'eip155:1:' + "0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb", // 사용자의 이더리움 메인넷 지갑 주소 넣기
'eip155:137:' + "0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb", // 사용자의 폴리곤 메인넷 지갑 주소 넣기
],
},
},
});
// ...
.on("session_proposal")
이벤트에서 proposal을 받아 Namespace Builder를 생성하고, Approve를 통해 세션을 승인하는 함수를 만들어보겠습니다.
먼저, onSessionProposal 함수를 만들어 세션 제안을 받은 후 Namespace Builder를 생성하고 세션을 승인하는 과정을 작성합니다. 세션을 승인하면 세션이 설정되고, 세션을 거절하면 거절 사유를 반환합니다.
세션을 승인하는 함수는 approveSession
메소드를 사용하고, 세션을 거절하는 함수는 rejectSession
메소드를 사용합니다.import { buildApprovedNamespaces, getSdkError } from "@reown/walletkit";
import { Alert, Button, Text, TextInput } from 'react-native';
// ...
const App = () => {
const [walletKit, setWalletKit] = useState<WalletKitType>();
// ...
async function onSessionProposal({
id,
params,
}: WalletKitTypes.SessionProposal) {
try {
const approvedNamespaces = buildApprovedNamespaces({
proposal: params,
supportedNamespaces: {
eip155: {
chains: ['eip155:1', 'eip155:137'],
methods: ['eth_sendTransaction', 'personal_sign'],
events: ['accountsChanged', 'chainChanged'],
accounts: [
'eip155:1:' + "0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb", // 사용자의 이더리움 메인넷 지갑 주소 넣기
'eip155:137:' + "0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb", // 사용자의 폴리곤 메인넷 지갑 주소 넣기
],
},
},
});
const session = await walletKit?.approveSession({
id,
namespaces: approvedNamespaces,
});
Alert.alert('Session Approved');
console.log('session', session);
} catch (error) {
console.error(error);
await walletKit?.rejectSession({
id: params.id,
reason: getSdkError('USER_REJECTED'),
});
}
}
// ...
}
// ...
// ...
const App = () => {
// ...
useEffect(() => {
walletKit?.on('session_proposal', onSessionProposal);
return () => {
walletKit?.off('session_proposal', onSessionProposal);
};
}, [walletKit]);
// ...
}
// ...
// ...
const App = () => {
// ...
const [uri, setUri] = useState('');
return (
<SafeAreaView style={{ padding: 20 }}>
<Text>{walletKit?.metadata.name}</Text>
<TextInput
placeholder="Enter WalletConnect URI"
value={uri}
onChangeText={setUri}
style={{
width: '100%',
marginVertical: 10,
padding: 10,
fontSize: 16,
borderRadius: 8,
borderWidth: 1,
borderColor: '#ccc',
marginBottom: 10,
}}
/>
<Button
title="Connect"
onPress={() => walletKit?.pair({ uri })}
disabled={!uri}
/>
</SafeAreaView>
);
};
export default App;
import '@walletconnect/react-native-compat';
import { WalletKit, WalletKitTypes } from '@reown/walletkit';
import { WalletKit as WalletKitType } from '@reown/walletkit/dist/types/client';
import { Core } from '@walletconnect/core';
import { buildApprovedNamespaces, getSdkError } from '@walletconnect/utils';
import { useEffect, useState } from 'react';
import { Alert, Button, Text, TextInput } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import useGetwallet from '@/hooks/useGetwallet';
const core = new Core({
projectId: 'your_project_id',
});
const App = () => {
const wallet = useGetwallet();
const [walletKit, setWalletKit] = useState<WalletKitType | null>(null);
const [uri, setUri] = useState('');
async function onSessionProposal({
id,
params,
}: WalletKitTypes.SessionProposal) {
try {
const approvedNamespaces = buildApprovedNamespaces({
proposal: params,
supportedNamespaces: {
eip155: {
chains: ['eip155:1', 'eip155:137'],
methods: ['eth_sendTransaction', 'personal_sign'],
events: ['accountsChanged', 'chainChanged'],
accounts: [
'eip155:1:' + "0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb", // 사용자의 이더리움 메인넷 지갑 주소 넣기
'eip155:137:' + "0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb", // 사용자의 이더리움 메인넷 지갑 주소 넣기
],
},
},
});
const session = await walletKit?.approveSession({
id,
namespaces: approvedNamespaces,
});
Alert.alert('Session Approved');
console.log('session', session);
} catch (error) {
console.error(error);
await walletKit?.rejectSession({
id: params.id,
reason: getSdkError('USER_REJECTED'),
});
}
}
useEffect(() => {
WalletKit.init({
core,
metadata: { // 지갑 메타데이터 (본인 상황에 맞게 수정)
name: 'Demo React Native Wallet Promlee',
description: 'Demo RN Wallet to interface with Dapps',
url: 'www.promleeblog.com',
icons: ['https://your_wallet_icon.png'],
redirect: {
native: 'promleewallet://',
},
},
}).then((kit) => {
setWalletKit(kit);
});
}, []);
useEffect(() => {
walletKit?.on('session_proposal', onSessionProposal);
return () => {
walletKit?.off('session_proposal', onSessionProposal);
};
}, [walletKit]);
return (
<SafeAreaView style={{ padding: 20 }}>
<Text>{walletKit?.metadata.name}</Text>
<TextInput
placeholder="Enter WalletConnect URI"
value={uri}
onChangeText={setUri}
style={{
width: '100%',
marginVertical: 10,
padding: 10,
fontSize: 16,
borderRadius: 8,
borderWidth: 1,
borderColor: '#ccc',
marginBottom: 10,
}}
/>
<Button
title="Connect"
onPress={() => walletKit?.pair({ uri })}
disabled={!uri}
/>
</SafeAreaView>
);
};
export default App;