@firefly-exchange/library-sui
Version:
Sui library housing helper methods, classes to interact with Bluefin protocol(s) deployed on Sui
98 lines (97 loc) • 4.09 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Signature = void 0;
const utils_1 = require("@noble/hashes/utils");
const types_1 = require("../../types");
const library_1 = require("../../library");
const bcs_1 = require("@mysten/sui/bcs");
const blv_1 = require("../../blv");
const verify_1 = require("@mysten/sui/verify");
const helpers_1 = require("../../helpers");
const classes_1 = require("../../classes");
const blake2b_1 = require("@noble/hashes/blake2b");
class Signature {
/**
* Given a hex data string computes its blake2b hash and returns the hex
* @param hexData a hex string
* @returns hex sha256 hash
*/
static hash(hexData) {
return (0, utils_1.bytesToHex)((0, blake2b_1.blake2b)((0, utils_1.hexToBytes)(hexData), { dkLen: 32 }));
}
/**
* Signs the provided request object
* @param signer The signer object
* @param data A JSON request payload
* @returns A base64 representation of signature containing:
* 1. scheme (1 byte),
* 2. signature (64 bytes)
* 3. public key (32/33 bytes)
*/
static async signRequest(signer, msgBytes) {
const { signature } = await signer.signPersonalMessage(msgBytes);
return signature;
}
/**
* Validates if the signature is for the provided quote
* @param data The JSON request data that was signed to create the signature
* @param signature The base64 signature containing wallet scheme + signature + public key
* @param signer The expected address of the signer
* @returns True if the signature is created on the given quote and belongs to provided `signer`
*/
static async verifyRequestSignature(data, signature, signer) {
try {
const msgBytes = Signature.marshalDataToMsgBytes(data);
const pk = await (0, verify_1.verifyPersonalMessageSignature)(msgBytes, signature);
return pk.toSuiAddress() == signer;
}
catch (e) {
console.log(e);
return false;
}
}
/**
* Verifies the given payload/signature on-chain
* @param serializedData The BCS serialized data of the payload that was signed
* @param signature The signature created
* @param type The payload/request type
* @param expectedSigner The address of the expected signer
* @param chain chain details including the pkg id and the sui client
* @param stringify
* @returns True if the signature is verified on-chain
*/
static async verifyRequestSignatureOnChain(serializedData, signature, type, expectedSigner, chain, verbose = false) {
const txb = new types_1.TransactionBlock();
txb.moveCall({
arguments: [
txb.pure.vector("u8", Array.from((0, library_1.hexStrToUint8)(serializedData))),
txb.pure.vector("u8", Array.from((0, blv_1.fromBase64)(signature))),
txb.pure.string(type)
],
target: `${chain.pkg}::signature::verify`
});
const result = await chain.client.devInspectTransactionBlock({
transactionBlock: txb,
sender: helpers_1.TEST_WALLETS[0].address
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const status = classes_1.Transaction.getStatus(result);
if (status == "success") {
const signer = bcs_1.bcs.Address.parse(Uint8Array.from(result.results[0].returnValues[0][0]));
return expectedSigner == signer;
}
else {
if (verbose) {
console.log(`Signature verification failed: ${JSON.stringify(result)}`);
console.log(`\nError code: ${classes_1.Transaction.getErrorCode(result)}`);
}
return false;
}
}
static marshalDataToMsgBytes(data) {
return typeof data === "string"
? (0, library_1.hexStrToUint8)(data)
: new TextEncoder().encode(JSON.stringify(data, null, 2));
}
}
exports.Signature = Signature;
;