From 0c8662589fd3678989f8016afcd68af718fd7146 Mon Sep 17 00:00:00 2001 From: Maayan Date: Thu, 2 Nov 2023 10:24:13 -0700 Subject: [PATCH] Use legacy ed25519 as the default key scheme (#163) * use legcy ed25519 as default key scheme * comments and changelog --- CHANGELOG.md | 1 + src/core/account.ts | 38 +++++---- src/core/crypto/secp256k1.ts | 5 +- src/internal/account.ts | 13 ++- src/types/index.ts | 27 +++--- tests/e2e/api/account.test.ts | 6 +- tests/e2e/transaction/signTransaction.test.ts | 4 +- .../transaction/transactionBuilder.test.ts | 8 +- .../transaction/transactionSimulation.test.ts | 4 +- .../transaction/transactionSubmission.test.ts | 4 +- tests/unit/account.test.ts | 84 ++++++++++++------- tests/unit/helper.ts | 8 ++ tests/unit/secp256k1.test.ts | 2 +- 13 files changed, 124 insertions(+), 80 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b5bc15fe..4a4fed5b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to the Aptos TypeScript SDK will be captured in this file. T - Support derive account from private key `Account.fromPrivateKey()` - Derive account from derivation path secp256k1 support +- Default Account generation to Legacy Ed25519 ## 0.0.3 (2023-10-31) diff --git a/src/core/account.ts b/src/core/account.ts index 64d38d0fa..61fc8f3d9 100644 --- a/src/core/account.ts +++ b/src/core/account.ts @@ -69,13 +69,14 @@ export class Account { */ private constructor(args: { privateKey: PrivateKey; address: AccountAddress; legacy?: boolean }) { const { privateKey, address, legacy } = args; + const useLegacy = legacy ?? true; // Derive the public key from the private key this.publicKey = privateKey.publicKey(); // Derive the signing scheme from the public key if (this.publicKey instanceof Ed25519PublicKey) { - if (legacy) { + if (useLegacy) { this.signingScheme = SigningScheme.Ed25519; } else { this.publicKey = new AnyPublicKey(this.publicKey); @@ -96,7 +97,8 @@ export class Account { /** * Derives an account with random private key and address. - * Default generation is using the Unified flow with ED25519 key + * + * Default generation is using the Legacy ED25519 key * * @param args optional. Unify GenerateAccount type for Legacy and Unified keys * @@ -122,19 +124,23 @@ export class Account { * @returns Account with the given signing scheme */ static generate(args?: GenerateAccount): Account { + const useLegacy = args?.legacy ?? true; + let privateKey: PrivateKey; + let publicKey: PublicKey; switch (args?.scheme) { case SigningSchemeInput.Secp256k1Ecdsa: privateKey = Secp256k1PrivateKey.generate(); + publicKey = new AnyPublicKey(privateKey.publicKey()); break; default: privateKey = Ed25519PrivateKey.generate(); - } - - let publicKey = privateKey.publicKey(); - if (!args?.legacy) { - publicKey = new AnyPublicKey(privateKey.publicKey()); + if (useLegacy === false) { + publicKey = new AnyPublicKey(privateKey.publicKey()); + } else { + publicKey = privateKey.publicKey(); + } } const address = new AccountAddress({ @@ -142,7 +148,7 @@ export class Account { publicKey, }).toUint8Array(), }); - return new Account({ privateKey, address, legacy: args?.legacy }); + return new Account({ privateKey, address, legacy: useLegacy }); } /** @@ -152,13 +158,14 @@ export class Account { * that has not had its authentication key rotated. * * @param privateKey PrivateKey - private key of the account - * @param args.legacy optional. If set to true, the keypair generated is a Legacy keypair. Defaults - * to generating a Unified keypair + * @param args.legacy optional. If set to false, the keypair generated is a Unified keypair. Defaults + * to generating a Legacy Ed25519 keypair * * @returns Account */ static fromPrivateKey(args: { privateKey: PrivateKey; legacy?: boolean }): Account { const { privateKey, legacy } = args; + const useLegacy = legacy ?? true; let publicKey; if (privateKey instanceof Secp256k1PrivateKey) { @@ -166,7 +173,7 @@ export class Account { publicKey = new AnyPublicKey(privateKey.publicKey()); } else if (privateKey instanceof Ed25519PrivateKey) { // legacy Ed25519 - if (legacy) { + if (useLegacy) { publicKey = privateKey.publicKey(); } else { // Ed25519 single sender @@ -178,7 +185,7 @@ export class Account { const authKey = AuthenticationKey.fromPublicKey({ publicKey }); const address = new AccountAddress({ data: authKey.toUint8Array() }); - return new Account({ privateKey, address, legacy }); + return new Account({ privateKey, address, legacy: useLegacy }); } /** @@ -187,8 +194,8 @@ export class Account { * * @param args.privateKey PrivateKey - the underlying private key for the account * @param args.address AccountAddress - The account address the `Account` will sign for - * @param args.legacy An optional flag to indicate that the authentication key derivation should - * use the legacy Ed25519 scheme. Defaults to false + * @param args.legacy optional. If set to false, the keypair generated is a Unified keypair. Defaults + * to generating a Legacy Ed25519 keypair * * @returns Account */ @@ -209,7 +216,8 @@ export class Account { * or non-hardened path (e.g. m/44'/637'/0'/0/0) for secp256k1 * Detailed description: {@link https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki} * @param args.mnemonic the mnemonic seed phrase of the account - * @param args.legacy optional. To indicate whether to use a legacy Ed25519 + * @param args.legacy optional. If set to false, the keypair generated is a Unified keypair. Defaults + * to generating a Legacy Ed25519 keypair * * @returns Account */ diff --git a/src/core/crypto/secp256k1.ts b/src/core/crypto/secp256k1.ts index c0e1e17c7..91e61852e 100644 --- a/src/core/crypto/secp256k1.ts +++ b/src/core/crypto/secp256k1.ts @@ -201,8 +201,9 @@ export class Secp256k1PrivateKey extends PrivateKey { * @returns The generated key */ private static fromDerivationPathInner(path: string, seed: Uint8Array): Secp256k1PrivateKey { - const { privateKey } = HDKey.fromMasterSeed(seed).derive(path); - + const { privateKey, publicKey } = HDKey.fromMasterSeed(seed).derive(path); + console.log(privateKey); + console.log(publicKey); // library returns privateKey as Uint8Array | null if (privateKey === null) { throw new Error("Invalid key"); diff --git a/src/internal/account.ts b/src/internal/account.ts index b5ccdddae..dae9faac3 100644 --- a/src/internal/account.ts +++ b/src/internal/account.ts @@ -492,6 +492,15 @@ export async function getAccountOwnedObjects(args: { return data.current_objects; } +/** + * NOTE: There is a potential issue once unified single signer scheme will be adopted + * by the community. + * + * Becuase on could create 2 accounts with the same private key with this new authenticator type, + * we’ll need to determine the order in which we lookup the accounts. First unified + * scheme and then legacy scheme vs first legacy scheme and then unified scheme. + * + */ export async function deriveAccountFromPrivateKey(args: { aptosConfig: AptosConfig; privateKey: PrivateKey; @@ -518,14 +527,14 @@ export async function deriveAccountFromPrivateKey(args: { }); if (isSingleSenderTransactionAuthenticator) { const address = new AccountAddress({ data: SingleSenderTransactionAuthenticatorAuthKey.toUint8Array() }); - return Account.fromPrivateKeyAndAddress({ privateKey, address }); + return Account.fromPrivateKeyAndAddress({ privateKey, address, legacy: false }); } // lookup legacy ed25519 const legacyAuthKey = AuthenticationKey.fromPublicKeyAndScheme({ publicKey, scheme: SigningScheme.Ed25519 }); const isLegacyEd25519 = await isAccountExist({ authKey: legacyAuthKey, aptosConfig }); if (isLegacyEd25519) { const address = new AccountAddress({ data: legacyAuthKey.toUint8Array() }); - return Account.fromPrivateKeyAndAddress({ privateKey, address, legacy: true }); + return Account.fromPrivateKeyAndAddress({ privateKey, address }); } } // if we are here, it means we couldn't find an address with an diff --git a/src/types/index.ts b/src/types/index.ts index d6c14a4d2..bdb05e55b 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -997,28 +997,23 @@ export type WaitForTransactionOptions = { checkSuccess?: boolean; indexerVersionCheck?: boolean; }; + /** - * Account input type to generate an account using Legacy - * Ed25519 or MultiEd25519 keys or without a specified `scheme`. - * If `scheme` is not specified, we default to ED25519 - * In this case `legacy` is always true + * Input type to generate an account using Single Signer + * Ed25519 or Legacy Ed25519 */ -export type GenerateAccountWithLegacyKey = { - scheme?: SigningSchemeInput.Ed25519; - legacy: true; +export type GenerateAccountWithEd25519 = { + scheme: SigningSchemeInput.Ed25519; + legacy: boolean; }; /** - * Account input type to generate an account using Unified - * Secp256k1Ecdsa key - * In this case `legacy` is always false + * Input type to generate an account using Single Signer + * Secp256k1 */ -export type GenerateAccountWithUnifiedKey = { - scheme: SigningSchemeInput.Secp256k1Ecdsa | SigningSchemeInput.Ed25519; +export type GenerateAccountWithSingleSignerSecp256k1Key = { + scheme: SigningSchemeInput.Secp256k1Ecdsa; legacy?: false; }; -/** - * Unify GenerateAccount type for Legacy and Unified keys - */ -export type GenerateAccount = GenerateAccountWithLegacyKey | GenerateAccountWithUnifiedKey; +export type GenerateAccount = GenerateAccountWithEd25519 | GenerateAccountWithSingleSignerSecp256k1Key; diff --git a/tests/e2e/api/account.test.ts b/tests/e2e/api/account.test.ts index 797c13870..7bfcd70ae 100644 --- a/tests/e2e/api/account.test.ts +++ b/tests/e2e/api/account.test.ts @@ -216,7 +216,7 @@ describe("account api", () => { test("single sender ed25519", async () => { const config = new AptosConfig({ network: Network.LOCAL }); const aptos = new Aptos(config); - const account = Account.generate(); + const account = Account.generate({ scheme: SigningSchemeInput.Ed25519, legacy: false }); await aptos.fundAccount({ accountAddress: account.accountAddress.toString(), amount: 100 }); const derivedAccount = await aptos.deriveAccountFromPrivateKey({ privateKey: account.privateKey }); @@ -233,7 +233,7 @@ describe("account api", () => { test("legacy ed25519", async () => { const config = new AptosConfig({ network: Network.LOCAL }); const aptos = new Aptos(config); - const account = Account.generate({ legacy: true }); + const account = Account.generate(); await aptos.fundAccount({ accountAddress: account.accountAddress.toString(), amount: 100 }); const derivedAccount = await aptos.deriveAccountFromPrivateKey({ privateKey: account.privateKey }); @@ -309,7 +309,7 @@ describe("account api", () => { const aptos = new Aptos(config); // Current Account - const account = Account.generate({ scheme: SigningSchemeInput.Ed25519, legacy: true }); + const account = Account.generate(); await aptos.fundAccount({ accountAddress: account.accountAddress.toString(), amount: 1_000_000_000 }); // account that holds the new key diff --git a/tests/e2e/transaction/signTransaction.test.ts b/tests/e2e/transaction/signTransaction.test.ts index 7a7ba70d6..eefa9b856 100644 --- a/tests/e2e/transaction/signTransaction.test.ts +++ b/tests/e2e/transaction/signTransaction.test.ts @@ -12,8 +12,8 @@ const aptos = new Aptos(config); describe("sign transaction", () => { const contractPublisherAccount = Account.generate(); - const singleSignerED25519SenderAccount = Account.generate(); - const legacyED25519SenderAccount = Account.generate({ legacy: true }); + const singleSignerED25519SenderAccount = Account.generate({ scheme: SigningSchemeInput.Ed25519, legacy: false }); + const legacyED25519SenderAccount = Account.generate(); const receiverAccounts = [Account.generate(), Account.generate()]; const singleSignerSecp256k1Account = Account.generate({ scheme: SigningSchemeInput.Secp256k1Ecdsa }); const secondarySignerAccount = Account.generate(); diff --git a/tests/e2e/transaction/transactionBuilder.test.ts b/tests/e2e/transaction/transactionBuilder.test.ts index 86d9d467a..fecd13653 100644 --- a/tests/e2e/transaction/transactionBuilder.test.ts +++ b/tests/e2e/transaction/transactionBuilder.test.ts @@ -12,7 +12,7 @@ import { EntryFunctionABI, parseTypeTag, } from "../../../src"; -import { AccountAuthenticator, AccountAuthenticatorSingleKey } from "../../../src/transactions/authenticator/account"; +import { AccountAuthenticator, AccountAuthenticatorEd25519 } from "../../../src/transactions/authenticator/account"; import { FeePayerRawTransaction, MultiAgentRawTransaction, @@ -364,7 +364,7 @@ describe("transaction builder", () => { expect(accountAuthenticator instanceof AccountAuthenticator).toBeTruthy(); const deserializer = new Deserializer(accountAuthenticator.bcsToBytes()); const authenticator = AccountAuthenticator.deserialize(deserializer); - expect(authenticator instanceof AccountAuthenticatorSingleKey).toBeTruthy(); + expect(authenticator instanceof AccountAuthenticatorEd25519).toBeTruthy(); }); test("it signs a fee payer transaction", async () => { @@ -390,7 +390,7 @@ describe("transaction builder", () => { expect(accountAuthenticator instanceof AccountAuthenticator).toBeTruthy(); const deserializer = new Deserializer(accountAuthenticator.bcsToBytes()); const authenticator = AccountAuthenticator.deserialize(deserializer); - expect(authenticator instanceof AccountAuthenticatorSingleKey).toBeTruthy(); + expect(authenticator instanceof AccountAuthenticatorEd25519).toBeTruthy(); }); test("it signs a multi agent transaction", async () => { @@ -420,7 +420,7 @@ describe("transaction builder", () => { expect(accountAuthenticator instanceof AccountAuthenticator).toBeTruthy(); const deserializer = new Deserializer(accountAuthenticator.bcsToBytes()); const authenticator = AccountAuthenticator.deserialize(deserializer); - expect(authenticator instanceof AccountAuthenticatorSingleKey).toBeTruthy(); + expect(authenticator instanceof AccountAuthenticatorEd25519).toBeTruthy(); }); }); describe("generateSignedTransaction", () => { diff --git a/tests/e2e/transaction/transactionSimulation.test.ts b/tests/e2e/transaction/transactionSimulation.test.ts index 36a79a6af..9a6158ec9 100644 --- a/tests/e2e/transaction/transactionSimulation.test.ts +++ b/tests/e2e/transaction/transactionSimulation.test.ts @@ -6,8 +6,8 @@ describe("transaction simulation", () => { const config = new AptosConfig({ network: Network.LOCAL }); const aptos = new Aptos(config); const contractPublisherAccount = Account.generate(); - const singleSignerED25519SenderAccount = Account.generate(); - const legacyED25519SenderAccount = Account.generate({ legacy: true }); + const singleSignerED25519SenderAccount = Account.generate({ scheme: SigningSchemeInput.Ed25519, legacy: false }); + const legacyED25519SenderAccount = Account.generate(); const singleSignerSecp256k1Account = Account.generate({ scheme: SigningSchemeInput.Secp256k1Ecdsa }); const recieverAccounts = [Account.generate(), Account.generate()]; const secondarySignerAccount = Account.generate(); diff --git a/tests/e2e/transaction/transactionSubmission.test.ts b/tests/e2e/transaction/transactionSubmission.test.ts index b51f8d22a..7adf8d4e4 100644 --- a/tests/e2e/transaction/transactionSubmission.test.ts +++ b/tests/e2e/transaction/transactionSubmission.test.ts @@ -25,8 +25,8 @@ const config = new AptosConfig({ network: Network.LOCAL }); const aptos = new Aptos(config); describe("transaction submission", () => { const contractPublisherAccount = Account.generate(); - const singleSignerED25519SenderAccount = Account.generate(); - const legacyED25519SenderAccount = Account.generate({ legacy: true }); + const singleSignerED25519SenderAccount = Account.generate({ scheme: SigningSchemeInput.Ed25519, legacy: false }); + const legacyED25519SenderAccount = Account.generate(); const receiverAccounts = [Account.generate(), Account.generate()]; const singleSignerSecp256k1Account = Account.generate({ scheme: SigningSchemeInput.Secp256k1Ecdsa }); const secondarySignerAccount = Account.generate(); diff --git a/tests/unit/account.test.ts b/tests/unit/account.test.ts index 3cc7a1b7a..6e8209024 100644 --- a/tests/unit/account.test.ts +++ b/tests/unit/account.test.ts @@ -14,37 +14,37 @@ import { } from "../../src"; import { AnyPublicKey } from "../../src/core/crypto/anyPublicKey"; -import { ed25519, secp256k1TestObject, secp256k1WalletTestObject, singleSignerED25519, wallet } from "./helper"; +import { + ed25519, + secp256k1TestObject, + secp256k1WalletTestObject, + singleSignerED25519, + wallet, + Ed25519WalletTestObject, +} from "./helper"; describe("Account", () => { describe("generate", () => { - it("should create an instance of Account when Secp256k1 scheme is specified", () => { - // Account with Ed25519 SingleKey scheme - const secpAccount = Account.generate({ scheme: SigningSchemeInput.Secp256k1Ecdsa }); - expect(secpAccount).toBeInstanceOf(Account); - expect(secpAccount.publicKey).toBeInstanceOf(AnyPublicKey); - expect(secpAccount.signingScheme).toEqual(SigningScheme.SingleKey); - }); - it("should create an instance of Account with a legacy ED25519 scheme is not specified and legacy set to true", () => { - // Account with Ed25519 SingleKey scheme - const edAccount = Account.generate({ legacy: true }); + it("should create an instance of Account with a legacy ED25519 when nothing is specified", () => { + // Account with Legacy Ed25519 scheme + const edAccount = Account.generate(); expect(edAccount).toBeInstanceOf(Account); expect(edAccount.publicKey).toBeInstanceOf(Ed25519PublicKey); expect(edAccount.signingScheme).toEqual(SigningScheme.Ed25519); }); - it("should create an instance of Account with a Single Sender ED25519 when scheme and legacy not specified", () => { - // Account with Ed25519 SingleKey scheme - const edAccount = Account.generate(); + it("should create an instance of Account with a Single Sender ED25519 when scheme and legacy specified", () => { + // Account with SingleKey Ed25519 scheme + const edAccount = Account.generate({ scheme: SigningSchemeInput.Ed25519, legacy: false }); expect(edAccount).toBeInstanceOf(Account); expect(edAccount.publicKey).toBeInstanceOf(AnyPublicKey); expect(edAccount.signingScheme).toEqual(SigningScheme.SingleKey); }); - it("should create an instance of Account with a legacy ED25519 when scheme and legacy specified", () => { - // Account with Ed25519 SingleKey scheme - const edAccount = Account.generate({ scheme: SigningSchemeInput.Ed25519, legacy: true }); - expect(edAccount).toBeInstanceOf(Account); - expect(edAccount.publicKey).toBeInstanceOf(Ed25519PublicKey); - expect(edAccount.signingScheme).toEqual(SigningScheme.Ed25519); + it("should create an instance of Account when Secp256k1 scheme is specified", () => { + // Account with SingleKey Secp256k1 scheme + const secpAccount = Account.generate({ scheme: SigningSchemeInput.Secp256k1Ecdsa }); + expect(secpAccount).toBeInstanceOf(Account); + expect(secpAccount.publicKey).toBeInstanceOf(AnyPublicKey); + expect(secpAccount.signingScheme).toEqual(SigningScheme.SingleKey); }); }); describe("fromPrivateKeyAndAddress", () => { @@ -52,8 +52,10 @@ describe("Account", () => { const { privateKey: privateKeyBytes, publicKey, address } = ed25519; const privateKey = new Ed25519PrivateKey(privateKeyBytes); const accountAddress = AccountAddress.fromHexInput(address); - const newAccount = Account.fromPrivateKeyAndAddress({ privateKey, address: accountAddress, legacy: true }); + const newAccount = Account.fromPrivateKeyAndAddress({ privateKey, address: accountAddress }); expect(newAccount).toBeInstanceOf(Account); + expect(newAccount.publicKey).toBeInstanceOf(Ed25519PublicKey); + expect(newAccount.privateKey).toBeInstanceOf(Ed25519PrivateKey); expect((newAccount.privateKey as Ed25519PrivateKey).toString()).toEqual(privateKey.toString()); expect((newAccount.publicKey as Ed25519PublicKey).toString()).toEqual(new Ed25519PublicKey(publicKey).toString()); expect(newAccount.accountAddress.toString()).toEqual(address); @@ -63,8 +65,10 @@ describe("Account", () => { const { privateKey: privateKeyBytes, publicKey, address } = singleSignerED25519; const privateKey = new Ed25519PrivateKey(privateKeyBytes); const accountAddress = AccountAddress.fromHexInput(address); - const newAccount = Account.fromPrivateKeyAndAddress({ privateKey, address: accountAddress }); + const newAccount = Account.fromPrivateKeyAndAddress({ privateKey, address: accountAddress, legacy: false }); expect(newAccount).toBeInstanceOf(Account); + expect(newAccount.publicKey).toBeInstanceOf(AnyPublicKey); + expect(newAccount.privateKey).toBeInstanceOf(Ed25519PrivateKey); expect((newAccount.privateKey as Ed25519PrivateKey).toString()).toEqual(privateKey.toString()); expect((newAccount.publicKey as Ed25519PublicKey).toString()).toEqual(new Ed25519PublicKey(publicKey).toString()); expect(newAccount.accountAddress.toString()).toEqual(address); @@ -76,6 +80,8 @@ describe("Account", () => { const accountAddress = AccountAddress.fromHexInput(address); const newAccount = Account.fromPrivateKeyAndAddress({ privateKey, address: accountAddress }); expect(newAccount).toBeInstanceOf(Account); + expect(newAccount.publicKey).toBeInstanceOf(AnyPublicKey); + expect(newAccount.privateKey).toBeInstanceOf(Secp256k1PrivateKey); expect((newAccount.privateKey as Secp256k1PrivateKey).toString()).toEqual(privateKey.toString()); expect((newAccount.publicKey as Secp256k1PublicKey).toString()).toEqual( new Secp256k1PublicKey(publicKey).toString(), @@ -88,8 +94,10 @@ describe("Account", () => { it("derives the correct account from a legacy ed25519 private key", () => { const { privateKey: privateKeyBytes, publicKey, address } = ed25519; const privateKey = new Ed25519PrivateKey(privateKeyBytes); - const newAccount = Account.fromPrivateKey({ privateKey, legacy: true }); + const newAccount = Account.fromPrivateKey({ privateKey }); expect(newAccount).toBeInstanceOf(Account); + expect(newAccount.publicKey).toBeInstanceOf(Ed25519PublicKey); + expect(newAccount.privateKey).toBeInstanceOf(Ed25519PrivateKey); expect((newAccount.privateKey as Ed25519PrivateKey).toString()).toEqual(privateKey.toString()); expect((newAccount.publicKey as Ed25519PublicKey).toString()).toEqual(new Ed25519PublicKey(publicKey).toString()); expect(newAccount.accountAddress.toString()).toEqual(address); @@ -98,8 +106,10 @@ describe("Account", () => { it("derives the correct account from a single signer ed25519 private key", () => { const { privateKey: privateKeyBytes, publicKey, address } = singleSignerED25519; const privateKey = new Ed25519PrivateKey(privateKeyBytes); - const newAccount = Account.fromPrivateKey({ privateKey }); + const newAccount = Account.fromPrivateKey({ privateKey, legacy: false }); expect(newAccount).toBeInstanceOf(Account); + expect(newAccount.publicKey).toBeInstanceOf(AnyPublicKey); + expect(newAccount.privateKey).toBeInstanceOf(Ed25519PrivateKey); expect((newAccount.privateKey as Ed25519PrivateKey).toString()).toEqual(privateKey.toString()); expect((newAccount.publicKey as Ed25519PublicKey).toString()).toEqual(new Ed25519PublicKey(publicKey).toString()); expect(newAccount.accountAddress.toString()).toEqual(address); @@ -110,6 +120,8 @@ describe("Account", () => { const privateKey = new Secp256k1PrivateKey(privateKeyBytes); const newAccount = Account.fromPrivateKey({ privateKey }); expect(newAccount).toBeInstanceOf(Account); + expect(newAccount.publicKey).toBeInstanceOf(AnyPublicKey); + expect(newAccount.privateKey).toBeInstanceOf(Secp256k1PrivateKey); expect((newAccount.privateKey as Secp256k1PrivateKey).toString()).toEqual(privateKey.toString()); expect((newAccount.publicKey as Secp256k1PublicKey).toString()).toEqual( new Secp256k1PublicKey(publicKey).toString(), @@ -118,18 +130,28 @@ describe("Account", () => { }); }); describe("fromDerivationPath", () => { - it("should create a new account from bip44 path and mnemonics with legacy Ed255519", async () => { + it("should create a new account from bip44 path and mnemonics with legacy Ed25519", async () => { const { mnemonic, address, path } = wallet; const newAccount = Account.fromDerivationPath({ path, mnemonic, scheme: SigningSchemeInput.Ed25519, - legacy: true, }); expect(newAccount.accountAddress.toString()).toEqual(address); }); - it("should create a new account from bip44 path and mnemonics with secp256k1", () => { + it("should create a new account from bip44 path and mnemonics with single signer Ed25519", async () => { + const { mnemonic, address, path } = Ed25519WalletTestObject; + const newAccount = Account.fromDerivationPath({ + path, + mnemonic, + scheme: SigningSchemeInput.Ed25519, + legacy: false, + }); + expect(newAccount.accountAddress.toString()).toEqual(address); + }); + + it("should create a new account from bip44 path and mnemonics with single signer secp256k1", () => { const { mnemonic, address, path } = secp256k1WalletTestObject; const newAccount = Account.fromDerivationPath({ path, @@ -141,7 +163,7 @@ describe("Account", () => { }); describe("sign and verify", () => { - it("signs a message with Secp256k1 scheme and verifies succefully", () => { + it("signs a message with single signer Secp256k1 scheme and verifies successfully", () => { const { privateKey: privateKeyBytes, address, signatureHex, messageEncoded } = secp256k1TestObject; const privateKey = new Secp256k1PrivateKey(privateKeyBytes); const accountAddress = AccountAddress.fromHexInput(address); @@ -151,11 +173,11 @@ describe("Account", () => { expect(secpAccount.verifySignature({ message: messageEncoded, signature })).toBeTruthy(); }); - it("signs a message with ed25519 scheme and verifies succefully", () => { + it("signs a message with single signer ed25519 scheme and verifies successfully", () => { const { privateKey: privateKeyBytes, address, signatureHex, messageEncoded } = singleSignerED25519; const privateKey = new Ed25519PrivateKey(privateKeyBytes); const accountAddress = AccountAddress.fromHexInput(address); - const edAccount = Account.fromPrivateKeyAndAddress({ privateKey, address: accountAddress }); + const edAccount = Account.fromPrivateKeyAndAddress({ privateKey, address: accountAddress, legacy: false }); const signature = edAccount.sign(messageEncoded); expect(signature.toString()).toEqual(signatureHex); expect(edAccount.verifySignature({ message: messageEncoded, signature })).toBeTruthy(); @@ -165,7 +187,7 @@ describe("Account", () => { const { privateKey: privateKeyBytes, address, signedMessage, message } = ed25519; const privateKey = new Ed25519PrivateKey(privateKeyBytes); const accountAddress = AccountAddress.fromHexInput(address); - const legacyEdAccount = Account.fromPrivateKeyAndAddress({ privateKey, address: accountAddress, legacy: true }); + const legacyEdAccount = Account.fromPrivateKeyAndAddress({ privateKey, address: accountAddress }); const signature = legacyEdAccount.sign(message); expect(signature.toString()).toEqual(signedMessage); expect(legacyEdAccount.verifySignature({ message, signature })).toBeTruthy(); diff --git a/tests/unit/helper.ts b/tests/unit/helper.ts index de79a2ea9..a69f75d66 100644 --- a/tests/unit/helper.ts +++ b/tests/unit/helper.ts @@ -14,6 +14,14 @@ export const wallet = { publicKey: "0xea526ba1710343d953461ff68641f1b7df5f23b9042ffa2d2a798d3adb3f3d6c", }; +export const Ed25519WalletTestObject = { + address: "0x28b829b524d7c24aa7fd8916573c814df766dae542f724e1cf8914536232c346", + mnemonic: "shoot island position soft burden budget tooth cruel issue economy destroy above", + path: "m/44'/637'/0'/0'/0'", + privateKey: "0x5d996aa76b3212142792d9130796cd2e11e3c445a93118c08414df4f66bc60ec", + publicKey: "0xea526ba1710343d953461ff68641f1b7df5f23b9042ffa2d2a798d3adb3f3d6c", +}; + export const secp256k1WalletTestObject = { address: "0x4b4aa8759fcef40ba49e999409eb73a98252f44f6612a4de2b23bad5c37b15a6", mnemonic: "shoot island position soft burden budget tooth cruel issue economy destroy above", diff --git a/tests/unit/secp256k1.test.ts b/tests/unit/secp256k1.test.ts index df836ccc2..62c2dc288 100644 --- a/tests/unit/secp256k1.test.ts +++ b/tests/unit/secp256k1.test.ts @@ -138,7 +138,7 @@ describe("Secp256k1PrivateKey", () => { const { mnemonic, path, privateKey } = secp256k1WalletTestObject; const key = Secp256k1PrivateKey.fromDerivationPath(path, mnemonic); expect(key).toBeInstanceOf(Secp256k1PrivateKey); - expect(privateKey).toEqual(key.toString()); + expect(key.toString()).toEqual(privateKey); }); });