이 문서는 dApp과 지갑 간의 통신을 위한 오픈소스 프로토콜인 WalletConnect의 구현에 대해 다룹니다. 이를 통해 사용자는 개인 키를 애플리케이션에 노출시키지 않고도 개인 지갑에서 직접 dApp이 제안한 트랜잭션을 안전하게 서명할 수 있습니다.
거의 모든 탈중앙화 애플리케이션은 블록체인에 서명된 트랜잭션을 보내기 위해 사용자 인증이 필요합니다. 토큰 민팅부터 간단한 전송까지, 클라이언트 측 애플리케이션이 사용자의 계정이 필요한 스마트 컨트랙트 메서드를 호출해야 할 때마다 사용자는 항상 자신의 트랜잭션에 서명해야 합니다.
WalletConnect와 같은 솔루션 없이는, 사용자가 서명하기 위해 개인 키를 dApp에 신뢰해야 합니다. 명백한 이유로, 테스트 환경 외에는 이는 심각한 보안 문제입니다. dApp이 악의적으로 자금을 훔치거나 사용자가 승인하지 않은 것을 서명하기 위해 키를 사용할 수 있기 때문입니다.
WalletConnect는 탈중앙화 애플리케이션을 지갑에 연결하기 위한 확립된 체인 무관 오픈소스 프로토콜입니다. 이러한 연결을 안전하게 구현하는 방법에는 다양한 옵션이 있지만, WalletConnect는 다양한 지갑, 체인 및 애플리케이션에서 널리 지원되는 표준이며, 기술적 접근 방식이 간단하고 안전하며 검증되었습니다.
이 문서는 COZ의 WalletConnect 2.0 SDK의 사용법을 소개합니다. 이는 WalletConnect 위에 구축된 보조 라이브러리로, Neo 생태계 내에서의 통합을 위해 프로토콜을 래핑합니다.

애플리케이션이 연결 페이로드를 생성하고 사용자에게 제공하여(일반적으로 QR 코드로) 지갑에 제공합니다. QR 코드에는 릴레이 서버를 통해 요청하는 애플리케이션과 지갑 간의 안전한 통신 채널을 생성하는 데 필요한 정보가 포함되어 있습니다.
이제 애플리케이션은 사용자의 지갑에 직접 요청을 보낼 수 있는 능력을 갖게 됩니다.
요청을 받으면 지갑은 사용자에게 트랜잭션 승인을 요청합니다. 그런 다음 트랜잭션에 서명하고 네트워크로 전송한 후 블록체인에서 받은 응답을 dApp에 다시 응답합니다.
Project를 만드세요. 폼에 몇 개의 필드만 입력하면 되므로 매우 쉽습니다. 그 후 projectId를 얻어 애플리케이션에서 사용할 수 있습니다.COZ의 WalletConnect 2.0 SDK에는 현재 두 개의 패키지가 있습니다:
Core SDK는 모든 프론트엔드 프레임워크에서 사용할 수 있고,
React SDK는 상태 변경을 처리하는 컨텍스트 프로바이더가 있는 React 라이브러리입니다.
여기서부터 경로를 선택해야 합니다. 다음 섹션들은 각 패키지를 사용하여 WalletConnect 기본 기능의 구현을 간략히 보여줄 것입니다.
클라이언트 측 애플리케이션에 의존성을 설치하세요
npm i @cityofzion/wallet-connect-sdk-core @walletconnect/sign-client @walletconnect/types
yarn add @cityofzion/wallet-connect-sdk-core @walletconnect/sign-client @walletconnect/types
다음 코드로 SDK를 초기화하세요:
import WcSdk from "@cityofzion/wallet-connect-sdk-core";
import SignClient from "@walletconnect/sign-client";
const wcSdk = new WcSdk(
await SignClient.init({
projectId: "<your wc project id>", // Wallet Connect 웹사이트에서의 프로젝트 ID
relayUrl: "wss://relay.walletconnect.com", // walletconnect의 공식 릴레이 서버를 사용합니다
metadata: {
name: "MyApplicationName", // 지갑에 표시될 애플리케이션 이름
description: "My Application description", // 지갑에 표시될 설명
url: "https://myapplicationdescription.app/", // 지갑에서 연결될 URL
icons: ["https://myapplicationdescription.app/myappicon.png"], // 지갑에 표시될 아이콘
},
})
);
SDK는 한 번만 초기화하면 되므로, 애플리케이션의 진입점에서 하는 것을 권장합니다.
클라이언트를 초기화한 직후 manageSession을 한 번 호출할 수 있습니다. 이는 사용자의 연결된 세션을 다시 로드하고 disconnect 이벤트를 구독합니다.
await wcSdk.manageSession();
튜토리얼을 계속하려면 SDK 사용하기로 이동하세요.
애플리케이션에 의존성을 설치하세요
npm i @cityofzion/wallet-connect-sdk-react @walletconnect/sign-client @walletconnect/types
yarn add @cityofzion/wallet-connect-sdk-react @walletconnect/sign-client @walletconnect/types
WalletConnectProvider로 App을 감싸고 옵션을 선언하세요
import { WalletConnectProvider } from "@cityofzion/wallet-connect-sdk-react";
const wcOptions = {
projectId: "<your wc project id>", // Wallet Connect 웹사이트에서의 프로젝트 ID
relayUrl: "wss://relay.walletconnect.com", // walletconnect의 공식 릴레이 서버를 사용합니다
metadata: {
name: "MyApplicationName", // 지갑에 표시될 애플리케이션 이름
description: "My Application description", // 지갑에 표시될 설명
url: "https://myapplicationdescription.app/", // 지갑에서 연결될 URL
icons: ["https://myapplicationdescription.app/myappicon.png"], // 지갑에 표시될 아이콘
},
};
ReactDOM.render(
<>
<WalletConnectProvider autoManageSession={true} options={wcOptions}>
<App />
</WalletConnectProvider>
</>,
document.getElementById("root")
);
이제부터 WalletConnect를 사용해야 할 때마다 useWalletConnect 훅을 간단히 사용할 수 있습니다:
import { useWalletConnect } from "@cityofzion/wallet-connect-sdk-react";
export default function MyComponent() {
const wcSdk = useWalletConnect();
// 무언가를 수행
}
이 시점에서 언제든지 isConnected 메서드를 호출하여 사용자가 연결되어 있는지 확인할 수 있습니다. 다음 코드는 선택사항이며, 사용자 연결 상태를 확인하는 방법을 보여주기 위한 것입니다.
if (wcSdk.isConnected()) {
console.log(wcSdk.getAccountAddress()); // 첫 번째 연결된 계정 주소를 출력
console.log(wcSdk.getChainId()); // 첫 번째 연결된 계정의 체인 정보를 출력
console.log(wcSdk.session.namespaces); // 메서드, 계정 및 이벤트가 포함된 블록체인 딕셔너리를 출력
console.log(wcSdk.session.peer.metadata); // 지갑 메타데이터를 출력
}
하지만 아직 연결하지 않았기 때문에 false를 반환할 것입니다. 그럼 연결해봅시다!
지갑에 연결하려면 connect 메서드를 호출해야 합니다.
먼저 사용자가 이미 연결되어 있는지 확인하고, 그렇지 않으면 connect 메서드를 호출합니다.
연결하려는 블록체인과 사용하려는 메서드를 선택하는 것이 중요합니다.
if (!wcSdk.isConnected()) {
// neo3:mainnet, neo3:testnet 또는 neo3:private 중에서 선택하고, 사용하려는 메서드를 선택하세요
await wcSdk.connect("neo3:testnet", [
"invokeFunction",
"testInvoke",
"signMessage",
"verifyMessage",
]);
// 연결이 있는지 확인
console.log(wcSdk.isConnected() ? "성공적으로 연결됨" : "연결 거부됨");
}
connect 메서드는 사용자가 지갑과 연결하는 데 도움이 되도록 새로운 브라우저 탭을 열 것입니다. 하지만 연결을 자신만의 방식으로 처리할 수 있습니다. 방법을 보려면
문서를 확인하세요.
사용자가 지갑 연결을 해제할 수 있도록 버튼을 두는 것이 좋습니다. 이 경우 disconnect를 호출하세요:
await wcSdk.disconnect();
SDK 사용에 문제가 있으시면 이슈를 열어주세요 또는 Neo의 Discord 서버에서 COZ에 문의하세요.