@desig/web3
Version:
Desig: The Blockchain-Agnostic Multisig Solution
150 lines • 8.14 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Proposal = void 0;
const core_1 = require("@desig/core");
const sha3_1 = require("@noble/hashes/sha3");
const utils_1 = require("@noble/hashes/utils");
const ec = __importStar(require("@noble/secp256k1"));
const ed = __importStar(require("@noble/ed25519"));
const bs58_1 = require("bs58");
const connection_1 = require("./connection");
const supported_chains_1 = require("@desig/supported-chains");
class Proposal extends connection_1.Connection {
constructor(cluster, privkey, keypair) {
super(cluster, (0, bs58_1.decode)(privkey), keypair);
this.watch = (callback) => {
const multisigId = (0, bs58_1.encode)(this.keypair.masterkey);
const unwatch = this.on(connection_1.EventStreaming.approval, multisigId, callback);
return unwatch;
};
this.getProposals = (chainId, { size = 10, after } = {}) => __awaiter(this, void 0, void 0, function* () {
const { data } = yield this.connection.get('/proposal', {
params: {
multisigId: (0, bs58_1.encode)(this.keypair.masterkey),
chainId,
size,
after,
},
});
return data;
});
this.getProposal = (proposalId) => __awaiter(this, void 0, void 0, function* () {
const { data } = yield this.connection.get(`/proposal/${proposalId}`);
return data;
});
this.getApproval = (approvalId) => __awaiter(this, void 0, void 0, function* () {
const { data } = yield this.connection.get(`/approval/${approvalId}`);
return data;
});
this.initializeProposal = ({ raw, msg, chainId, ttl, }) => __awaiter(this, void 0, void 0, function* () {
const payload = {
multisigId: (0, bs58_1.encode)(this.keypair.masterkey),
msg: (0, bs58_1.encode)(msg),
raw: (0, bs58_1.encode)(raw),
chainId,
};
if (ttl)
payload.ttl = ttl;
const Authorization = yield this.getAuthorization(payload);
const { data } = yield this.connection.post('/proposal', payload, {
headers: { Authorization, 'X-Desig-Curve': this.keypair.curve },
});
return data;
});
this.approveProposal = (proposalId) => __awaiter(this, void 0, void 0, function* () {
const signature = yield (() => {
switch (this.keypair.curve) {
case supported_chains_1.Curve.ed25519:
return this.approveEd25519Proposal(proposalId);
case supported_chains_1.Curve.secp256k1:
return this.approveSecp256k1Proposal(proposalId);
default:
throw new Error('Unsupported elliptic curve.');
}
})();
const approvalId = Proposal.deriveApprovalId(proposalId, this.index);
const payload = { signature };
const Authorization = yield this.getAuthorization(payload);
const { data } = yield this.connection.patch(`/approval/${approvalId}`, payload, { headers: { Authorization } });
return data;
});
this.approveEd25519Proposal = (proposalId) => __awaiter(this, void 0, void 0, function* () {
const { msg, approvals, R } = yield this.getProposal(proposalId);
const { randomness } = approvals.find(({ signer: { id } }) => id === (0, bs58_1.encode)(this.keypair.index));
const elgamal = new core_1.ElGamal();
const r = elgamal.decrypt((0, bs58_1.decode)(randomness), this.privkey);
const signature = core_1.EdTSS.sign((0, bs58_1.decode)(msg), (0, bs58_1.decode)(R), this.keypair.masterkey, r, this.keypair.share);
return (0, bs58_1.encode)(signature);
});
this.approveSecp256k1Proposal = (proposalId) => __awaiter(this, void 0, void 0, function* () {
const { msg, approvals, R } = yield this.getProposal(proposalId);
const { randomness } = approvals.find(({ signer: { id } }) => id === (0, bs58_1.encode)(this.keypair.index));
const elgamal = new core_1.ElGamal();
const x = elgamal.decrypt((0, bs58_1.decode)(randomness), this.privkey);
const signature = core_1.ECTSS.sign((0, bs58_1.decode)(msg), (0, bs58_1.decode)(R), x, this.keypair.share);
return (0, bs58_1.encode)(signature);
});
this.updateTxHash = (proposalId, txHash) => __awaiter(this, void 0, void 0, function* () {
const payload = { txHash };
const Authorization = yield this.getAuthorization(payload);
const { data } = yield this.connection.patch(`/proposal/${proposalId}`, payload, { headers: { Authorization } });
return data;
});
this.finalizeSignature = (proposalId) => __awaiter(this, void 0, void 0, function* () {
const { data: { sig, recv }, } = yield this.connection.get(`/proposal/${proposalId}/signature`, {
headers: { 'X-Desig-Curve': this.keypair.curve },
});
return { sig: (0, bs58_1.decode)(sig), recv };
});
this.verifySignature = (id, signature) => __awaiter(this, void 0, void 0, function* () {
const { msg } = yield this.getProposal(id);
if (this.keypair.curve === supported_chains_1.Curve.ed25519)
return ed.verify(signature, (0, bs58_1.decode)(msg), this.keypair.masterkey);
if (this.keypair.curve === supported_chains_1.Curve.secp256k1)
return ec.verify(signature, (0, bs58_1.decode)(msg), this.keypair.masterkey);
throw new Error('Invalid crypto system');
});
}
static deriveApprovalId(proposalId, signerId) {
const seed = (0, utils_1.concatBytes)((0, bs58_1.decode)(proposalId), (0, bs58_1.decode)(signerId));
return (0, bs58_1.encode)((0, sha3_1.keccak_256)(seed));
}
}
exports.Proposal = Proposal;
Proposal.deriveProposalId = (multisigId, msg) => {
const seed = (0, utils_1.concatBytes)((0, bs58_1.decode)(multisigId), msg);
return (0, bs58_1.encode)((0, sha3_1.keccak_256)(seed));
};
//# sourceMappingURL=proposal.js.map