@coinbase/wallet-sdk
Advanced tools
Comparing version 4.0.0-rc.3 to 4.0.0
@@ -5,8 +5,10 @@ import EventEmitter from 'eventemitter3'; | ||
import { AccountsUpdate, ChainUpdate } from './sign/interface'; | ||
import { SignHandler } from './sign/SignHandler'; | ||
export declare class CoinbaseWalletProvider extends EventEmitter implements ProviderInterface { | ||
private readonly metadata; | ||
private readonly preference; | ||
private readonly communicator; | ||
private signer; | ||
protected accounts: AddressString[]; | ||
protected chain: Chain; | ||
protected signHandler: SignHandler; | ||
constructor(params: Readonly<ConstructorOptions>); | ||
constructor({ metadata, preference: { keysUrl, ...preference } }: Readonly<ConstructorOptions>); | ||
get connected(): boolean; | ||
@@ -31,2 +33,4 @@ request<T>(args: RequestArguments): Promise<T>; | ||
}; | ||
private requestSignerSelection; | ||
private initSigner; | ||
} |
"use strict"; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -9,10 +20,16 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
const error_1 = require("./core/error"); | ||
const serialize_1 = require("./core/error/serialize"); | ||
const type_1 = require("./core/type"); | ||
const util_1 = require("./core/type/util"); | ||
const SignHandler_1 = require("./sign/SignHandler"); | ||
const SCWSigner_1 = require("./sign/scw/SCWSigner"); | ||
const util_2 = require("./sign/util"); | ||
const WalletLinkSigner_1 = require("./sign/walletlink/WalletLinkSigner"); | ||
const provider_1 = require("./util/provider"); | ||
const Communicator_1 = require("./core/communicator/Communicator"); | ||
const method_1 = require("./core/provider/method"); | ||
const ScopedLocalStorage_1 = require("./util/ScopedLocalStorage"); | ||
class CoinbaseWalletProvider extends eventemitter3_1.default { | ||
constructor(params) { | ||
var _a, _b; | ||
constructor(_a) { | ||
var _b, _c; | ||
var { metadata } = _a, _d = _a.preference, { keysUrl } = _d, preference = __rest(_d, ["keysUrl"]); | ||
super(); | ||
@@ -24,5 +41,11 @@ this.accounts = []; | ||
try { | ||
const accounts = this.connected // already connected | ||
? this.accounts | ||
: await this.signHandler.handshake(); | ||
if (this.connected) { | ||
this.emit('connect', { chainId: (0, util_1.hexStringFromIntNumber)((0, type_1.IntNumber)(this.chain.id)) }); | ||
return this.accounts; | ||
} | ||
const signerType = await this.requestSignerSelection(); | ||
const signer = this.initSigner(signerType); | ||
const accounts = await signer.handshake(); | ||
this.signer = signer; | ||
(0, util_2.storeSignerType)(signerType); | ||
this.emit('connect', { chainId: (0, util_1.hexStringFromIntNumber)((0, type_1.IntNumber)(this.chain.id)) }); | ||
@@ -37,7 +60,7 @@ return accounts; | ||
sign: async (request) => { | ||
if (!this.connected) { | ||
if (!this.connected || !this.signer) { | ||
throw error_1.standardErrors.provider.unauthorized("Must call 'eth_requestAccounts' before other methods"); | ||
} | ||
try { | ||
return await this.signHandler.request(request); | ||
return await this.signer.request(request); | ||
} | ||
@@ -94,6 +117,11 @@ catch (error) { | ||
}; | ||
this.metadata = metadata; | ||
this.preference = preference; | ||
this.communicator = new Communicator_1.Communicator(keysUrl); | ||
this.chain = { | ||
id: (_b = (_a = params.metadata.appChainIds) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : 1, | ||
id: (_c = (_b = metadata.appChainIds) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : 1, | ||
}; | ||
this.signHandler = new SignHandler_1.SignHandler(Object.assign(Object.assign({}, params), { listener: this.updateListener })); | ||
// Load states from storage | ||
const signerType = (0, util_2.loadSignerType)(); | ||
this.signer = signerType ? this.initSigner(signerType) : null; | ||
} | ||
@@ -105,8 +133,13 @@ get connected() { | ||
var _a; | ||
const invalidArgsError = (0, provider_1.checkErrorForInvalidRequestArgs)(args); | ||
if (invalidArgsError) | ||
throw invalidArgsError; | ||
// unrecognized methods are treated as fetch requests | ||
const category = (_a = (0, method_1.determineMethodCategory)(args.method)) !== null && _a !== void 0 ? _a : 'fetch'; | ||
return this.handlers[category](args); | ||
try { | ||
const invalidArgsError = (0, provider_1.checkErrorForInvalidRequestArgs)(args); | ||
if (invalidArgsError) | ||
throw invalidArgsError; | ||
// unrecognized methods are treated as fetch requests | ||
const category = (_a = (0, method_1.determineMethodCategory)(args.method)) !== null && _a !== void 0 ? _a : 'fetch'; | ||
return this.handlers[category](args); | ||
} | ||
catch (error) { | ||
return Promise.reject((0, serialize_1.serializeError)(error, args.method)); | ||
} | ||
} | ||
@@ -128,6 +161,35 @@ handleUnauthorizedError(error) { | ||
this.chain = { id: 1 }; | ||
this.signHandler.disconnect(); | ||
ScopedLocalStorage_1.ScopedLocalStorage.clearAll(); | ||
this.emit('disconnect', error_1.standardErrors.provider.disconnected('User initiated disconnection')); | ||
} | ||
requestSignerSelection() { | ||
return (0, util_2.fetchSignerType)({ | ||
communicator: this.communicator, | ||
preference: this.preference, | ||
metadata: this.metadata, | ||
}); | ||
} | ||
initSigner(signerType) { | ||
switch (signerType) { | ||
case 'scw': | ||
return new SCWSigner_1.SCWSigner({ | ||
metadata: this.metadata, | ||
updateListener: this.updateListener, | ||
postMessageToPopup: this.communicator.postRequestAndWaitForResponse, | ||
}); | ||
case 'walletlink': | ||
return new WalletLinkSigner_1.WalletLinkSigner({ | ||
metadata: this.metadata, | ||
updateListener: this.updateListener, | ||
}); | ||
case 'extension': { | ||
const injectedSigner = (0, provider_1.getCoinbaseInjectedSigner)(); | ||
if (!injectedSigner) { | ||
throw error_1.standardErrors.rpc.internal('injected signer not found'); | ||
} | ||
return injectedSigner; | ||
} | ||
} | ||
} | ||
} | ||
exports.CoinbaseWalletProvider = CoinbaseWalletProvider; |
@@ -5,2 +5,3 @@ "use strict"; | ||
const constants_1 = require("./constants"); | ||
const utils_1 = require("./utils"); | ||
exports.standardErrors = { | ||
@@ -62,27 +63,9 @@ rpc: { | ||
// Internal | ||
function isJsonRpcServerError(code) { | ||
return code >= -32099 && code <= -32000; | ||
} | ||
function hasKey(obj, key) { | ||
return Object.prototype.hasOwnProperty.call(obj, key); | ||
} | ||
function getMessageFromCode(code) { | ||
if (code && Number.isInteger(code)) { | ||
const codeString = code.toString(); | ||
if (hasKey(constants_1.errorValues, codeString)) { | ||
return constants_1.errorValues[codeString].message; | ||
} | ||
if (isJsonRpcServerError(code)) { | ||
return 'Unspecified server error.'; | ||
} | ||
} | ||
return 'Unspecified error message.'; | ||
} | ||
function getEthJsonRpcError(code, arg) { | ||
const [message, data] = parseOpts(arg); | ||
return new EthereumRpcError(code, message || getMessageFromCode(code), data); | ||
return new EthereumRpcError(code, message || (0, utils_1.getMessageFromCode)(code), data); | ||
} | ||
function getEthProviderError(code, arg) { | ||
const [message, data] = parseOpts(arg); | ||
return new EthereumProviderError(code, message || getMessageFromCode(code), data); | ||
return new EthereumProviderError(code, message || (0, utils_1.getMessageFromCode)(code), data); | ||
} | ||
@@ -89,0 +72,0 @@ function parseOpts(arg) { |
export { standardErrorCodes } from './constants'; | ||
export { standardErrors } from './errors'; | ||
export type { SerializedEthereumRpcError } from './type'; | ||
export type { SerializedEthereumRpcError } from './utils'; |
import { EventEmitter } from 'eventemitter3'; | ||
import { Method } from './method'; | ||
import { AddressString } from '../type'; | ||
export interface RequestArguments { | ||
@@ -44,2 +45,7 @@ readonly method: Method | string; | ||
} | ||
export interface Signer { | ||
handshake(): Promise<AddressString[]>; | ||
request<T>(request: RequestArguments): Promise<T>; | ||
disconnect: () => Promise<void>; | ||
} | ||
export {}; |
declare const mapping: { | ||
readonly handshake: readonly ["eth_requestAccounts"]; | ||
readonly sign: readonly ["eth_ecRecover", "personal_sign", "personal_ecRecover", "eth_signTransaction", "eth_sendTransaction", "eth_signTypedData_v1", "eth_signTypedData_v3", "eth_signTypedData_v4", "eth_signTypedData", "wallet_addEthereumChain", "wallet_switchEthereumChain", "wallet_watchAsset", "wallet_getCapabilities", "wallet_sendCalls"]; | ||
readonly sign: readonly ["eth_ecRecover", "personal_sign", "personal_ecRecover", "eth_signTransaction", "eth_sendTransaction", "eth_signTypedData_v1", "eth_signTypedData_v3", "eth_signTypedData_v4", "eth_signTypedData", "wallet_addEthereumChain", "wallet_switchEthereumChain", "wallet_watchAsset", "wallet_getCapabilities", "wallet_sendCalls", "wallet_showCallsStatus"]; | ||
readonly state: readonly ["eth_chainId", "eth_accounts", "eth_coinbase", "net_version"]; | ||
@@ -5,0 +5,0 @@ readonly deprecated: readonly ["eth_sign", "eth_signTypedData_v2"]; |
@@ -21,2 +21,3 @@ "use strict"; | ||
'wallet_sendCalls', | ||
'wallet_showCallsStatus', | ||
], | ||
@@ -23,0 +24,0 @@ state: [ |
"use strict"; | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
// Copyright (c) 2018-2023 Coinbase, Inc. <https://www.coinbase.com/> | ||
@@ -3,0 +4,0 @@ Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -1,8 +0,2 @@ | ||
import { RequestArguments } from '../core/provider/interface'; | ||
import { AddressString, Chain } from '../core/type'; | ||
export interface Signer { | ||
handshake(): Promise<AddressString[]>; | ||
request<T>(request: RequestArguments): Promise<T>; | ||
disconnect: () => Promise<void>; | ||
} | ||
type UpdateSource = 'wallet' | 'storage'; | ||
@@ -9,0 +3,0 @@ export interface AccountsUpdate { |
@@ -1,4 +0,4 @@ | ||
import { Signer, StateUpdateListener } from '../interface'; | ||
import { KeysPopupCommunicator } from '../../core/communicator/KeysPopupCommunicator'; | ||
import { AppMetadata, RequestArguments } from '../../core/provider/interface'; | ||
import { StateUpdateListener } from '../interface'; | ||
import { RPCRequestMessage, RPCResponseMessage } from '../../core/message'; | ||
import { AppMetadata, RequestArguments, Signer } from '../../core/provider/interface'; | ||
import { AddressString } from '../../core/type'; | ||
@@ -12,3 +12,3 @@ export declare class SCWSigner implements Signer { | ||
metadata: AppMetadata; | ||
postMessageToPopup: KeysPopupCommunicator['postMessage']; | ||
postMessageToPopup: (_: RPCRequestMessage) => Promise<RPCResponseMessage>; | ||
updateListener: StateUpdateListener; | ||
@@ -15,0 +15,0 @@ }); |
"use strict"; | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
// Copyright (c) 2018-2023 Coinbase, Inc. <https://www.coinbase.com/> | ||
Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -1,5 +0,1 @@ | ||
export interface RelayUIOptions { | ||
version: string; | ||
darkMode: boolean; | ||
} | ||
export interface RelayUI { | ||
@@ -19,6 +15,2 @@ attach(): void; | ||
}): () => void; | ||
/** | ||
* Reload document ui | ||
*/ | ||
reloadUI(): void; | ||
} |
@@ -12,3 +12,2 @@ import { RelayUI } from './RelayUI'; | ||
}): () => void; | ||
reloadUI(): void; | ||
} |
@@ -72,7 +72,3 @@ "use strict"; | ||
} | ||
/* istanbul ignore next */ | ||
reloadUI() { | ||
document.location.reload(); | ||
} | ||
} | ||
exports.WalletLinkRelayUI = WalletLinkRelayUI; |
@@ -14,3 +14,2 @@ import { RelayUI } from './RelayUI'; | ||
}): () => void; | ||
reloadUI(): void; | ||
} |
@@ -49,4 +49,3 @@ "use strict"; | ||
} | ||
reloadUI() { } // no-op | ||
} | ||
exports.WLMobileRelayUI = WLMobileRelayUI; |
@@ -16,3 +16,2 @@ /// <reference types="node" /> | ||
storage: ScopedLocalStorage; | ||
reloadOnDisconnect?: boolean; | ||
} | ||
@@ -34,3 +33,2 @@ export declare class WalletLinkRelay implements WalletLinkConnectionUpdateListener { | ||
protected appLogoUrl: string | null; | ||
private _reloadOnDisconnect; | ||
isLinked: boolean | undefined; | ||
@@ -37,0 +35,0 @@ isUnlinkedErrorState: boolean | undefined; |
@@ -15,5 +15,5 @@ "use strict"; | ||
const util_2 = require("../../../core/type/util"); | ||
const ScopedLocalStorage_1 = require("../../../util/ScopedLocalStorage"); | ||
class WalletLinkRelay { | ||
constructor(options) { | ||
var _a; | ||
this.accountsCallback = null; | ||
@@ -87,3 +87,2 @@ this.chainCallbackParams = { chainId: '', jsonRpcUrl: '' }; // to implement distinctUntilChanged | ||
this.relayEventManager = new RelayEventManager_1.RelayEventManager(); | ||
this._reloadOnDisconnect = (_a = options.reloadOnDisconnect) !== null && _a !== void 0 ? _a : false; | ||
this.ui = ui; | ||
@@ -123,16 +122,5 @@ } | ||
if ((storedSession === null || storedSession === void 0 ? void 0 : storedSession.id) === this._session.id) { | ||
this.storage.clear(); | ||
ScopedLocalStorage_1.ScopedLocalStorage.clearAll(); | ||
} | ||
if (this._reloadOnDisconnect) { | ||
this.ui.reloadUI(); | ||
return; | ||
} | ||
if (this.accountsCallback) { | ||
this.accountsCallback([], true); | ||
} | ||
const { session, ui, connection } = this.subscribe(); | ||
this._session = session; | ||
this.connection = connection; | ||
this.ui = ui; | ||
this.attachUI(); | ||
document.location.reload(); | ||
}) | ||
@@ -139,0 +127,0 @@ .catch((_) => { }); |
@@ -1,4 +0,15 @@ | ||
import { ConstructorOptions, ProviderInterface, RequestArguments } from '../core/provider/interface'; | ||
import { ConstructorOptions, ProviderInterface, RequestArguments, Signer } from '../core/provider/interface'; | ||
import { Chain } from '../core/type'; | ||
export declare function fetchRPCRequest(request: RequestArguments, chain: Chain): Promise<any>; | ||
export interface CBWindow { | ||
coinbaseWalletSigner?: Signer; | ||
top: CBWindow; | ||
ethereum?: CBInjectedProvider; | ||
coinbaseWalletExtension?: CBInjectedProvider; | ||
} | ||
export interface CBInjectedProvider extends ProviderInterface { | ||
isCoinbaseBrowser?: boolean; | ||
setAppInfo?: (...args: unknown[]) => unknown; | ||
} | ||
export declare function getCoinbaseInjectedSigner(): Signer | undefined; | ||
export declare function getCoinbaseInjectedProvider({ metadata, preference, }: Readonly<ConstructorOptions>): ProviderInterface | undefined; | ||
@@ -5,0 +16,0 @@ /** |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.checkErrorForInvalidRequestArgs = exports.getCoinbaseInjectedProvider = exports.fetchRPCRequest = void 0; | ||
exports.checkErrorForInvalidRequestArgs = exports.getCoinbaseInjectedProvider = exports.getCoinbaseInjectedSigner = exports.fetchRPCRequest = void 0; | ||
const version_1 = require("../version"); | ||
@@ -20,16 +20,23 @@ const error_1 = require("../core/error"); | ||
exports.fetchRPCRequest = fetchRPCRequest; | ||
function getCoinbaseInjectedSigner() { | ||
const window = globalThis; | ||
return window.coinbaseWalletSigner; | ||
} | ||
exports.getCoinbaseInjectedSigner = getCoinbaseInjectedSigner; | ||
function getCoinbaseInjectedProvider({ metadata, preference, }) { | ||
var _a, _b, _c, _d; | ||
var _a, _b, _c; | ||
const window = globalThis; | ||
if (preference.options !== 'smartWalletOnly') { | ||
const signer = getCoinbaseInjectedSigner(); | ||
if (signer) | ||
return undefined; // use signer instead | ||
const extension = window.coinbaseWalletExtension; | ||
if (extension && !('shouldUseSigner' in extension && extension.shouldUseSigner)) { | ||
if (extension) { | ||
const { appName, appLogoUrl, appChainIds } = metadata; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
(_b = (_a = extension).setAppInfo) === null || _b === void 0 ? void 0 : _b.call(_a, appName, appLogoUrl, appChainIds); | ||
(_a = extension.setAppInfo) === null || _a === void 0 ? void 0 : _a.call(extension, appName, appLogoUrl, appChainIds); | ||
return extension; | ||
} | ||
} | ||
const ethereum = (_c = window.ethereum) !== null && _c !== void 0 ? _c : (_d = window.top) === null || _d === void 0 ? void 0 : _d.ethereum; | ||
if (ethereum && 'isCoinbaseBrowser' in ethereum && ethereum.isCoinbaseBrowser) { | ||
const ethereum = (_b = window.ethereum) !== null && _b !== void 0 ? _b : (_c = window.top) === null || _c === void 0 ? void 0 : _c.ethereum; | ||
if (ethereum === null || ethereum === void 0 ? void 0 : ethereum.isCoinbaseBrowser) { | ||
return ethereum; | ||
@@ -48,3 +55,3 @@ } | ||
if (!args || typeof args !== 'object' || Array.isArray(args)) { | ||
return error_1.standardErrors.rpc.invalidRequest({ | ||
return error_1.standardErrors.rpc.invalidParams({ | ||
message: 'Expected a single, non-array, object argument.', | ||
@@ -56,3 +63,3 @@ data: args, | ||
if (typeof method !== 'string' || method.length === 0) { | ||
return error_1.standardErrors.rpc.invalidRequest({ | ||
return error_1.standardErrors.rpc.invalidParams({ | ||
message: "'args.method' must be a non-empty string.", | ||
@@ -65,3 +72,3 @@ data: args, | ||
(typeof params !== 'object' || params === null)) { | ||
return error_1.standardErrors.rpc.invalidRequest({ | ||
return error_1.standardErrors.rpc.invalidParams({ | ||
message: "'args.params' must be an object or array if provided.", | ||
@@ -68,0 +75,0 @@ data: args, |
@@ -1,1 +0,1 @@ | ||
export declare const LIB_VERSION = "4.0.0-rc.3"; | ||
export declare const LIB_VERSION = "4.0.0"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LIB_VERSION = void 0; | ||
exports.LIB_VERSION = '4.0.0-rc.3'; | ||
exports.LIB_VERSION = '4.0.0'; |
{ | ||
"name": "@coinbase/wallet-sdk", | ||
"version": "4.0.0-rc.3", | ||
"version": "4.0.0", | ||
"description": "Coinbase Wallet JavaScript SDK", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -5,14 +5,4 @@ # Coinbase Wallet SDK | ||
1. [Coinbase smart wallet](https://keys.coinbase.com/onboarding) | ||
- EIP-4337 account abstraction using passkeys | ||
- No passwords or PIN | ||
- No seed phrase management | ||
- No extension or app downloads | ||
- Near instant onboarding | ||
- Spend with Coinbase balance | ||
- Gas sponsorship via paymasters | ||
- Batch transactions | ||
- Desktop and mobile compatible | ||
1. [Coinbase Smart Wallet](https://keys.coinbase.com/onboarding) | ||
- [Docs](https://www.smartwallet.dev/) | ||
1. Coinbase Wallet mobile for [Android](https://play.google.com/store/apps/details?id=org.toshi&referrer=utm_source%3DWallet_LP) and [iOS](https://apps.apple.com/app/apple-store/id1278383455?pt=118788940&ct=Wallet_LP&mt=8) | ||
@@ -24,6 +14,2 @@ - Desktop: Users can connect to your dapp by scanning a QR code | ||
## Installing and Upgrading | ||
> Migrating from v3 to v4? Please see our [v4 migration guide](https://github.com/coinbase/coinbase-wallet-sdk/blob/docs/migration_guide.md) for a full list of breaking changes. | ||
### Installing Wallet SDK | ||
@@ -106,3 +92,5 @@ | ||
```js | ||
const addresses = provider.request('eth_requestAccounts'); | ||
const addresses = provider.request({ | ||
method: 'eth_requestAccounts', | ||
}); | ||
``` | ||
@@ -160,5 +148,1 @@ | ||
1. Visit localhost:3001 in your browser to view the testapp | ||
## Attributions | ||
- [eth-rpc-errors](https://github.com/MetaMask/eth-rpc-errors/blob/main/LICENSE) under the MIT license |
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
254288
6003
1
145