@firefly-exchange/library-sui
Version:
Sui library housing helper methods, classes to interact with Bluefin protocol(s) deployed on Sui
113 lines (112 loc) • 5.53 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Signer = exports.SignatureStruct = exports.SignaturePayloadStruct = void 0;
const bcs_1 = require("@mysten/sui/bcs");
const sha256_1 = require("@noble/hashes/sha256");
const ed25519_1 = require("@noble/curves/ed25519");
const ed25519_2 = require("@mysten/sui/keypairs/ed25519");
const secp256k1_1 = require("@mysten/sui/keypairs/secp256k1");
const utils_1 = require("./utils");
const utils_2 = require("../utils");
exports.SignaturePayloadStruct = bcs_1.bcs.struct("SignaturePayloadStruct", {
target: bcs_1.bcs.Address, // ID or the address of rewards pool or the vault
receiver: bcs_1.bcs.Address, // the address of reward's receiver or the person eligible for claiming funds
amount: bcs_1.bcs.u64(), // quantity/amount of rewards - MUST be in 9 DECIMAL PLACES or amount that can be claimed (must be in 6 decimals)
expiry: bcs_1.bcs.u64(), // timestamp till which signature is valid
nonce: bcs_1.bcs.u128(), // a random number
type: bcs_1.bcs.u8() // the signature payload type. Could be 1 (Rewards Claim) or 2 (Funds Claim)
});
/// The signature data that is to be send on-chain
exports.SignatureStruct = bcs_1.bcs.struct("SignatureStruct", {
sig: bcs_1.bcs.vector(bcs_1.bcs.u8()), // the signature generated by the signer using `SignaturePayload`
pk: bcs_1.bcs.vector(bcs_1.bcs.u8()), // public key of the signer
scheme: bcs_1.bcs.u8() // 0 if the wallet type is Secp 1 otherwise (ED25519)
});
class Signer {
/**
* Provided a payload for generating reward or funds claim signature, serializes it and returns its sha 256 hash to be signed
* @param data signature payload to be signed
* @returns sha256 hash of serialized data payload provided as input
*/
static getPayloadHash(data) {
// take sha256 hash of the serialized data
return (0, sha256_1.sha256)(exports.SignaturePayloadStruct.serialize(data).toBytes());
}
/**
* Uses the provided signer key pair to generate signature for the users to use and claim rewards or funds
* @param signer KeyPair of the signer. The signer must be the operator/controller of the rewards pool or claims_manager of the vault
* @param payload The payload to be signed
* @returns serialized signature that can be provided to user to perform on-chain `claim_rewards` call.
*/
static async sign(signer, payload) {
// compute hash of the payload
const hash = Signer.getPayloadHash(payload);
// create signature
const sig = await signer.sign(hash);
// create signature payload
const signature = {
sig,
pk: signer.getPublicKey().toRawBytes(),
scheme: signer.getKeyScheme() == "Secp256k1" ? 0 : 1
};
// serialize and return the hex of the signature
return exports.SignatureStruct.serialize(signature).toHex();
}
/**
* Uses the provided signer key pair to generate signature for the users to use and claim rewards or funds
* @param signer KeyPair of the signer. The signer must be the operator/controller of the rewards pool or claims_manager of the vault
* @param payload The payload to be signed
* @returns serialized signature that can be provided to user to perform on-chain `claim_rewards` call.
*/
static async signUsingKMS(signer, payload) {
// compute hash of the payload
const hash = Signer.getPayloadHash(payload);
// create signature
const sig = await signer.sign(hash);
// create signature payload
const signature = {
sig,
pk: signer.getPublicKey().toRawBytes(),
scheme: signer.getKeyScheme() == "Secp256k1" ? 0 : 1
};
// serialize and return the hex of the signature
return exports.SignatureStruct.serialize(signature).toHex();
}
/**
* Given an array of data bytes and serialized signature returns true if the signature is valid
* @param signature bcs serialized signature (returned by `Signer.sign` method)
* @param data data bytes array
* @param payload
* @returns True if signature is valid
*/
static verify(signature, payload) {
// de-serialize the signature content
const deSig = exports.SignatureStruct.parse((0, utils_1.hexToUint8Array)(signature));
// get hex of the signature
const hexSig = Buffer.from(deSig.sig).toString("hex");
// extract signer's public key
const pk = Uint8Array.from(deSig.pk);
// get the payload hash that was signed
const data = Signer.getPayloadHash(payload);
// todo add more types!
switch (deSig.scheme) {
case 0: // Secp256K1
return (0, utils_2.verifySECP)(hexSig, (0, sha256_1.sha256)(data), pk);
case 1: // ED25519
return ed25519_1.ed25519.verify(hexSig, data, pk);
default:
throw "Signature is created using invalid signer type";
}
}
static getSuiAddressFromPublicKey(publicKey, scheme) {
switch (scheme) {
case "ED25519":
return new ed25519_2.Ed25519PublicKey(publicKey).toSuiAddress();
case "Secp256k1":
return new secp256k1_1.Secp256k1PublicKey(publicKey).toSuiAddress();
default:
throw new Error("Provided scheme is invalid");
}
}
}
exports.Signer = Signer;
;