UNPKG

@unilogin/sdk

Version:

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

487 lines 26.5 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; 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 }; } }; 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 __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var chai_1 = __importStar(require("chai")); var chai_as_promised_1 = __importDefault(require("chai-as-promised")); var sinon_chai_1 = __importDefault(require("sinon-chai")); var ethereum_waffle_1 = require("ethereum-waffle"); var ethers_1 = require("ethers"); var testutils_1 = require("@unilogin/contracts/testutils"); var basicSDK_1 = __importStar(require("../../fixtures/basicSDK")); var commons_1 = require("@unilogin/commons"); var src_1 = __importStar(require("../../../src")); var waitForSuccess_1 = require("../../helpers/waitForSuccess"); chai_1.default.use(ethereum_waffle_1.solidity); chai_1.default.use(sinon_chai_1.default); chai_1.default.use(chai_as_promised_1.default); var loadFixture = ethereum_waffle_1.createFixtureLoader(); var gasPrice = commons_1.TEST_GAS_PRICE_IN_TOKEN; describe('INT: DeployedWallet', function () { var provider; var relayer; var mockToken; var deployedWallet; var ensName; var message; var wallet; var walletContract; var otherWallet; var contractAddress; var privateKey; var sdk; var publicKey = commons_1.createKeyPair().publicKey; var publicKey2 = commons_1.createKeyPair().publicKey; beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () { var rest; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, loadFixture(basicSDK_1.default)]; case 1: rest = __rest.apply(void 0, [_a.sent(), []]); (wallet = rest.wallet, sdk = rest.sdk, provider = rest.provider, otherWallet = rest.otherWallet, relayer = rest.relayer, walletContract = rest.walletContract, contractAddress = rest.contractAddress, privateKey = rest.privateKey, mockToken = rest.mockToken, ensName = rest.ensName); return [4 /*yield*/, relayer.setupTestPartner()]; case 2: _a.sent(); deployedWallet = new src_1.DeployedWallet(contractAddress, ensName, privateKey, sdk); message = __assign(__assign({}, basicSDK_1.transferMessage), { from: contractAddress, gasToken: commons_1.ETHER_NATIVE_TOKEN.address, data: '0x' }); return [2 /*return*/]; } }); }); }); it('construction', function () { return __awaiter(void 0, void 0, void 0, function () { var _a, _b, _c, _d, _e, _f, _g; return __generator(this, function (_h) { switch (_h.label) { case 0: _a = chai_1.expect; return [4 /*yield*/, deployedWallet.keyExist(publicKey)]; case 1: _a.apply(void 0, [_h.sent()]).to.be.false; _b = chai_1.expect; return [4 /*yield*/, deployedWallet.keyExist(publicKey2)]; case 2: _b.apply(void 0, [_h.sent()]).to.be.false; _c = chai_1.expect; return [4 /*yield*/, deployedWallet.keyExist(deployedWallet.publicKey)]; case 3: _c.apply(void 0, [_h.sent()]).to.be.true; _d = chai_1.expect; return [4 /*yield*/, deployedWallet.getNonce()]; case 4: _d.apply(void 0, [_h.sent()]).to.eq(0); _e = chai_1.expect; return [4 /*yield*/, deployedWallet.getKeys()]; case 5: _e.apply(void 0, [_h.sent()]).to.deep.eq([deployedWallet.publicKey]); _f = chai_1.expect; return [4 /*yield*/, deployedWallet.getRequiredSignatures()]; case 6: _f.apply(void 0, [_h.sent()]).to.eq(1); _g = chai_1.expect; return [4 /*yield*/, deployedWallet.getConnectedDevices()]; case 7: _g.apply(void 0, [(_h.sent())[0]]).to.include({ contractAddress: deployedWallet.contractAddress, publicKey: deployedWallet.publicKey, }); return [2 /*return*/]; } }); }); }); it('setRequiredSignatures', function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, waitForSuccess_1.waitForSuccess(deployedWallet.addKey(publicKey, { gasPrice: gasPrice, gasToken: mockToken.address }))]; case 1: _a.sent(); return [4 /*yield*/, waitForSuccess_1.waitForSuccess(deployedWallet.setRequiredSignatures(2, { gasPrice: gasPrice, gasToken: mockToken.address }))]; case 2: _a.sent(); return [4 /*yield*/, chai_1.expect(deployedWallet.getRequiredSignatures()).to.eventually.eq(2)]; case 3: _a.sent(); return [2 /*return*/]; } }); }); }); it('generateBackupCodes', function () { return __awaiter(void 0, void 0, void 0, function () { var _a, waitToBeSuccess, waitForTransactionHash, transactionHash, codes, address, _b, connectedDevices; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, deployedWallet.generateBackupCodes({ gasPrice: gasPrice, gasToken: mockToken.address })]; case 1: _a = _c.sent(), waitToBeSuccess = _a.waitToBeSuccess, waitForTransactionHash = _a.waitForTransactionHash; return [4 /*yield*/, waitForTransactionHash()]; case 2: transactionHash = (_c.sent()).transactionHash; chai_1.expect(transactionHash).to.be.properHex; return [4 /*yield*/, waitToBeSuccess()]; case 3: codes = _c.sent(); chai_1.expect(codes.length).to.eq(1); return [4 /*yield*/, commons_1.walletFromBrain(ensName, codes[0])]; case 4: address = (_c.sent()).address; _b = chai_1.expect; return [4 /*yield*/, deployedWallet.keyExist(address)]; case 5: _b.apply(void 0, [_c.sent()]).to.be.true; return [4 /*yield*/, deployedWallet.getConnectedDevices()]; case 6: connectedDevices = _c.sent(); chai_1.expect(connectedDevices.map(function (_a) { var publicKey = _a.publicKey; return publicKey; })).to.include(address); return [2 /*return*/]; } }); }); }).timeout(15000); it('addKey and removeKey', function () { return __awaiter(void 0, void 0, void 0, function () { var _a, transactionHash, state, _b, _c, _d, _e, _f, _g; var _h; return __generator(this, function (_j) { switch (_j.label) { case 0: return [4 /*yield*/, waitForSuccess_1.waitForSuccess(deployedWallet.addKey(publicKey, commons_1.TEST_EXECUTION_OPTIONS))]; case 1: _a = _j.sent(), transactionHash = _a.transactionHash, state = _a.state; _b = chai_1.expect; return [4 /*yield*/, deployedWallet.keyExist(publicKey)]; case 2: _b.apply(void 0, [_j.sent()]).to.be.true; _c = chai_1.expect; return [4 /*yield*/, deployedWallet.getKeys()]; case 3: _c.apply(void 0, [_j.sent()]).to.include(publicKey); _d = chai_1.expect; return [4 /*yield*/, deployedWallet.getNonce()]; case 4: _d.apply(void 0, [_j.sent()]).to.eq(1); chai_1.expect(transactionHash).to.be.properHex(64); chai_1.expect(state).to.eq('Success'); return [4 /*yield*/, waitForSuccess_1.waitForSuccess(deployedWallet.removeKey(publicKey, commons_1.TEST_EXECUTION_OPTIONS))]; case 5: (_h = _j.sent(), transactionHash = _h.transactionHash, state = _h.state); _e = chai_1.expect; return [4 /*yield*/, deployedWallet.keyExist(publicKey)]; case 6: _e.apply(void 0, [_j.sent()]).to.be.false; _f = chai_1.expect; return [4 /*yield*/, deployedWallet.getKeys()]; case 7: _f.apply(void 0, [_j.sent()]).not.to.include(publicKey); _g = chai_1.expect; return [4 /*yield*/, deployedWallet.getNonce()]; case 8: _g.apply(void 0, [_j.sent()]).to.eq(2); chai_1.expect(transactionHash).to.be.properHex(64); chai_1.expect(state).to.eq('Success'); return [2 /*return*/]; } }); }); }); xit('addKeys', function () { return __awaiter(void 0, void 0, void 0, function () { var _a, transactionHash, state, _b, _c, _d, _e, _f; return __generator(this, function (_g) { switch (_g.label) { case 0: return [4 /*yield*/, waitForSuccess_1.waitForSuccess(deployedWallet.addKeys([publicKey, publicKey2], commons_1.TEST_EXECUTION_OPTIONS))]; case 1: _a = _g.sent(), transactionHash = _a.transactionHash, state = _a.state; _b = chai_1.expect; return [4 /*yield*/, deployedWallet.keyExist(publicKey)]; case 2: _b.apply(void 0, [_g.sent()]).to.be.true; _c = chai_1.expect; return [4 /*yield*/, deployedWallet.keyExist(publicKey2)]; case 3: _c.apply(void 0, [_g.sent()]).to.be.true; _d = chai_1.expect; return [4 /*yield*/, deployedWallet.getKeys()]; case 4: _d.apply(void 0, [_g.sent()]).to.include(publicKey); _e = chai_1.expect; return [4 /*yield*/, deployedWallet.getKeys()]; case 5: _e.apply(void 0, [_g.sent()]).to.include(publicKey2); _f = chai_1.expect; return [4 /*yield*/, deployedWallet.getNonce()]; case 6: _f.apply(void 0, [_g.sent()]).to.eq(1); chai_1.expect(transactionHash).to.be.properHex(64); chai_1.expect(state).to.eq('Success'); return [2 /*return*/]; } }); }); }); it('getMessageStatus', function () { return __awaiter(void 0, void 0, void 0, function () { var msg, _a, _b, _c, messageStatus, waitForTransactionHash, status; return __generator(this, function (_d) { switch (_d.label) { case 0: return [4 /*yield*/, deployedWallet.addKey(otherWallet.address, commons_1.TEST_EXECUTION_OPTIONS)]; case 1: _d.sent(); return [4 /*yield*/, deployedWallet.setRequiredSignatures(2, commons_1.TEST_EXECUTION_OPTIONS)]; case 2: _d.sent(); _a = [__assign({}, message)]; _b = { to: otherWallet.address }; return [4 /*yield*/, walletContract.nonce()]; case 3: msg = __assign.apply(void 0, _a.concat([(_b.nonce = _d.sent(), _b)])); return [4 /*yield*/, deployedWallet.execute(msg)]; case 4: _c = _d.sent(), messageStatus = _c.messageStatus, waitForTransactionHash = _c.waitForTransactionHash; return [4 /*yield*/, sdk.getMessageStatus(messageStatus.messageHash)]; case 5: status = _d.sent(); chai_1.expect(status.collectedSignatures.length).to.eq(1); return [4 /*yield*/, waitForTransactionHash()]; case 6: _d.sent(); return [2 /*return*/]; } }); }); }); describe('Execute signed message', function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { it('Should execute signed message', function () { return __awaiter(void 0, void 0, void 0, function () { var expectedBalance, waitToBeSuccess, transactionHash, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, provider.getBalance(message.to)]; case 1: expectedBalance = (_b.sent()).add(ethers_1.utils.parseEther('0.5')); return [4 /*yield*/, deployedWallet.execute(message)]; case 2: waitToBeSuccess = (_b.sent()).waitToBeSuccess; return [4 /*yield*/, waitToBeSuccess()]; case 3: transactionHash = (_b.sent()).transactionHash; chai_1.expect(transactionHash).to.match(/^[0x|0-9|a-f|A-F]{66}/); _a = chai_1.expect; return [4 /*yield*/, provider.getBalance(message.to)]; case 4: _a.apply(void 0, [_b.sent()]).to.eq(expectedBalance); return [2 /*return*/]; } }); }); }); it('Should return transaction hash and proper state', function () { return __awaiter(void 0, void 0, void 0, function () { var waitToBeSuccess, _a, transactionHash, state; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, deployedWallet.execute(message)]; case 1: waitToBeSuccess = (_b.sent()).waitToBeSuccess; return [4 /*yield*/, waitToBeSuccess()]; case 2: _a = _b.sent(), transactionHash = _a.transactionHash, state = _a.state; chai_1.expect(transactionHash).to.be.properHex(64); chai_1.expect(state).to.eq('Success'); return [2 /*return*/]; } }); }); }); it('Should return transaction hash and proper state with free transaction', function () { return __awaiter(void 0, void 0, void 0, function () { var startingBalance, refundPaidSdk, waitToBeSuccess, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, provider.getBalance(message.from)]; case 1: startingBalance = (_b.sent()); refundPaidSdk = new src_1.default(relayer.url(), provider, __assign(__assign({}, commons_1.TEST_SDK_CONFIG), { mineableFactoryTimeout: 3000, apiKey: commons_1.TEST_REFUND_PAYER.apiKey })); return [4 /*yield*/, refundPaidSdk.start()]; case 2: _b.sent(); deployedWallet = new src_1.DeployedWallet(contractAddress, ensName, privateKey, refundPaidSdk); return [4 /*yield*/, deployedWallet.execute(message)]; case 3: waitToBeSuccess = (_b.sent()).waitToBeSuccess; return [4 /*yield*/, waitToBeSuccess()]; case 4: _b.sent(); _a = chai_1.expect; return [4 /*yield*/, provider.getBalance(message.from)]; case 5: _a.apply(void 0, [_b.sent()]).to.eq(startingBalance.sub(ethers_1.utils.parseEther('0.5'))); refundPaidSdk.stop(); return [2 /*return*/]; } }); }); }); it('when not enough tokens ', function () { return __awaiter(void 0, void 0, void 0, function () { var mockToken; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, commons_1.deployContract(wallet, testutils_1.mockContracts.MockToken)]; case 1: mockToken = _a.sent(); return [4 /*yield*/, mockToken.transfer(walletContract.address, 1)]; case 2: _a.sent(); message = __assign(__assign({}, message), { gasToken: mockToken.address }); return [4 /*yield*/, chai_1.expect(deployedWallet.execute(message)).to.be.eventually.rejectedWith('Not enough tokens')]; case 3: _a.sent(); return [2 /*return*/]; } }); }); }); it('when not enough ether', function () { return __awaiter(void 0, void 0, void 0, function () { var amountToTransfer; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, otherWallet.getBalance()]; case 1: amountToTransfer = (_a.sent()).add(ethers_1.utils.parseEther('0.5')); return [4 /*yield*/, chai_1.expect(deployedWallet.execute(__assign(__assign({}, message), { to: otherWallet.address, value: amountToTransfer }))).rejectedWith('Not enough tokens')]; case 2: _a.sent(); return [2 /*return*/]; } }); }); }); it('when not enough gas', function () { return __awaiter(void 0, void 0, void 0, function () { var baseGas, notEnoughGasLimit; return __generator(this, function (_a) { switch (_a.label) { case 0: baseGas = 88720; notEnoughGasLimit = 100; message = __assign(__assign({}, message), { gasLimit: baseGas + notEnoughGasLimit }); return [4 /*yield*/, chai_1.expect(deployedWallet.execute(message)).to.be.eventually.rejectedWith("Insufficient Gas. gasLimit should be greater than " + commons_1.GAS_BASE)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }); it('Throws when the gas limit is above the relayers maxGasLimit', function () { return __awaiter(void 0, void 0, void 0, function () { var secondSdk, secondDeployedWallet; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, loadFixture(basicSDK_1.default)]; case 1: secondSdk = (_a.sent()).sdk; message.gasLimit = secondSdk.getRelayerConfig().maxGasLimit + 1; secondDeployedWallet = new src_1.DeployedWallet(contractAddress, '', privateKey, secondSdk); return [4 /*yield*/, chai_1.expect(secondDeployedWallet.execute(message)).to.be.eventually .rejectedWith('Invalid gas limit. 500001 provided, when relayer\'s max gas limit is 500000')]; case 2: _a.sent(); return [2 /*return*/]; } }); }); }); it('Passes when the gas limit is equal to the relayers maxGasLimit', function () { return __awaiter(void 0, void 0, void 0, function () { var secondSdk, secondDeployedWallet, waitToBeSuccess; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, loadFixture(basicSDK_1.default)]; case 1: secondSdk = (_a.sent()).sdk; secondDeployedWallet = new src_1.DeployedWallet(contractAddress, '', privateKey, secondSdk); return [4 /*yield*/, secondDeployedWallet.execute(message)]; case 2: waitToBeSuccess = (_a.sent()).waitToBeSuccess; return [4 /*yield*/, chai_1.expect(waitToBeSuccess()).to.be.eventually.fulfilled]; case 3: _a.sent(); return [2 /*return*/]; } }); }); }); return [2 /*return*/]; }); }); }); afterEach(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, relayer.clearDatabase()]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }); after(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, relayer.stop()]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }); }); //# sourceMappingURL=DeployedWallet.int.test.js.map