AppKit 연결
연결
connect(options?)
등록된 커넥터 또는 지정한 커넥터로 지갑을 연결합니다.
connect(options?: ConnectOptions): Promise<WalletConnection>
| 파라미터 | 필수 | 설명 |
|---|---|---|
options.connector | 아니요 | 등록된 커넥터 ID. 생략하면 현재 환경에서 사용 가능한 첫 커넥터를 선택합니다. |
반환: 사용자가 승인하고 계정·체인을 읽은 뒤 WalletConnection으로 Promise가 이행됩니다.
오류: INVALID_CONFIG, WALLET_NOT_FOUND, USER_REJECTED, INVALID_RESPONSE. 사용자 정의 커넥터가 던진 오류가 전파될 수도 있습니다.
genericWalletSession이 켜져 있으면 connect()는 지갑 연결 후 추가로 Connect 백엔드에 세션을 생성하고(POST /api/v1/connect/sessions, X-App-Key 헤더) connect 기록과 personal_sign 소유 증명을 남깁니다. 프로젝트 인증에는 생성자에서 받은 clientId를 사용합니다(백엔드 루트는 빌드 시점 고정). 이 기록이 실패해도 connect() 결과에는 영향을 주지 않습니다. injected EVM(eip155:) 연결에만 적용되고 릴레이·Phantom 모바일·비 EVM 연결은 제외됩니다.
const connection = await appKit.connect({ connector: "injected" });
console.info(connection.chainId);
selectWallet(walletId, options?)
지원 지갑 목록의 지갑을 현재 환경에 맞는 커넥터로 연결합니다. 데스크톱은 EIP-6963, 모바일 MetaMask는 SDK 딥링크, Solana는 주입형 또는 모바일 커넥터를 사용합니다.
selectWallet(
walletId: WalletId,
options?: SelectWalletOptions,
): Promise<WalletConnection>
| 파라미터 | 필수 | 설명 |
|---|---|---|
walletId | 예 | 지원 지갑 목록의 지갑 ID |
options.chainId | 아니요 | 연결 대상 CAIP-2 체인. 체인의 네임스페이스로 커넥터를 선택합니다 — eip155: 체인은 연결 후 해당 체인으로 전환을 요청하고, solana: 체인은 처음부터 해당 클러스터를 대상으로 연결합니다(전환 요청 없음). 생략하면 지갑의 기본 네임스페이스로 연결합니다(Solana 기본 클러스터는 solana:mainnet). |
반환: 최종 대상 체인에 연결된 WalletConnection입니다.
오류: INVALID_CONFIG, WALLET_NOT_FOUND, UNSUPPORTED_CHAIN(지갑이 지원하지 않는 네임스페이스의 chainId 포함), USER_REJECTED, INVALID_RESPONSE. 모바일 경로에서는 BACKEND_ERROR, SESSION_TIMEOUT, RPC_ERROR 또는 세션 어댑터 오류가 추가될 수 있습니다.
const evm = await appKit.selectWallet("metamask", {
chainId: "eip155:11155111",
});
// Solana 지갑은 chainId를 생략하면 기본 클러스터(solana:mainnet)로 연결합니다.
const solana = await appKit.selectWallet("phantom");
// 다른 클러스터가 필요하면 solana: 체인을 전달합니다.
const devnet = await appKit.selectWallet("phantom", {
chainId: "solana:devnet",
});
console.info(evm.chainId, solana.account, devnet.chainId);
pair(options)
릴레이 프로토콜을 지원하는 지갑과 페어링을 시작합니다. 릴레이 관련 설정은 필요하지 않습니다 — 릴레이 WSS 엔드포인트와 백엔드 루트가 모두 SDK 빌드 시점에 고정되고(DEFAULT_RELAY_URL / DEFAULT_CONNECT_BASE_URL), clientId는 생성자 필수 옵션입니다. 즉 초기화된 AppKit은 언제나 페어링할 수 있습니다.
pair(options: PairOptions): Promise<PairResult>
| 파라미터 | 필수 | 설명 |
|---|---|---|
requiredNamespaces | 예 | 반드시 승인받아야 하는 CAIP-25 네임스페이스 |
optionalNamespaces | 아니요 | 선택 네임스페이스 |
metadata | 아니요 | 승인 화면에 표시할 dApp 이름·URL·아이콘. 생략하면 { name: "scope-connect dApp" }이 전송됩니다. |
운영에서는 metadata에 실제 dApp 이름·URL·아이콘을 지정해 사용자가 연결 대상을 확인할 수 있게 합니다. 기본 이름은 개발 중 동작 확인에만 사용합니다.
반환: 릴레이 연결과 토큰 발급이 끝나면 PairResult를 반환합니다. 실제 지갑 세션 승인은 반환값의 session Promise에서 완료되며, 이행된 연결은 transport: "relay"입니다(지갑이 만료를 보낸 경우 expiry 포함). 이행된 WalletConnection의 account·chainId는 지갑이 승인한 첫 번째 계정에서 파생됩니다 — 지갑은 일반적으로 요청한 chains 순서대로 계정을 승인하므로, 기본 체인으로 쓸 체인을 requiredNamespaces의 첫 항목에 둡니다. 반환값의 topic·timeoutMs·cancel() 설명은 PairResult를 참고합니다 — timeoutMs로 QR 카운트다운을 그리고, 사용자가 모달을 닫으면 cancel()로 페어링을 중단합니다(session이 거부됨).
오류: 호출 단계는 INVALID_CONFIG, BACKEND_ERROR, INVALID_RESPONSE 또는 릴레이 연결 오류(RelayConnectionError)를 낼 수 있습니다. session은 SESSION_TIMEOUT, USER_REJECTED, INVALID_RESPONSE, 릴레이 RPC 오류(RelayRpcError) 또는 cancel() 호출로 거부될 수 있습니다. 공개 PairOptions에는 세션 연결 제한 시간을 바꾸는 필드가 없습니다(대기 시간은 PairResult.timeoutMs로 확인).
const relayAppKit = new AppKit({
clientId: "ck_public_example",
// 선택 — 콘솔에서 보이는 수집 정보는 입력한 userHash 값을 기준으로 수집됩니다.
// userHash 값을 입력하지 않으면 정보가 수집되지 않습니다.
userHash: getOrCreateUserHash(),
telemetry: false,
});
relayAppKit.init();
const pairing = await relayAppKit.pair({
requiredNamespaces: {
eip155: {
chains: ["eip155:11155111"],
methods: ["eth_signTypedData_v4"],
events: [],
},
},
metadata: { name: "Example dApp", url: "https://example.com" },
});
console.info(pairing.qr);
const connection = await pairing.session;
console.info(connection.account);
switchNetwork(chainId)
활성 EVM 지갑을 다른 EVM 체인으로 전환하고 연결 스냅샷을 갱신합니다.
switchNetwork(chainId: Caip2ChainId): Promise<WalletConnection>
파라미터: chainId는 eip155: 네임스페이스여야 합니다.
반환: 전환 후 다시 읽은 WalletConnection입니다. 지갑이 체인을 알지 못하면(EIP-1193 오류 4902) 네트워크 기본값으로 wallet_addEthereumChain을 호출해 체인을 등록한 뒤 다시 전환합니다.
오류: NOT_CONNECTED, UNSUPPORTED_CHAIN, INVALID_CONFIG, USER_REJECTED, RPC_ERROR.
const connection = await appKit.switchNetwork("eip155:11155111");
console.info(connection.chainId);
addNetwork(input, options?)
연결된 지갑에 EVM 네트워크를 wallet_addEthereumChain(EIP-3085)으로 등록합니다. 지갑에 내장되지 않은 체인(예: 신규 출시 L2)을 사용자가 선택할 수 있게 만듭니다. SDK는 UI를 제공하지 않으며, 승인 화면은 지갑이 직접 띄웁니다.
addNetwork(input: AddNetworkInput, options?: AddNetworkOptions): Promise<WalletConnection | null>
전제: 지갑이 먼저 선택되어 있어야 합니다. 이 메서드는 활성 연결에 대해 동작하므로 selectWallet() 또는 connect()를 먼저 호출해야 하며, 연결이 없으면 SDK가 임의로 지갑을 고르지 않고 NOT_CONNECTED를 던집니다.
파라미터:
| 이름 | 설명 |
|---|---|
input | SDK에 내장된 체인의 CAIP-2 체인 id("eip155:11155111") — SDK 공개 기본값 사용, 또는 내장되지 않은 체인의 AddEthereumChainParameter 전체 |
options.switch | 등록 후 해당 체인으로 전환할지 여부(기본 false) |
반환: options.switch를 준 경우 전환 후 다시 읽은 WalletConnection, 그렇지 않으면 null입니다. 등록만으로는 지갑의 현재 체인이 바뀌지 않습니다.
오류: NOT_CONNECTED(지갑 미선택), UNSUPPORTED_METHOD(체인이 고정되는 릴레이·Klip A2A 트랜스포트이거나 비-EVM 연결), INVALID_CONFIG(EIP-3085 파라미터 위반, 또는 switch 대상이 프로젝트 허용 목록 밖), UNSUPPORTED_CHAIN(CAIP-2 id가 비-EVM이거나 SDK 내장 정보에 해당 체인의 EIP-3085 파라미터가 없음), USER_REJECTED.
허용 목록: 등록 자체는 프로젝트의 체인 허용 목록으로 막지 않습니다 — 지갑에 네트워크를 넣는 것은 연결이 아니라 지갑 설정 변경이기 때문입니다. 전환은 막습니다. 따라서 콘솔에서 활성화하지 않은 체인은 추가는 되지만 전환은 되지 않습니다(INVALID_CONFIG).
await appKit.selectWallet("metamask");
// SDK 내장 체인 — SDK가 EIP-3085 파라미터를 제공. 등록 후 전환까지.
const connection = await appKit.addNetwork("eip155:91342", { switch: true });
console.info(connection?.chainId); // eip155:91342
// 내장되지 않은 체인 — 호출자가 파라미터를 제공.
// (아래는 위 GIWA 호출과 동등한 명시 형태 — SDK에 내장돼 있으므로 실제로는 불필요합니다.)
await appKit.addNetwork({
chainId: "0x164ce", // 91342 — 0x 접두, 앞자리 0 없음
chainName: "GIWA Sepolia",
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: ["https://sepolia-rpc.giwa.io"],
blockExplorerUrls: ["https://sepolia-explorer.giwa.io"],
});
어떤 체인을 CAIP-2 id만으로 지정할 수 있나: SDK에 체인 정보(체인 이름, 네이티브 토큰, 공개 RPC 주소 — EIP-3085 파라미터)가 미리 내장된 체인만 가능합니다. 현재는 Ethereum, Ethereum Sepolia, GIWA Sepolia 세 가지입니다.
지갑에 새 체인을 추가하려면 관리자에게 요청해 목록에 추가한 다음, 콘솔에서 해당 체인을 추가해야 합니다.
파라미터 검증: 지갑은 어떤 필드가 잘못됐든 -32602 하나로 뭉뚱그려 반환하므로, SDK가 먼저 EIP-3085 규칙(chainId 16진 형식·최대 안전 정수, rpcUrls 최소 1개, nativeCurrency.decimals 음수 아닌 정수)을 검사하고 위반한 필드명을 담아 INVALID_CONFIG로 던집니다. rpcUrls·blockExplorerUrls는 HTTPS만 허용하며, 로컬 개발 체인을 위해 loopback 호스트에 한해 http를 허용합니다. MetaMask 고유 제약인 심볼 2~6자는 EIP-3085 규칙이 아니므로 거부하지 않고 경고만 남깁니다.
disconnect()
활성 커넥터와 릴레이를 닫고 연결 상태를 지웁니다.
disconnect(): Promise<void>
반환: 정리가 끝나면 void로 Promise가 이행됩니다.
오류: 기본 릴레이 정리는 반복 호출에 안전하지만 사용자 정의 커넥터의 disconnect()가 거부하면 그 오류가 전파될 수 있습니다.
try {
await appKit.disconnect();
} finally {
console.info(appKit.connection);
}
getSupportedWallets(options?)
현재 환경 기준 지갑 정보를 반환합니다. 반환 배열을 변경해도 SDK 내부 상태에는 영향을 주지 않습니다. loadConfig()로 프로젝트가 활성화한 지갑 정보를 로드했으면 그 집합으로 필터링하고, 로드 전이거나 비어 있으면 전체 내용을 반환합니다. 단, 릴레이로 연결하는 자체 지갑(scope 등 릴레이 지원 지갑)은 항상 포함되며, 목록의 맨 뒤에 정렬됩니다.
getSupportedWallets(options?: { mobile?: boolean }): SupportWalletInfo[]
주의: mobile: true는 현재 EVM 모바일 전략 또는 릴레이 지원을 기준으로 필터링합니다. 모든 Solana 모바일 지갑 목록을 의미하지 않습니다. 반대로 mobile: false(또는 데스크톱으로 자동 감지된 경우)에는 환경 필터링을 하지 않고 전체 지갑 목록을 그대로 반환하므로, 데스크톱에서 확장 프로그램으로 연결할 수 없는 지갑(모바일 App2App 전용 klip)도 포함됩니다. 데스크톱 목록은 eip155.rdns(주입형 EIP-6963 발견 정보) 유무로 직접 걸러 냅니다 — rdns가 없는 지갑에 selectWallet()을 호출하면 INVALID_CONFIG가 발생합니다.
오류: 없음.
const walletNames = appKit
.getSupportedWallets({ mobile: false })
.map((wallet) => wallet.displayName);
getSupportedNetworks()
프로젝트가 선택할 수 있는 네트워크를 반환합니다. loadConfig()가 실행된 뒤에는 콘솔에서 설정한 네트워크 목록이며, 콘솔에서 정한 표시 순서를 따릅니다. 콘솔에 등록된 체인은 SDK 릴리스 없이 바로 선택할 수 있고, 표시 이름(displayName)·테스트넷 여부·아이콘도 콘솔에서 설정된 값을 사용합니다.
loadConfig() 이전이거나 첫 요청이 실패했거나 프로젝트가 아무 네트워크도 활성화하지 않았으면 전체 내장 정보를 반환합니다. 이전 호출에서 설정을 성공적으로 불러온 뒤 재호출이 실패하면 기존 설정을 사용합니다.
getSupportedNetworks(): NetworkInfo[]
반환: 네트워크 항목을 돌려줍니다. 반환 배열을 변경해도 SDK 내부 상태에는 영향을 주지 않습니다. 프로젝트 설정을 불러오지 못하면 내장 정보(Ethereum, Ethereum Sepolia, GIWA Sepolia, Solana, Solana Devnet)를 반환합니다.
오류: 없음.
const testnets = appKit.getSupportedNetworks().filter((network) => network.isTestnet);
getActiveProvider()
활성 EVM 커넥터의 최소 EIP-1193 프로바이더를 반환합니다.
getActiveProvider(): Eip1193Provider | null
반환: EVM 연결이면 request()만 보장하는 프로바이더, 연결 전이거나 비 EVM 연결이면 null입니다.
오류: 없음. 공개 타입은 on()이나 removeListener()를 보장하지 않습니다.
const provider = appKit.getActiveProvider();
const blockNumber = provider
? await provider.request<string>({ method: "eth_blockNumber" })
: null;