Skip to content

Commit

Permalink
feat(connect): add validation schema to cardanoComposeTransaction
Browse files Browse the repository at this point in the history
  • Loading branch information
martykan committed Jan 14, 2025
1 parent ab8cd6e commit 36c817f
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 17 deletions.
22 changes: 8 additions & 14 deletions packages/connect/src/api/cardano/api/cardanoComposeTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { trezorUtils, CoinSelectionError } from '@fivebinaries/coin-selection';

import { AssertWeak } from '@trezor/schema-utils';

import { AbstractMethod } from '../../../core/AbstractMethod';
import { validateParams } from '../../common/paramsValidator';
import { composeTxPlan } from '../cardanoUtils';
import type {
CardanoComposeTransactionParams,
PrecomposedTransactionCardano,
import {
CardanoComposeTransactionParamsSchema,
type CardanoComposeTransactionParams,
type PrecomposedTransactionCardano,
} from '../../../types/api/cardanoComposeTransaction';

export default class CardanoComposeTransaction extends AbstractMethod<
Expand All @@ -16,16 +18,8 @@ export default class CardanoComposeTransaction extends AbstractMethod<
const { payload } = this;

// validate incoming parameters
validateParams(payload, [
{ name: 'account', type: 'object', required: true },
{ name: 'feeLevels', type: 'array' },
{ name: 'outputs', type: 'array' },
{ name: 'certificates', type: 'array', allowEmpty: true },
{ name: 'withdrawals', type: 'array', allowEmpty: true },
{ name: 'changeAddress', type: 'object', required: true },
{ name: 'addressParameters', type: 'object', required: true },
{ name: 'testnet', type: 'boolean' },
]);
// TODO: weak assert for compatibility purposes (issue #10841)
AssertWeak(CardanoComposeTransactionParamsSchema, payload);

this.useDevice = false;
this.useDeviceState = false;
Expand Down
136 changes: 134 additions & 2 deletions packages/connect/src/types/api/cardanoComposeTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import type { types, trezorUtils } from '@fivebinaries/coin-selection';

import { Static, Type } from '@trezor/schema-utils';

import { PROTO } from '../../exports';
import type { AccountAddresses, AccountUtxo } from '../../exports';
import type { Params, Response } from '../params';
import type { CardanoCertificate, CardanoInput, CardanoOutput } from './cardano';
import { DerivationPath, type Params, type Response } from '../params';
import { CardanoCertificatePointer, CardanoCertificate } from './cardano';
import type { CardanoInput, CardanoOutput } from './cardano';
import type {
PrecomposeResultFinal,
PrecomposeResultNonFinal,
Expand Down Expand Up @@ -39,6 +43,20 @@ export type PrecomposedTransactionCardano =
| PrecomposedTransactionNonFinalCardano
| PrecomposedTransactionErrorCardano;

export const AccountAddress = Type.Object(
{
address: Type.String(),
path: Type.String(),
transfers: Type.Number(),
balance: Type.Optional(Type.String()),
sent: Type.Optional(Type.String()),
received: Type.Optional(Type.String()),
},
{
$id: 'AccountAddress',
},
);

export type CardanoComposeTransactionParams = {
account: {
descriptor: string;
Expand All @@ -54,6 +72,120 @@ export type CardanoComposeTransactionParams = {
testnet?: boolean;
};

// Typebox schema for CardanoComposeTransactionParams, used in Explorer
export type CardanoComposeTransactionParamsSchema = Static<
typeof CardanoComposeTransactionParamsSchema
>;
export const CardanoComposeTransactionParamsSchema = Type.Object({
account: Type.Object({
descriptor: Type.String(),
addresses: Type.Object({
change: Type.Array(AccountAddress),
used: Type.Array(AccountAddress),
unused: Type.Array(AccountAddress),
}),
utxo: Type.Array(
Type.Object(
{
txid: Type.String(),
vout: Type.Number(),
amount: Type.String(),
blockHeight: Type.Number(),
address: Type.String(),
path: Type.String(),
confirmations: Type.Number(),
coinbase: Type.Optional(Type.Boolean()),
cardanoSpecific: Type.Optional(
Type.Object({
unit: Type.String(),
}),
),
},
{ $id: 'AccountUtxo' },
),
),
}),
feeLevels: Type.Optional(
Type.Array(
Type.Object({
feePerUnit: Type.Optional(Type.String()),
}),
),
),
outputs: Type.Optional(
Type.Array(
Type.Intersect(
[
Type.Object(
{
isChange: Type.Optional(Type.Boolean()),
assets: Type.Array(
Type.Object({
unit: Type.String(),
quantity: Type.String(),
}),
),
},
{ $id: 'BaseOutput' },
),
Type.Union([
Type.Object(
{
address: Type.String(),
amount: Type.String(),
setMax: Type.Optional(Type.Literal(false)),
},
{ $id: 'ExternalOutput' },
),
Type.Object(
{
address: Type.Optional(Type.String()),
amount: Type.Optional(Type.String()),
setMax: Type.Boolean(),
},
{ $id: 'ExternalOutputIncomplete' },
),
]),
],
{ $id: 'UserOutput' },
),
),
),
certificates: Type.Optional(Type.Array(CardanoCertificate)),
withdrawals: Type.Optional(
Type.Array(
Type.Object(
{
stakeAddress: Type.String(),
amount: Type.String(),
},
{ $id: 'Withdrawal' },
),
),
),
changeAddress: Type.Object({
address: Type.String(),
path: Type.String(),
}),
addressParameters: Type.Object(
{
addressType: PROTO.EnumCardanoAddressType,
path: DerivationPath,
stakingPath: Type.Optional(DerivationPath),
stakingKeyHash: Type.Optional(Type.String()),
certificatePointer: Type.Optional(CardanoCertificatePointer),
},
{ $id: 'CardanoAddressParameters' },
),
testnet: Type.Optional(Type.Boolean()),
});

// TS - Assert type of CardanoComposeTransactionParams is compatible with CardanoComposeTransactionParamsSchema
const _params: CardanoComposeTransactionParamsSchema = {} as CardanoComposeTransactionParams;
const _paramsOld: CardanoComposeTransactionParams = {} as CardanoComposeTransactionParamsSchema;
// eslint-disable-next-line
[_params, _paramsOld];

export declare function cardanoComposeTransaction(
params: Params<CardanoComposeTransactionParams>,
): Response<PrecomposedTransactionCardano[]>;
2 changes: 1 addition & 1 deletion packages/connect/src/types/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export interface TrezorConnect {
// https://connect.trezor.io/9/methods/cardano/cardanoSignTransaction/
cardanoSignTransaction: typeof cardanoSignTransaction;

// todo: link docs
// https://connect.trezor.io/9/methods/cardano/cardanoComposeTransaction/
cardanoComposeTransaction: typeof cardanoComposeTransaction;

// https://connect.trezor.io/9/methods/device/changeLanguage/
Expand Down

0 comments on commit 36c817f

Please sign in to comment.