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
Add non-breaking muxed account support to fee-bump transactions. #434
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple questions and thoughts shared inline.
* @param {string} id - the ID of the new muxed account | ||
* @return {MuxedAccount} a new instance w/ the specified parameters | ||
*/ | ||
createSubaccount(id) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we need this method can we rename this to createdMuxedAccount
? See #433 for why.
However, I think this function confusing. You can't create a muxed account that multiplexes another muxed account. The following code, although verbose, seems much clearer. Is there a reason we can't use it? or a reason we need to be able to create muxed accounts from muxed accounts?
muxedAccount.baseAccount().createMuxedAccount(id)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I completely agree that it's odd to have this method on this object, I added it to MuxedAccount
so that there was "interface" compatibility with Account
. And 👍 for the rename, though unfortunate that it wasn't noted at its introduction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is driving the need for this interface compatibility? I don't see anything new calling createSubaccount
in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no true need (especially since nobody is using muxed accounts); I just had it in mind after stellar/js-stellar-sdk#653.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, interesting. In this case, I don't think all accounts should have this capability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree in theory, but then you cannot use MuxedAccount
abstraction where Account
is allowed, yet the two should be largely interchangeable. Fixing this imo fundamentally requires a bigger change (see this comment, where createSubaccount
exists only on the non-interface), but that's out of scope here, so for now I think making muxed accounts "quack like an Account" is a reasonable measure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Thanks for explaining.
For my own understanding, which is limited here, is there no way in JavaScript/TypeScript to specify an interface type that provides a set of functions, so AccountResponse and MuxedAccount don't always have to have the exact same function set as Account, but rather there could be some interface Account that is a common subset that doesn't include createSubaccount
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're essentially describing exactly what I want: an interface that covers the common subset of functionality across AccountResponse
, MuxedAccount
, and Account
. This would involve replacing everywhere that says Account
(an object) which used to act as said "common subset" with some new interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a final pass I noticed a function below that has a confusing name. I defer to you on it though. Otherwise the PR looks good.
src/account.js
Outdated
* @param {string} mAddress - muxed address to convert | ||
* @returns {string} underlying G-address | ||
*/ | ||
static parseBaseAddress(mAddress) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name of this function is a little confusing. Often functions named parseX
are understood to "parse X". In this case the function is named parseBaseAddress
but what it does is "parse an M address".
I think it would be easier to understand the intent of this function if it was named parseMuxedAddress
and it returned all the components of a muxed address. I thought we would have had something like this already, but I guess we don't?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you're saying. We do have that: MuxedAccount.fromAddress
, but doing M -> G strings becomes unwieldy:
const muxed = new MuxedAccount.fromAddress(mAddress, '0');
const gAddress = muxed.baseAccount().accountId();
(see cfc6df0). How about extract
over parse
, @leighmcculloch? e.g.
const gAddress = MuxedAccount.extractBaseAddress(mAddress);
Closes #422 |
* Make `MuxedAccount` conform to the `Account` pseudo-interface. * Add test that fails without muxed support for fee bumps. * Add muxing support to fee-bump transactions and their builder * Improve payment error message
To avoid a breaking change, I've introduced a way to set the source of a fee-bump transaction via account strings (in both
G...
andM...
form). To enable proper muxed accounts, you passwithMuxing: true
as the last parameter ofTransactionBuilder.buildFeeBumpTransaction()
just like everywhere else to explicitly opt-in. Namely,