@web3auth/ws-embed
Version:
Embed script
204 lines (191 loc) • 6.77 kB
JavaScript
import _objectSpread from '@babel/runtime/helpers/objectSpread2';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import { createLoggerMiddleware } from '@toruslabs/base-controllers';
import { SafeEventEmitter, ObjectMultiplex, createClientStreamMiddlewareV2, JRPCEngineV2, rpcErrors, randomId, serializeJrpcError } from '@web3auth/auth';
import { pipeline } from 'readable-stream';
import { isDuplexStream } from './isStream.js';
import messages from './messages.js';
import { createErrorMiddleware, logStreamDisconnectWarning } from './utils.js';
/**
* @param connectionStream - A Node.js duplex stream
* @param opts - An options bag
*/
class BaseProvider extends SafeEventEmitter {
constructor(connectionStream, {
maxEventListeners = 100,
jsonRpcStreamName = "provider"
}) {
super();
_defineProperty(this, "rpcEngine", void 0);
_defineProperty(this, "jsonRpcConnectionEvents", new SafeEventEmitter());
/**
* Indicating that this provider is a Web3Auth provider.
*/
_defineProperty(this, "isWeb3Auth", void 0);
_defineProperty(this, "state", void 0);
if (!isDuplexStream(connectionStream)) {
throw new Error(messages.errors.invalidDuplexStream());
}
this.isWeb3Auth = true;
this.setMaxListeners(maxEventListeners);
this.handleConnect = this.handleConnect.bind(this);
this.handleDisconnect = this.handleDisconnect.bind(this);
this.handleStreamDisconnect = this.handleStreamDisconnect.bind(this);
this.rpcRequest = this.rpcRequest.bind(this);
this.initializeState = this.initializeState.bind(this);
this.request = this.request.bind(this);
this.sendAsync = this.sendAsync.bind(this);
this.send = this.send.bind(this);
// this.enable = this.enable.bind(this);
// setup connectionStream multiplexing
const mux = new ObjectMultiplex();
pipeline(connectionStream, mux, connectionStream, this.handleStreamDisconnect.bind(this, "Web3Auth"));
// ignore phishing warning message (handled elsewhere)
mux.ignoreStream("phishing");
// setup own event listeners
// connect to async provider
const {
middleware: streamMiddleware,
stream: clientStream
} = createClientStreamMiddlewareV2({
notificationEmitter: this.jsonRpcConnectionEvents
});
const engine = JRPCEngineV2.create({
middleware: [createErrorMiddleware(), createLoggerMiddleware({
origin: location.origin
}), streamMiddleware]
});
pipeline(clientStream, mux.createStream(jsonRpcStreamName), clientStream, this.handleStreamDisconnect.bind(this, "Web3Auth RpcProvider"));
this.rpcEngine = engine;
}
/**
* Submits an RPC request for the given method, with the given params.
* Resolves with the result of the method call, or rejects on error.
*
* @param args - The RPC request arguments.
* @returns A Promise that resolves with the result of the RPC method,
* or rejects if an error is encountered.
*/
async request(args) {
if (!args || typeof args !== "object" || Array.isArray(args)) {
throw rpcErrors.invalidRequest({
message: messages.errors.invalidRequestArgs(),
data: _objectSpread(_objectSpread({}, args || {}), {}, {
cause: messages.errors.invalidRequestArgs()
})
});
}
const {
method,
params
} = args;
if (typeof method !== "string" || method.length === 0) {
throw rpcErrors.invalidRequest({
message: messages.errors.invalidRequestMethod(),
data: _objectSpread(_objectSpread({}, args || {}), {}, {
cause: messages.errors.invalidRequestArgs()
})
});
}
if (params !== undefined && !Array.isArray(params) && (typeof params !== "object" || params === null)) {
throw rpcErrors.invalidRequest({
message: messages.errors.invalidRequestParams(),
data: _objectSpread(_objectSpread({}, args || {}), {}, {
cause: messages.errors.invalidRequestArgs()
})
});
}
return this.rpcRequest({
id: randomId(),
method,
params
});
}
/**
* Submits an RPC request per the given JSON-RPC request object.
*
* @param payload - The RPC request object.
* @param cb - The callback function.
*/
send(payload, callback) {
const resolveCallback = (error, result) => {
callback(error, result);
};
this.rpcRequest(payload).then(result => {
return resolveCallback(null, {
id: payload.id,
jsonrpc: "2.0",
result
});
}).catch(err => {
const error = err instanceof Error ? err : rpcErrors.internal({
message: "Internal JSON-RPC error",
data: {
cause: err
}
});
return resolveCallback(error, {
id: payload.id,
jsonrpc: "2.0",
error: serializeJrpcError(error, {
shouldIncludeStack: false,
shouldPreserveMessage: true,
fallbackError: rpcErrors.internal({
message: "Internal JSON-RPC error",
data: {
cause: "Internal JSON-RPC error"
}
})
})
});
});
}
/**
* Submits an RPC request per the given JSON-RPC request object.
*
* @param payload - The RPC request object.
* @param cb - The callback function.
*/
sendAsync(payload) {
return this.rpcRequest(payload);
}
/**
* Called when connection is lost to critical streams.
*
* emits InpageProvider#disconnect
*/
handleStreamDisconnect(streamName, error) {
logStreamDisconnectWarning(streamName, error, this);
this.handleDisconnect(false, error ? error.message : undefined);
}
// Private Methods
//= ===================
/**
* Constructor helper.
* Populates initial state by calling 'wallet_getProviderState' and emits
* necessary events.
*/
/**
* Internal RPC method. Forwards requests to background via the RPC engine.
* Also remap ids inbound and outbound
*/
/**
* When the provider becomes connected, updates internal state and emits
* required events. Idempotent.
*
* @param chainId - The ID of the newly connected chain.
* emits InPageProvider#connect
*/
/**
* When the provider becomes disconnected, updates internal state and emits
* required events. Idempotent with respect to the isRecoverable parameter.
*
* Error codes per the CloseEvent status codes as required by EIP-1193:
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
*
* @param isRecoverable - Whether the disconnection is recoverable.
* @param errorMessage - A custom error message.
* emits InpageProvider#disconnect
*/
}
export { BaseProvider as default };