Last active
November 24, 2023 15:28
-
-
Save WietseWind/96ab2c11eec2e681d142144b66896327 to your computer and use it in GitHub Desktop.
XLS20 NFToken ID calculation with fixNFTokenRemint compatibility
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Based on: https://gist.github.com/N3TC4T/a20fb528931ed009ebdd708be4938748 | |
import { derive, utils, signAndSubmit, } from "xrpl-accountlib" | |
import { XrplClient } from "xrpl-client" | |
import { decodeAccountID } from "ripple-address-codec" | |
import { TxData } from 'xrpl-txdata' | |
// const wss = [ 'wss://testnet.xrpl-labs.com', 'wss://s.altnet.rippletest.net:51233', ] | |
const wss = [ 'wss://s.devnet.rippletest.net:51233/' ] | |
const client = new XrplClient(wss) | |
const account = derive.familySeed("sxxxxxxxx") | |
const networkInfo = await utils.txNetworkAndAccountValues(client, account) | |
const tx = { | |
TransactionType: "NFTokenMint", | |
TransferFee: 314, | |
NFTokenTaxon: 0, | |
Flags: 8, | |
URI: "697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A6469", | |
Memos: [ | |
{ | |
Memo: { | |
MemoType: "687474703A2F2F6578616D706C652E636F6D2F6D656D6F2F67656E65726963", | |
MemoData: "72656E74" | |
} | |
} | |
], | |
...networkInfo.txValues, | |
NetworkID: undefined, | |
} | |
const submitted = await signAndSubmit(tx, client, account) | |
console.log(submitted) | |
client.close() | |
const txd = new TxData(wss, { AllowNoFullHistory: true, }) | |
const finishedTx = await txd.getOne(submitted.tx_id) | |
console.log(finishedTx) | |
//////////////////////////////////// | |
const getTokenID = ({ transaction: { Account, Issuer, NFTokenTaxon, TransferFee, Flags }, meta }) => { | |
let TokenSequence; | |
let NextTokenSequence; | |
let FirstNFTokenSequence; | |
meta.AffectedNodes.forEach((node) => { | |
if ( | |
node.ModifiedNode && | |
node.ModifiedNode.LedgerEntryType === "AccountRoot" | |
) { | |
const { PreviousFields, FinalFields } = node.ModifiedNode; | |
if (PreviousFields && FinalFields && FinalFields.Account === (Issuer || Account)) { | |
TokenSequence = PreviousFields.MintedNFTokens; | |
NextTokenSequence = FinalFields.MintedNFTokens; | |
FirstNFTokenSequence = PreviousFields?.FirstNFTokenSequence || FinalFields?.FirstNFTokenSequence; | |
} | |
} | |
}); | |
// First minted token, set token sequence to zero | |
if (typeof TokenSequence === "undefined" && NextTokenSequence === 1) { | |
TokenSequence = 0; | |
} | |
TokenSequence += FirstNFTokenSequence ?? 0 | |
// Unable to find TokenSequence | |
if (typeof TokenSequence === "undefined") { | |
throw new Error("Unable to find Token Sequnce"); | |
} | |
const _Issuer = decodeAccountID(Issuer || Account); | |
const CipheredTaxon = NFTokenTaxon ^ (384160001 * TokenSequence + 2459); | |
const TokenID = Buffer.concat([ | |
Buffer.from([(Flags >> 8) & 0xff, Flags & 0xff]), | |
Buffer.from([(TransferFee >> 8) & 0xff, TransferFee & 0xff]), | |
_Issuer, | |
Buffer.from([ | |
(CipheredTaxon >> 24) & 0xff, | |
(CipheredTaxon >> 16) & 0xff, | |
(CipheredTaxon >> 8) & 0xff, | |
CipheredTaxon & 0xff, | |
]), | |
Buffer.from([ | |
(TokenSequence >> 24) & 0xff, | |
(TokenSequence >> 16) & 0xff, | |
(TokenSequence >> 8) & 0xff, | |
TokenSequence & 0xff, | |
]), | |
]); | |
// should be 32 bytes | |
if (TokenID.length !== 32) { | |
throw new Error("Invalid token id lenght"); | |
} | |
return TokenID.toString('hex').toUpperCase(); | |
} | |
//////////////////////////////////// | |
const tokenID = getTokenID(finishedTx.result) | |
console.log(tokenID) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment