@stellar/stellar-sdk
Version:
A library for working with the Stellar network, including communication with the Horizon and Soroban RPC servers.
450 lines (447 loc) • 18.7 kB
JavaScript
import { Asset } from './asset.js';
import { LiquidityPoolAsset } from './liquidity_pool_asset.js';
import { Claimant } from './claimant.js';
import { StrKey } from './strkey.js';
import { LiquidityPoolId } from './liquidity_pool_id.js';
import types from './generated/curr_generated.js';
import { trimEnd } from './util/util.js';
import { encodeMuxedAccountToAddress } from './util/decode_encode_muxed_account.js';
import { manageSellOffer } from './operations/manage_sell_offer.js';
import { createPassiveSellOffer } from './operations/create_passive_sell_offer.js';
import { accountMerge } from './operations/account_merge.js';
import { allowTrust } from './operations/allow_trust.js';
import { bumpSequence } from './operations/bump_sequence.js';
import { changeTrust } from './operations/change_trust.js';
import { createAccount } from './operations/create_account.js';
import { createClaimableBalance } from './operations/create_claimable_balance.js';
import { claimClaimableBalance } from './operations/claim_claimable_balance.js';
import { clawbackClaimableBalance } from './operations/clawback_claimable_balance.js';
import { inflation } from './operations/inflation.js';
import { manageData } from './operations/manage_data.js';
import { manageBuyOffer } from './operations/manage_buy_offer.js';
import { pathPaymentStrictReceive } from './operations/path_payment_strict_receive.js';
import { pathPaymentStrictSend } from './operations/path_payment_strict_send.js';
import { payment } from './operations/payment.js';
import { setOptions } from './operations/set_options.js';
import { beginSponsoringFutureReserves } from './operations/begin_sponsoring_future_reserves.js';
import { endSponsoringFutureReserves } from './operations/end_sponsoring_future_reserves.js';
import { revokeAccountSponsorship, revokeTrustlineSponsorship, revokeOfferSponsorship, revokeDataSponsorship, revokeClaimableBalanceSponsorship, revokeLiquidityPoolSponsorship, revokeSignerSponsorship } from './operations/revoke_sponsorship.js';
import { clawback } from './operations/clawback.js';
import { setTrustLineFlags } from './operations/set_trustline_flags.js';
import { liquidityPoolDeposit } from './operations/liquidity_pool_deposit.js';
import { liquidityPoolWithdraw } from './operations/liquidity_pool_withdraw.js';
import { invokeHostFunction, createStellarAssetContract, invokeContractFunction, createCustomContract, uploadContractWasm } from './operations/invoke_host_function.js';
import { extendFootprintTtl } from './operations/extend_footprint_ttl.js';
import { restoreFootprint } from './operations/restore_footprint.js';
import { fromXDRAmount, fromXDRPrice } from './util/operations.js';
const AuthRequiredFlag = 1 << 0;
const AuthRevocableFlag = 1 << 1;
const AuthImmutableFlag = 1 << 2;
const AuthClawbackEnabledFlag = 1 << 3;
class Operation {
/**
* Deconstructs the raw XDR operation object into the structured object that
* was used to create the operation (i.e. the `opts` parameter to most ops).
*
* @param operation - An XDR Operation.
*/
static fromXDRObject(operation) {
const result = {};
const sourceAccount = operation.sourceAccount();
if (sourceAccount) {
result.source = encodeMuxedAccountToAddress(sourceAccount);
}
const attrs = operation.body().value();
const operationName = operation.body().switch().name;
switch (operationName) {
case "createAccount": {
result.type = "createAccount";
result.destination = accountIdtoAddress(attrs.destination());
result.startingBalance = fromXDRAmount(attrs.startingBalance());
break;
}
case "payment": {
result.type = "payment";
result.destination = encodeMuxedAccountToAddress(attrs.destination());
result.asset = Asset.fromOperation(attrs.asset());
result.amount = fromXDRAmount(attrs.amount());
break;
}
case "pathPaymentStrictReceive": {
result.type = "pathPaymentStrictReceive";
result.sendAsset = Asset.fromOperation(attrs.sendAsset());
result.sendMax = fromXDRAmount(attrs.sendMax());
result.destination = encodeMuxedAccountToAddress(attrs.destination());
result.destAsset = Asset.fromOperation(attrs.destAsset());
result.destAmount = fromXDRAmount(attrs.destAmount());
result.path = [];
const path = attrs.path();
Object.keys(path).forEach((pathKey) => {
result.path.push(Asset.fromOperation(path[pathKey]));
});
break;
}
case "pathPaymentStrictSend": {
result.type = "pathPaymentStrictSend";
result.sendAsset = Asset.fromOperation(attrs.sendAsset());
result.sendAmount = fromXDRAmount(attrs.sendAmount());
result.destination = encodeMuxedAccountToAddress(attrs.destination());
result.destAsset = Asset.fromOperation(attrs.destAsset());
result.destMin = fromXDRAmount(attrs.destMin());
result.path = [];
const path = attrs.path();
Object.keys(path).forEach((pathKey) => {
result.path.push(Asset.fromOperation(path[pathKey]));
});
break;
}
case "changeTrust": {
result.type = "changeTrust";
switch (attrs.line().switch()) {
case types.AssetType.assetTypePoolShare():
result.line = LiquidityPoolAsset.fromOperation(attrs.line());
break;
default:
result.line = Asset.fromOperation(attrs.line());
break;
}
result.limit = fromXDRAmount(attrs.limit());
break;
}
case "allowTrust": {
result.type = "allowTrust";
result.trustor = accountIdtoAddress(attrs.trustor());
result.assetCode = attrs.asset().value().toString();
result.assetCode = trimEnd(result.assetCode, "\0");
result.authorize = attrs.authorize();
break;
}
case "setOptions": {
result.type = "setOptions";
if (attrs.inflationDest()) {
result.inflationDest = accountIdtoAddress(attrs.inflationDest());
}
result.clearFlags = attrs.clearFlags();
result.setFlags = attrs.setFlags();
result.masterWeight = attrs.masterWeight();
result.lowThreshold = attrs.lowThreshold();
result.medThreshold = attrs.medThreshold();
result.highThreshold = attrs.highThreshold();
result.homeDomain = attrs.homeDomain() !== void 0 ? attrs.homeDomain().toString("ascii") : void 0;
if (attrs.signer()) {
const signer = {};
const arm = attrs.signer().key().arm();
if (arm === "ed25519") {
signer.ed25519PublicKey = accountIdtoAddress(attrs.signer().key());
} else if (arm === "preAuthTx") {
signer.preAuthTx = attrs.signer().key().preAuthTx();
} else if (arm === "hashX") {
signer.sha256Hash = attrs.signer().key().hashX();
} else if (arm === "ed25519SignedPayload") {
const signedPayload = attrs.signer().key().ed25519SignedPayload();
signer.ed25519SignedPayload = StrKey.encodeSignedPayload(
signedPayload.toXDR()
);
}
signer.weight = attrs.signer().weight();
result.signer = signer;
}
break;
}
// the next case intentionally falls through!
case "manageOffer":
case "manageSellOffer": {
result.type = "manageSellOffer";
result.selling = Asset.fromOperation(attrs.selling());
result.buying = Asset.fromOperation(attrs.buying());
result.amount = fromXDRAmount(attrs.amount());
result.price = fromXDRPrice(attrs.price());
result.offerId = attrs.offerId().toString();
break;
}
case "manageBuyOffer": {
result.type = "manageBuyOffer";
result.selling = Asset.fromOperation(attrs.selling());
result.buying = Asset.fromOperation(attrs.buying());
result.buyAmount = fromXDRAmount(attrs.buyAmount());
result.price = fromXDRPrice(attrs.price());
result.offerId = attrs.offerId().toString();
break;
}
// the next case intentionally falls through!
case "createPassiveOffer":
case "createPassiveSellOffer": {
result.type = "createPassiveSellOffer";
result.selling = Asset.fromOperation(attrs.selling());
result.buying = Asset.fromOperation(attrs.buying());
result.amount = fromXDRAmount(attrs.amount());
result.price = fromXDRPrice(attrs.price());
break;
}
case "accountMerge": {
result.type = "accountMerge";
result.destination = encodeMuxedAccountToAddress(attrs);
break;
}
case "manageData": {
result.type = "manageData";
result.name = attrs.dataName().toString("ascii");
result.value = attrs.dataValue();
break;
}
case "inflation": {
result.type = "inflation";
break;
}
case "bumpSequence": {
result.type = "bumpSequence";
result.bumpTo = attrs.bumpTo().toString();
break;
}
case "createClaimableBalance": {
result.type = "createClaimableBalance";
result.asset = Asset.fromOperation(attrs.asset());
result.amount = fromXDRAmount(attrs.amount());
result.claimants = [];
attrs.claimants().forEach((claimant) => {
result.claimants.push(Claimant.fromXDR(claimant));
});
break;
}
case "claimClaimableBalance": {
result.type = "claimClaimableBalance";
result.balanceId = attrs.toXDR("hex");
break;
}
case "beginSponsoringFutureReserves": {
result.type = "beginSponsoringFutureReserves";
result.sponsoredId = accountIdtoAddress(attrs.sponsoredId());
break;
}
case "endSponsoringFutureReserves": {
result.type = "endSponsoringFutureReserves";
break;
}
case "revokeSponsorship": {
extractRevokeSponshipDetails(attrs, result);
break;
}
case "clawback": {
result.type = "clawback";
result.amount = fromXDRAmount(attrs.amount());
result.from = encodeMuxedAccountToAddress(attrs.from());
result.asset = Asset.fromOperation(attrs.asset());
break;
}
case "clawbackClaimableBalance": {
result.type = "clawbackClaimableBalance";
result.balanceId = attrs.toXDR("hex");
break;
}
case "setTrustLineFlags": {
result.type = "setTrustLineFlags";
result.asset = Asset.fromOperation(attrs.asset());
result.trustor = accountIdtoAddress(attrs.trustor());
const clears = attrs.clearFlags();
const sets = attrs.setFlags();
const mapping = {
authorized: types.TrustLineFlags.authorizedFlag(),
authorizedToMaintainLiabilities: types.TrustLineFlags.authorizedToMaintainLiabilitiesFlag(),
clawbackEnabled: types.TrustLineFlags.trustlineClawbackEnabledFlag()
};
const getFlagValue = (key) => {
const bit = mapping[key]?.value ?? 0;
if (sets & bit) {
return true;
}
if (clears & bit) {
return false;
}
return void 0;
};
const flags = {};
Object.keys(mapping).forEach((flagName) => {
flags[flagName] = getFlagValue(flagName);
});
result.flags = flags;
break;
}
case "liquidityPoolDeposit": {
result.type = "liquidityPoolDeposit";
result.liquidityPoolId = attrs.liquidityPoolId().toString("hex");
result.maxAmountA = fromXDRAmount(attrs.maxAmountA());
result.maxAmountB = fromXDRAmount(attrs.maxAmountB());
result.minPrice = fromXDRPrice(attrs.minPrice());
result.maxPrice = fromXDRPrice(attrs.maxPrice());
break;
}
case "liquidityPoolWithdraw": {
result.type = "liquidityPoolWithdraw";
result.liquidityPoolId = attrs.liquidityPoolId().toString("hex");
result.amount = fromXDRAmount(attrs.amount());
result.minAmountA = fromXDRAmount(attrs.minAmountA());
result.minAmountB = fromXDRAmount(attrs.minAmountB());
break;
}
case "invokeHostFunction": {
result.type = "invokeHostFunction";
result.func = attrs.hostFunction();
result.auth = attrs.auth() ?? [];
break;
}
case "extendFootprintTtl": {
result.type = "extendFootprintTtl";
result.extendTo = attrs.extendTo();
break;
}
case "restoreFootprint": {
result.type = "restoreFootprint";
break;
}
default: {
throw new Error(`Unknown operation: ${operationName}`);
}
}
return result;
}
// Attach all imported operations as static methods on the Operation class
static accountMerge = accountMerge;
static allowTrust = allowTrust;
static bumpSequence = bumpSequence;
static changeTrust = changeTrust;
static createAccount = createAccount;
static createClaimableBalance = createClaimableBalance;
static claimClaimableBalance = claimClaimableBalance;
static clawbackClaimableBalance = clawbackClaimableBalance;
static createPassiveSellOffer = createPassiveSellOffer;
static inflation = inflation;
static manageData = manageData;
static manageSellOffer = manageSellOffer;
static manageBuyOffer = manageBuyOffer;
static pathPaymentStrictReceive = pathPaymentStrictReceive;
static pathPaymentStrictSend = pathPaymentStrictSend;
static payment = payment;
static setOptions = setOptions;
static beginSponsoringFutureReserves = beginSponsoringFutureReserves;
static endSponsoringFutureReserves = endSponsoringFutureReserves;
static revokeAccountSponsorship = revokeAccountSponsorship;
static revokeTrustlineSponsorship = revokeTrustlineSponsorship;
static revokeOfferSponsorship = revokeOfferSponsorship;
static revokeDataSponsorship = revokeDataSponsorship;
static revokeClaimableBalanceSponsorship = revokeClaimableBalanceSponsorship;
static revokeLiquidityPoolSponsorship = revokeLiquidityPoolSponsorship;
static revokeSignerSponsorship = revokeSignerSponsorship;
static clawback = clawback;
static setTrustLineFlags = setTrustLineFlags;
static liquidityPoolDeposit = liquidityPoolDeposit;
static liquidityPoolWithdraw = liquidityPoolWithdraw;
static invokeHostFunction = invokeHostFunction;
static extendFootprintTtl = extendFootprintTtl;
static restoreFootprint = restoreFootprint;
// These are not `xdr.Operation`s directly, but proxies for common
// versions of `Operation.invokeHostFunction`
static createStellarAssetContract = createStellarAssetContract;
static invokeContractFunction = invokeContractFunction;
static createCustomContract = createCustomContract;
static uploadContractWasm = uploadContractWasm;
}
function extractRevokeSponshipDetails(attrs, result) {
switch (attrs.switch().name) {
case "revokeSponsorshipLedgerEntry": {
const ledgerKey = attrs.ledgerKey();
switch (ledgerKey.switch().name) {
case types.LedgerEntryType.account().name: {
result.type = "revokeAccountSponsorship";
result.account = accountIdtoAddress(ledgerKey.account().accountId());
break;
}
case types.LedgerEntryType.trustline().name: {
result.type = "revokeTrustlineSponsorship";
result.account = accountIdtoAddress(
ledgerKey.trustLine().accountId()
);
const xdrAsset = ledgerKey.trustLine().asset();
switch (xdrAsset.switch()) {
case types.AssetType.assetTypePoolShare():
result.asset = LiquidityPoolId.fromOperation(xdrAsset);
break;
default:
result.asset = Asset.fromOperation(xdrAsset);
break;
}
break;
}
case types.LedgerEntryType.offer().name: {
result.type = "revokeOfferSponsorship";
result.seller = accountIdtoAddress(ledgerKey.offer().sellerId());
result.offerId = ledgerKey.offer().offerId().toString();
break;
}
case types.LedgerEntryType.data().name: {
result.type = "revokeDataSponsorship";
result.account = accountIdtoAddress(ledgerKey.data().accountId());
result.name = ledgerKey.data().dataName().toString("ascii");
break;
}
case types.LedgerEntryType.claimableBalance().name: {
result.type = "revokeClaimableBalanceSponsorship";
result.balanceId = ledgerKey.claimableBalance().balanceId().toXDR("hex");
break;
}
case types.LedgerEntryType.liquidityPool().name: {
result.type = "revokeLiquidityPoolSponsorship";
result.liquidityPoolId = ledgerKey.liquidityPool().liquidityPoolId().toString("hex");
break;
}
default: {
throw new Error(`Unknown ledgerKey: ${attrs.switch().name}`);
}
}
break;
}
case "revokeSponsorshipSigner": {
result.type = "revokeSignerSponsorship";
result.account = accountIdtoAddress(attrs.signer().accountId());
result.signer = convertXDRSignerKeyToObject(attrs.signer().signerKey());
break;
}
default: {
throw new Error(`Unknown revokeSponsorship: ${attrs.switch().name}`);
}
}
}
function convertXDRSignerKeyToObject(signerKey) {
const attrs = {};
switch (signerKey.switch().name) {
case types.SignerKeyType.signerKeyTypeEd25519().name: {
attrs.ed25519PublicKey = StrKey.encodeEd25519PublicKey(
signerKey.ed25519()
);
break;
}
case types.SignerKeyType.signerKeyTypePreAuthTx().name: {
attrs.preAuthTx = signerKey.preAuthTx().toString("hex");
break;
}
case types.SignerKeyType.signerKeyTypeHashX().name: {
attrs.sha256Hash = signerKey.hashX().toString("hex");
break;
}
case types.SignerKeyType.signerKeyTypeEd25519SignedPayload().name: {
const signedPayload = signerKey.ed25519SignedPayload();
attrs.ed25519SignedPayload = StrKey.encodeSignedPayload(
signedPayload.toXDR()
);
break;
}
default: {
throw new Error(`Unknown signerKey: ${signerKey.switch().name}`);
}
}
return attrs;
}
function accountIdtoAddress(accountId) {
return StrKey.encodeEd25519PublicKey(accountId.ed25519());
}
export { AuthClawbackEnabledFlag, AuthImmutableFlag, AuthRequiredFlag, AuthRevocableFlag, Operation };
//# sourceMappingURL=operation.js.map