@kilnfi/sdk
Version:
JavaScript sdk for Kiln API
126 lines • 4.89 kB
JavaScript
import { formatEther, formatUnits } from 'viem';
export class FireblocksSigner {
constructor(fireblocks, vaultId) {
Object.defineProperty(this, "fireblocks", {
enumerable: true,
configurable: true,
writable: true,
value: fireblocks
});
Object.defineProperty(this, "vaultId", {
enumerable: true,
configurable: true,
writable: true,
value: vaultId
});
}
/**
* Wait for given transaction to be completed
* @param fbTx fireblocks transaction
*/
async waitForTxCompletion(fbTx) {
let tx = fbTx;
while (tx.status !== 'COMPLETED') {
// see https://developers.fireblocks.com/reference/transaction-substatuses#failed-substatuses
const ERRORS = {
BLOCKED: 'The transaction has been blocked by the TAP security policy.',
FAILED: 'The transaction has failed.',
CANCELLED: 'The transaction has been cancelled.',
REJECTED: 'The transaction has been rejected, make sure that the TAP security policy is not blocking the transaction.',
};
if (tx.status && tx.status in ERRORS) {
throw Error(ERRORS[tx.status]);
}
// wait a bit before polling again
await new Promise((r) => setTimeout(r, 500));
tx = (await this.fireblocks.transactions.getTransaction({ txId: fbTx.id })).data;
}
return tx;
}
/**
* Sign a transaction with fireblocks using Fireblocks raw message signing feature
* @param payloadToSign transaction data in hexadecimal
* @param assetId fireblocks asset id
* @param note optional fireblocks custom note
*/
async sign(payloadToSign, assetId, note = '') {
const assetArgs = assetId
? {
assetId,
source: {
type: 'VAULT_ACCOUNT',
id: this.vaultId,
},
}
: undefined;
const tx = {
...assetArgs,
operation: 'RAW',
note,
extraParameters: payloadToSign,
};
const fbTx = (await this.fireblocks.transactions.createTransaction({ transactionRequest: tx })).data;
return await this.waitForTxCompletion(fbTx);
}
/**
* Sign an EIP-712 Ethereum typed message with fireblocks
* @param eip712message eip712message to sign
* @param assetId fireblocks asset id
* @param note optional fireblocks custom note
*/
async signTypedMessage(eip712message, assetId, note = '') {
const tx = {
assetId: assetId,
operation: 'TYPED_MESSAGE',
source: {
type: 'VAULT_ACCOUNT',
id: this.vaultId,
},
note,
extraParameters: {
rawMessageData: {
messages: [
{
content: eip712message,
type: 'EIP712',
},
],
},
},
};
const fbTx = (await this.fireblocks.transactions.createTransaction({ transactionRequest: tx })).data;
return await this.waitForTxCompletion(fbTx);
}
/**
* Sign and broadcast a transaction with fireblocks using Fireblocks contract call feature
* @param payloadToSign transaction data in hexadecimal
* @param assetId fireblocks asset id
* @param note optional fireblocks custom note
* @param tx Ethereum transaction
* @param destinationId Fireblocks destination id, this corresponds to the Fireblocks whitelisted contract address id
* @param sendAmount send the amount in tx to smart contract
*/
async signAndBroadcastWith(payloadToSign, assetId, tx, destinationId, sendAmount = true, note = '') {
const txArgs = {
assetId: assetId,
operation: 'CONTRACT_CALL',
source: {
type: 'VAULT_ACCOUNT',
id: this.vaultId,
},
destination: {
type: 'EXTERNAL_WALLET',
id: destinationId,
},
amount: tx.amount_wei && sendAmount ? formatEther(BigInt(tx.amount_wei), 'wei') : '0',
note,
extraParameters: payloadToSign,
gasLimit: tx.gas_limit,
priorityFee: formatUnits(BigInt(tx.max_priority_fee_per_gas_wei), 9),
maxFee: formatUnits(BigInt(tx.max_fee_per_gas_wei), 9),
};
const fbTx = (await this.fireblocks.transactions.createTransaction({ transactionRequest: txArgs })).data;
return await this.waitForTxCompletion(fbTx);
}
}
//# sourceMappingURL=fireblocks_signer.js.map