@flarenetwork/flare-stake-tool
Version:
Utilities for staking on the Flare network
173 lines • 6.57 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendToForDefi = sendToForDefi;
exports.getSignature = getSignature;
exports.getVaultPublickey = getVaultPublickey;
const fs_1 = require("fs");
const crypto_1 = __importDefault(require("crypto"));
const utils_1 = require("../utils");
const utils_2 = require("./utils");
const forDefi_1 = require("../constants/forDefi");
/**
* @description - Send signature to forDefi
* @param unsignedTxidFile - path to the file
* @param ctxFile - ctx file
* @param evmTx - true if it is a regular EVM transaction
* @returns
*/
async function sendToForDefi(unsignedTxidFile, ctxFile, evmTx = false) {
const accessToken = (0, fs_1.readFileSync)("./token", "utf8");
const file = (0, fs_1.readFileSync)(ctxFile, "utf8");
const ctx = JSON.parse(file);
// check if ctx file is valid
if (!ctx.vaultId) {
throw Error("vaultId not found in context");
}
const vault_id = ctx.vaultId;
// vaultPublicKey should match public key in context file
let vaultPublicKey = await getVaultPublickey(vault_id);
if ((0, utils_1.unPrefix0x)(ctx.publicKey) != vaultPublicKey) {
throw Error("public key does not match the vault");
}
let hash;
let txidObj;
if (!evmTx) {
txidObj = (0, utils_1.readUnsignedTxJson)(unsignedTxidFile);
hash = txidObj.signatureRequests[0].message;
}
else {
txidObj = (0, utils_2.readUnsignedEvmTx)(unsignedTxidFile);
hash = txidObj.message;
}
let hashBase64 = Buffer.from(hash, "hex").toString("base64");
const requestJson = {
vault_id: vault_id,
signer_type: "api_signer",
type: "black_box_signature",
details: {
format: "hash_binary",
hash_binary: hashBase64,
},
};
const requestBody = JSON.stringify(requestJson);
const path = "/api/v1/transactions";
const timestamp = new Date().getTime();
const payload = `${path}|${timestamp}|${requestBody}`;
const privateKeyFile = "./private.pem";
const secretPem = (0, fs_1.readFileSync)(privateKeyFile, "utf8");
const privateKey = crypto_1.default.createPrivateKey(secretPem);
const sign = crypto_1.default.createSign("SHA256").update(payload, "utf8").end();
const signature1 = sign.sign(privateKey, "base64");
const response = await fetch(`https://${forDefi_1.gatewayHost}${path}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
"X-Timestamp": timestamp.toString(),
"X-Signature": signature1,
},
body: requestBody,
});
const responseJson = await response.json();
let txId = responseJson.id;
// write tx id (to later fetch the signature)
txidObj.forDefiTxId = txId;
(0, fs_1.writeFileSync)(`${forDefi_1.forDefiDirectory}/${forDefi_1.forDefiUnsignedTxnDirectory}/${unsignedTxidFile}.unsignedTx.json`, JSON.stringify(txidObj), "utf8");
return txId;
}
/**
* @description - gets the signature from forDefi
* @param unsignedTxidFile - unsigned transaction file
* @param evmTx - true if it is a regular EVM transaction
* @returns signature
*/
async function getSignature(unsignedTxidFile, evmTx = false) {
const path = "/api/v1/transactions";
const accessToken = (0, fs_1.readFileSync)("./token", "utf8");
let txidObj;
let signedTxObj;
if (!evmTx) {
txidObj = (0, utils_1.readUnsignedTxJson)(unsignedTxidFile);
signedTxObj = txidObj;
}
else {
txidObj = (0, utils_2.readUnsignedEvmTx)(unsignedTxidFile);
signedTxObj = txidObj;
}
let id = txidObj.forDefiTxId;
let responseSignature;
responseSignature = await fetch(`https://${forDefi_1.gatewayHost}${path}/${id}`, {
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const responseJson = await responseSignature.json();
let signatureHex;
try {
signatureHex = Buffer.from(responseJson.signatures[0].data, "base64").toString("hex");
}
catch (e) {
throw Error("Transaction is not signed yet? " + e);
}
signedTxObj.signature = signatureHex;
(0, fs_1.mkdirSync)(`${forDefi_1.forDefiDirectory}/${forDefi_1.forDefiSignedTxnDirectory}`, {
recursive: true,
});
(0, fs_1.writeFileSync)(`${forDefi_1.forDefiDirectory}/${forDefi_1.forDefiSignedTxnDirectory}/${unsignedTxidFile}.signedTx.json`, JSON.stringify(signedTxObj), "utf8");
return signatureHex;
}
/**
* @description Gets the vault public key
* @param vaultId - the vault id
* @returns returns vault public key
*/
async function getVaultPublickey(vaultId) {
const path = "/api/v1/vaults";
const accessToken = (0, fs_1.readFileSync)("./token", "utf8");
let response = await fetch(`https://${forDefi_1.gatewayHost}${path}/${vaultId}`, {
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const responseJson = await response.json();
let pubKey = responseJson.public_key_compressed;
// vault invalid or wrong environment (token) is used
if (!pubKey) {
throw new Error('public_key_compressed not found in vault response');
}
let pubKeyHex = Buffer.from(pubKey, "base64").toString("hex");
return pubKeyHex;
}
async function createVault(vaultName, tokenPath) {
const accessToken = (0, fs_1.readFileSync)(tokenPath, "utf8");
const requestJson = {
type: "black_box",
key_type: "ecdsa_secp256k1",
name: vaultName,
};
const requestBody = JSON.stringify(requestJson);
const path = "/api/v1/vaults";
let response = await fetch(`https://${forDefi_1.gatewayHost}${path}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: requestBody,
});
const responseJson = await response.json();
console.log(responseJson);
let pubKey = responseJson.public_key_compressed;
if (!pubKey) {
throw new Error('public_key_compressed not found in vault response');
}
let pubKeyHex = Buffer.from(pubKey, "base64").toString("hex");
console.log(pubKeyHex);
return responseJson["id"];
}
//# sourceMappingURL=transaction.js.map