2026-08-03
엔드포인트를 빌드 시점 값으로 고정 — 릴레이 WSS 주소와 Connect 백엔드 루트를 실행 시점 설정에서 제거하고 SDK 번들과 배포 파일에 포함했습니다. 두 값은 dApp·지갑별 설정이 아니라 배포 환경에 따라 결정됩니다. WalletKit은 스캔한 페어링 URI의 relay-url보다 빌드 값을 우선합니다. QR은 신뢰할 수 없는 입력이므로 지갑의 연결 대상을 바꿀 수 없어야 합니다.
주요 변경
백엔드 루트 (connectBaseUrl)
AppKitOptions.connectBaseUrl을 제거했습니다. 전달하던 dApp은 해당 옵션을 지우면 되며 백엔드 호출은 그대로 동작합니다.@scope-connect/appkit-react의ScopeAppKitConfig.connectBaseUrl제거AppKit.connectBaseUrl속성은 남지만 항상 빌드 시점 값을 반환하며 실행 중에는 덮어쓸 수 없습니다.@scope-connect/appkit-react의 백엔드 세션 활성화 조건 변경 — Phantom 모바일 백엔드 암호화 세션과 일반 지갑 세션은 이전에는clientId와 명시적connectBaseUrl이 모두 있을 때만 활성화되었습니다. 백엔드 루트가 항상 설정되므로 이제clientId만 있으면 활성화됩니다(clientId는 필수이므로 사실상 항상 활성화). 이 기능을 끄려면 UI 없는AppKit을 직접 구성합니다.genericWalletSession은 계속 명시적으로 켜야 합니다(기본값off).
릴레이 (relayUrl)
AppKitOptions.relayUrl을 제거했습니다. 전달하던 dApp은 해당 옵션을 지우면 되며 릴레이 페어링은 그대로 동작합니다.@scope-connect/appkit-react의ScopeAppKitConfig.relayUrl제거pair()가 더 이상 릴레이 설정 누락으로INVALID_CONFIG를 던지지 않는다 — 초기화된 AppKit은 언제나 페어링할 수 있다- WalletKit
WalletKitConfig.relayUrl을 Kotlin·Swift에서 모두 제거했습니다. Swift는 기본 인자가 연결되지 않으므로 호출 코드에서 인자를 지워야 컴파일됩니다. - WalletKit은 페어링 URI의
relay-url을 연결 대상으로 사용하지 않습니다. dApp과 지갑이 서로 다른 릴레이로 빌드되면 페어링이 성립하지 않으며, 불일치는WalletSessionResult.steps에 기록됩니다.
추가
@scope-connect/appkit이DEFAULT_RELAY_URL상수와normalizeRelayUrl함수를 공개 API로 제공 — CSPconnect-src처럼 애플리케이션이 릴레이 origin을 알아야 하는 곳에서 사용한다 (DEFAULT_CONNECT_BASE_URL·normalizeConnectBaseUrl도 공개 API로 제공)- WalletKit
RelayDefaults.DEFAULT_RELAY_URL— 빌드 시점에 생성되는 상수
변경
- 빌드 시점 지정 방법
- AppKit: 빌드 환경의
APPKIT_CONNECT_BASE_URL과APPKIT_RELAY_URL을 번들에 포함합니다. 데모 이미지는docker build --build-arg APPKIT_CONNECT_BASE_URL=… --build-arg APPKIT_RELAY_URL=…로 지정합니다. - WalletKit:
./gradlew :walletkit:build -PscopeRelayUrl=…또는SCOPE_RELAY_URL=… - 지정하지 않으면 개발용 기본 엔드포인트 사용
- AppKit: 빌드 환경의
- 데모 dApp(connect/payment)에서
APPKIT_RELAY_URL·APPKIT_CONNECT_BASE_URL런타임 주입 제거 —entrypoint.sh/__ENV.js/.env.example에서 빠졌다. 잔액 조회·스크리닝·CSP도 SDK의 빌드 시점 상수를 읽는다. 런타임 env로 남는 것은APPKIT_CLIENT_ID(+데모 전용 키)뿐이다
적용 방법
- dApp: 설정에서
relayUrl·connectBaseUrl두 줄만 삭제합니다. 표준 배포에는 그 밖의 조치가 필요 없습니다. - 비표준 엔드포인트를 쓰던 dApp: 실행 시점에 주입하는 대신 빌드할 때
APPKIT_CONNECT_BASE_URL과APPKIT_RELAY_URL을 지정합니다. @scope-connect/appkit-react를 쓰면서 일반 지갑 세션 기록을 원하지 않는 dApp: 이전에는connectBaseUrl을 생략해 우회했지만 이제는 불가능합니다. UI 없는AppKit을 직접 구성하고genericWalletSession을 생략합니다.- 지갑(WalletKit):
WalletKitConfig(...)에서relayUrl인자를 삭제합니다. 다른 릴레이가 필요하면-PscopeRelayUrl로 다시 빌드합니다.
참고
- 릴레이 주소에 잘못된 값(
ws(s)://가 아닌 문자열)이 들어오면 내장 기본값을 사용한다 — QR을 띄운 뒤에야 지갑 쪽에서 거부당하는 상황을 막기 위해서다 - 두 값이 빌드에 고정되면서 신뢰 경계가 실행 시점 설정에서 빌드 과정으로 이동합니다. 운영 번들이 운영 엔드포인트를 사용하도록 빌드되었는지 릴리스 체크리스트에서 확인합니다.
연결·서명 결과값 보강 — dApp이 반환값만으로 어떤 지갑에 연결되었고 다음에 무엇을 해야 하는지 알 수 있도록 SDK 결과 타입에 필드를 추가했습니다. 기존 필드는 바꾸지 않아 기존 dApp 코드도 그대로 동작합니다.
연결·서명 결과 추가
WalletConnection.walletId— 연결에 사용한 지갑 ID입니다.selectWallet()은 선택한 ID를 항상 기록하고,connect()는 새 공개 함수walletIdForConnectorId로 커넥터 ID에 대응하는 지갑 ID를 확인할 수 있을 때 채웁니다. 릴레이 연결은 세션 승인 응답에 지갑 ID가 없어 설정되지 않습니다.WalletConnection.transport— 모든 내장 커넥터가 값을 설정합니다. EIP-1193 계열(주입형/EIP-6963/MetaMask SDK)은injected, Phantom 모바일은connect-service입니다. 직접 구현한 외부 커넥터에서만 이 값이 없을 수 있습니다.WalletConnection.expiry— 릴레이 세션의 settle이 만료(epoch 초)를 실은 경우 노출PairResult.topic/timeoutMs/cancel()— 페어링 토픽과 QR 유효 시간, 진행 중인 페어링을 중단하는 함수를 추가했습니다.cancel()을 호출하면sessionPromise가 거부됩니다.SolanaSignedTransaction.userSignature— 연결된 지갑의 서명입니다. 서명자 키를 연결 계정과 대조해 찾고, 확인할 수 없으면 마지막으로 값이 있는 슬롯을 사용합니다. 데스크톱·모바일 모두 같은 필드를 사용하므로 dApp에서 슬롯 규칙을 따로 처리할 필요가 없습니다.@scope-connect/appkit-react:useWalletConnection·세션 훅 3종에lastError { code, message }— 연결 실패 원인을AppResultCode(예:USER_REJECTEDvsWALLET_NOT_FOUND)로 분기해 안내할 수 있다. 재시도 시 초기화
수정
- 페어링 진행 중 소켓이 닫히면(취소 포함) 연결 과정의 대기 Promise에서 처리되지 않은 거부 오류가 남던 문제를 수정했습니다.