I am building an API that will send out signed transactions to users and allow them to submit the transactions themselves.

I am attempting to send a user three different transactions however I would like the user to select between these options and select only one.

Question is; once the user submits one of these transactions, how do I prevent the others being sent?

I was attempting to use sequence numbers to prevent this but cannot figure out how to assign the same sequence id to all transactions on the javascript SDK so that only one is accepted.

Is there a better way to do this and if not how can I set the sequence number with the JS-sdk?

  • Thank you all; these solutions are correct and I was able to manually set the sequence number in the account object before each transaction to ensure it was the same. – Momentus Mitch Aug 20 at 16:38
up vote 6 down vote accepted

The same sequence number is the solution for this case. I also had the similar issue setting up same sequence number for multiple transactions, here's a sample js sdk code I used to set same sequence number,

// This method is not recommended but seems to be only working options
// I could find at the time.

// load account, which will have initial sequence number
var account = await server.loadAccount(public);

const transaction1 = new StellarSdk.TransactionBuilder(account)
    .addOperation(...).build();

// the sequence number has increased, I had tried many methods for setting
// the same sequence number, but nothing seems to work,

// Solution I used, load the account again

account = await server.loadAccount(public);

const transaction2 = new StellarSdk.TransactionBuilder(account)
    .addOperation(...).build();

// This transaction has same sequence number
  • 1
    Looks like you should be able to rebuild the account with the current sequence number using new Account(publicKey, sequenceNumber) – Paul Aug 20 at 13:23

Having the same sequence number for each transaction is the perfect solution. (Well almost perfect. This will get you at most one, rather than exactly one).

In regard to managing the sequence number, the docs state:

There are two ways to ensure correct sequence numbers:

  1. Read the source account’s sequence number before submitting a transaction
  2. Manage the sequence number locally

I read this to mean that the JS library will not automatically update the sequence number each time a transaction is built. You should be OK to fetch the sequence number once (from Horizon or your app's local store if you are keeping track) and build 3 transactions with that sequence number.

  • 1
    The JS library actually does update the sequence number each time a transaction is built, but it's based on the parameters you give to it. Send in the same (account id, sequence number) tuple, and you're good to go. – Johan Stén Aug 20 at 2:17
  • The sequence number is locally updated on the account object per 'build()' call. However I was able to manually decrement or set the sequence number in the account object to be the same. Thanks! – Momentus Mitch Aug 20 at 16:39

TransactionBuilder takes an Account object as its first parameter, an Account consists of a public key, and a sequence number.

You can do loadAccount once, to get the current sequence number, and then simply re-use it (the sequence number) for the next transactions.

const account = await server.loadAccount(accoundId);
const sequenceNumber = account.sequenceNumber();

then every time you want to create a transaction:

const account = new StellarSdk.Account(accountId, sequenceNumber); 
const builder = new StellarSdk.TransactionBuilder(account);
  • 1
    Yes, but you have to be careful to re-use the sequence number (by resetting it manually), not just use the same account over and over again. The sequence number of the source account is bumped by the various SDKs when the transaction is built, not when it is submitted. – Paul Aug 20 at 13:20
  • 1
    Definitely, you have to get the sequence number out of the Account, and create a new Account for each TransactionBuilder you create. Your comment is what I commented to Jem already :) – Johan Stén Aug 20 at 15:06
  • We can use the same account locally since we have yet to submit the transaction. Build() will increment the account sequence locally but we can manually decrement or set the sequence value to override after each build() – Momentus Mitch Aug 20 at 16:40
  • What you do is what Paul and I have been saying all along.. – Johan Stén Aug 21 at 4:43

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.