glip-wallet-sdk
Version:
Guide for installation and usage of Glip's Web3 Wallet.\ Glip Wallet through its SDK provides a signer using which a user's transaction can be signed.\ It also contains a iframe based UI element which can be embedded into any webpage.\ The UI contains
243 lines (242 loc) • 10.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ethers_1 = require("ethers");
const ethers_2 = require("ethers");
let chainDict = false;
// This funcion calls fetch only once
// once fetched, it stores the chainDict in a variable
async function getChainDict() {
if (chainDict) {
return chainDict;
}
// Make a await call to fetch
let chainList = await fetch('https://chainid.network/chains_mini.json');
// Convert to json
let chainListJSON = await chainList.json();
// Create a dict
chainDict = {};
// convert chainList to dict with key chainId
chainListJSON.forEach((chain) => {
chainDict[chain.chainId] = chain;
});
return chainDict;
}
// Call getChainDict() to get the chainDict
// Then return the chain with chainId
async function getChainDetails(chainId) {
let chainValue;
try {
chainValue = (await getChainDict())[chainId];
}
catch (e) {
return false;
}
return chainValue;
}
const SIGNER_EXTENSION_URL = 'wallet-confirmation/';
const API_KEY_INFURA = 'a0425606c7964da3a91be846c891fee7';
function getInfuraHttpRpcUrl(rpcValues) {
console.log('rpcValues', rpcValues);
for (let rpcValue of rpcValues) {
// check if rpcvalue starts with https
// and has infura in string
if (rpcValue.startsWith('https') && rpcValue.includes('infura')) {
// replace ${INFURA_API_KEY} with apikey
return rpcValue.replace('${INFURA_API_KEY}', API_KEY_INFURA);
}
}
return false;
}
function getHttpRpcUrl(rpcValues) {
console.log('rpcValues', rpcValues);
for (let rpcValue of rpcValues) {
// check if rpcvalue starts with https
if (rpcValue.startsWith('https')) {
return rpcValue;
}
}
return false;
}
async function getInternalProvider(chainId) {
console.log('chainId', chainId);
let chainValue = await getChainDetails(chainId);
if (!chainValue) {
throw new Error(`ChainId not found ${chainId}`);
}
console.log('chainValue', chainValue);
let infuraRPC = getInfuraHttpRpcUrl(chainValue.rpc);
let httpRPC = getHttpRpcUrl(chainValue.rpc);
let rpcUrl = infuraRPC || httpRPC;
let jsonRpcProvider = new ethers_2.ethers.providers.JsonRpcProvider(rpcUrl);
return jsonRpcProvider;
}
class ExtendedSigner extends ethers_1.Signer {
constructor(address, walletURI, isMobile, chainId, socketUUID, provider) {
super();
this.isMobile = true;
this.mobileSDK = false;
this.openedWindow = null;
if (provider && !ethers_1.providers.Provider.isProvider(provider)) {
throw (`invalid provider provided`);
}
if (provider) {
this.connect(provider);
}
console.log('this provider', this.provider);
this.address = address;
this.walletURI = walletURI + SIGNER_EXTENSION_URL;
this.isMobile = isMobile;
this.chainId = chainId;
console.log('this.chainId', this.chainId);
this.socketUUID = socketUUID;
}
connect(provider) {
this.provider = provider;
if (provider && !ethers_1.providers.Provider.isProvider(provider)) {
throw (`invalid provider provided`);
}
return this;
}
getAddress() {
return Promise.resolve(this.address);
}
async signMessage(message, isMobileSDK, hashMessage) {
this.mobileSDK = isMobileSDK || false;
//TODO: check if message is url encoded string
let stringifyied_message = encodeURIComponent(message);
let chainId = this.chainId;
let path = window.location.href.split('?')[0];
path = encodeURIComponent(path);
console.log('path', path);
let finalURL = this.walletURI + `?signMessage=${stringifyied_message}&chainId=${chainId}&lastLocation=${path}&socketUUID=${this.socketUUID}&isMobileSDK=${this.mobileSDK}&hashMessage=${hashMessage}`;
let that = this;
return new Promise(function (resolve, reject) {
that.signedMessageCB = resolve;
that.signedMessageRejectCB = reject;
if (that.mobileSDK) {
window.location = finalURL;
return;
}
that.openedWindow = window.open(finalURL, '_blank', 'height=720,width=550');
});
// let message_stringify = JSON.stringify(message);
// let that = this;
// let finalURL = this.walletURI;
// return new Promise(function(resolve:any, reject:any){
// that.signedMessageCB = resolve;
// that.signedMessageRejectCB = reject;
// window.open(finalURL, '_blank', 'height=720,width=550');
// });
}
async signPersonalMessage(message, isMobileSDK) {
this.mobileSDK = isMobileSDK || false;
//TODO: check if message is url encoded string
let stringifyied_message = encodeURIComponent(message);
let chainId = this.chainId;
console.log('chainId', chainId);
let path = window.location.href.split('?')[0];
path = encodeURIComponent(path);
console.log('path', path);
let finalURL = this.walletURI + `?signPersonalMessage=${stringifyied_message}&chainId=${chainId}&lastLocation=${path}&socketUUID=${this.socketUUID}&isMobileSDK=${this.mobileSDK}`;
let that = this;
return new Promise(function (resolve, reject) {
that.signedMessageCB = resolve;
that.signedMessageRejectCB = reject;
if (that.mobileSDK) {
window.location = finalURL;
return;
}
that.openedWindow = window.open(finalURL, '_blank', 'height=720,width=550');
});
// let message_stringify = JSON.stringify(message);
// let that = this;
// let finalURL = this.walletURI;
// return new Promise(function(resolve:any, reject:any){
// that.signedMessageCB = resolve;
// that.signedMessageRejectCB = reject;
// window.open(finalURL, '_blank', 'height=720,width=550');
// });
}
async signTransaction(transaction, overviewMessage, mobileSDK) {
this.mobileSDK = mobileSDK || false;
let tx = await ethers_1.utils.resolveProperties(transaction);
if (tx.from != null) {
if (ethers_1.utils.getAddress(tx.from) !== this.address) {
delete tx.from;
return Promise.reject('Tx from address does not match signer address');
}
}
let stringifyied_tx = JSON.stringify(tx);
let that = this;
//Check if transaction has chainId
// if it is not the same as the signer's chainId
// send that chain in request
let chainId = this.chainId;
if (tx.chainId != chainId && tx.chainId) {
console.log('tx.chainId', tx.chainId);
chainId = tx.chainId;
}
let path = window.location.href.split('?')[0];
path = encodeURIComponent(path);
let finalURL = this.walletURI + `?signTransaction=${stringifyied_tx}&chainId=${chainId}&lastLocation=${path}&socketUUID=${this.socketUUID}&isMobileSDK=${this.mobileSDK}`;
if (overviewMessage) {
finalURL += `&overviewMessage=${overviewMessage}`;
}
//open a new tab if mobile and popup window if desktop with finalURL
if (!this.mobileSDK) {
return new Promise(function (resolve, reject) {
that.signedTransactionCB = resolve;
that.signedTransactionRejectCB = reject;
if (that.mobileSDK) {
window.location = finalURL;
return;
}
that.openedWindow = window.open(finalURL, '_blank', 'height=720,width=550');
});
}
else {
return new Promise(function (resolve, reject) {
that.signedTransactionCB = resolve;
that.signedTransactionRejectCB = reject;
window.location = finalURL;
});
}
}
async sendTransaction(transaction, overviewMessage, mobileSDK) {
console.log('sendTransaction');
if (!this.provider) {
this.provider = await getInternalProvider(this.chainId);
}
this._checkProvider("sendTransaction");
console.log('transaction', transaction);
//let tx = await ethersUtils.resolveProperties(transaction);
const signedTx = await this.signTransaction(transaction, overviewMessage, mobileSDK);
console.log('signedTx', signedTx);
let sendingTx = await this.provider.sendTransaction(signedTx);
console.log('sendingTx', sendingTx);
return sendingTx;
}
async handleTransactionResponse(data) {
var _a, _b;
if (data.action === 'approve') {
(_a = this === null || this === void 0 ? void 0 : this.openedWindow) === null || _a === void 0 ? void 0 : _a.close();
this.signedTransactionCB(data.signedTransaction);
}
else if (data.action === 'decline') {
(_b = this === null || this === void 0 ? void 0 : this.openedWindow) === null || _b === void 0 ? void 0 : _b.close();
this.signedTransactionRejectCB(data.errorReason);
}
}
async handleMessageResponse(data) {
var _a, _b;
if (data.action === 'approve') {
(_a = this === null || this === void 0 ? void 0 : this.openedWindow) === null || _a === void 0 ? void 0 : _a.close();
this.signedMessageCB(data.signedMessage);
}
else if (data.action === 'decline') {
(_b = this === null || this === void 0 ? void 0 : this.openedWindow) === null || _b === void 0 ? void 0 : _b.close();
this.signedMessageRejectCB(data.errorReason);
}
}
}
exports.default = ExtendedSigner;