UNPKG

@unilogin/sdk

Version:

SDK is a JS library, that communicates with relayer. SDK allows managing contract, by creating basic contract-calling messages.

425 lines 22.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var commons_1 = require("@unilogin/commons"); var errors_1 = require("../utils/errors"); var ethers_1 = require("ethers"); var __1 = require("../.."); var reactive_properties_1 = require("reactive-properties"); var WalletSerializer_1 = require("./WalletSerializer"); var ConnectingWallet_1 = require("../../api/wallet/ConnectingWallet"); var NoopStorageService_1 = require("./NoopStorageService"); var WalletStorageService_1 = require("./WalletStorageService"); var WalletService = /** @class */ (function () { function WalletService(sdk, walletFromPassphrase, storageService) { if (walletFromPassphrase === void 0) { walletFromPassphrase = commons_1.walletFromBrain; } if (storageService === void 0) { storageService = new NoopStorageService_1.NoopStorageService(); } this.sdk = sdk; this.walletFromPassphrase = walletFromPassphrase; this._stateProperty = new reactive_properties_1.State({ kind: 'None' }); this.stateProperty = this._stateProperty; this.walletDeployed = this.stateProperty.pipe(reactive_properties_1.map(function (state) { return state.kind === 'Deployed'; })); this.isAuthorized = this.walletDeployed; this.walletStorage = new WalletStorageService_1.WalletStorageService(storageService, sdk.config.network); this.walletSerializer = new WalletSerializer_1.WalletSerializer(sdk); } Object.defineProperty(WalletService.prototype, "state", { get: function () { return this.stateProperty.get(); }, enumerable: true, configurable: true }); WalletService.prototype.setState = function (state) { this.saveToStorage(state); this._stateProperty.set(state); }; WalletService.prototype.getDeployedWallet = function () { commons_1.ensure(this.state.kind === 'Deployed', errors_1.InvalidWalletState, 'Deployed', this.state.kind); return this.state.wallet; }; WalletService.prototype.getFutureWallet = function () { commons_1.ensure(this.state.kind === 'Future', errors_1.InvalidWalletState, 'Future', this.state.kind); return this.state.wallet; }; WalletService.prototype.getDeployingWallet = function () { commons_1.ensure(this.state.kind === 'Deploying', errors_1.InvalidWalletState, 'Deploying', this.state.kind); return this.state.wallet; }; WalletService.prototype.getConnectingWallet = function () { commons_1.ensure(this.state.kind === 'Connecting', Error, 'Invalid state: expected connecting wallet'); return this.state.wallet; }; WalletService.prototype.createDeployingWallet = function (name) { return __awaiter(this, void 0, void 0, function () { var futureWallet, deployingWallet; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.sdk.createFutureWallet(name, '0', commons_1.ETHER_NATIVE_TOKEN.address)]; case 1: futureWallet = _a.sent(); return [4 /*yield*/, futureWallet.deploy()]; case 2: deployingWallet = _a.sent(); this.setDeploying(deployingWallet); return [2 /*return*/, deployingWallet]; } }); }); }; WalletService.prototype.createFutureWallet = function (name, gasToken) { if (gasToken === void 0) { gasToken = commons_1.ETHER_NATIVE_TOKEN.address; } return __awaiter(this, void 0, void 0, function () { var gasModes, gasOption, futureWallet; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.sdk.getGasModes()]; case 1: gasModes = _a.sent(); gasOption = commons_1.findGasOption(gasModes[commons_1.FAST_GAS_MODE_INDEX].gasOptions, gasToken); return [4 /*yield*/, this.sdk.createFutureWallet(name, gasOption.gasPrice.toString(), gasToken)]; case 2: futureWallet = _a.sent(); this.setFutureWallet(futureWallet, name); return [2 /*return*/, futureWallet]; } }); }); }; WalletService.prototype.createWallet = function (name, gasToken) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { if (this.sdk.isRefundPaid()) { return [2 /*return*/, this.createDeployingWallet(name)]; } return [2 /*return*/, this.createFutureWallet(name, gasToken)]; }); }); }; WalletService.prototype.initDeploy = function () { return __awaiter(this, void 0, void 0, function () { var deploy, deployingWallet; return __generator(this, function (_a) { switch (_a.label) { case 0: commons_1.ensure(this.state.kind === 'Future', errors_1.InvalidWalletState, 'Future', this.state.kind); deploy = this.state.wallet.deploy; return [4 /*yield*/, deploy()]; case 1: deployingWallet = _a.sent(); this.setState({ kind: 'Deploying', wallet: deployingWallet }); return [2 /*return*/, this.getDeployingWallet()]; } }); }); }; WalletService.prototype.waitForTransactionHash = function () { return __awaiter(this, void 0, void 0, function () { var deployingWallet, transactionHash; return __generator(this, function (_a) { switch (_a.label) { case 0: if (this.state.kind === 'Deployed') { return [2 /*return*/, this.state.wallet]; } deployingWallet = this.getDeployingWallet(); return [4 /*yield*/, deployingWallet.waitForTransactionHash()]; case 1: transactionHash = (_a.sent()).transactionHash; commons_1.ensureNotFalsy(transactionHash, errors_1.TransactionHashNotFound); this.setState({ kind: 'Deploying', wallet: deployingWallet, transactionHash: transactionHash }); return [2 /*return*/, deployingWallet]; } }); }); }; WalletService.prototype.waitToBeSuccess = function () { return __awaiter(this, void 0, void 0, function () { var deployingWallet, deployedWallet; return __generator(this, function (_a) { switch (_a.label) { case 0: if (this.state.kind === 'Deployed') { return [2 /*return*/, this.state.wallet]; } deployingWallet = this.getDeployingWallet(); return [4 /*yield*/, deployingWallet.waitToBeSuccess()]; case 1: deployedWallet = _a.sent(); this.setState({ kind: 'Deployed', wallet: deployedWallet }); return [2 /*return*/, deployedWallet]; } }); }); }; WalletService.prototype.deployFutureWallet = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.initDeploy()]; case 1: _a.sent(); return [4 /*yield*/, this.waitForTransactionHash()]; case 2: _a.sent(); return [2 /*return*/, this.waitToBeSuccess()]; } }); }); }; WalletService.prototype.setFutureWallet = function (wallet, name) { commons_1.ensure(this.state.kind === 'None', errors_1.WalletOverridden); this.setState({ kind: 'Future', name: name, wallet: wallet }); }; WalletService.prototype.setDeployed = function () { commons_1.ensure(this.state.kind === 'Future', errors_1.InvalidWalletState, 'Future', this.state.kind); var _a = this.state, name = _a.name, _b = _a.wallet, contractAddress = _b.contractAddress, privateKey = _b.privateKey; var wallet = new __1.DeployedWallet(contractAddress, name, privateKey, this.sdk); this.setState({ kind: 'Deployed', wallet: wallet }); }; WalletService.prototype.setDeploying = function (wallet) { commons_1.ensure(this.state.kind === 'None', errors_1.WalletOverridden); this.setState({ kind: 'Deploying', wallet: wallet }); }; WalletService.prototype.setConnecting = function (wallet) { commons_1.ensure(this.state.kind === 'None', errors_1.WalletOverridden); this._stateProperty.set({ kind: 'Connecting', wallet: wallet }); }; WalletService.prototype.setWallet = function (wallet) { commons_1.ensure(this.state.kind === 'None' || this.state.kind === 'Connecting', errors_1.WalletOverridden); this.setState({ kind: 'Deployed', wallet: new __1.DeployedWallet(wallet.contractAddress, wallet.name, wallet.privateKey, this.sdk), }); }; WalletService.prototype.recover = function (name, passphrase) { return __awaiter(this, void 0, void 0, function () { var contractAddress, wallet, deployedWallet, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.sdk.getWalletContractAddress(name)]; case 1: contractAddress = _b.sent(); return [4 /*yield*/, this.walletFromPassphrase(name, passphrase)]; case 2: wallet = _b.sent(); deployedWallet = new __1.DeployedWallet(contractAddress, name, wallet.privateKey, this.sdk); _a = commons_1.ensure; return [4 /*yield*/, deployedWallet.keyExist(wallet.address)]; case 3: _a.apply(void 0, [_b.sent(), errors_1.InvalidPassphrase]); this.setWallet(deployedWallet.asApplicationWallet); return [2 /*return*/]; } }); }); }; WalletService.prototype.initializeConnection = function (name) { return __awaiter(this, void 0, void 0, function () { var contractAddress, _a, privateKey, securityCode, connectingWallet; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.sdk.getWalletContractAddress(name)]; case 1: contractAddress = _b.sent(); return [4 /*yield*/, this.sdk.connect(contractAddress)]; case 2: _a = _b.sent(), privateKey = _a.privateKey, securityCode = _a.securityCode; connectingWallet = new ConnectingWallet_1.ConnectingWallet(contractAddress, name, privateKey, this.sdk); this.setConnecting(connectingWallet); this.setState({ kind: 'Connecting', wallet: connectingWallet }); return [2 /*return*/, securityCode]; } }); }); }; WalletService.prototype.waitForConnection = function () { return __awaiter(this, void 0, void 0, function () { var connectingWallet, filter, addKeyEvent; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: if (this.state.kind === 'Deployed') return [2 /*return*/]; commons_1.ensure(this.state.kind === 'Connecting', errors_1.InvalidWalletState, 'Connecting', this.state.kind); connectingWallet = this.getConnectingWallet(); filter = { contractAddress: connectingWallet.contractAddress, key: connectingWallet.publicKey, }; return [4 /*yield*/, this.sdk.walletContractService.getEventNameFor(connectingWallet.contractAddress, 'KeyAdded')]; case 1: addKeyEvent = _a.sent(); return [2 /*return*/, new Promise(function (resolve, reject) { var setWallet = _this.setWallet.bind(_this); var unsubscribe = _this.sdk.subscribe(addKeyEvent, filter, function () { setWallet(connectingWallet); unsubscribe(); resolve(); }); connectingWallet.unsubscribe = unsubscribe; })]; } }); }); }; WalletService.prototype.cancelWaitForConnection = function (tick, timeout) { if (tick === void 0) { tick = 500; } if (timeout === void 0) { timeout = 1500; } return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: if (this.state.kind === 'Deployed') return [2 /*return*/]; return [4 /*yield*/, commons_1.waitUntil(function () { return !!_this.getConnectingWallet().unsubscribe; }, tick, timeout)]; case 1: _a.sent(); this.getConnectingWallet().unsubscribe(); this.disconnect(); return [2 /*return*/]; } }); }); }; WalletService.prototype.connect = function (name, callback) { return __awaiter(this, void 0, void 0, function () { var contractAddress, _a, privateKey, securityCode, connectingWallet, filter, addKeyEvent, unsubscribe; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.sdk.getWalletContractAddress(name)]; case 1: contractAddress = _b.sent(); return [4 /*yield*/, this.sdk.connect(contractAddress)]; case 2: _a = _b.sent(), privateKey = _a.privateKey, securityCode = _a.securityCode; connectingWallet = new ConnectingWallet_1.ConnectingWallet(contractAddress, name, privateKey, this.sdk); this.setConnecting(connectingWallet); this.setState({ kind: 'Connecting', wallet: connectingWallet }); filter = { contractAddress: contractAddress, key: ethers_1.utils.computeAddress(privateKey), }; return [4 /*yield*/, this.sdk.walletContractService.getEventNameFor(connectingWallet.contractAddress, 'KeyAdded')]; case 3: addKeyEvent = _b.sent(); unsubscribe = this.sdk.subscribe(addKeyEvent, filter, function () { _this.setWallet(connectingWallet); unsubscribe; callback(); }); return [2 /*return*/, { unsubscribe: unsubscribe, securityCode: securityCode }]; } }); }); }; WalletService.prototype.removeWallet = function (executionOptions) { return __awaiter(this, void 0, void 0, function () { var existingKeysCount, execution; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: if (this.state.kind !== 'Deployed') { this.disconnect(); return [2 /*return*/]; } return [4 /*yield*/, this.state.wallet.getKeys()]; case 1: existingKeysCount = (_a.sent()).length; if (!(existingKeysCount > 1)) return [3 /*break*/, 3]; return [4 /*yield*/, this.state.wallet.removeCurrentKey(executionOptions)]; case 2: execution = _a.sent(); execution.waitToBeSuccess().then(function () { return _this.disconnect(); }); return [2 /*return*/, execution]; case 3: this.disconnect(); return [2 /*return*/]; } }); }); }; WalletService.prototype.disconnect = function () { this.setState({ kind: 'None' }); }; WalletService.prototype.saveToStorage = function (state) { var serialized = this.walletSerializer.serialize(state); if (serialized !== undefined) { this.walletStorage.save(serialized); } }; WalletService.prototype.loadFromStorage = function () { var _a, _b; return __awaiter(this, void 0, void 0, function () { var state; return __generator(this, function (_c) { switch (_c.label) { case 0: commons_1.ensure(this.state.kind === 'None', errors_1.WalletOverridden); return [4 /*yield*/, ((_b = (_a = this.walletStorage).migrate) === null || _b === void 0 ? void 0 : _b.call(_a))]; case 1: _c.sent(); state = this.walletStorage.load(); this._stateProperty.set(this.walletSerializer.deserialize(state)); return [2 /*return*/]; } }); }); }; WalletService.prototype.finalize = function () { this._stateProperty.set({ kind: 'None' }); }; WalletService.prototype.getRequiredDeploymentBalance = function () { commons_1.ensure(this.state.kind === 'Future', errors_1.InvalidWalletState, 'Future', this.state.kind); return this.state.wallet.getMinimalAmount(); }; WalletService.prototype.isKind = function (kind) { return this.state.kind === kind; }; WalletService.prototype.getContractAddress = function () { commons_1.ensure(this.state.kind !== 'None', errors_1.InvalidWalletState, 'not None', this.state.kind); return this.state.wallet.contractAddress; }; return WalletService; }()); exports.WalletService = WalletService; //# sourceMappingURL=WalletService.js.map