@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
JavaScript
"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