XRPLF / xrpl.js

A JavaScript/TypeScript API for interacting with the XRP Ledger in Node.js and the browser
https://xrpl.org/
1.2k stars 511 forks source link

terPRE_SEQ - Missing/inapplicable prior transaction #901

Closed biniama closed 6 years ago

biniama commented 6 years ago

I would like to implement a PAYMENT from one address to another using a test network and test accounts.

I am getting terPRE_SEQ - Missing/inapplicable prior transaction and I couldn't get the solution. Please help solve the issue and feel free to refactor the code.

Here is the code and the output. NOTE: I added 4 to the ledgerVersion based on https://developers.ripple.com/reliable-transaction-submission.html#lastledgersequence and I added 1 to sequenceNumber to use the next sequence value

const RippleAPI = require('ripple-lib').RippleAPI;

const api = new RippleAPI({
  server: 'wss://s.altnet.rippletest.net:51233'
});

const address = "rh3YMnG2kuFCHde3RZiHwNa4U1q4a6skFz";
const secret = 'shNJ3oMV16FapRB373Qq7Ztjaog2q';

function getMaxLedgerVersion() {
  return api.getLedger().then(ledger => {  
    console.log("ledger.ledgerVersion ", ledger.ledgerVersion);
    return ledger.ledgerVersion + 4;
  }).catch(err => console.error(err));
}

function getSequenceNumber() {
  return api.getAccountInfo(address).then(info =>  {
    console.log("info.sequence ", info.sequence);
    return info.sequence + 1;
  }).catch(err => console.error(err));
}

function prepareTransaction(maxLedgerVersion, sequenceNumber) {

  var txJSON = `{
    "TransactionType": "Payment",
    "Account": "rh3YMnG2kuFCHde3RZiHwNa4U1q4a6skFz",
    "Destination": "rKtPQgCQRyd7dxm1kJ1rA7CnsGADm3yfCt",
    "Amount": "100000000",
    "LastLedgerSequence": ` + maxLedgerVersion + `,
    "Fee": "12",
    "Sequence": ` + sequenceNumber + `
  }`;

  console.log(txJSON);

  return txJSON;
}

api.connect().then(() => {
  console.log('Connected');
  return getMaxLedgerVersion().then(maxLedgerVersion => {
    return getSequenceNumber().then(sequenceNumber => {
      let txJSON = prepareTransaction(maxLedgerVersion, sequenceNumber);

      var result = api.sign(txJSON, secret);
      return result.signedTransaction;
    }).then((signedTransaction) => {
        console.log("signedTransaction %j", signedTransaction);
        return api.submit(signedTransaction).then(result => {
          console.log(result);
          return result;
        }).catch(err => console.error(err));
      });
    });
}).then(() => {
  api.disconnect().then(() => {
    console.log('api disconnected');
    process.exit();
  });
}).catch(console.error);

OUTPUT

[ripple-demo (master)]$ node sign-submit.js
Connected
ledger.ledgerVersion  9391045
info.sequence  2
{
    "TransactionType": "Payment",
    "Account": "rh3YMnG2kuFCHde3RZiHwNa4U1q4a6skFz",
    "Destination": "rKtPQgCQRyd7dxm1kJ1rA7CnsGADm3yfCt",
    "Amount": "100000000",
    "LastLedgerSequence": 9391050,
    "Fee": "12",
    "Sequence": 3
  }
signedTransaction "1200002400000003201B008F4BCA614000000005F5E10068400000000000000C732103747EC17FFC28323293A3F7AF3C646985F100721D2BB1220ED1FE95C2B7DF378E744630440220777F04584D87EEC359DD2A12D046D84F75DB4D8EC0F350472CDA398AF3B4A12B02206B5191AB9A18D723D284CECE3AF4E65772CF63E921E4F1E78045FD94A7F4408881142255749AD40BAC79F5ED4B74E2CA17C1F07A75818314CF2A2F07085D0B9DEF4BA2ABDC6453DCECBE49E4"
{ resultCode: 'terPRE_SEQ',
  resultMessage: 'Missing/inapplicable prior transaction.' }
api disconnected
wilsonianb commented 6 years ago

Hi @biniama You shouldn't need to add 1 to the sequence number returned by getAccountInfo https://github.com/ripple/ripple-lib/blob/develop/docs/index.md#getaccountinfo That sequence is The next (smallest unused) sequence number for this account.

biniama commented 6 years ago

Thanks, @wilsonianb. Now, I got the following reply.

{
    resultCode: 'tesSUCCESS',
    resultMessage: 'The transaction was applied. Only final in a validated ledger.' 
}