Skip to content

Commit

Permalink
fixup! feat: sign new certificate types
Browse files Browse the repository at this point in the history
  • Loading branch information
vetalcore committed Apr 23, 2024
1 parent 3e09025 commit f2f491e
Show file tree
Hide file tree
Showing 14 changed files with 917 additions and 128 deletions.
2 changes: 1 addition & 1 deletion packages/e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"access": "public"
},
"dependencies": {
"@cardano-foundation/ledgerjs-hw-app-cardano": "^7.0.0",
"@cardano-foundation/ledgerjs-hw-app-cardano": "^7.1.2",
"@cardano-ogmios/client": "5.6.0",
"@cardano-sdk/cardano-services": "workspace:~",
"@cardano-sdk/cardano-services-client": "workspace:~",
Expand Down
2 changes: 1 addition & 1 deletion packages/hardware-ledger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"typescript": "^4.7.4"
},
"dependencies": {
"@cardano-foundation/ledgerjs-hw-app-cardano": "^7.0.0",
"@cardano-foundation/ledgerjs-hw-app-cardano": "^7.1.2",
"@cardano-sdk/core": "workspace:~",
"@cardano-sdk/crypto": "workspace:~",
"@cardano-sdk/key-management": "workspace:~",
Expand Down
3 changes: 2 additions & 1 deletion packages/hardware-ledger/src/LedgerKeyAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,12 +533,13 @@ export class LedgerKeyAgent extends KeyAgentBase {
// TODO: Allow additional key paths
async signTransaction(
{ body, hash }: Cardano.TxBodyWithHash,
{ knownAddresses, txInKeyPathMap }: SignTransactionContext
{ knownAddresses, txInKeyPathMap, dRepPublicKey }: SignTransactionContext
): Promise<Cardano.Signatures> {
try {
const ledgerTxData = await toLedgerTx(body, {
accountIndex: this.accountIndex,
chainId: this.chainId,
dRepPublicKey,
knownAddresses,
txInKeyPathMap
});
Expand Down
44 changes: 33 additions & 11 deletions packages/hardware-ledger/src/transformers/certificates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,21 +289,24 @@ const poolRetirementCertificate: Transform<
};
};

const checkDrepPublicKeyAgainstCredential = (
const checkDrepPublicKeyAgainstCredential = async (
dRepPublicKey: Crypto.Ed25519PublicKeyHex | undefined,
hash: Crypto.Hash28ByteBase16
) => {
if (!dRepPublicKey || dRepPublicKey !== Crypto.Ed25519PublicKeyHex(hash)) {
if (
!dRepPublicKey ||
(await Crypto.Ed25519PublicKey.fromHex(dRepPublicKey).hash()).hex() !== Crypto.Ed25519KeyHashHex(hash)
) {
throw new InvalidArgumentError('certificate', 'dRepPublicKey does not match certificate drep credential.');
}
};

const drepRegistrationCertificate: Transform<
Cardano.RegisterDelegateRepresentativeCertificate | Cardano.UnRegisterDelegateRepresentativeCertificate,
Ledger.Certificate,
Promise<Ledger.Certificate>,
LedgerTxTransformerContext
> = (certificate, context): Ledger.Certificate => {
checkDrepPublicKeyAgainstCredential(context?.dRepPublicKey, certificate.dRepCredential.hash);
> = async (certificate, context): Promise<Ledger.Certificate> => {
await checkDrepPublicKeyAgainstCredential(context?.dRepPublicKey, certificate.dRepCredential.hash);

const params: Ledger.DRepRegistrationParams = {
...mapAnchorToParams(certificate),
Expand All @@ -320,6 +323,24 @@ const drepRegistrationCertificate: Transform<
};
};

const updateDRepCertificate: Transform<
Cardano.UpdateDelegateRepresentativeCertificate,
Promise<Ledger.Certificate>,
LedgerTxTransformerContext
> = async (certificate, context): Promise<Ledger.Certificate> => {
await checkDrepPublicKeyAgainstCredential(context?.dRepPublicKey, certificate.dRepCredential.hash);

const params: Ledger.DRepUpdateParams = {
...mapAnchorToParams(certificate),
dRepCredential: credentialMapper(certificate.dRepCredential, certificate.dRepCredential.type, null)
};

return {
params,
type: Ledger.CertificateType.DREP_UPDATE
};
};

const drepMapper = (drep: Cardano.DelegateRepresentative, context: LedgerTxTransformerContext): Ledger.DRepParams => {
if (Cardano.isDRepAlwaysAbstain(drep)) {
return {
Expand Down Expand Up @@ -351,7 +372,7 @@ export const voteDelegationCertificate: Transform<
type: Ledger.CertificateType.VOTE_DELEGATION
});

const toCert = (cert: Cardano.Certificate, context: LedgerTxTransformerContext): Ledger.Certificate => {
const toCert = async (cert: Cardano.Certificate, context: LedgerTxTransformerContext): Promise<Ledger.Certificate> => {
switch (cert.__typename) {
case Cardano.CertificateType.StakeRegistration:
return getStakeAddressCertificate(cert, context);
Expand All @@ -376,20 +397,21 @@ const toCert = (cert: Cardano.Certificate, context: LedgerTxTransformerContext):
case Cardano.CertificateType.ResignCommitteeCold:
return getResignCommitteeColdCertificate(cert, context);
case Cardano.CertificateType.RegisterDelegateRepresentative:
return drepRegistrationCertificate(cert, context);
return await drepRegistrationCertificate(cert, context);
case Cardano.CertificateType.UnregisterDelegateRepresentative:
return drepRegistrationCertificate(cert, context);
return await drepRegistrationCertificate(cert, context);
case Cardano.CertificateType.UpdateDelegateRepresentative:
return await updateDRepCertificate(cert, context);
default:
throw new InvalidArgumentError('cert', `Certificate ${cert.__typename} not supported.`);
}
};

export const mapCerts = (
export const mapCerts = async (
certs: Cardano.Certificate[] | undefined,
context: LedgerTxTransformerContext
): Ledger.Certificate[] | null => {
): Promise<Ledger.Certificate[] | null> => {
if (!certs) return null;

return certs.map((coreCert) => toCert(coreCert, context));
return Promise.all(certs.map((coreCert) => toCert(coreCert, context)));
};
2 changes: 1 addition & 1 deletion packages/hardware-ledger/src/transformers/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import { mapRequiredSigners } from './requiredSigners';
import { mapTokenMap } from './assets';
import { mapTxIns } from './txIn';
import { mapTxOuts } from './txOut';
import { mapWithdrawals } from './withdrawals';
import { mapVotingProcedures } from './votingProcedures';
import { mapWithdrawals } from './withdrawals';

export const LedgerTxTransformer: Transformer<Cardano.TxBody, Ledger.Transaction, LedgerTxTransformerContext> = {
auxiliaryData: ({ auxiliaryDataHash }) => mapAuxiliaryData(auxiliaryDataHash),
Expand Down
35 changes: 16 additions & 19 deletions packages/hardware-ledger/src/transformers/votingProcedures.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import {
Vote as LedgerVote,
Voter as LedgerVoter,
VoterVotes,
VoterType as LedgerVoterType,
Vote as LedgerVote,
VoteOption
VoteOption,
VoterVotes
} from '@cardano-foundation/ledgerjs-hw-app-cardano';
// import { LedgerTxTransformerContext } from '../types';

import { Cardano } from '@cardano-sdk/core';

const mapVoter = (voter: Cardano.Voter): LedgerVoter => {
switch (voter.__typename) {
case Cardano.VoterType.dRepKeyHash: {
return {
type: LedgerVoterType.DREP_KEY_HASH,
keyHashHex: voter.credential.hash
keyHashHex: voter.credential.hash,
type: LedgerVoterType.DREP_KEY_HASH
};
}
case Cardano.VoterType.dRepScriptHash: {
return {
type: LedgerVoterType.DREP_SCRIPT_HASH,
scriptHashHex: voter.credential.hash
scriptHashHex: voter.credential.hash,
type: LedgerVoterType.DREP_SCRIPT_HASH
};
}
case Cardano.VoterType.stakePoolKeyHash: {
return {
type: LedgerVoterType.STAKE_POOL_KEY_HASH,
keyHashHex: voter.credential.hash
keyHashHex: voter.credential.hash,
type: LedgerVoterType.STAKE_POOL_KEY_HASH
};
}

Expand All @@ -44,8 +44,6 @@ const mapVote = (vote: Cardano.Vote): VoteOption => {
return VoteOption.ABSTAIN;
case Cardano.Vote.no:
return VoteOption.NO;
default:
throw new Error('unknown vote option');
}
};

Expand All @@ -54,23 +52,22 @@ const mapVotes = (
actionId: Cardano.GovernanceActionId;
votingProcedure: Cardano.VotingProcedure;
}>
): Array<LedgerVote> => {
return votes.map((vote) => ({
): Array<LedgerVote> =>
votes.map((vote) => ({
govActionId: {
txHashHex: vote.actionId.id,
govActionIndex: vote.actionId.actionIndex
govActionIndex: vote.actionId.actionIndex,
txHashHex: vote.actionId.id
},
votingProcedure: {
vote: mapVote(vote.votingProcedure.vote),
...(vote.votingProcedure.anchor && {
anchor: {
url: vote.votingProcedure.anchor.url,
hashHex: vote.votingProcedure.anchor.dataHash
hashHex: vote.votingProcedure.anchor.dataHash,
url: vote.votingProcedure.anchor.url
}
})
}
}));
};

export const mapVotingProcedures = (
votingProcedures: Cardano.VotingProcedures | undefined
Expand Down

0 comments on commit f2f491e

Please sign in to comment.