Skip to content

Commit

Permalink
refactor(wallet): remove direct dependency on @emurgo/cardano-seriali…
Browse files Browse the repository at this point in the history
…zation-lib-nodejs
  • Loading branch information
rhyslbw committed Sep 24, 2021
1 parent d161aae commit 0fadf84
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 73 deletions.
1 change: 0 additions & 1 deletion packages/wallet/package.json
Expand Up @@ -30,7 +30,6 @@
"@cardano-sdk/cardano-serialization-lib": "0.1.0",
"@cardano-sdk/cip2": "0.1.0",
"@cardano-sdk/core": "0.1.0",
"@emurgo/cardano-serialization-lib-nodejs": "^8.0.0",
"ts-log": "^2.2.3"
}
}
4 changes: 2 additions & 2 deletions packages/wallet/src/InMemoryUtxoRepository.ts
Expand Up @@ -3,7 +3,7 @@ import { UtxoRepository } from './UtxoRepository';
import { CardanoProvider, Ogmios } from '@cardano-sdk/core';
import { dummyLogger, Logger } from 'ts-log';
import { InputSelector, SelectionConstraints, SelectionResult } from '@cardano-sdk/cip2';
import CardanoSerializationLib from '@emurgo/cardano-serialization-lib-nodejs';
import { CSL } from '@cardano-sdk/cardano-serialization-lib';
import { KeyManager } from './KeyManagement';

export class InMemoryUtxoRepository implements UtxoRepository {
Expand Down Expand Up @@ -47,7 +47,7 @@ export class InMemoryUtxoRepository implements UtxoRepository {
}

public async selectInputs(
outputs: CardanoSerializationLib.TransactionOutputs,
outputs: CSL.TransactionOutputs,
constraints: SelectionConstraints
): Promise<SelectionResult> {
if (this.#utxoSet.size === 0) {
Expand Down
12 changes: 5 additions & 7 deletions packages/wallet/src/KeyManagement/KeyManager.ts
@@ -1,4 +1,4 @@
import CardanoSerializationLib from '@emurgo/cardano-serialization-lib-nodejs';
import { CSL } from '@cardano-sdk/cardano-serialization-lib';
import { Address } from '../';

export interface KeyManager {
Expand All @@ -8,10 +8,8 @@ export interface KeyManager {
signingIndex: number,
message: string
) => Promise<{ publicKey: string; signature: string }>;
publicKey: CardanoSerializationLib.PublicKey;
publicParentKey: CardanoSerializationLib.PublicKey;
signTransaction: (
txHash: CardanoSerializationLib.TransactionHash
) => Promise<CardanoSerializationLib.TransactionWitnessSet>;
stakeKey: CardanoSerializationLib.PublicKey;
publicKey: CSL.PublicKey;
publicParentKey: CSL.PublicKey;
signTransaction: (txHash: CSL.TransactionHash) => Promise<CSL.TransactionWitnessSet>;
stakeKey: CSL.PublicKey;
}
35 changes: 17 additions & 18 deletions packages/wallet/src/SingleAddressWallet.ts
@@ -1,5 +1,5 @@
import Schema from '@cardano-ogmios/schema';
import CardanoSerializationLib from '@emurgo/cardano-serialization-lib-nodejs';
import { CardanoSerializationLib, CSL } from '@cardano-sdk/cardano-serialization-lib';
import { CardanoProvider, Ogmios, Transaction } from '@cardano-sdk/core';
import { createTransactionInternals, KeyManagement, TxInternals, UtxoRepository } from './';
import { dummyLogger, Logger } from 'ts-log';
Expand All @@ -14,11 +14,8 @@ export type InitializeTxProps = {
export interface SingleAddressWallet {
address: Schema.Address;
initializeTx: (props: InitializeTxProps) => Promise<TxInternals>;
signTx: (
body: CardanoSerializationLib.TransactionBody,
hash: CardanoSerializationLib.TransactionHash
) => Promise<CardanoSerializationLib.Transaction>;
submitTx: (tx: CardanoSerializationLib.Transaction) => Promise<boolean>;
signTx: (body: CSL.TransactionBody, hash: CSL.TransactionHash) => Promise<CSL.Transaction>;
submitTx: (tx: CSL.Transaction) => Promise<boolean>;
}

const ensureValidityInterval = (
Expand All @@ -29,7 +26,7 @@ const ensureValidityInterval = (
({ invalidHereafter: currentSlot + 3600, ...validityInterval });

export const createSingleAddressWallet = async (
CSL: typeof CardanoSerializationLib,
csl: CardanoSerializationLib,
provider: CardanoProvider,
keyManager: KeyManagement.KeyManager,
utxoRepository: UtxoRepository,
Expand All @@ -42,13 +39,13 @@ export const createSingleAddressWallet = async (
initializeTx: async (props) => {
const tip = await provider.ledgerTip();
const validityInterval = ensureValidityInterval(tip.slot, props.options?.validityInterval);
const txOutputs = CSL.TransactionOutputs.new();
const txOutputs = csl.TransactionOutputs.new();
for (const output of props.outputs) {
txOutputs.add(Ogmios.OgmiosToCardanoWasm.txOut(output));
}
const inputSelectionResult = await utxoRepository.selectInputs(txOutputs, {
computeMinimumCost: async ({ utxo, outputs, change }) => {
const transactionInternals = await createTransactionInternals(CSL, {
const transactionInternals = await createTransactionInternals(csl, {
changeAddress: address,
inputSelection: {
outputs,
Expand All @@ -59,15 +56,17 @@ export const createSingleAddressWallet = async (
validityInterval
});
const witnessSet = await keyManager.signTransaction(transactionInternals.hash);
const tx = CSL.Transaction.new(transactionInternals.body, witnessSet);
const tx = csl.Transaction.new(transactionInternals.body, witnessSet);
return BigInt(
CSL.min_fee(
tx,
CSL.LinearFee.new(
CSL.BigNum.from_str(protocolParameters.minFeeCoefficient.toString()),
CSL.BigNum.from_str(protocolParameters.minFeeConstant.toString())
csl
.min_fee(
tx,
csl.LinearFee.new(
csl.BigNum.from_str(protocolParameters.minFeeCoefficient.toString()),
csl.BigNum.from_str(protocolParameters.minFeeConstant.toString())
)
)
).to_str()
.to_str()
);
},
tokenBundleSizeExceedsLimit: (tokenBundle) => {
Expand All @@ -83,15 +82,15 @@ export const createSingleAddressWallet = async (
return 5;
}
});
return createTransactionInternals(CSL, {
return createTransactionInternals(csl, {
changeAddress: address,
inputSelection: inputSelectionResult.selection,
validityInterval
});
},
signTx: async (body, hash) => {
const witnessSet = await keyManager.signTransaction(hash);
return CSL.Transaction.new(body, witnessSet);
return csl.Transaction.new(body, witnessSet);
},
submitTx: async (tx) => provider.submitTx(tx)
};
Expand Down
7 changes: 2 additions & 5 deletions packages/wallet/src/UtxoRepository.ts
@@ -1,14 +1,11 @@
import Schema from '@cardano-ogmios/schema';
import { SelectionConstraints, SelectionResult } from '@cardano-sdk/cip2';
import CardanoSerializationLib from '@emurgo/cardano-serialization-lib-nodejs';
import { CSL } from '@cardano-sdk/cardano-serialization-lib';

export interface UtxoRepository {
allUtxos: Schema.Utxo;
rewards: Schema.Lovelace;
delegation: Schema.PoolId;
sync: () => Promise<void>;
selectInputs: (
outputs: CardanoSerializationLib.TransactionOutputs,
constraints: SelectionConstraints
) => Promise<SelectionResult>;
selectInputs: (outputs: CSL.TransactionOutputs, constraints: SelectionConstraints) => Promise<SelectionResult>;
}
17 changes: 8 additions & 9 deletions packages/wallet/src/createTransactionInternals.ts
@@ -1,11 +1,10 @@
// Importing types from cardano-serialization-lib-browser will cause TypeScript errors.
import CardanoSerializationLib from '@emurgo/cardano-serialization-lib-nodejs';
import { CardanoSerializationLib, CSL } from '@cardano-sdk/cardano-serialization-lib';
import { SelectionResult } from '@cardano-sdk/cip2';
import { Transaction } from '@cardano-sdk/core';

export type TxInternals = {
hash: CardanoSerializationLib.TransactionHash;
body: CardanoSerializationLib.TransactionBody;
hash: CSL.TransactionHash;
body: CSL.TransactionBody;
};

export type CreateTxInternalsProps = {
Expand All @@ -15,24 +14,24 @@ export type CreateTxInternalsProps = {
};

export const createTransactionInternals = async (
cardanoSerializationLib: typeof CardanoSerializationLib,
csl: CardanoSerializationLib,
props: CreateTxInternalsProps
): Promise<TxInternals> => {
const inputs = cardanoSerializationLib.TransactionInputs.new();
const inputs = csl.TransactionInputs.new();
for (const utxo of props.inputSelection.inputs) {
inputs.add(utxo.input());
}
const body = cardanoSerializationLib.TransactionBody.new(
const body = csl.TransactionBody.new(
inputs,
props.inputSelection.outputs,
cardanoSerializationLib.BigNum.from_str(props.inputSelection.fee.toString()),
csl.BigNum.from_str(props.inputSelection.fee.toString()),
props.validityInterval.invalidHereafter
);
if (props.validityInterval.invalidBefore !== undefined) {
body.set_validity_start_interval(props.validityInterval.invalidBefore);
}
return {
body,
hash: cardanoSerializationLib.hash_transaction(body)
hash: csl.hash_transaction(body)
};
};
11 changes: 5 additions & 6 deletions packages/wallet/test/InMemoryUtxoRepository.test.ts
Expand Up @@ -2,8 +2,7 @@ import { CardanoProvider, Ogmios } from '@cardano-sdk/core';
import { UtxoRepository } from '@src/UtxoRepository';
import { InMemoryUtxoRepository } from '@src/InMemoryUtxoRepository';
import { roundRobinRandomImprove, InputSelector } from '@cardano-sdk/cip2';
import CardanoSerializationLib from '@emurgo/cardano-serialization-lib-nodejs';
import { loadCardanoSerializationLib } from '@cardano-sdk/cardano-serialization-lib';
import { loadCardanoSerializationLib, CardanoSerializationLib, CSL } from '@cardano-sdk/cardano-serialization-lib';
import { providerStub, delegate, rewards } from './ProviderStub';
import { createInMemoryKeyManager, util } from '@cardano-sdk/in-memory-key-manager';
import { NO_CONSTRAINTS } from './util';
Expand All @@ -18,7 +17,7 @@ const addresses = [
// { txId: '08fc1f8af3abbc8fc1f8a466e6e754833a08a62a059bf059bf5483a8a66e6e74', index: 0 }
// ];

const outputs = CardanoSerializationLib.TransactionOutputs.new();
const outputs = CSL.TransactionOutputs.new();

outputs.add(
Ogmios.OgmiosToCardanoWasm.txOut({
Expand All @@ -39,12 +38,12 @@ describe('InMemoryUtxoRepository', () => {
let utxoRepository: UtxoRepository;
let provider: CardanoProvider;
let inputSelector: InputSelector;
let cardanoSerializationLib: typeof CardanoSerializationLib;
let csl: CardanoSerializationLib;

beforeEach(async () => {
provider = providerStub();
cardanoSerializationLib = await loadCardanoSerializationLib();
inputSelector = roundRobinRandomImprove(cardanoSerializationLib);
csl = await loadCardanoSerializationLib();
inputSelector = roundRobinRandomImprove(csl);
const keyManager = createInMemoryKeyManager({
mnemonic: util.generateMnemonic(),
networkId: 0,
Expand Down
21 changes: 8 additions & 13 deletions packages/wallet/test/SingleAddressWallet.test.ts
@@ -1,41 +1,36 @@
/* eslint-disable max-len */

// All types should be imported from cardano-serialization-lib-nodejs.
// Importing from cardano-serialization-lib-browser will cause TypeScript errors.
// Do not create objects from direct imports of serialization lib, use @cardano-sdk/cardano-serialization-lib.

import { createSingleAddressWallet, SingleAddressWallet } from '@src/SingleAddressWallet';
import * as KeyManagement from '@src/KeyManagement';
import { Cardano, CardanoProvider } from '@cardano-sdk/core';
import { createInMemoryKeyManager, util } from '@cardano-sdk/in-memory-key-manager';
import CardanoSerializationLib from '@emurgo/cardano-serialization-lib-nodejs';
import { loadCardanoSerializationLib } from '@cardano-sdk/cardano-serialization-lib';
import { loadCardanoSerializationLib, CardanoSerializationLib } from '@cardano-sdk/cardano-serialization-lib';
import { InMemoryUtxoRepository } from '@src/InMemoryUtxoRepository';
import { UtxoRepository } from '@src/UtxoRepository';
import { InputSelector, roundRobinRandomImprove } from '@cardano-sdk/cip2';
import { providerStub } from './ProviderStub';

describe('Wallet', () => {
let CSL: typeof CardanoSerializationLib;
let csl: CardanoSerializationLib;
let inputSelector: InputSelector;
let keyManager: KeyManagement.KeyManager;
let provider: CardanoProvider;
let utxoRepository: UtxoRepository;

beforeEach(async () => {
CSL = await loadCardanoSerializationLib();
csl = await loadCardanoSerializationLib();
keyManager = createInMemoryKeyManager({
mnemonic: util.generateMnemonic(),
networkId: Cardano.NetworkId.testnet,
password: '123'
});
provider = providerStub();
inputSelector = roundRobinRandomImprove(CSL);
inputSelector = roundRobinRandomImprove(csl);
utxoRepository = new InMemoryUtxoRepository(provider, keyManager, inputSelector);
});

test('createWallet', async () => {
const wallet = await createSingleAddressWallet(CSL, provider, keyManager, utxoRepository);
const wallet = await createSingleAddressWallet(csl, provider, keyManager, utxoRepository);
expect(wallet.address).toBeDefined();
expect(typeof wallet.initializeTx).toBe('function');
expect(typeof wallet.signTx).toBe('function');
Expand All @@ -54,13 +49,13 @@ describe('Wallet', () => {
};

beforeEach(async () => {
wallet = await createSingleAddressWallet(CSL, provider, keyManager, utxoRepository);
wallet = await createSingleAddressWallet(csl, provider, keyManager, utxoRepository);
});

test('initializeTx', async () => {
const txInternals = await wallet.initializeTx(props);
expect(txInternals.body).toBeInstanceOf(CSL.TransactionBody);
expect(txInternals.hash).toBeInstanceOf(CSL.TransactionHash);
expect(txInternals.body).toBeInstanceOf(csl.TransactionBody);
expect(txInternals.hash).toBeInstanceOf(csl.TransactionHash);
});

test('signTx', async () => {
Expand Down
20 changes: 8 additions & 12 deletions packages/wallet/test/createTransactionInternals.test.ts
@@ -1,8 +1,4 @@
// All types should be imported from cardano-serialization-lib-nodejs.
// Importing from cardano-serialization-lib-browser will cause TypeScript errors.
// Do not create objects from direct imports of serialization lib, use @cardano-sdk/cardano-serialization-lib.
import CardanoSerializationLib from '@emurgo/cardano-serialization-lib-nodejs';
import { loadCardanoSerializationLib } from '@cardano-sdk/cardano-serialization-lib';
import { loadCardanoSerializationLib, CardanoSerializationLib, CSL } from '@cardano-sdk/cardano-serialization-lib';
import { createTransactionInternals } from '@src/createTransactionInternals';
import { InputSelector, roundRobinRandomImprove } from '@cardano-sdk/cip2';
import { Cardano, CardanoProvider, Ogmios } from '@cardano-sdk/core';
Expand All @@ -15,7 +11,7 @@ import { NO_CONSTRAINTS } from './util';
const address =
'addr_test1qq585l3hyxgj3nas2v3xymd23vvartfhceme6gv98aaeg9muzcjqw982pcftgx53fu5527z2cj2tkx2h8ux2vxsg475q2g7k3g';

const outputs = CardanoSerializationLib.TransactionOutputs.new();
const outputs = CSL.TransactionOutputs.new();

outputs.add(
Ogmios.OgmiosToCardanoWasm.txOut({
Expand All @@ -33,15 +29,15 @@ outputs.add(
);

describe('createTransactionInternals', () => {
let CSL: typeof CardanoSerializationLib;
let csl: CardanoSerializationLib;
let provider: CardanoProvider;
let inputSelector: InputSelector;
let utxoRepository: UtxoRepository;

beforeEach(async () => {
CSL = await loadCardanoSerializationLib();
csl = await loadCardanoSerializationLib();
provider = providerStub();
inputSelector = roundRobinRandomImprove(CSL);
inputSelector = roundRobinRandomImprove(csl);
const keyManager = createInMemoryKeyManager({
mnemonic: util.generateMnemonic(),
networkId: Cardano.NetworkId.testnet,
Expand All @@ -53,14 +49,14 @@ describe('createTransactionInternals', () => {
test('simple transaction', async () => {
const result = await utxoRepository.selectInputs(outputs, NO_CONSTRAINTS);
const ledgerTip = await provider.ledgerTip();
const { body, hash } = await createTransactionInternals(CSL, {
const { body, hash } = await createTransactionInternals(csl, {
changeAddress: 'addr_test1gz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspqgpsqe70et',
inputSelection: result.selection,
validityInterval: {
invalidHereafter: ledgerTip.slot + 3600
}
});
expect(body).toBeInstanceOf(CardanoSerializationLib.TransactionBody);
expect(hash).toBeInstanceOf(CardanoSerializationLib.TransactionHash);
expect(body).toBeInstanceOf(csl.TransactionBody);
expect(hash).toBeInstanceOf(csl.TransactionHash);
});
});

0 comments on commit 0fadf84

Please sign in to comment.