Skip to content
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

decodedTransaction.publicKey.toString() returns [object Object] #1381

Open
2 of 4 tasks
kujtimprenku opened this issue Sep 8, 2024 · 7 comments
Open
2 of 4 tasks
Assignees
Labels
bug Something isn't working

Comments

@kujtimprenku
Copy link

kujtimprenku commented Sep 8, 2024

Prerequisites

  • I'm using the latest version of near-api-js.
  • I have tried to start with a fresh project and reproduce the defect with minimal code changes.
  • I have read the console error messages carefully (if applicable).

Description

Unable get convert the public key to string from a decoded transaction.

Reproducible demo

https://github.com/kujtimprenku/naj-publickey

Steps to reproduce

  ...
  const encoded = tx.encode();
  const decoded = transactions.Transaction.decode(encoded)

  console.log({ originalTX: tx })
  console.log({ publicKey: decoded.publicKey.toString() }) // '[object Object]'

Live demo: https://kujtimprenku.github.io/naj-publickey/

Expected behavior

The publicKey.toString() should return the string value for the public key: ed25519:xxxxxxxxxxx.

Actual behavior

It returns '[object Object]'

Your environment

  • NEAR JavaScript API version used: v4.0.3 and v5
  • Frontend framework (if applicable): any
  • Relevant dependencies (if applicable): n/a

Self-service

  • I'd be willing to fix this bug myself.
@kujtimprenku kujtimprenku added the bug Something isn't working label Sep 8, 2024
@kujtimprenku
Copy link
Author

Also, the enum key is missing in the action(s) for decoded transactions.

image

@kujtimprenku
Copy link
Author

Some information is being lost on tx.encode() and tx.decode() on publicKey (keyType and other info) and actions (enum value).

@andy-haynes
Copy link
Collaborator

andy-haynes commented Sep 16, 2024

Thank you for the bug report, @kujtimprenku ! Really appreciate the example code and call out on the missing enum key.

Unfortunately I think this has always been the behavior here. borsh appears to only initialize structs as object literals, so the deserialized object is just a POJO without any methods from the target class. Do you know if this was working in previous versions?

In any case, this is only a limitation of borsh - this could be fixed in the decodeTransaction method to ensure the publicKey (and any other fields similarly affected), e.g.

// providers/src/schema.ts
export function decodeTransaction(bytes: Uint8Array) {
    const decoded = new Transaction(deserialize(SCHEMA.Transaction, bytes));
    const { publicKey: { ed25519Key, secp256k1Key } } = decoded;
    decoded.publicKey = new PublicKey({
        keyType: ed25519Key ? KeyType.ED25519 : KeyType.SECP256K1,
        data: ed25519Key ? ed25519Key.data || secp256k1Key.data,
    });
    return decoded;
}

@kujtimprenku
Copy link
Author

kujtimprenku commented Sep 17, 2024

Thank you for the bug report, @kujtimprenku ! Really appreciate the example code and call out on the missing enum key.

Unfortunately I think this has always been the behavior here. borsh appears to only initialize structs as object literals, so the deserialized object is just a POJO without any methods from the target class. Do you know if this was working in previous versions?

In any case, this is only a limitation of borsh - this could be fixed in the decodeTransaction method to ensure the publicKey (and any other fields similarly affected), e.g.

// providers/src/schema.ts
export function decodeTransaction(bytes: Uint8Array) {
    const decoded = new Transaction(deserialize(SCHEMA.Transaction, bytes));
    const { publicKey: { ed25519Key, secp256k1Key } } = decoded;
    decoded.publicKey = new PublicKey({
        keyType: ed25519Key ? KeyType.ED25519 : KeyType.SECP256K1,
        data: ed25519Key ? ed25519Key.data || secp256k1Key.data,
    });
    return decoded;
}

Actually in versions before moving to borsh 1.0.0 this info was available after decoding the transaction:.

I pushed a new branch in the example code above to demo it:
https://github.com/kujtimprenku/naj-publickey/tree/naj-2.1.4

I also deployed this branch to gh-pages of the example:
https://kujtimprenku.github.io/naj-publickey/

In the past this code used to work properly now because of the missing enum it's broken

image

@kujtimprenku
Copy link
Author

But as you mentioned maybe the decodeTransaction must be updated to handle these cases when some info is lost.

@andy-haynes
Copy link
Collaborator

Thanks for the clarification, I did check previous behavior but I only went back as far as version 3 lol

That makes sense about [email protected], IIRC that was the change that fixed compatibility between NAJ versions. The fix I proposed is a kludge, but since the usage is confined to the one module it feels like an acceptable tradeoff.

@andy-haynes andy-haynes self-assigned this Sep 17, 2024
@kujtimprenku
Copy link
Author

I agree, the proposed fix would work just fine without digging through borsh-js.
Thanks for taking the time to look into this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: NEW❗
Development

No branches or pull requests

2 participants