@kilnfi/sdk
Version:
JavaScript sdk for Kiln API
822 lines • 29.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FireblocksService = void 0;
const ts_sdk_1 = require("@fireblocks/ts-sdk");
const fireblocks_signer_js_1 = require("./fireblocks_signer.js");
const ERRORS = {
MISSING_SIGNATURE: 'An error occurred while attempting to retrieve the signature from Fireblocks.',
FAILED_TO_PREPARE: 'An error occurred while attempting to add the signature to the transaction.',
};
class FireblocksService {
constructor(client) {
Object.defineProperty(this, "client", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.client = client;
}
getSdk(integration) {
if (integration.instance) {
return integration.instance;
}
return new ts_sdk_1.Fireblocks(integration.config);
}
getSigner(integration) {
const sdk = this.getSdk(integration);
return new fireblocks_signer_js_1.FireblocksSigner(sdk, integration.vaultId);
}
async getPubkey(integration, assetId) {
const fbSdk = this.getSdk(integration);
const data = await fbSdk.vaults.getPublicKeyInfoForAddress({
assetId: assetId,
vaultAccountId: integration.vaultId,
change: 0,
addressIndex: 0,
compressed: true,
});
return data.data;
}
async getAssets(integration) {
const fbSdk = this.getSdk(integration);
return (await fbSdk.blockchainsAssets.getSupportedAssets()).data;
}
async signSolTx(integration, tx, assetId, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'SOL tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, assetId, fbNote);
const signatures = fbTx.signedMessages
?.filter((signedMessage) => signedMessage.derivationPath?.[3] === 0)
.map((signedMessage) => signedMessage.signature?.fullSig)
.filter((s) => s !== undefined);
if (!signatures) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/sol/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
signatures: signatures,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signAdaTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
},
{
content: tx.unsigned_tx_hash,
bip44change: 2,
},
],
},
inputsSelection: {
inputsToSpend: tx.inputs,
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'ADA tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'ADA', fbNote);
const signedMessages = fbTx.signedMessages?.map((message) => ({
pubkey: message.publicKey,
signature: message.signature?.fullSig,
}));
if (!signedMessages) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/ada/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
signed_messages: signedMessages,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signAtomTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'ATOM tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'ATOM_COS', fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/atom/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signDydxTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'DYDX tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'DYDX_DYDX', fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/dydx/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signFetTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
derivationPath: [44, 118, Number(integration.vaultId), 0, 0],
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
algorithm: ts_sdk_1.SignedMessageAlgorithmEnum.EcdsaSecp256K1,
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'FET tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, undefined, fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/fet/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signOmTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
derivationPath: [44, 118, Number(integration.vaultId), 0, 0],
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
algorithm: ts_sdk_1.SignedMessageAlgorithmEnum.EcdsaSecp256K1,
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'OM tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, undefined, fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/om/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signInjTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'INJ tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'INJ_INJ', fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/inj/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signKavaTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
derivationPath: [44, 459, Number(integration.vaultId), 0, 0],
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
algorithm: ts_sdk_1.SignedMessageAlgorithmEnum.EcdsaSecp256K1,
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'KAVA tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, undefined, fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/kava/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signCroTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
derivationPath: [44, 394, Number(integration.vaultId), 0, 0],
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
algorithm: ts_sdk_1.SignedMessageAlgorithmEnum.EcdsaSecp256K1,
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'CRO tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, undefined, fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/cro/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signNobleTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
derivationPath: [44, 118, Number(integration.vaultId), 0, 0],
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
algorithm: ts_sdk_1.SignedMessageAlgorithmEnum.EcdsaSecp256K1,
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'NOBLE tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, undefined, fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/noble/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signOsmoTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'OSMO tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'OSMO', fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/osmo/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signTiaTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'TIA tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'CELESTIA', fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/tia/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signZetaTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
derivationPath: [44, 118, Number(integration.vaultId), 0, 0],
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
algorithm: ts_sdk_1.SignedMessageAlgorithmEnum.EcdsaSecp256K1,
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'ZETA tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, undefined, fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/zeta/transaction/prepare', {
body: {
pubkey: tx.pubkey,
tx_body: tx.tx_body,
tx_auth_info: tx.tx_auth_info,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signDotTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_payload.substring(2),
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'DOT tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'DOT', fbNote);
if (!fbTx.signedMessages?.[0]?.signature?.fullSig) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const signature = `0x00${fbTx.signedMessages?.[0]?.signature.fullSig}`;
const preparedTx = await this.client.POST('/dot/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signKsmTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_payload.substring(2),
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'KSM tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'KSM', fbNote);
if (!fbTx.signedMessages?.[0]?.signature?.fullSig) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const signature = `0x00${fbTx.signedMessages?.[0]?.signature.fullSig}`;
const preparedTx = await this.client.POST('/ksm/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signEthTx(integration, tx, assetId, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'KECCAK256',
},
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'ETH tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, assetId, fbNote);
const signature = fbTx?.signedMessages?.[0]?.signature;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/eth/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
r: `0x${signature.r}`,
s: `0x${signature.s}`,
v: signature.v ?? 0,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signAndBroadcastEthTx(integration, tx, assetId, fireblocksDestinationId, note) {
const payload = {
contractCallData: tx.contract_call_data,
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'ETH tx from @kilnfi/sdk';
return await fbSigner.signAndBroadcastWith(payload, assetId, tx, fireblocksDestinationId, true, fbNote);
}
async signPolTx(integration, tx, assetId, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'KECCAK256',
},
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'POL tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, assetId, fbNote);
const signature = fbTx?.signedMessages?.[0]?.signature;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/pol/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
r: `0x${signature.r}`,
s: `0x${signature.s}`,
v: signature.v ?? 0,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signAndBroadcastPolTx(integration, tx, assetId, fireblocksDestinationId, note) {
const payload = {
contractCallData: tx.contract_call_data,
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'POL tx from @kilnfi/sdk';
return await fbSigner.signAndBroadcastWith(payload, assetId, tx, fireblocksDestinationId, true, fbNote);
}
async signTonTx(integration, tx, assetId, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'TON tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, assetId, fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/ton/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
signature: signature,
from: tx.from,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signXtzTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'XTZ tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'XTZ', fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/xtz/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signNearTx(integration, tx, assetId, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_hash,
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'NEAR tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, assetId, fbNote);
const signature = fbTx.signedMessages?.[0]?.signature?.fullSig;
if (!signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const preparedTx = await this.client.POST('/near/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
async signTrxTx(integration, tx, note) {
const payload = {
rawMessageData: {
messages: [
{
content: tx.unsigned_tx_id,
preHash: {
content: tx.unsigned_tx_serialized,
hashAlgorithm: 'SHA256',
},
},
],
},
};
const fbSigner = this.getSigner(integration);
const fbNote = note ? note : 'TRX tx from @kilnfi/sdk';
const fbTx = await fbSigner.sign(payload, 'TRX', fbNote);
if (!fbTx.signedMessages?.[0]?.signature) {
throw new Error(ERRORS.MISSING_SIGNATURE);
}
const signature = `${fbTx.signedMessages[0].signature.fullSig}0${fbTx.signedMessages[0].signature.v}`;
const preparedTx = await this.client.POST('/trx/transaction/prepare', {
body: {
unsigned_tx_serialized: tx.unsigned_tx_serialized,
signature: signature,
},
});
if (preparedTx.error) {
throw new Error(ERRORS.FAILED_TO_PREPARE);
}
return {
signed_tx: preparedTx.data,
fireblocks_tx: fbTx,
};
}
}
exports.FireblocksService = FireblocksService;
//# sourceMappingURL=fireblocks.js.map