Skip to content

Commit

Permalink
feat: add Trezor conway era certificates
Browse files Browse the repository at this point in the history
  • Loading branch information
AngelCastilloB committed Sep 4, 2024
1 parent 2ef1f57 commit fac6b73
Show file tree
Hide file tree
Showing 12 changed files with 1,081 additions and 289 deletions.
4 changes: 2 additions & 2 deletions packages/hardware-trezor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
"@cardano-sdk/key-management": "workspace:~",
"@cardano-sdk/tx-construction": "workspace:~",
"@cardano-sdk/util": "workspace:~",
"@trezor/connect": "9.1.6",
"@trezor/connect-web": "9.1.6",
"@trezor/connect": "9.4.0",
"@trezor/connect-web": "9.4.0",
"lodash": "^4.17.21",
"ts-custom-error": "^3.2.0",
"ts-log": "^2.2.4"
Expand Down
1 change: 1 addition & 0 deletions packages/hardware-trezor/src/TrezorKeyAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export class TrezorKeyAgent extends KeyAgentBase {
accountIndex: this.accountIndex,
chainId: this.chainId,
knownAddresses,
tagCborSets: txBody.hasTaggedSets(),
txInKeyPathMap
});

Expand Down
100 changes: 100 additions & 0 deletions packages/hardware-trezor/src/transformers/certificates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export const getStakeAddressCertificate: Transform<
? Trezor.PROTO.CardanoCertificateType.STAKE_REGISTRATION
: Trezor.PROTO.CardanoCertificateType.STAKE_DEREGISTRATION;
return {
dRep: undefined,
deposit: undefined,
keyHash: credentials.keyHash,
path: credentials.path,
pool: undefined,
Expand All @@ -85,6 +87,8 @@ export const getStakeDelegationCertificate: Transform<
context?.knownAddresses
);
return {
dRep: undefined,
deposit: undefined,
keyHash: credentials.keyHash,
path: credentials.path,
pool: poolIdKeyHash,
Expand All @@ -94,6 +98,92 @@ export const getStakeDelegationCertificate: Transform<
};
};

export const getNewStakeAddressCertificate: Transform<
Cardano.NewStakeAddressCertificate,
Trezor.CardanoCertificate,
TrezorTxTransformerContext
> = (certificate, context) => {
const credentials = getCertCredentials(
certificate.stakeCredential.hash as unknown as Crypto.Ed25519KeyHashHex,
context?.knownAddresses
);
const certificateType =
certificate.__typename === Cardano.CertificateType.Registration
? Trezor.PROTO.CardanoCertificateType.STAKE_REGISTRATION_CONWAY
: Trezor.PROTO.CardanoCertificateType.STAKE_DEREGISTRATION_CONWAY;

return {
dRep: undefined,
deposit: certificate.deposit.toString(),
keyHash: credentials.keyHash,
path: credentials.path,
pool: undefined,
poolParameters: undefined,
scriptHash: credentials.scriptHash,
type: certificateType
};
};

const drepParamsMapper = (drep: Cardano.Credential, credentialType: Cardano.CredentialType) => {
let dRepParams;

switch (credentialType) {
case Cardano.CredentialType.KeyHash: {
dRepParams = {
keyHash: drep.hash,
type: Trezor.PROTO.CardanoDRepType.KEY_HASH
};
break;
}
case Cardano.CredentialType.ScriptHash:
default: {
dRepParams = {
scriptHash: drep.hash,
type: Trezor.PROTO.CardanoDRepType.SCRIPT_HASH
};
}
}

return dRepParams;
};

const drepMapper = (drep: Cardano.DelegateRepresentative) => {
if (Cardano.isDRepAlwaysAbstain(drep)) {
return {
type: Trezor.PROTO.CardanoDRepType.ABSTAIN
};
} else if (Cardano.isDRepAlwaysNoConfidence(drep)) {
return {
type: Trezor.PROTO.CardanoDRepType.NO_CONFIDENCE
};
} else if (Cardano.isDRepCredential(drep)) {
return drepParamsMapper(drep, drep.type);
}
throw new Error('incorrect drep supplied');
};

export const voteDelegationCertificate: Transform<
Cardano.VoteDelegationCertificate,
Trezor.CardanoCertificate,
TrezorTxTransformerContext
> = (certificate, context) => {
const credentials = getCertCredentials(
certificate.stakeCredential.hash as unknown as Crypto.Ed25519KeyHashHex,
context?.knownAddresses
);

return {
dRep: drepMapper(certificate.dRep),
deposit: undefined,
keyHash: credentials.keyHash,
path: credentials.path,
pool: undefined,
poolParameters: undefined,
scriptHash: credentials.scriptHash,
type: Trezor.PROTO.CardanoCertificateType.VOTE_DELEGATION
};
};

export const getPoolRegistrationCertificate: Transform<
Cardano.PoolRegistrationCertificate,
Trezor.CardanoCertificate,
Expand All @@ -102,6 +192,8 @@ export const getPoolRegistrationCertificate: Transform<
if (!certificate.poolParameters.metadataJson)
throw new InvalidArgumentError('certificate', 'Missing pool registration pool metadata.');
return {
dRep: undefined,
deposit: undefined,
keyHash: undefined,
path: undefined,
pool: undefined,
Expand Down Expand Up @@ -161,6 +253,14 @@ const toCert = (cert: Cardano.Certificate, context: TrezorTxTransformerContext)
return getStakeDelegationCertificate(cert, context);
case Cardano.CertificateType.PoolRegistration:
return getPoolRegistrationCertificate(cert, context);

// Supported Conway Era Certs
case Cardano.CertificateType.Registration:
return getNewStakeAddressCertificate(cert, context);
case Cardano.CertificateType.Unregistration:
return getNewStakeAddressCertificate(cert, context);
case Cardano.CertificateType.VoteDelegation:
return voteDelegationCertificate(cert, context);
default:
throw new InvalidArgumentError('cert', `Certificate ${cert.__typename} not supported.`);
}
Expand Down
6 changes: 5 additions & 1 deletion packages/hardware-trezor/src/transformers/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { mapTokenMap } from './assets';

export const trezorTxTransformer: Transformer<
Cardano.TxBody,
Omit<Trezor.CardanoSignTransaction, 'signingMode' | 'derivationType' | 'includeNetworkId'>,
Omit<Trezor.CardanoSignTransaction, 'signingMode' | 'derivationType' | 'includeNetworkId' | 'chunkify' | 'ttl'> & {
/* eslint-disable @typescript-eslint/no-explicit-any */
ttl: any; // TODO: the Transformer util cant handle ttl as TOptional<string | number>
},
TrezorTxTransformerContext
> = {
additionalWitnessRequests: ({ inputs }, context) => mapAdditionalWitnessRequests(inputs, context!),
Expand All @@ -28,6 +31,7 @@ export const trezorTxTransformer: Transformer<
requiredSigners: ({ requiredExtraSignatures }, context) =>
requiredExtraSignatures ? mapRequiredSigners(requiredExtraSignatures, context!) : undefined,
scriptDataHash: ({ scriptIntegrityHash }) => scriptIntegrityHash?.toString(),
tagCborSets: (_, context) => context!.tagCborSets,
totalCollateral: ({ totalCollateral }) => totalCollateral?.toString(),
ttl: ({ validityInterval }) => validityInterval?.invalidHereafter?.toString(),
validityIntervalStart: ({ validityInterval }) => validityInterval?.invalidBefore?.toString(),
Expand Down
2 changes: 2 additions & 0 deletions packages/hardware-trezor/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export type TrezorTxTransformerContext = {
chainId: Cardano.ChainId;
/** Non-hardened account in cip1852 */
accountIndex: number;
/** Whether sets should be encoded as tagged set in CBOR */
tagCborSets: boolean;
} & SignTransactionContext;

export type TrezorTxOutputDestination =
Expand Down
6 changes: 4 additions & 2 deletions packages/hardware-trezor/test/TrezorKeyAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ describe('TrezorKeyAgent', () => {
inputs: [txInWithPath],
networkId: 0,
outputs: [txOutToOwnedAddress],
protocolMagic: 999
protocolMagic: 999,
ttl: 999
};

const validMultisigTx: Omit<Trezor.CardanoSignTransaction, 'signingMode'> = {
Expand All @@ -58,7 +59,8 @@ describe('TrezorKeyAgent', () => {
networkId: 0,
// All third party outputs
outputs: [txOut],
protocolMagic: 999
protocolMagic: 999,
ttl: 999
};

const poolRegistrationCertificate = {
Expand Down
12 changes: 12 additions & 0 deletions packages/hardware-trezor/test/testData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,18 @@ export const stakeDeregistrationCertificate = {
stakeCredential
} as Cardano.StakeAddressCertificate;

export const conwayRegistrationCertificate = {
__typename: Cardano.CertificateType.Registration,
deposit: 10_000_000n,
stakeCredential
} as Cardano.NewStakeAddressCertificate;

export const conwayDeregistrationCertificate = {
__typename: Cardano.CertificateType.Unregistration,
deposit: 10_000_000n,
stakeCredential
} as Cardano.NewStakeAddressCertificate;

export const stakeDelegationCertificate = {
__typename: Cardano.CertificateType.StakeDelegation,
poolId: poolId2,
Expand Down
Loading

0 comments on commit fac6b73

Please sign in to comment.