Skip to content

Commit

Permalink
refactor!: the key-management package now uses the new Ed25519
Browse files Browse the repository at this point in the history
cryptographic provider
  • Loading branch information
AngelCastilloB committed Jan 31, 2023
1 parent 839183e commit cf73daf
Show file tree
Hide file tree
Showing 38 changed files with 238 additions and 152 deletions.
10 changes: 5 additions & 5 deletions packages/e2e/.env.example
Expand Up @@ -7,11 +7,11 @@ FAUCET_PROVIDER_PARAMS='{"baseUrl":"http://localhost:8090/v2","mnemonic":"fire m

# Key management setup - required by getWallet
KEY_MANAGEMENT_PROVIDER=inMemory
KEY_MANAGEMENT_PARAMS='{"accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"vacant violin soft weird deliver render brief always monitor general maid smart jelly core drastic erode echo there clump dizzy card filter option defense"}'
#KEY_MANAGEMENT_PARAMS='{"accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"slab gorilla reflect display cage aim silver add own arrange crew start female bitter menu inner combine exit swallow bamboo midnight wealth culture picnic"}'
#KEY_MANAGEMENT_PARAMS='{"accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"decorate survey empower stairs pledge humble social leisure baby wrap grief exact monster rug dash kiss perfect select science light frame play swallow day"}'
#KEY_MANAGEMENT_PARAMS='{"accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"phrase raw learn suspect inmate powder combine apology regular hero gain chronic fruit ritual short screen goddess odor keen creek brand today kit machine"}'
#KEY_MANAGEMENT_PARAMS='{"accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"salon zoo engage submit smile frost later decide wing sight chaos renew lizard rely canal coral scene hobby scare step bus leaf tobacco slice"}'
KEY_MANAGEMENT_PARAMS='{"cryptoProvider": "CML", "accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"vacant violin soft weird deliver render brief always monitor general maid smart jelly core drastic erode echo there clump dizzy card filter option defense"}'
#KEY_MANAGEMENT_PARAMS='{"cryptoProvider": "CML", "accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"slab gorilla reflect display cage aim silver add own arrange crew start female bitter menu inner combine exit swallow bamboo midnight wealth culture picnic"}'
#KEY_MANAGEMENT_PARAMS='{"cryptoProvider": "CML", "accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"decorate survey empower stairs pledge humble social leisure baby wrap grief exact monster rug dash kiss perfect select science light frame play swallow day"}'
#KEY_MANAGEMENT_PARAMS='{"cryptoProvider": "CML", "accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"phrase raw learn suspect inmate powder combine apology regular hero gain chronic fruit ritual short screen goddess odor keen creek brand today kit machine"}'
#KEY_MANAGEMENT_PARAMS='{"cryptoProvider": "CML", "accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "password":"some_password","mnemonic":"salon zoo engage submit smile frost later decide wing sight chaos renew lizard rely canal coral scene hobby scare step bus leaf tobacco slice"}'

# Providers setup - required by getWallet
ASSET_PROVIDER=http
Expand Down
4 changes: 3 additions & 1 deletion packages/e2e/src/environment.ts
Expand Up @@ -7,6 +7,7 @@ export interface KeyManagementParams {
mnemonic: string;
chainId: Cardano.ChainId;
password: string;
cryptoProvider: string;
}

export interface ProviderParams {
Expand All @@ -33,10 +34,11 @@ const keyManagementParams = makeValidator((value) =>
properties: {
accountIndex: { minimum: 0, type: 'integer' },
chainId: { $ref: '/ChainId' },
cryptoProvider: { type: 'string' },
mnemonic: { type: 'string' },
password: { type: 'string' }
},
required: ['accountIndex', 'mnemonic', 'chainId', 'password'],
required: ['accountIndex', 'mnemonic', 'chainId', 'password', 'cryptoProvider'],
type: 'object'
},
{
Expand Down
9 changes: 9 additions & 0 deletions packages/e2e/src/factories.ts
@@ -1,4 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as Crypto from '@cardano-sdk/crypto';
import {
AssetProvider,
Cardano,
Expand Down Expand Up @@ -66,8 +67,14 @@ export const rewardsProviderFactory = new ProviderFactory<RewardsProvider>();
export const txSubmitProviderFactory = new ProviderFactory<TxSubmitProvider>();
export const utxoProviderFactory = new ProviderFactory<UtxoProvider>();
export const stakePoolProviderFactory = new ProviderFactory<StakePoolProvider>();
export const cryptoProviderFactory = new ProviderFactory<Crypto.Ed25519Provider>();

// Crypto Providers

cryptoProviderFactory.register('CML', async () => new Crypto.CmlEd25519Provider());

// Faucet providers

faucetProviderFactory.register('cardano-wallet', CardanoWalletFaucetProvider.create);

// Asset providers
Expand Down Expand Up @@ -305,12 +312,14 @@ export const getWallet = async (props: GetWalletProps) => {
const envKeyParams = customKeyParams ? customKeyParams : env.KEY_MANAGEMENT_PARAMS;
const keyManagementParams = { ...envKeyParams, ...(idx === undefined ? {} : { accountIndex: idx }) };

const cryptoProvider = await cryptoProviderFactory.create(env.KEY_MANAGEMENT_PROVIDER.cryptoProvider, null, logger);
const { wallet } = await setupWallet({
createKeyAgent: keyAgent
? () => Promise.resolve(keyAgent)
: await keyManagementFactory.create(env.KEY_MANAGEMENT_PROVIDER, keyManagementParams, logger),
createWallet: async (asyncKeyAgent: AsyncKeyAgent) =>
new SingleAddressWallet({ name, polling }, { ...providers, keyAgent: asyncKeyAgent, logger, stores }),
cryptoProvider,
logger
});

Expand Down
7 changes: 6 additions & 1 deletion packages/e2e/src/scripts/mnemonic.ts
@@ -1,5 +1,6 @@
/* eslint-disable no-console */
/* eslint-disable @typescript-eslint/no-floating-promises */
import * as Crypto from '@cardano-sdk/crypto';
import { AddressType, InMemoryKeyAgent, util } from '@cardano-sdk/key-management';
import { localNetworkChainId } from '../util';

Expand All @@ -17,7 +18,11 @@ import { localNetworkChainId } from '../util';
getPassword: async () => Buffer.from(''),
mnemonicWords: mnemonicArray
},
{ inputResolver: { resolveInputAddress: async () => null }, logger: console }
{
cryptoProvider: new Crypto.CmlEd25519Provider(),
inputResolver: { resolveInputAddress: async () => null },
logger: console
}
);

const derivedAddress = await keyAgentFromMnemonic.deriveAddress({
Expand Down
4 changes: 4 additions & 0 deletions packages/e2e/src/util/StubKeyAgent.ts
Expand Up @@ -21,6 +21,10 @@ export class StubKeyAgent implements KeyAgent {
return this.#knownAddresses;
}

get cryptoProvider(): Crypto.Ed25519Provider {
throw new NotImplementedError('cryptoProvider');
}

get chainId(): Cardano.ChainId {
throw new NotImplementedError('chainId');
}
Expand Down
Expand Up @@ -14,6 +14,7 @@ import {
MeasurementUtil,
assetProviderFactory,
chainHistoryProviderFactory,
cryptoProviderFactory,
getEnv,
getLoadTestScheduler,
keyManagementFactory,
Expand Down Expand Up @@ -70,8 +71,9 @@ const getKeyAgent = async (accountIndex: number) => {
{ ...env.KEY_MANAGEMENT_PARAMS, accountIndex },
logger
);
const cryptoProvider = await cryptoProviderFactory.create(env.KEY_MANAGEMENT_PARAMS.cryptoProvider, null, logger);
const walletUtil = createLazyWalletUtil();
const keyAgent = await createKeyAgent({ inputResolver: walletUtil, logger });
const keyAgent = await createKeyAgent({ cryptoProvider, inputResolver: walletUtil, logger });
return { keyAgent, walletUtil };
};

Expand Down
4 changes: 2 additions & 2 deletions packages/e2e/test/local-network/register-pool.test.ts
@@ -1,5 +1,4 @@
/* eslint-disable max-statements */
import * as Crypto from '@cardano-sdk/crypto';
import { Cardano } from '@cardano-sdk/core';
import { KeyAgentFactoryProps, TestWallet, getEnv, getWallet, walletVariables } from '../../src';
import { logger } from '@cardano-sdk/util-dev';
Expand Down Expand Up @@ -33,7 +32,6 @@ const wallet2Params: KeyAgentFactoryProps = {
describe('local-network/register-pool', () => {
let wallet1: TestWallet;
let wallet2: TestWallet;
const cryptoProvider = new Crypto.CmlEd25519Provider();

beforeAll(async () => {
jest.setTimeout(180_000);
Expand Down Expand Up @@ -76,6 +74,7 @@ describe('local-network/register-pool', () => {
role: KeyRole.External
});

const cryptoProvider = await poolKeyAgent.getCryptoProvider();
const poolKeyHash = await cryptoProvider.getPubKeyHash(poolPubKey);
const poolId = Cardano.PoolId.fromKeyHash(poolKeyHash);
const poolRewardAccount = (
Expand Down Expand Up @@ -157,6 +156,7 @@ describe('local-network/register-pool', () => {
role: KeyRole.External
});

const cryptoProvider = await poolKeyAgent.getCryptoProvider();
const poolKeyHash = await cryptoProvider.getPubKeyHash(poolPubKey);
const poolId = Cardano.PoolId.fromKeyHash(poolKeyHash);
const poolRewardAccount = (
Expand Down
3 changes: 1 addition & 2 deletions packages/e2e/test/long-running/cache-invalidation.test.ts
@@ -1,5 +1,4 @@
/* eslint-disable max-statements */
import * as Crypto from '@cardano-sdk/crypto';
import { AddressType, KeyRole } from '@cardano-sdk/key-management';
import { Cardano } from '@cardano-sdk/core';
import { KeyAgentFactoryProps, TestWallet, getEnv, getWallet, walletVariables } from '../../src';
Expand All @@ -26,7 +25,6 @@ const wallet1Params: KeyAgentFactoryProps = {

describe('cache invalidation', () => {
let wallet1: TestWallet;
const cryptoProvider = new Crypto.CmlEd25519Provider();

beforeAll(async () => {
jest.setTimeout(180_000);
Expand Down Expand Up @@ -57,6 +55,7 @@ describe('cache invalidation', () => {
role: KeyRole.External
});

const cryptoProvider = await poolKeyAgent.getCryptoProvider();
const poolKeyHash = await cryptoProvider.getPubKeyHash(poolPubKey);
const poolId = Cardano.PoolId.fromKeyHash(poolKeyHash);
const poolRewardAccount = (
Expand Down
10 changes: 8 additions & 2 deletions packages/e2e/test/util.ts
@@ -1,4 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as Crypto from '@cardano-sdk/crypto';
import * as envalid from 'envalid';
import { Cardano, createSlotEpochCalc } from '@cardano-sdk/core';
import {
Expand Down Expand Up @@ -239,13 +240,18 @@ export const submitCertificate = async (certificate: Cardano.Certificate, wallet
*
* @param mnemonics The random set of mnemonics.
* @param genesis Network genesis parameters
* @param cryptoProvider The Ed25519 cryptographic provider.
*/
export const createStandaloneKeyAgent = async (mnemonics: string[], genesis: Cardano.CompactGenesis) =>
export const createStandaloneKeyAgent = async (
mnemonics: string[],
genesis: Cardano.CompactGenesis,
cryptoProvider: Crypto.Ed25519Provider
) =>
await InMemoryKeyAgent.fromBip39MnemonicWords(
{
chainId: genesis,
getPassword: async () => Buffer.from(''),
mnemonicWords: mnemonics
},
{ inputResolver: { resolveInputAddress: async () => null }, logger }
{ cryptoProvider, inputResolver: { resolveInputAddress: async () => null }, logger }
);
10 changes: 6 additions & 4 deletions packages/e2e/test/wallet/SingleAddressWallet/mint.test.ts
@@ -1,5 +1,4 @@
/* eslint-disable sonarjs/no-duplicate-string */
import * as Crypto from '@cardano-sdk/crypto';
import { Cardano, nativeScriptPolicyId } from '@cardano-sdk/core';
import { KeyRole, util } from '@cardano-sdk/key-management';
import { SingleAddressWallet } from '@cardano-sdk/wallet';
Expand All @@ -13,7 +12,6 @@ const logger = createLogger();

describe('SingleAddressWallet/mint', () => {
let wallet: SingleAddressWallet;
const cryptoProvider = new Crypto.CmlEd25519Provider();

afterAll(() => {
wallet.shutdown();
Expand All @@ -26,15 +24,19 @@ describe('SingleAddressWallet/mint', () => {

const genesis = await firstValueFrom(wallet.genesisParameters$);

const aliceKeyAgent = await createStandaloneKeyAgent(util.generateMnemonicWords(), genesis);
const aliceKeyAgent = await createStandaloneKeyAgent(
util.generateMnemonicWords(),
genesis,
await wallet.keyAgent.getCryptoProvider()
);

const derivationPath = {
index: 0,
role: KeyRole.External
};

const alicePubKey = await aliceKeyAgent.derivePublicKey(derivationPath);
const aliceKeyHash = await cryptoProvider.getPubKeyHash(alicePubKey);
const aliceKeyHash = await aliceKeyAgent.cryptoProvider.getPubKeyHash(alicePubKey);

const alicePolicySigner = new util.KeyAgentTransactionSigner(aliceKeyAgent, derivationPath);

Expand Down
@@ -1,5 +1,4 @@
/* eslint-disable sonarjs/no-duplicate-string */
import * as Crypto from '@cardano-sdk/crypto';
import { Cardano, nativeScriptPolicyId } from '@cardano-sdk/core';
import { KeyRole, util } from '@cardano-sdk/key-management';
import { SingleAddressWallet } from '@cardano-sdk/wallet';
Expand All @@ -13,7 +12,6 @@ const logger = createLogger();

describe('SingleAddressWallet/multisignature', () => {
let wallet: SingleAddressWallet;
const cryptoProvider = new Crypto.CmlEd25519Provider();
const assetName = '3030303030';

afterAll(() => {
Expand All @@ -27,19 +25,27 @@ describe('SingleAddressWallet/multisignature', () => {

const genesis = await firstValueFrom(wallet.genesisParameters$);

const aliceKeyAgent = await createStandaloneKeyAgent(util.generateMnemonicWords(), genesis);
const bobKeyAgent = await createStandaloneKeyAgent(util.generateMnemonicWords(), genesis);
const aliceKeyAgent = await createStandaloneKeyAgent(
util.generateMnemonicWords(),
genesis,
await wallet.keyAgent.getCryptoProvider()
);
const bobKeyAgent = await createStandaloneKeyAgent(
util.generateMnemonicWords(),
genesis,
await wallet.keyAgent.getCryptoProvider()
);

const derivationPath = {
index: 0,
role: KeyRole.External
};

const alicePubKey = await aliceKeyAgent.derivePublicKey(derivationPath);
const aliceKeyHash = await cryptoProvider.getPubKeyHash(alicePubKey);
const aliceKeyHash = await aliceKeyAgent.cryptoProvider.getPubKeyHash(alicePubKey);

const bobPubKey = await bobKeyAgent.derivePublicKey(derivationPath);
const bobKeyHash = await cryptoProvider.getPubKeyHash(bobPubKey);
const bobKeyHash = await bobKeyAgent.cryptoProvider.getPubKeyHash(bobPubKey);

const alicePolicySigner = new util.KeyAgentTransactionSigner(aliceKeyAgent, derivationPath);
const bobPolicySigner = new util.KeyAgentTransactionSigner(bobKeyAgent, derivationPath);
Expand Down
10 changes: 6 additions & 4 deletions packages/e2e/test/wallet/SingleAddressWallet/nft.test.ts
@@ -1,5 +1,4 @@
/* eslint-disable sonarjs/no-duplicate-string */
import * as Crypto from '@cardano-sdk/crypto';
import { Cardano, metadatum, nativeScriptPolicyId } from '@cardano-sdk/core';
import { KeyRole, TransactionSigner, util } from '@cardano-sdk/key-management';
import { SingleAddressWallet } from '@cardano-sdk/wallet';
Expand All @@ -23,7 +22,6 @@ describe('SingleAddressWallet.assets/nft', () => {
let assetIds: Cardano.AssetId[];
let fingerprints: Cardano.AssetFingerprint[];
const assetNames = ['4e46542d66696c6573', '4e46542d303031', '4e46542d303032'];
const cryptoProvider = new Crypto.CmlEd25519Provider();
let walletAddress: Cardano.Address;

beforeAll(async () => {
Expand All @@ -33,14 +31,18 @@ describe('SingleAddressWallet.assets/nft', () => {

const genesis = await firstValueFrom(wallet.genesisParameters$);

const keyAgent = await createStandaloneKeyAgent(util.generateMnemonicWords(), genesis);
const keyAgent = await createStandaloneKeyAgent(
util.generateMnemonicWords(),
genesis,
await wallet.keyAgent.getCryptoProvider()
);

const pubKey = await keyAgent.derivePublicKey({
index: 0,
role: KeyRole.External
});

const keyHash = await cryptoProvider.getPubKeyHash(pubKey);
const keyHash = await keyAgent.cryptoProvider.getPubKeyHash(pubKey);

policySigner = new util.KeyAgentTransactionSigner(keyAgent, {
index: 0,
Expand Down
3 changes: 2 additions & 1 deletion packages/e2e/test/web-extension/extension/ui.ts
Expand Up @@ -9,7 +9,7 @@ import {
exposeApi
} from '@cardano-sdk/web-extension';
import { adaPriceServiceChannel, getObservableWalletName, userPromptServiceChannel, walletName } from './const';
import { keyManagementFactory } from '../../../src';
import { cryptoProviderFactory, keyManagementFactory } from '../../../src';

import { combineLatest, firstValueFrom, of } from 'rxjs';
import { runtime } from 'webextension-polyfill';
Expand Down Expand Up @@ -126,6 +126,7 @@ const createWallet = async (accountIndex: number) => {
)
)(dependencies),
createWallet: async () => wallet,
cryptoProvider: await cryptoProviderFactory.create(env.KEY_MANAGEMENT_PARAMS.cryptoProvider, null, logger),
logger
});

Expand Down
5 changes: 3 additions & 2 deletions packages/governance/test/integration/cip36KeyAgents.test.ts
Expand Up @@ -23,14 +23,15 @@ describe('cip36', () => {
// - it can also be a separate key agent, then it would be using a different seedphrase,
// but right now it's the only way to support voting when stake key is controlled by a HW device.
const votingKeyAgent: InMemoryKeyAgent = (await testKeyAgent()) as unknown as InMemoryKeyAgent;
votingKeyPair = util.toEd25519KeyPair(
votingKeyPair = await util.toEd25519KeyPair(
await votingKeyAgent.exportExtendedKeyPair([
cip36.VotingKeyDerivationPath.PURPOSE,
cip36.VotingKeyDerivationPath.COIN_TYPE,
walletKeyAgent.accountIndex, // using same account index as wallet's key agent here
0, // chain as per cip36
0 // address_index as per cip36
])
]),
votingKeyAgent.cryptoProvider
);
});

Expand Down
1 change: 1 addition & 0 deletions packages/key-management/package.json
Expand Up @@ -64,6 +64,7 @@
"@cardano-sdk/crypto": "^0.1.0",
"@cardano-sdk/dapp-connector": "^0.6.1",
"@cardano-sdk/util": "^0.7.0",
"@cardano-sdk/util-dev": "^0.6.0",
"@emurgo/cardano-message-signing-nodejs": "^1.0.1",
"@ledgerhq/hw-transport": "^6.27.2",
"@ledgerhq/hw-transport-node-hid-noevents": "^6.27.2",
Expand Down

0 comments on commit cf73daf

Please sign in to comment.