@coinbase/wallet-sdk
Advanced tools
Comparing version 4.0.0-beta.1 to 4.0.0-beta.2
import EventEmitter from 'eventemitter3'; | ||
import { ProviderInterface, RequestArguments } from './core/type/ProviderInterface'; | ||
import { ConnectionPreference } from './core/communicator/ConnectionPreference'; | ||
interface ConstructorOptions { | ||
scwUrl?: string; | ||
appName: string; | ||
appLogoUrl?: string | null; | ||
appChainIds: number[]; | ||
connectionPreference: ConnectionPreference; | ||
smartWalletOnly: boolean; | ||
} | ||
@@ -16,2 +14,3 @@ export declare class CoinbaseWalletProvider extends EventEmitter implements ProviderInterface { | ||
get chainId(): number; | ||
get isCoinbaseWallet(): boolean; | ||
constructor(options: Readonly<ConstructorOptions>); | ||
@@ -18,0 +17,0 @@ get connected(): boolean; |
@@ -21,2 +21,5 @@ "use strict"; | ||
} | ||
get isCoinbaseWallet() { | ||
return true; | ||
} | ||
constructor(options) { | ||
@@ -23,0 +26,0 @@ var _a, _b; |
import { LogoType } from './assets/wallet-logo'; | ||
import { ProviderInterface } from './core/type/ProviderInterface'; | ||
import { ConnectionPreference } from './core/communicator/ConnectionPreference'; | ||
/** Coinbase Wallet SDK Constructor Options */ | ||
@@ -13,3 +12,3 @@ export interface CoinbaseWalletSDKOptions { | ||
/** @optional Pre-select the wallet connection method */ | ||
connectionPreference?: ConnectionPreference; | ||
smartWalletOnly?: boolean; | ||
} | ||
@@ -19,3 +18,3 @@ export declare class CoinbaseWalletSDK { | ||
private appLogoUrl; | ||
private connectionPreference; | ||
private smartWalletOnly; | ||
private chainIds; | ||
@@ -22,0 +21,0 @@ /** |
@@ -16,3 +16,3 @@ "use strict"; | ||
constructor(options) { | ||
this.connectionPreference = options.connectionPreference || 'default'; | ||
this.smartWalletOnly = options.smartWalletOnly || false; | ||
this.chainIds = options.chainIds ? options.chainIds.map(Number) : []; | ||
@@ -29,3 +29,3 @@ this.appName = options.appName || 'DApp'; | ||
var _a; | ||
if (this.connectionPreference !== 'embedded') { | ||
if (!this.smartWalletOnly) { | ||
const extension = this.walletExtension; | ||
@@ -45,3 +45,3 @@ if (extension) { | ||
appChainIds: this.chainIds, | ||
connectionPreference: this.connectionPreference, | ||
smartWalletOnly: this.smartWalletOnly, | ||
}); | ||
@@ -48,0 +48,0 @@ } |
@@ -6,2 +6,3 @@ import { Message } from './Message'; | ||
get connected(): boolean; | ||
protected set connected(value: boolean); | ||
protected abstract onConnect(): Promise<void>; | ||
@@ -13,5 +14,5 @@ protected abstract onDisconnect(): void; | ||
protected peerWindow: Window | null; | ||
protected postMessage(message: Message, options?: { | ||
postMessage(message: Message, options?: { | ||
bypassTargetOriginCheck: boolean; | ||
}): void; | ||
} |
@@ -14,2 +14,5 @@ "use strict"; | ||
} | ||
set connected(value) { | ||
this._connected = value; | ||
} | ||
async connect() { | ||
@@ -20,7 +23,7 @@ window.addEventListener('message', this.onEvent.bind(this)); | ||
disconnect() { | ||
this._connected = false; | ||
this.connected = false; | ||
this.onDisconnect(); | ||
} | ||
postMessage(message, options) { | ||
var _a, _b; | ||
var _a; | ||
let targetOrigin = (_a = this.url) === null || _a === void 0 ? void 0 : _a.origin; | ||
@@ -35,5 +38,8 @@ if (targetOrigin === undefined) { | ||
} | ||
(_b = this.peerWindow) === null || _b === void 0 ? void 0 : _b.postMessage(message, targetOrigin); | ||
if (!this.peerWindow) { | ||
throw error_1.standardErrors.rpc.internal('Communicator: No peer window found'); | ||
} | ||
this.peerWindow.postMessage(message, targetOrigin); | ||
} | ||
} | ||
exports.CrossDomainCommunicator = CrossDomainCommunicator; |
export declare const CB_KEYS_URL = "https://keys.coinbase.com/connect"; | ||
export declare const CB_KEYS_BACKEND_URL = "https://scw-manager.cbhq.net/rpc/v3/scw/sdk-proxy"; | ||
export declare const WALLETLINK_URL = "https://www.walletlink.org"; | ||
export declare const CBW_MOBILE_DEEPLINK_URL = "https://go.cb-w.com/walletlink"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CBW_MOBILE_DEEPLINK_URL = exports.WALLETLINK_URL = exports.CB_KEYS_URL = void 0; | ||
exports.CBW_MOBILE_DEEPLINK_URL = exports.WALLETLINK_URL = exports.CB_KEYS_BACKEND_URL = exports.CB_KEYS_URL = void 0; | ||
exports.CB_KEYS_URL = 'https://keys.coinbase.com/connect'; | ||
exports.CB_KEYS_BACKEND_URL = 'https://scw-manager.cbhq.net/rpc/v3/scw/sdk-proxy'; | ||
exports.WALLETLINK_URL = 'https://www.walletlink.org'; | ||
exports.CBW_MOBILE_DEEPLINK_URL = 'https://go.cb-w.com/walletlink'; |
@@ -5,3 +5,2 @@ import { CoinbaseWalletProvider } from './CoinbaseWalletProvider'; | ||
export { CoinbaseWalletSDK } from './CoinbaseWalletSDK'; | ||
export type { ConnectionPreference } from './core/communicator/ConnectionPreference'; | ||
export default CoinbaseWalletSDK; | ||
@@ -8,0 +7,0 @@ declare global { |
@@ -12,3 +12,6 @@ export declare enum SupportedEthereumMethods { | ||
WalletSwitchEthereumChain = "wallet_switchEthereumChain", | ||
WalletAddEthereumChain = "wallet_addEthereumChain" | ||
WalletAddEthereumChain = "wallet_addEthereumChain", | ||
WalletGetCapabilities = "wallet_getCapabilities", | ||
WalletSendTransaction = "wallet_sendTransaction", | ||
WalletGetTransactionStatus = "wallet_getTransactionStatus" | ||
} | ||
@@ -116,3 +119,25 @@ export type RequestAccountsAction = { | ||
}; | ||
export type AllAction = RequestAccountsAction | SignAction | PersonalSignAction | SignTypedDataV1Action | SignTypedDataV3Action | SignTypedDataV4Action | SignTransactionAction | SendTransactionAction | SendRawTransactionAction | SwitchEthereumChainAction | AddEthereumChainAction; | ||
export type GetCapabilitiesAction = { | ||
method: SupportedEthereumMethods.WalletGetCapabilities; | ||
}; | ||
export type WalletSendTransactionAction = { | ||
method: SupportedEthereumMethods.WalletSendTransaction; | ||
params: { | ||
chainId: string; | ||
sender: string; | ||
version: string; | ||
gas?: string; | ||
calls: { | ||
target: string; | ||
value: string; | ||
data: string; | ||
}[]; | ||
capabilities: object; | ||
}; | ||
}; | ||
export type GetTransactionStatusAction = { | ||
method: SupportedEthereumMethods.WalletGetTransactionStatus; | ||
params: [string]; | ||
}; | ||
export type AllAction = RequestAccountsAction | SignAction | PersonalSignAction | SignTypedDataV1Action | SignTypedDataV3Action | SignTypedDataV4Action | SignTransactionAction | SendTransactionAction | SendRawTransactionAction | SwitchEthereumChainAction | AddEthereumChainAction | GetCapabilitiesAction | WalletSendTransactionAction | GetTransactionStatusAction; | ||
export type Action = { | ||
@@ -119,0 +144,0 @@ method: SupportedEthereumMethods; |
@@ -17,5 +17,8 @@ "use strict"; | ||
SupportedEthereumMethods["EthSignTypedDataV4"] = "eth_signTypedData_v4"; | ||
// Chain | ||
// Wallet | ||
SupportedEthereumMethods["WalletSwitchEthereumChain"] = "wallet_switchEthereumChain"; | ||
SupportedEthereumMethods["WalletAddEthereumChain"] = "wallet_addEthereumChain"; | ||
SupportedEthereumMethods["WalletGetCapabilities"] = "wallet_getCapabilities"; | ||
SupportedEthereumMethods["WalletSendTransaction"] = "wallet_sendTransaction"; | ||
SupportedEthereumMethods["WalletGetTransactionStatus"] = "wallet_getTransactionStatus"; | ||
})(SupportedEthereumMethods || (exports.SupportedEthereumMethods = SupportedEthereumMethods = {})); |
@@ -8,3 +8,4 @@ import { ActionResult } from './ActionResult'; | ||
}; | ||
capabilities?: Record<string, object>; | ||
}; | ||
}; |
@@ -23,2 +23,3 @@ import { Signer, SignerUpdateListener } from '../SignerInterface'; | ||
private tryLocalHandling; | ||
private tryBackendHandling; | ||
private sendEncryptedRequest; | ||
@@ -25,0 +26,0 @@ private createRequestMessage; |
@@ -9,2 +9,3 @@ "use strict"; | ||
const SCWStateManager_1 = require("./SCWStateManager"); | ||
const constants_1 = require("../../core/constants"); | ||
const error_1 = require("../../core/error"); | ||
@@ -65,2 +66,6 @@ const util_1 = require("../../core/util"); | ||
} | ||
const backendResult = await this.tryBackendHandling(request); | ||
if (backendResult !== undefined) { | ||
return backendResult; | ||
} | ||
const response = await this.sendEncryptedRequest(request); | ||
@@ -92,2 +97,10 @@ const decrypted = await this.decryptResponseMessage(response); | ||
} | ||
case Action_1.SupportedEthereumMethods.WalletGetCapabilities: { | ||
const walletCapabilities = this.stateManager.walletCapabilities; | ||
if (!walletCapabilities) { | ||
// This should never be the case for scw connections as capabilities are set during handshake | ||
throw error_1.standardErrors.provider.unauthorized('No wallet capabilities found, please disconnect and reconnect'); | ||
} | ||
return walletCapabilities; | ||
} | ||
default: | ||
@@ -97,2 +110,19 @@ return undefined; | ||
} | ||
async tryBackendHandling(request) { | ||
switch (request.method) { | ||
case Action_1.SupportedEthereumMethods.WalletGetTransactionStatus: { | ||
const requestBody = Object.assign(Object.assign({}, request), { jsonrpc: '2.0', id: crypto.randomUUID() }); | ||
const res = await window.fetch(constants_1.CB_KEYS_BACKEND_URL, { | ||
method: 'POST', | ||
body: JSON.stringify(requestBody), | ||
mode: 'cors', | ||
headers: { 'Content-Type': 'application/json', 'X-Cbw-Sdk-Version': version_1.LIB_VERSION }, | ||
}); | ||
const response = await res.json(); | ||
return response; | ||
} | ||
default: | ||
return undefined; | ||
} | ||
} | ||
async sendEncryptedRequest(request) { | ||
@@ -138,3 +168,3 @@ if (!this.puc.connected) { | ||
updateInternalState(request, response) { | ||
var _a; | ||
var _a, _b; | ||
const availableChains = (_a = response.data) === null || _a === void 0 ? void 0 : _a.chains; | ||
@@ -144,2 +174,6 @@ if (availableChains) { | ||
} | ||
const walletCapabilities = (_b = response.data) === null || _b === void 0 ? void 0 : _b.capabilities; | ||
if (walletCapabilities) { | ||
this.stateManager.updateWalletCapabilities(walletCapabilities); | ||
} | ||
const result = response.result; | ||
@@ -146,0 +180,0 @@ if ('error' in result) |
@@ -7,2 +7,3 @@ import { StateUpdateListener } from '../UpdateListenerInterface'; | ||
private availableChains?; | ||
private _walletCapabilities?; | ||
private _accounts; | ||
@@ -12,5 +13,6 @@ private _activeChain; | ||
get activeChain(): Chain; | ||
get walletCapabilities(): Record<string, object> | undefined; | ||
constructor(options: { | ||
updateListener: StateUpdateListener; | ||
appChainIds: number[]; | ||
updateListener: StateUpdateListener; | ||
}); | ||
@@ -22,2 +24,3 @@ updateAccounts(accounts: AddressString[]): void; | ||
}): void; | ||
updateWalletCapabilities(capabilities: Record<string, object>): void; | ||
private storeItemToStorage; | ||
@@ -24,0 +27,0 @@ private loadItemFromStorage; |
@@ -8,2 +8,3 @@ "use strict"; | ||
const AVAILABLE_CHAINS_STORAGE_KEY = 'availableChains'; | ||
const WALLET_CAPABILITIES_STORAGE_KEY = 'walletCapabilities'; | ||
class SCWStateManager { | ||
@@ -16,2 +17,5 @@ get accounts() { | ||
} | ||
get walletCapabilities() { | ||
return this._walletCapabilities; | ||
} | ||
constructor(options) { | ||
@@ -22,2 +26,3 @@ var _a, _b; | ||
this.availableChains = this.loadItemFromStorage(AVAILABLE_CHAINS_STORAGE_KEY); | ||
this._walletCapabilities = this.loadItemFromStorage(WALLET_CAPABILITIES_STORAGE_KEY); | ||
const accounts = this.loadItemFromStorage(ACCOUNTS_KEY); | ||
@@ -71,2 +76,6 @@ const chain = this.loadItemFromStorage(ACTIVE_CHAIN_STORAGE_KEY); | ||
} | ||
updateWalletCapabilities(capabilities) { | ||
this._walletCapabilities = capabilities; | ||
this.storeItemToStorage(WALLET_CAPABILITIES_STORAGE_KEY, capabilities); | ||
} | ||
storeItemToStorage(key, item) { | ||
@@ -73,0 +82,0 @@ this.storage.setItem(key, JSON.stringify(item)); |
@@ -22,3 +22,3 @@ import { Message } from '../../../core/communicator/Message'; | ||
} | ||
export type ConnectionType = 'scw' | 'walletlink' | 'extension'; | ||
export type SignerType = 'scw' | 'walletlink'; | ||
export declare function isConfigMessage(msg: Message): msg is ConfigMessage; |
@@ -1,3 +0,2 @@ | ||
import { ConnectionType } from './ConfigMessage'; | ||
import { ConnectionPreference } from '../../../core/communicator/ConnectionPreference'; | ||
import { SignerType } from './ConfigMessage'; | ||
import { CrossDomainCommunicator } from '../../../core/communicator/CrossDomainCommunicator'; | ||
@@ -7,22 +6,17 @@ import { Message } from '../../../core/communicator/Message'; | ||
private requestMap; | ||
private wlQRCodeUrlCallback?; | ||
private popUpConfigurator; | ||
constructor({ url }: { | ||
url: string; | ||
}); | ||
setWLQRCodeUrlCallback(callback: () => string): void; | ||
protected onConnect(): Promise<void>; | ||
private respondToWlQRCodeUrlRequest; | ||
protected onEvent(event: MessageEvent<Message>): void; | ||
private resolvePopupReady?; | ||
private resolveConnectionType?; | ||
private handleConfigMessage; | ||
selectConnectionType({ connectionPreference, }: { | ||
connectionPreference: ConnectionPreference; | ||
}): Promise<ConnectionType>; | ||
protected onDisconnect(): void; | ||
setGetWalletLinkQRCodeUrlCallback(callback: () => string): void; | ||
selectSignerType({ smartWalletOnly }: { | ||
smartWalletOnly: boolean; | ||
}): Promise<SignerType>; | ||
walletLinkQrScanned(): void; | ||
private postClientConfigMessage; | ||
request(message: Message): Promise<Message>; | ||
protected onDisconnect(): void; | ||
private openFixedSizePopUpWindow; | ||
private closeChildWindow; | ||
} |
@@ -5,2 +5,3 @@ "use strict"; | ||
const ConfigMessage_1 = require("./ConfigMessage"); | ||
const PopUpConfigurator_1 = require("./PopUpConfigurator"); | ||
const CrossDomainCommunicator_1 = require("../../../core/communicator/CrossDomainCommunicator"); | ||
@@ -16,31 +17,13 @@ const error_1 = require("../../../core/error"); | ||
this.url = new URL(url); | ||
this.popUpConfigurator = new PopUpConfigurator_1.PopUpConfigurator({ communicator: this }); | ||
} | ||
// should be set before calling .connect() | ||
setWLQRCodeUrlCallback(callback) { | ||
this.wlQRCodeUrlCallback = callback; | ||
} | ||
onConnect() { | ||
return new Promise((resolve, reject) => { | ||
this.resolvePopupReady = resolve; | ||
return new Promise((resolve) => { | ||
this.popUpConfigurator.resolvePopupConnection = () => { | ||
this.connected = true; | ||
resolve(); | ||
}; | ||
this.openFixedSizePopUpWindow(); | ||
if (!this.peerWindow) { | ||
reject(error_1.standardErrors.rpc.internal('No pop up window opened')); | ||
} | ||
}); | ||
} | ||
respondToWlQRCodeUrlRequest() { | ||
if (!this.wlQRCodeUrlCallback) { | ||
throw error_1.standardErrors.rpc.internal('PopUpCommunicator.wlQRCodeUrlCallback not set! make sure .setWLQRCodeUrlCallback is called first'); | ||
} | ||
const wlQRCodeUrl = this.wlQRCodeUrlCallback(); | ||
const configMessage = { | ||
type: 'config', | ||
id: crypto.randomUUID(), | ||
event: { | ||
type: ConfigMessage_1.ClientConfigEventType.WalletLinkUrl, | ||
value: wlQRCodeUrl, | ||
}, | ||
}; | ||
this.postMessage(configMessage); | ||
} | ||
onEvent(event) { | ||
@@ -52,6 +35,6 @@ var _a, _b; | ||
if ((0, ConfigMessage_1.isConfigMessage)(message)) { | ||
this.handleConfigMessage(message); | ||
this.popUpConfigurator.handleConfigMessage(message); | ||
return; | ||
} | ||
if (!this._connected) | ||
if (!this.connected) | ||
return; | ||
@@ -65,44 +48,19 @@ if (!('requestId' in message)) | ||
} | ||
handleConfigMessage(message) { | ||
var _a, _b; | ||
switch (message.event.type) { | ||
case ConfigMessage_1.HostConfigEventType.PopupListenerAdded: | ||
// Handshake Step 2: After receiving POPUP_LISTENER_ADDED_MESSAGE from Dapp, | ||
// Dapp sends DAPP_ORIGIN_MESSAGE to FE to help FE confirm the origin of the Dapp | ||
this.postClientConfigMessage(ConfigMessage_1.ClientConfigEventType.DappOriginMessage); | ||
break; | ||
case ConfigMessage_1.HostConfigEventType.PopupReadyForRequest: | ||
// Handshake Step 4: After receiving POPUP_READY_MESSAGE from Dapp, FE knows that | ||
// Dapp is ready to receive requests, handshake is done | ||
this._connected = true; | ||
(_a = this.resolvePopupReady) === null || _a === void 0 ? void 0 : _a.call(this); | ||
this.resolvePopupReady = undefined; | ||
break; | ||
case ConfigMessage_1.HostConfigEventType.ConnectionTypeSelected: | ||
if (!this._connected) | ||
return; | ||
(_b = this.resolveConnectionType) === null || _b === void 0 ? void 0 : _b.call(this, message.event.value); | ||
this.resolveConnectionType = undefined; | ||
break; | ||
case ConfigMessage_1.HostConfigEventType.RequestWalletLinkUrl: | ||
if (!this._connected) | ||
return; | ||
if (!this.wlQRCodeUrlCallback) { | ||
throw error_1.standardErrors.rpc.internal('PopUpCommunicator.wlQRCodeUrlCallback not set! should never happen'); | ||
} | ||
this.respondToWlQRCodeUrlRequest(); | ||
break; | ||
case ConfigMessage_1.HostConfigEventType.PopupUnload: | ||
this.disconnect(); | ||
break; | ||
} | ||
onDisconnect() { | ||
this.connected = false; | ||
this.closeChildWindow(); | ||
this.requestMap.forEach((fulfillment, uuid, map) => { | ||
fulfillment.reject(error_1.standardErrors.provider.userRejectedRequest('Request rejected')); | ||
map.delete(uuid); | ||
}); | ||
this.popUpConfigurator.onDisconnect(); | ||
} | ||
selectConnectionType({ connectionPreference, }) { | ||
return new Promise((resolve, reject) => { | ||
if (!this.peerWindow) { | ||
reject(error_1.standardErrors.rpc.internal('No pop up window found. Make sure to run .connect() before .send()')); | ||
} | ||
this.resolveConnectionType = resolve; | ||
this.postClientConfigMessage(ConfigMessage_1.ClientConfigEventType.SelectConnectionType, { | ||
connectionPreference, | ||
setGetWalletLinkQRCodeUrlCallback(callback) { | ||
this.popUpConfigurator.getWalletLinkQRCodeUrlCallback = callback; | ||
} | ||
selectSignerType({ smartWalletOnly }) { | ||
return new Promise((resolve) => { | ||
this.popUpConfigurator.resolveSignerTypeSelection = resolve; | ||
this.popUpConfigurator.postClientConfigMessage(ConfigMessage_1.ClientConfigEventType.SelectConnectionType, { | ||
smartWalletOnly, | ||
}); | ||
@@ -112,24 +70,6 @@ }); | ||
walletLinkQrScanned() { | ||
this.postClientConfigMessage(ConfigMessage_1.ClientConfigEventType.WalletLinkQrScanned); | ||
this.popUpConfigurator.postClientConfigMessage(ConfigMessage_1.ClientConfigEventType.WalletLinkQrScanned); | ||
} | ||
postClientConfigMessage(type, options) { | ||
if (options && type !== ConfigMessage_1.ClientConfigEventType.SelectConnectionType) { | ||
throw error_1.standardErrors.rpc.internal('ClientConfigEvent does not accept options'); | ||
} | ||
const configMessage = { | ||
type: 'config', | ||
id: crypto.randomUUID(), | ||
event: { | ||
type, | ||
value: options, | ||
}, | ||
}; | ||
this.postMessage(configMessage); | ||
} | ||
// Send message that expect to receive response | ||
request(message) { | ||
return new Promise((resolve, reject) => { | ||
if (!this.peerWindow) { | ||
reject(error_1.standardErrors.rpc.internal('No pop up window found. Make sure to run .connect() before .send()')); | ||
} | ||
this.postMessage(message); | ||
@@ -144,11 +84,5 @@ const fulfillment = { | ||
} | ||
onDisconnect() { | ||
this._connected = false; | ||
this.closeChildWindow(); | ||
this.requestMap.forEach((fulfillment, uuid, map) => { | ||
fulfillment.reject(error_1.standardErrors.provider.userRejectedRequest('Request rejected')); | ||
map.delete(uuid); | ||
}); | ||
} | ||
// Window Management | ||
openFixedSizePopUpWindow() { | ||
var _a; | ||
const left = (window.innerWidth - POPUP_WIDTH) / 2 + window.screenX; | ||
@@ -163,5 +97,7 @@ const top = (window.innerHeight - POPUP_HEIGHT) / 2 + window.screenY; | ||
popupUrl.search = urlParams.toString(); | ||
const popupWindow = window.open(popupUrl, 'SCW Child Window', `width=${POPUP_WIDTH}, height=${POPUP_HEIGHT}, left=${left}, top=${top}`); | ||
this.peerWindow = popupWindow; | ||
popupWindow === null || popupWindow === void 0 ? void 0 : popupWindow.focus(); | ||
this.peerWindow = window.open(popupUrl, 'SCW Child Window', `width=${POPUP_WIDTH}, height=${POPUP_HEIGHT}, left=${left}, top=${top}`); | ||
(_a = this.peerWindow) === null || _a === void 0 ? void 0 : _a.focus(); | ||
if (!this.peerWindow) { | ||
throw error_1.standardErrors.rpc.internal('Pop up window failed to open'); | ||
} | ||
} | ||
@@ -168,0 +104,0 @@ closeChildWindow() { |
import { SignRequestHandlerListener } from './UpdateListenerInterface'; | ||
import { ConnectionPreference } from '../core/communicator/ConnectionPreference'; | ||
import { AddressString } from '../core/type'; | ||
@@ -7,33 +6,18 @@ import { RequestArguments } from '../core/type/ProviderInterface'; | ||
interface SignRequestHandlerOptions { | ||
scwUrl?: string; | ||
appName: string; | ||
appLogoUrl?: string | null; | ||
appChainIds: number[]; | ||
connectionPreference: ConnectionPreference; | ||
smartWalletOnly: boolean; | ||
updateListener: SignRequestHandlerListener; | ||
} | ||
export declare class SignRequestHandler implements RequestHandler { | ||
private appName; | ||
private appLogoUrl; | ||
private appChainIds; | ||
private connectionPreference; | ||
private connectionType; | ||
private connectionTypeSelectionResolver; | ||
private signer; | ||
private signerTypeStorage; | ||
private popupCommunicator; | ||
private updateListener; | ||
private signerConfigurator; | ||
constructor(options: Readonly<SignRequestHandlerOptions>); | ||
private readonly updateRelay; | ||
private initSigner; | ||
private initScwSigner; | ||
private initWalletLinkSigner; | ||
onDisconnect(): Promise<void>; | ||
handleRequest(request: RequestArguments, accounts: AddressString[]): Promise<unknown>; | ||
eth_requestAccounts(accounts: AddressString[]): Promise<AddressString[]>; | ||
private getWalletLinkUrl; | ||
private completeConnectionTypeSelection; | ||
private setConnectionType; | ||
private eth_requestAccounts; | ||
canHandleRequest(request: RequestArguments): boolean; | ||
onDisconnect(): Promise<void>; | ||
} | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SignRequestHandler = void 0; | ||
const SCWSigner_1 = require("./scw/SCWSigner"); | ||
const PopUpCommunicator_1 = require("./scw/transport/PopUpCommunicator"); | ||
const WLSigner_1 = require("./walletlink/WLSigner"); | ||
const SignerConfigurator_1 = require("./SignerConfigurator"); | ||
const constants_1 = require("../core/constants"); | ||
const error_1 = require("../core/error"); | ||
const ScopedLocalStorage_1 = require("../core/storage/ScopedLocalStorage"); | ||
const SIGNER_TYPE_KEY = 'SignerType'; | ||
class SignRequestHandler { | ||
constructor(options) { | ||
var _a; | ||
// should be encapsulated under ConnectorConfigurator | ||
this.signerTypeStorage = new ScopedLocalStorage_1.ScopedLocalStorage('CBWSDK', 'SignRequestHandler'); | ||
this.updateRelay = { | ||
onAccountsUpdate: (signer, ...rest) => { | ||
if (this.signer && signer !== this.signer) | ||
return; // ignore events from inactive signers | ||
this.updateListener.onAccountsUpdate(...rest); | ||
}, | ||
onChainUpdate: (signer, ...rest) => { | ||
var _a; | ||
if (this.signer && signer !== this.signer) | ||
return; // ignore events from inactive signers | ||
if (signer instanceof WLSigner_1.WLSigner) { | ||
(_a = this.connectionTypeSelectionResolver) === null || _a === void 0 ? void 0 : _a.call(this, 'walletlink'); | ||
} | ||
this.updateListener.onChainUpdate(...rest); | ||
}, | ||
}; | ||
this.initSigner = () => { | ||
if (this.connectionType === 'scw') { | ||
this.initScwSigner(); | ||
} | ||
else if (this.connectionType === 'walletlink') { | ||
this.initWalletLinkSigner(); | ||
} | ||
}; | ||
this.popupCommunicator = new PopUpCommunicator_1.PopUpCommunicator({ | ||
url: options.scwUrl || constants_1.CB_KEYS_URL, | ||
url: constants_1.CB_KEYS_URL, | ||
}); | ||
this.updateListener = options.updateListener; | ||
// getWalletLinkUrl is called by the PopUpCommunicator when | ||
// it receives message.type === 'wlQRCodeUrl' from the cb-wallet-scw popup | ||
// its injected because we don't want to instantiate WalletLinkSigner until we have to | ||
this.getWalletLinkUrl = this.getWalletLinkUrl.bind(this); | ||
this.popupCommunicator.setWLQRCodeUrlCallback(this.getWalletLinkUrl); | ||
this.appName = options.appName; | ||
this.appLogoUrl = (_a = options.appLogoUrl) !== null && _a !== void 0 ? _a : null; | ||
this.appChainIds = options.appChainIds; | ||
const persistedConnectionType = this.signerTypeStorage.getItem(SIGNER_TYPE_KEY); | ||
this.connectionType = persistedConnectionType; | ||
this.connectionPreference = options.connectionPreference; | ||
if (persistedConnectionType) { | ||
this.initSigner(); | ||
} | ||
this.setConnectionType = this.setConnectionType.bind(this); | ||
this.initWalletLinkSigner = this.initWalletLinkSigner.bind(this); | ||
this.signerConfigurator = new SignerConfigurator_1.SignerConfigurator(Object.assign(Object.assign({}, options), { popupCommunicator: this.popupCommunicator })); | ||
} | ||
initScwSigner() { | ||
if (this.signer instanceof SCWSigner_1.SCWSigner) | ||
return; | ||
this.signer = new SCWSigner_1.SCWSigner({ | ||
appName: this.appName, | ||
appLogoUrl: this.appLogoUrl, | ||
appChainIds: this.appChainIds, | ||
puc: this.popupCommunicator, | ||
updateListener: this.updateRelay, | ||
}); | ||
} | ||
initWalletLinkSigner() { | ||
if (this.signer instanceof WLSigner_1.WLSigner) | ||
return; | ||
this.signer = new WLSigner_1.WLSigner({ | ||
appName: this.appName, | ||
appLogoUrl: this.appLogoUrl, | ||
updateListener: this.updateRelay, | ||
}); | ||
} | ||
async onDisconnect() { | ||
var _a; | ||
this.connectionType = null; | ||
this.signerTypeStorage.removeItem(SIGNER_TYPE_KEY); | ||
await ((_a = this.signer) === null || _a === void 0 ? void 0 : _a.disconnect()); | ||
} | ||
async handleRequest(request, accounts) { | ||
@@ -92,6 +21,6 @@ try { | ||
} | ||
if (!this.signer || accounts.length <= 0) { | ||
if (!this.signerConfigurator.signer || accounts.length <= 0) { | ||
throw error_1.standardErrors.provider.unauthorized("Must call 'eth_requestAccounts' before other methods"); | ||
} | ||
return await this.signer.request(request); | ||
return await this.signerConfigurator.signer.request(request); | ||
} | ||
@@ -111,7 +40,6 @@ catch (err) { | ||
} | ||
if (!this.connectionType) { | ||
if (!this.signerConfigurator.signerType) { | ||
// WL: this promise hangs until the QR code is scanned | ||
// SCW: this promise hangs until the user signs in with passkey | ||
const connectionType = await this.completeConnectionTypeSelection(); | ||
this.setConnectionType(connectionType); | ||
await this.signerConfigurator.completeSignerTypeSelection(); | ||
} | ||
@@ -121,6 +49,6 @@ try { | ||
// when the wallet link QR code url is requested | ||
this.initSigner(); | ||
const ethAddresses = await ((_a = this.signer) === null || _a === void 0 ? void 0 : _a.handshake()); | ||
this.signerConfigurator.initSigner(); | ||
const ethAddresses = await ((_a = this.signerConfigurator.signer) === null || _a === void 0 ? void 0 : _a.handshake()); | ||
if (Array.isArray(ethAddresses)) { | ||
if (this.connectionType === 'walletlink') { | ||
if (this.signerConfigurator.signerType === 'walletlink') { | ||
this.popupCommunicator.walletLinkQrScanned(); | ||
@@ -134,5 +62,5 @@ } | ||
catch (err) { | ||
if (this.connectionType === 'walletlink') { | ||
if (this.signerConfigurator.signerType === 'walletlink') { | ||
this.popupCommunicator.disconnect(); | ||
this.onDisconnect(); | ||
await this.onDisconnect(); | ||
} | ||
@@ -142,29 +70,2 @@ throw err; | ||
} | ||
getWalletLinkUrl() { | ||
this.initWalletLinkSigner(); | ||
if (!(this.signer instanceof WLSigner_1.WLSigner)) { | ||
throw error_1.standardErrors.rpc.internal('Signer not initialized or Signer.getWalletLinkUrl not defined'); | ||
} | ||
return this.signer.getQRCodeUrl(); | ||
} | ||
async completeConnectionTypeSelection() { | ||
await this.popupCommunicator.connect(); | ||
return new Promise((resolve) => { | ||
this.connectionTypeSelectionResolver = resolve.bind(this); | ||
this.popupCommunicator | ||
.selectConnectionType({ | ||
connectionPreference: this.connectionPreference, | ||
}) | ||
.then((connectionType) => { | ||
resolve(connectionType); | ||
}); | ||
}); | ||
} | ||
// storage methods | ||
setConnectionType(connectionType) { | ||
if (this.connectionType === connectionType) | ||
return; | ||
this.connectionType = connectionType; | ||
this.signerTypeStorage.setItem(SIGNER_TYPE_KEY, this.connectionType); | ||
} | ||
canHandleRequest(request) { | ||
@@ -187,6 +88,12 @@ const methodsThatRequireSigning = [ | ||
'wallet_watchAsset', | ||
'wallet_getCapabilities', | ||
'wallet_sendTransaction', | ||
'wallet_getTransactionStatus', | ||
]; | ||
return methodsThatRequireSigning.includes(request.method); | ||
} | ||
async onDisconnect() { | ||
await this.signerConfigurator.onDisconnect(); | ||
} | ||
} | ||
exports.SignRequestHandler = SignRequestHandler; |
@@ -131,2 +131,3 @@ "use strict"; | ||
relay.resetAndReload(); | ||
this._storage.clear(); | ||
} | ||
@@ -133,0 +134,0 @@ async request(args) { |
@@ -1,1 +0,1 @@ | ||
export declare const LIB_VERSION = "4.0.0-beta.1"; | ||
export declare const LIB_VERSION = "4.0.0-beta.2"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LIB_VERSION = void 0; | ||
exports.LIB_VERSION = '4.0.0-beta.1'; | ||
exports.LIB_VERSION = '4.0.0-beta.2'; |
{ | ||
"name": "@coinbase/wallet-sdk", | ||
"version": "4.0.0-beta.1", | ||
"version": "4.0.0-beta.2", | ||
"description": "Coinbase Wallet JavaScript SDK", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
305077
150
7274