@ledgerhq/coin-stellar
Version:
Ledger Stellar Coin integration
103 lines (91 loc) • 2.74 kB
text/typescript
import { NetworkDown } from "@ledgerhq/errors";
import {
Memo,
Operation as StellarSdkOperation,
Transaction as StellarSdkTransaction,
xdr,
} from "@stellar/stellar-sdk";
import { getRecipientAccount, loadAccount } from "../network";
import { StellarAssetRequired, StellarMuxedAccountNotExist } from "../types";
import {
buildChangeTrustOperation,
buildCreateAccountOperation,
buildPaymentOperation,
buildTransactionBuilder,
} from "./sdkWrapper";
export async function craftTransaction(
account: {
address: string;
},
transaction: {
type: string;
recipient: string;
amount: bigint;
fee: bigint;
assetCode?: string | undefined;
assetIssuer?: string | undefined;
memoType?: string | null | undefined;
memoValue?: string | null | undefined;
},
): Promise<{ transaction: StellarSdkTransaction; xdr: string; signatureBase: string }> {
const { amount, recipient, fee, memoType, memoValue, type, assetCode, assetIssuer } = transaction;
const source = await loadAccount(account.address);
if (!source) {
throw new NetworkDown();
}
const transactionBuilder = buildTransactionBuilder(source, fee);
let operation: xdr.Operation<StellarSdkOperation.ChangeTrust> | null = null;
if (type === "changeTrust") {
if (!assetCode || !assetIssuer) {
throw new StellarAssetRequired("");
}
operation = buildChangeTrustOperation(assetCode, assetIssuer);
} else {
// Payment
const recipientAccount = await getRecipientAccount({
recipient,
});
if (recipientAccount?.id) {
operation = buildPaymentOperation({
destination: recipient,
amount,
assetCode,
assetIssuer,
});
} else {
if (recipientAccount?.isMuxedAccount) {
throw new StellarMuxedAccountNotExist("");
}
operation = buildCreateAccountOperation(recipient, amount);
}
}
transactionBuilder.addOperation(operation);
const memo = buildMemo(memoType, memoValue);
if (memo) {
transactionBuilder.addMemo(memo);
}
const craftedTransaction = transactionBuilder.setTimeout(0).build();
return {
transaction: craftedTransaction,
xdr: craftedTransaction.toXDR(),
signatureBase: craftedTransaction.signatureBase().toString("base64"),
};
}
function buildMemo(
memoType?: string | null | undefined,
memoValue?: string | null | undefined,
): Memo | null {
if (memoType && memoValue) {
switch (memoType) {
case "MEMO_TEXT":
return Memo.text(memoValue);
case "MEMO_ID":
return Memo.id(memoValue);
case "MEMO_HASH":
return Memo.hash(memoValue);
case "MEMO_RETURN":
return Memo.return(memoValue);
}
}
return null;
}