near / near-api-js

JavaScript library to interact with NEAR Protocol via RPC API
https://near.github.io/near-api-js
MIT License
390 stars 244 forks source link

Add support of secp256k1 key pairs #440

Open alexauroradev opened 3 years ago

alexauroradev commented 3 years ago

The rollout of EVM feature implies support of EVM-native keys generation, encoding, signing and verification. Users that are familiar with Ethereum should be able to use their accounts for working with NEAR EVM implementation.

mikedotexe commented 3 years ago

With Aurora launching, this is likely becoming high priority

mehtaphysical commented 3 years ago

It sounds like secp256k1 support in nearcore has been pushed until next quarter.

We should take this time to audit the elliptic package. If it looks good we can replace tweetnacl with it to prepare the way for secp256k1 support.

bowenwang1996 commented 3 years ago

It sounds like secp256k1 support in nearcore has been pushed until next quarter.

Can you elaborate on that? On the account level we already support secp256k1 key for a while now.

mehtaphysical commented 3 years ago

@bowenwang1996 that is just what I heard when I asked about this.

I've been messing around with adding a secp256k1 key with this code:

async function run() {
  const account = await near.account("rnm.testnet");
  const ec = new EC("secp256k1");
  const kp = ec.genKeyPair();

  const publicKey = `secp256k1:${base_encode(
    kp.getPublic().getX().toBuffer()
  )}`;
  // const kp = KeyPair.fromRandom("ed25519");
  // const publicKey = kp.getPublicKey().toString();

  const res = await account.addKey(publicKey);
  console.log(res);
}

But am getting the following error:

[-32602] Invalid params: Failed to decode transaction: Unexpected variant index: 31

If I do the same thing, replacing secp256k1 with ed25519 everything works fine:

async function run() {
  const account = await near.account("rnm.testnet");
  const ec = new EC("ed25519");
  const kp = ec.genKeyPair();

  const publicKey = `ed25519:${base_encode(
    kp.getPublic().getX().toBuffer()
  )}`;
  // const kp = KeyPair.fromRandom("ed25519");
  // const publicKey = kp.getPublicKey().toString();

  const res = await account.addKey(publicKey);
  console.log(res);
}

I can play around with it more.

bowenwang1996 commented 3 years ago

That is probably a borsh serialization issue in near-api-js

mehtaphysical commented 3 years ago

Created issue with borsh-js. https://github.com/near/borsh-js/issues/19

Waiting for feedback, then will implement a fix and implement this change

mikedotexe commented 2 years ago

I think we still need this, and want to bump it. Been fielding some questions from builders and believe it'd be good to remember it.

This is a good lead: https://www.npmjs.com/package/@ethersproject/signing-key

samingle commented 2 years ago

Have a draft of this in #810