Skip to content
This repository has been archived by the owner on Aug 12, 2022. It is now read-only.

Add support for Cardano #65

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ Note that the lenght of the action is not tied to the actual device actions. You
| getEntropy | size:&nbsp;number | Promise&lt;Response<br>&lt;{ bytes:&nbsp;string }&gt;&gt;&gt; | random data |
| getAddress | path:&nbsp;Array&lt;number&gt;<br>coin:&nbsp;string<br>display:&nbsp;boolean | Promise&lt;Response<br>&lt;{ address:&nbsp;string }&gt;&gt;&gt; | Gets address with a given path.<br>Coin is the name of coin ("bitcoin", "testnet", "litecoin",...)<br>if `display` is true, the address is displayed on TREZOR and user has to confirm. |
| ethereumGetAddress | address_n:&nbsp;Array&lt;number&gt;<br>display:&nbsp;?boolean | Promise&lt;Response<br>&lt;{ address:&nbsp;string, path:&nbsp;Array&lt;number&gt; }&gt;&gt; | Gets Ethereum address from a given path.<br>if `display` is true, the address is displayed on TREZOR and user has to confirm. |
| adaGetAddress | address_n:&nbsp;Array&lt;number&gt;<br>show_display:&nbsp;?boolean | Promise&lt;MessageResponse<br>&lt;trezor.CardanoAddress&gt;&gt; | Gets Cardano address<br>if `show_display` is true, the address is displayed on TREZOR and user has to confirm. |
| getAdaPublicKey | address_n:&nbsp;Array&lt;number&gt; | Promise&lt;MessageResponse<br>&lt;trezor.CardanoPublicKey&gt;&gt; | Gets Cardano public node and root hd passphrase from a given path. |
| verifyAdaMessage | publicKey:&nbsp;string<br>signature:&nbsp;string<br>message:&nbsp;string | Promise&lt;MessageResponse&lt;trezor.Success&gt;&gt; | Verifies Cardano message against public key and signature. |
| signAdaMessage | address_n:&nbsp;Array&lt;number&gt;<br>message:&nbsp;string | Promise&lt;MessageResponse&lt;trezor.MessageSignature&gt;&gt; | Sign Cardano message with keys from given path. |
| signAdaTransaction | inputs:&nbsp;Array&lt;trezor.CardanoTxInputType&gt;<br>outputs:&nbsp;Array&lt;trezor.CardanoTxOutputType&gt;<br>transactions:&nbsp;Array&lt;string&gt; | Promise&lt;MessageResponse&lt;trezor.CardanoSignedTransaction&gt;&gt; | For provided inputs, outputs, raw transactions bodies will sign transaction |
| verifyAddress | path:&nbsp;Array&lt;number&gt;<br>refAddress:&nbsp;string&nbsp;<br>coin:&nbsp;string&nbsp; | Promise&lt;boolean&gt; | Gets address with the given path, displays it on display and compares to the `refAddress`.<br><br>Note: promise doesn't reject on different result, but resolves with **false**. It rejects on user not confirming on device. |
| getHDNode | path:&nbsp;Array&lt;number&gt;<br>coin:&nbsp;string&nbsp; | Promise&lt;HDNode&gt; | Returns [bitcoin.js HDNode](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/hdnode.js) with the given path. (No confirmation needed; it's public node.) |
| wipeDevice | | Promise | Wipes the device (after user confirms). |
Expand Down
54 changes: 54 additions & 0 deletions src/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as hdnodeUtils from './utils/hdnode';
import * as signTxHelper from './utils/signtx';
import * as signBjsTxHelper from './utils/signbjstx';
import * as signEthTxHelper from './utils/signethtx';
import * as signAdaTxHelper from './utils/signadatx';
import {CallHelper} from './utils/call';

import * as trezor from './trezortypes';
Expand Down Expand Up @@ -165,6 +166,35 @@ export default class Session extends EventEmitter {
});
}

@integrityCheck
adaGetAddress(
address_n: Array<number>,
show_display: ?boolean
): Promise<MessageResponse<trezor.CardanoAddress>> {
return this.typedCall('CardanoGetAddress', 'CardanoAddress', {
address_n,
show_display: !!show_display,
});
}

@integrityCheck
getAdaPublicKey(
address_n: Array<number>,
): Promise<MessageResponse<trezor.CardanoPublicKey>> {
return this.typedCall('CardanoGetPublicKey', 'CardanoPublicKey', {
address_n: address_n,
});
}

@integrityCheck
signAdaTransaction(
inputs: Array<trezor.CardanoTxInputType>,
outputs: Array<trezor.CardanoTxOutputType>,
transactions: Array<string>
): Promise<MessageResponse<trezor.CardanoSignedTransaction>> {
return signAdaTxHelper.signAdaTx(this, inputs, outputs, transactions);
}

@integrityCheck
getPublicKey(
address_n: Array<number>,
Expand Down Expand Up @@ -295,6 +325,19 @@ export default class Session extends EventEmitter {
});
}

@integrityCheck
verifyAdaMessage(
publicKey: string,
signature: string,
message: string
): Promise<MessageResponse<trezor.Success>> {
return this.typedCall('CardanoVerifyMessage', 'Success', {
public_key: publicKey,
signature: signature,
message: message,
});
}

signMessage(
address_n: Array<number>,
message: string,
Expand All @@ -319,6 +362,17 @@ export default class Session extends EventEmitter {
});
}

@integrityCheck
signAdaMessage(
address_n: Array<number>,
message: string
): Promise<MessageResponse<trezor.MessageSignature>> {
return this.typedCall('CardanoSignMessage', 'CardanoMessageSignature', {
address_n: address_n,
message: message,
});
}

signIdentity(
identity: trezor.Identity,
challenge_hidden: string,
Expand Down
42 changes: 42 additions & 0 deletions src/trezortypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,45 @@ export type SignTxInfoToTrezor = {
extra_data_len?: number;
};

export type CardanoDerivationPath = {
address_n: Array<number>;
};

export type CardanoPublicKey = {
xpub: string;
node: HDPubNode;
root_hd_passphrase: string;
};

export type CardanoSignedTransaction = {
tx_hash?: string;
tx_body?: string;
};

export type CardanoTxInputType = {
tx_hash: string;
address_n: Array<number>;
output_index: number;
type?: number;
};

export type CardanoTxOutputType = {
address?: string;
address_n?: Array<number>;
amount: number;
};

export type CardanoAddress = {
address: string;
address_n?: Array<number>;
};

export type CardanoAddresses = {
addresses: CardanoAddress;
};

export type CardanoTxRequest = {
tx_index?: number;
tx_hash?: string;
tx_body?: string;
};
44 changes: 44 additions & 0 deletions src/utils/signadatx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* @flow */
'use strict';

import * as trezor from '../trezortypes';

import type Session, {MessageResponse} from '../session';

function processTxRequest(
session: Session,
request: trezor.CardanoTxRequest,
transactions: Array<string>
): Promise<MessageResponse<trezor.CardanoSignedTransaction>> {
if (request.tx_index === null || request.tx_index === undefined) {
return Promise.resolve({
message: request,
type: 'trezor.CardanoSignedTransaction',
});
}

const transaction = transactions[request.tx_index];

return session.typedCall('CardanoTxAck', 'CardanoTxRequest', {transaction: transaction}).then(
(response) => processTxRequest(
session,
response.message,
transactions
)
);
}

export function signAdaTx(
session: Session,
inputs: Array<trezor.CardanoTxInputType>,
outputs: Array<trezor.CardanoTxOutputType>,
transactions: Array<string>
): Promise<MessageResponse<trezor.CardanoSignedTransaction>> {
return session.typedCall('CardanoSignTransaction', 'CardanoTxRequest', {
inputs: inputs,
outputs: outputs,
transactions_count: transactions.length,
}).then((res) =>
processTxRequest(session, res.message, transactions)
);
}