Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow decoding transactions with muxed properties from raw XDR. #470

Merged
merged 3 commits into from
Oct 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- Allow muxed accounts when decoding transactions via `TransactionBuilder.fromXDR()` ([#470](https://github.com/stellar/js-stellar-base/pull/470)).


## [v6.0.3](https://github.com/stellar/js-stellar-base/compare/v6.0.2..v6.0.3)

Expand Down
42 changes: 27 additions & 15 deletions src/transaction_builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ export const TimeoutInfinite = 0;
* @param {string} [opts.networkPassphrase] passphrase of the
* target Stellar network (e.g. "Public Global Stellar Network ; September
* 2015" for the pubnet)
* @param {bool} [opts.withMuxing] - Indicates that the source account of
* every transaction created by this Builder can be interpreted as a proper
* muxed account (i.e. coming from an M... address). By default, this option
* is disabled until muxed accounts are mature.
* @param {bool} [opts.withMuxing] - Indicates any properties in
* this transaction or its underlying operations that use fully-muxed
* accounts (i.e. come from an M... address) should be interpreted as such.
* By default, this option is disabled until muxed accounts are mature.
*/
export class TransactionBuilder {
constructor(sourceAccount, opts = {}) {
Expand Down Expand Up @@ -283,11 +283,13 @@ export class TransactionBuilder {
* in inner transaction (**in stroops**)
* @param {Transaction} innerTx - {@link Transaction} to be bumped by
* the fee bump transaction
* @param {string} networkPassphrase - passphrase of the target Stellar
* network (e.g. "Public Global Stellar Network ; September 2015")
* @param {bool} [withMuxing] - allows fee sources to be proper
* muxed accounts (i.e. coming from an M... address). By default, this
* option is disabled until muxed accounts are mature.
* @param {string} networkPassphrase - passphrase of the target
* Stellar network (e.g. "Public Global Stellar Network ; September 2015",
* see {@link Networks})
* @param {bool} [withMuxing] - Indicates any properties in this
* transaction or its underlying operations that use fully-muxed accounts
* (i.e. come from an M... address) should be interpreted as such. By
* default, this option is disabled until muxed accounts are mature.
*
* @todo Alongside the next major version bump, this type signature can be
* changed to be less awkward: accept a MuxedAccount as the `feeSource`
Expand Down Expand Up @@ -374,21 +376,31 @@ export class TransactionBuilder {
}

/**
* Build a {@link Transaction} or {@link FeeBumpTransaction} from an xdr.TransactionEnvelope.
* @param {string|xdr.TransactionEnvelope} envelope - The transaction envelope object or base64 encoded string.
* @param {string} networkPassphrase - networkPassphrase of the target stellar network (e.g. "Public Global Stellar Network ; September 2015").
* Build a {@link Transaction} or {@link FeeBumpTransaction} from an
* xdr.TransactionEnvelope.
*
* @param {string|xdr.TransactionEnvelope} envelope - The transaction envelope
* object or base64 encoded string.
* @param {string} networkPassphrase - The network passphrase of the target
* Stellar network (e.g. "Public Global Stellar Network ; September
* 2015"), see {@link Networks}.
* @param {bool} [withMuxing] - Indicates any properties in this transaction
* or its underlying operations that use fully-muxed accounts (i.e. come
* from an M... address) should be interpreted as such. By default, this
* option is disabled until muxed accounts are mature.
*
* @returns {Transaction|FeeBumpTransaction}
*/
static fromXDR(envelope, networkPassphrase) {
static fromXDR(envelope, networkPassphrase, withMuxing) {
if (typeof envelope === 'string') {
envelope = xdr.TransactionEnvelope.fromXDR(envelope, 'base64');
}

if (envelope.switch() === xdr.EnvelopeType.envelopeTypeTxFeeBump()) {
return new FeeBumpTransaction(envelope, networkPassphrase);
return new FeeBumpTransaction(envelope, networkPassphrase, withMuxing);
}

return new Transaction(envelope, networkPassphrase);
return new Transaction(envelope, networkPassphrase, withMuxing);
}
}

Expand Down
32 changes: 32 additions & 0 deletions test/unit/transaction_builder_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,28 @@ describe('TransactionBuilder', function() {

expect(source.sequenceNumber()).to.equal('1235');
expect(source.baseAccount().sequenceNumber()).to.equal('1235');

// it should decode muxed properties when specified
let decodedTx = StellarBase.TransactionBuilder.fromXDR(
tx.toXDR('base64'),
networkPassphrase,
true
);
let paymentOp = decodedTx.operations[0];
expect(decodedTx.source).to.equal(source.accountId());
expect(paymentOp.destination).to.equal(destination);
expect(paymentOp.source).to.equal(source.accountId());

const expectedBaseAccount = source.baseAccount().accountId();
decodedTx = StellarBase.TransactionBuilder.fromXDR(
tx.toXDR('base64'),
networkPassphrase,
false
);
paymentOp = decodedTx.operations[0];
expect(decodedTx.source).to.equal(expectedBaseAccount);
expect(paymentOp.destination).to.equal(expectedBaseAccount); // dest and src are same base
expect(paymentOp.source).to.equal(expectedBaseAccount);
});

it('does not regress js-stellar-sdk#646', function() {
Expand Down Expand Up @@ -800,6 +822,16 @@ describe('TransactionBuilder', function() {
source.accountId()
);
expect(innerMux.id()).to.eql(MUXED_SRC_ID);

const decodedTx = StellarBase.TransactionBuilder.fromXDR(
feeTx.toXDR('base64'),
networkPassphrase,
true
);
expect(decodedTx.feeSource).to.equal(source.accountId());
expect(decodedTx.innerTransaction.operations[0].source).to.equal(
source.baseAccount().accountId()
);
});
});
});