XRPLF / xrpl4j

A 100% Java implementation to interact with the XRP Ledger.
ISC License
89 stars 49 forks source link

Signing of NfTokenMint transaction produces java.lang.NumberFormatException Error (XLS-20) #223

Closed Aless55 closed 2 years ago

Aless55 commented 2 years ago

Hello everyone, I run into a problem while trying to mint a NFT. I am using spring boot with gradle as well as jitpack.io to include the nft-support branch dependency. I used the faucet functionality on the XRPL site to get some accounts to use in my example. While signing the transaction a java.lang.NumberFormatException happens. The Stacktrace is added after my code. Note: If I try to use the send XRP tutorial code everything works fine.

  WalletFactory walletFactory = DefaultWalletFactory.getInstance();
        Wallet testWallet = walletFactory.fromSeed("shhf1NSyjZw1JLj9Y67XdiAeaqDou", true);

// Get the Classic address from testWallet
        Address classicAddress = testWallet.classicAddress();
        System.out.println(classicAddress); // "rMCcNuTcajgw7YTgBy1sys3b89QqjUrMpH"

// Connect --------------------------------------------------------------------
        HttpUrl rippledUrl = HttpUrl.get("http://xls20-sandbox.rippletest.net:51234");
        XrplClient xrplClient = new XrplClient(rippledUrl);

// Prepare transaction --------------------------------------------------------
// Look up your Account Info
        AccountInfoRequestParams requestParams = AccountInfoRequestParams.builder()
                .ledgerIndex(LedgerIndex.VALIDATED)
                .account(classicAddress)
                .build();
        AccountInfoResult accountInfoResult = xrplClient.accountInfo(requestParams);
        UnsignedInteger sequence = accountInfoResult.accountData().sequence();

// Request current fee information from rippled
        FeeResult feeResult = xrplClient.fee();
        XrpCurrencyAmount openLedgerFee = feeResult.drops().openLedgerFee();

// Get the latest validated ledger index
        LedgerIndex validatedLedger = xrplClient.ledger(
                        LedgerRequestParams.builder()
                                .ledgerIndex(LedgerIndex.VALIDATED)
                                .build()
                )
                .ledgerIndex()
                .orElseThrow(() -> new RuntimeException("LedgerIndex not available."));

// Workaround for https://github.com/XRPLF/xrpl4j/issues/84
        UnsignedInteger lastLedgerSequence = UnsignedInteger.valueOf(
                validatedLedger.plus(UnsignedLong.valueOf(4)).unsignedLongValue().intValue()
        );

        NfTokenMint nfTokenMint = NfTokenMint.builder()
                .account(classicAddress)
                .sequence(sequence)
                .fee(openLedgerFee)
                .flags(Flags.NfTokenMintFlags.builder().tfBurnable(true).tfTransferable(true).tfOnlyXRP(true).build())
                .uri("ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi")
                .tokenTaxon(UnsignedLong.valueOf(146999694L))
                .signingPublicKey(testWallet.publicKey())
                .lastLedgerSequence(lastLedgerSequence)
                .build();

// Sign transaction -----------------------------------------------------------
// Construct a SignatureService to sign the Payment
        PrivateKey privateKey = PrivateKey.fromBase16EncodedPrivateKey(
                testWallet.privateKey().get()
        );
        SignatureService signatureService = new SingleKeySignatureService(privateKey);

// Sign the Payment ---> Error happens here
        SignedTransaction<NfTokenMint> signedNfTokenMint = signatureService.sign(
                KeyMetadata.EMPTY,
                nfTokenMint
        );
java.lang.NumberFormatException: NfTokenMint
    at com.google.common.primitives.UnsignedLongs.parseUnsignedLong(UnsignedLongs.java:351) ~[guava-29.0-jre.jar:na]
    at com.google.common.primitives.UnsignedLong.valueOf(UnsignedLong.java:123) ~[guava-29.0-jre.jar:na]
    at com.google.common.primitives.UnsignedLong.valueOf(UnsignedLong.java:110) ~[guava-29.0-jre.jar:na]
    at org.xrpl.xrpl4j.codec.binary.types.UInt16Type.fromJson(UInt16Type.java:28) ~[xrpl4j-binary-codec-nft-support-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.codec.binary.types.UInt16Type.fromJson(UInt16Type.java:11) ~[xrpl4j-binary-codec-nft-support-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.codec.binary.serdes.BinarySerializer.writeFieldAndValue(BinarySerializer.java:90) ~[xrpl4j-binary-codec-nft-support-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.codec.binary.types.STObjectType.lambda$fromJson$2(STObjectType.java:78) ~[xrpl4j-binary-codec-nft-support-SNAPSHOT.jar:na]
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) ~[na:na]
    at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[na:na]
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[na:na]
    at org.xrpl.xrpl4j.codec.binary.types.STObjectType.fromJson(STObjectType.java:76) ~[xrpl4j-binary-codec-nft-support-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.codec.binary.XrplBinaryCodec.encode(XrplBinaryCodec.java:61) ~[xrpl4j-binary-codec-nft-support-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.codec.binary.XrplBinaryCodec.encodeForSigning(XrplBinaryCodec.java:75) ~[xrpl4j-binary-codec-nft-support-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.crypto.signing.SignatureUtils.toSignableBytes(SignatureUtils.java:67) ~[xrpl4j-crypto-core-nft-support-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.crypto.signing.AbstractSignatureService.signWithBehavior(AbstractSignatureService.java:69) ~[xrpl4j-crypto-core-nft-support-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.crypto.signing.AbstractSignatureService.sign(AbstractSignatureService.java:54) ~[xrpl4j-crypto-core-nft-support-SNAPSHOT.jar:na]

I tried adding and removing some of the build() functions as well as changing their respective values without success. I would really appreciate any hints on how to resolve this problem.

sappenin commented 2 years ago

@mukulljangid this seems to be the same issue as the SO filed last week.

Aless55 commented 2 years ago

@sappenin Since I didn't receive an answer on SO and couldn't find one by myself (my time at the moment is a little limited) I decided to open an issue here in the hope that someone with experience might A) be faster in seeing the problem or B) already know the problem.

sappenin commented 2 years ago

Ok, great - thanks for clarifying- better (for us at least) to triage here in GitHub anyway. Thanks!

sappenin commented 2 years ago

Our theory is that you maybe have a different objectmapper in the class path (probably coming from spring). Might be worth double checking how you're wiring up the xrpl4j classes.

Aless55 commented 2 years ago

Yeah I am using spring boot. I setup the dependencies like this:

repositories {
    maven { url "https://jitpack.io" }
}

dependencies {
        ....
        implementation 'com.github.xrplf.xrpl4j:xrpl4j-client:nft-support-SNAPSHOT'
    implementation 'com.github.xrplf.xrpl4j:xrpl4j-model:nft-support-SNAPSHOT'
    implementation 'com.github.xrplf.xrpl4j:xrpl4j-address-codec:nft-support-SNAPSHOT'
    implementation 'com.github.xrplf.xrpl4j:xrpl4j-binary-codec:nft-support-SNAPSHOT'
    implementation 'com.github.xrplf.xrpl4j:xrpl4j-keypairs:nft-support-SNAPSHOT'
    implementation 'com.github.xrplf.xrpl4j:xrpl4j-crypto-bouncycastle:nft-support-SNAPSHOT'
    implementation 'com.github.xrplf.xrpl4j:xrpl4j-crypto-core:nft-support-SNAPSHOT'
}

Afterwards the classes are imported like:

import org.xrpl.xrpl4j.crypto.signing.SingleKeySignatureService;
mukulljangid commented 2 years ago

The issue was fixed in the NFT Support PR (https://github.com/XRPLF/xrpl4j/pull/178) by commits fd115ee and ab3d709

Aless55 commented 2 years ago

@mukulljangid I pulled the newest code, the above error is gone. Now I am getting: java.lang.NumberFormatException: For input string: "R" under radix 16 But I saw that you already pushed another version, so I will try that one then. Edit: still the same error

Aless55 commented 2 years ago

Just an update, I tried the mj/ branch with the NfTokenUri.ofPlainText() method but still got an error on the signing line:

java.lang.NumberFormatException: For input string: "Q" under radix 16
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) ~[na:na]
    at java.base/java.lang.Integer.parseInt(Integer.java:668) ~[na:na]
    at java.base/java.math.BigInteger.<init>(BigInteger.java:536) ~[na:na]
    at org.xrpl.xrpl4j.codec.addresses.UnsignedByte.of(UnsignedByte.java:65) ~[xrpl4j-address-codec-mj~json-nft-tests-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.codec.addresses.ByteUtils.parse(ByteUtils.java:70) ~[xrpl4j-address-codec-mj~json-nft-tests-SNAPSHOT.jar:na]
    at org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray.fromHex(UnsignedByteArray.java:85) ~[xrpl4j-address-codec-mj~json-nft-tests-SNAPSHOT.jar:na]
Aless55 commented 2 years ago

@mukulljangid I had another unrelated error in my code which resulted in getting the public key in a wrong format. Your branch fixes the issues as expected. Thank you for your work.

mukulljangid commented 2 years ago

This issue was fixed here (https://github.com/XRPLF/xrpl4j/pull/225)