@ledgerhq/coin-hedera
Version:
Ledger Hedera Coin integration
187 lines • 8.73 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.craftTransaction = craftTransaction;
const sdk_1 = require("@hashgraph/sdk");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const invariant_1 = __importDefault(require("invariant"));
const constants_1 = require("../constants");
const rpc_1 = require("../network/rpc");
const utils_1 = require("../network/utils");
const utils_2 = require("./utils");
async function buildUnsignedCoinTransaction({ account, transaction, }) {
const accountId = account.accountId;
const hbarAmount = sdk_1.Hbar.fromTinybars(transaction.amount);
const tx = new sdk_1.TransferTransaction()
.setTransactionValidDuration(constants_1.TRANSACTION_VALID_DURATION_SECONDS)
.setTransactionId(transaction.transactionId)
.setTransactionMemo(transaction.memo)
.addHbarTransfer(accountId, hbarAmount.negated())
.addHbarTransfer(transaction.recipient, hbarAmount);
if (transaction.maxFee) {
tx.setMaxTransactionFee(sdk_1.Hbar.fromTinybars(transaction.maxFee.toNumber()));
}
return tx.freezeWith(await rpc_1.rpcClient.getInstance());
}
async function buildUnsignedHTSTokenTransaction({ account, transaction, }) {
const accountId = account.accountId;
const tokenId = transaction.tokenAddress;
const tx = new sdk_1.TransferTransaction()
.setTransactionValidDuration(constants_1.TRANSACTION_VALID_DURATION_SECONDS)
.setTransactionId(transaction.transactionId)
.setTransactionMemo(transaction.memo)
.addTokenTransfer(tokenId, accountId, transaction.amount.negated().toNumber())
.addTokenTransfer(tokenId, transaction.recipient, transaction.amount.toNumber());
if (transaction.maxFee) {
tx.setMaxTransactionFee(sdk_1.Hbar.fromTinybars(transaction.maxFee.toNumber()));
}
return tx.freezeWith(await rpc_1.rpcClient.getInstance());
}
async function buildUnsignedERC20TokenTransaction({ transaction, }) {
const contractId = sdk_1.ContractId.fromEvmAddress(0, 0, transaction.tokenAddress);
const recipientEvmAddress = await (0, utils_2.toEVMAddress)(transaction.recipient);
(0, invariant_1.default)(recipientEvmAddress, `hedera: EVM address is missing ${transaction.recipient}`);
const gas = transaction.gasLimit.toNumber();
// create function parameters for ERC20 transfer function
// transfer(address to, uint256 amount) returns (bool)
const functionParameters = new sdk_1.ContractFunctionParameters()
.addAddress(recipientEvmAddress)
.addUint256(transaction.amount.toNumber());
const tx = new sdk_1.ContractExecuteTransaction()
.setTransactionValidDuration(constants_1.TRANSACTION_VALID_DURATION_SECONDS)
.setTransactionId(transaction.transactionId)
.setTransactionMemo(transaction.memo ?? "")
.setContractId(contractId)
.setGas(gas)
.setFunction("transfer", functionParameters);
if (transaction.maxFee) {
tx.setMaxTransactionFee(sdk_1.Hbar.fromTinybars(transaction.maxFee.toNumber()));
}
return tx.freezeWith(await rpc_1.rpcClient.getInstance());
}
async function buildTokenAssociateTransaction({ account, transaction, }) {
const accountId = account.accountId;
const tx = new sdk_1.TokenAssociateTransaction()
.setTransactionValidDuration(constants_1.TRANSACTION_VALID_DURATION_SECONDS)
.setTransactionId(transaction.transactionId)
.setTransactionMemo(transaction.memo)
.setAccountId(accountId)
.setTokenIds([transaction.tokenId]);
if (transaction.maxFee) {
tx.setMaxTransactionFee(sdk_1.Hbar.fromTinybars(transaction.maxFee.toNumber()));
}
return tx.freezeWith(await rpc_1.rpcClient.getInstance());
}
async function buildUnsignedUpdateAccountTransaction({ account, transaction, }) {
const accountId = account.accountId;
const tx = new sdk_1.AccountUpdateTransaction()
.setTransactionValidDuration(constants_1.TRANSACTION_VALID_DURATION_SECONDS)
.setTransactionId(transaction.transactionId)
.setTransactionMemo(transaction.memo ?? "")
.setAccountId(accountId);
if (transaction.maxFee) {
tx.setMaxTransactionFee(sdk_1.Hbar.fromTinybars(transaction.maxFee.toNumber()));
}
if (typeof transaction.stakingNodeId === "number") {
tx.setStakedNodeId(transaction.stakingNodeId);
}
if (transaction.stakingNodeId === null) {
tx.clearStakedNodeId();
}
return tx.freezeWith(await rpc_1.rpcClient.getInstance());
}
function isStakingMode(type) {
return (type === constants_1.HEDERA_TRANSACTION_MODES.Redelegate ||
type === constants_1.HEDERA_TRANSACTION_MODES.Undelegate ||
type === constants_1.HEDERA_TRANSACTION_MODES.Delegate);
}
async function craftTransaction({ txIntent, customFees, config, }) {
const account = { accountId: txIntent.sender };
const maxFee = customFees ? new bignumber_js_1.default(customFees.value.toString()) : undefined;
const transactionId = await (0, utils_1.createTransactionId)(account.accountId, config);
let tx;
if (txIntent.type === constants_1.HEDERA_TRANSACTION_MODES.TokenAssociate) {
(0, invariant_1.default)(txIntent.asset.type !== "native", "hedera: invalid asset type");
(0, invariant_1.default)("assetReference" in txIntent.asset, "hedera: assetReference is missing");
tx = await buildTokenAssociateTransaction({
account,
transaction: {
type: txIntent.type,
transactionId,
tokenId: txIntent.asset.assetReference,
memo: txIntent.memo.value,
maxFee,
},
});
}
else if (txIntent.type === constants_1.HEDERA_TRANSACTION_MODES.Send && txIntent.asset.type === "hts") {
(0, invariant_1.default)("assetReference" in txIntent.asset, "hedera: no assetReference in token transfer");
const amount = new bignumber_js_1.default(txIntent.amount.toString());
tx = await buildUnsignedHTSTokenTransaction({
account,
transaction: {
type: txIntent.type,
transactionId,
tokenAddress: txIntent.asset.assetReference,
amount,
recipient: txIntent.recipient,
memo: txIntent.memo.value,
maxFee,
},
});
}
else if (txIntent.type === constants_1.HEDERA_TRANSACTION_MODES.Send && txIntent.asset.type === "erc20") {
(0, invariant_1.default)("assetReference" in txIntent.asset, "hedera: no assetReference in token transfer");
const amount = new bignumber_js_1.default(txIntent.amount.toString());
const gasLimit = (0, utils_2.hasSpecificIntentData)(txIntent, "erc20")
? new bignumber_js_1.default(txIntent.data.gasLimit.toString())
: constants_1.DEFAULT_GAS_LIMIT;
tx = await buildUnsignedERC20TokenTransaction({
transaction: {
type: txIntent.type,
transactionId,
tokenAddress: txIntent.asset.assetReference,
amount,
recipient: txIntent.recipient,
memo: txIntent.memo.value,
maxFee,
gasLimit,
},
});
}
else if (isStakingMode(txIntent.type)) {
const stakingNodeId = (0, utils_2.hasSpecificIntentData)(txIntent, "staking")
? txIntent.data.stakingNodeId
: undefined;
tx = await buildUnsignedUpdateAccountTransaction({
account,
transaction: {
type: txIntent.type,
transactionId,
memo: txIntent.memo.value,
maxFee,
stakingNodeId,
},
});
}
// HEDERA_TRANSACTION_MODES.ClaimRewards is just a coin transfer that triggers staking rewards claim
else {
const amount = new bignumber_js_1.default(txIntent.amount.toString());
tx = await buildUnsignedCoinTransaction({
account,
transaction: {
type: constants_1.HEDERA_TRANSACTION_MODES.Send,
transactionId,
amount,
recipient: txIntent.recipient,
memo: txIntent.memo.value,
maxFee,
},
});
}
const serializedTx = (0, utils_2.serializeTransaction)(tx);
return { tx, serializedTx };
}
//# sourceMappingURL=craftTransaction.js.map