@cardano-sdk/key-management 0.2.0-nightly.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +5 -0
- package/README.md +1 -0
- package/dist/cjs/InMemoryKeyAgent.d.ts +23 -0
- package/dist/cjs/InMemoryKeyAgent.d.ts.map +1 -0
- package/dist/cjs/InMemoryKeyAgent.js +136 -0
- package/dist/cjs/InMemoryKeyAgent.js.map +1 -0
- package/dist/cjs/KeyAgentBase.d.ts +20 -0
- package/dist/cjs/KeyAgentBase.d.ts.map +1 -0
- package/dist/cjs/KeyAgentBase.js +77 -0
- package/dist/cjs/KeyAgentBase.js.map +1 -0
- package/dist/cjs/LedgerKeyAgent.d.ts +42 -0
- package/dist/cjs/LedgerKeyAgent.d.ts.map +1 -0
- package/dist/cjs/LedgerKeyAgent.js +208 -0
- package/dist/cjs/LedgerKeyAgent.js.map +1 -0
- package/dist/cjs/TrezorKeyAgent.d.ts +29 -0
- package/dist/cjs/TrezorKeyAgent.d.ts.map +1 -0
- package/dist/cjs/TrezorKeyAgent.js +134 -0
- package/dist/cjs/TrezorKeyAgent.js.map +1 -0
- package/dist/cjs/cip8/cip30signData.d.ts +22 -0
- package/dist/cjs/cip8/cip30signData.d.ts.map +1 -0
- package/dist/cjs/cip8/cip30signData.js +81 -0
- package/dist/cjs/cip8/cip30signData.js.map +1 -0
- package/dist/cjs/cip8/index.d.ts +2 -0
- package/dist/cjs/cip8/index.d.ts.map +1 -0
- package/dist/cjs/cip8/index.js +18 -0
- package/dist/cjs/cip8/index.js.map +1 -0
- package/dist/cjs/cip8/types.d.ts +4 -0
- package/dist/cjs/cip8/types.d.ts.map +1 -0
- package/dist/cjs/cip8/types.js +3 -0
- package/dist/cjs/cip8/types.js.map +1 -0
- package/dist/cjs/cip8/util.d.ts +7 -0
- package/dist/cjs/cip8/util.d.ts.map +1 -0
- package/dist/cjs/cip8/util.js +10 -0
- package/dist/cjs/cip8/util.js.map +1 -0
- package/dist/cjs/emip3.d.ts +4 -0
- package/dist/cjs/emip3.d.ts.map +1 -0
- package/dist/cjs/emip3.js +48 -0
- package/dist/cjs/emip3.js.map +1 -0
- package/dist/cjs/errors/AuthenticationError.d.ts +6 -0
- package/dist/cjs/errors/AuthenticationError.d.ts.map +1 -0
- package/dist/cjs/errors/AuthenticationError.js +16 -0
- package/dist/cjs/errors/AuthenticationError.js.map +1 -0
- package/dist/cjs/errors/HwMappingError.d.ts +6 -0
- package/dist/cjs/errors/HwMappingError.d.ts.map +1 -0
- package/dist/cjs/errors/HwMappingError.js +16 -0
- package/dist/cjs/errors/HwMappingError.js.map +1 -0
- package/dist/cjs/errors/InvalidMnemonicError.d.ts +5 -0
- package/dist/cjs/errors/InvalidMnemonicError.d.ts.map +1 -0
- package/dist/cjs/errors/InvalidMnemonicError.js +13 -0
- package/dist/cjs/errors/InvalidMnemonicError.js.map +1 -0
- package/dist/cjs/errors/InvalidSerializableDataError.d.ts +5 -0
- package/dist/cjs/errors/InvalidSerializableDataError.d.ts.map +1 -0
- package/dist/cjs/errors/InvalidSerializableDataError.js +15 -0
- package/dist/cjs/errors/InvalidSerializableDataError.js.map +1 -0
- package/dist/cjs/errors/ProofGenerationError.d.ts +6 -0
- package/dist/cjs/errors/ProofGenerationError.d.ts.map +1 -0
- package/dist/cjs/errors/ProofGenerationError.js +16 -0
- package/dist/cjs/errors/ProofGenerationError.js.map +1 -0
- package/dist/cjs/errors/TransportError.d.ts +6 -0
- package/dist/cjs/errors/TransportError.d.ts.map +1 -0
- package/dist/cjs/errors/TransportError.js +16 -0
- package/dist/cjs/errors/TransportError.js.map +1 -0
- package/dist/cjs/errors/index.d.ts +7 -0
- package/dist/cjs/errors/index.d.ts.map +1 -0
- package/dist/cjs/errors/index.js +23 -0
- package/dist/cjs/errors/index.js.map +1 -0
- package/dist/cjs/index.d.ts +12 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +42 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/restoreKeyAgent.d.ts +9 -0
- package/dist/cjs/restoreKeyAgent.d.ts.map +1 -0
- package/dist/cjs/restoreKeyAgent.js +31 -0
- package/dist/cjs/restoreKeyAgent.js.map +1 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -0
- package/dist/cjs/types.d.ts +127 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +43 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/util/KeyAgentTransactionSigner.d.ts +8 -0
- package/dist/cjs/util/KeyAgentTransactionSigner.d.ts.map +1 -0
- package/dist/cjs/util/KeyAgentTransactionSigner.js +38 -0
- package/dist/cjs/util/KeyAgentTransactionSigner.js.map +1 -0
- package/dist/cjs/util/bip39.d.ts +8 -0
- package/dist/cjs/util/bip39.d.ts.map +1 -0
- package/dist/cjs/util/bip39.js +39 -0
- package/dist/cjs/util/bip39.js.map +1 -0
- package/dist/cjs/util/createAsyncKeyAgent.d.ts +3 -0
- package/dist/cjs/util/createAsyncKeyAgent.d.ts.map +1 -0
- package/dist/cjs/util/createAsyncKeyAgent.js +26 -0
- package/dist/cjs/util/createAsyncKeyAgent.js.map +1 -0
- package/dist/cjs/util/index.d.ts +8 -0
- package/dist/cjs/util/index.d.ts.map +1 -0
- package/dist/cjs/util/index.js +24 -0
- package/dist/cjs/util/index.js.map +1 -0
- package/dist/cjs/util/key.d.ts +11 -0
- package/dist/cjs/util/key.d.ts.map +1 -0
- package/dist/cjs/util/key.js +30 -0
- package/dist/cjs/util/key.js.map +1 -0
- package/dist/cjs/util/mapHardwareSigningData.d.ts +38 -0
- package/dist/cjs/util/mapHardwareSigningData.d.ts.map +1 -0
- package/dist/cjs/util/mapHardwareSigningData.js +864 -0
- package/dist/cjs/util/mapHardwareSigningData.js.map +1 -0
- package/dist/cjs/util/ownSignatureKeyPaths.d.ts +4 -0
- package/dist/cjs/util/ownSignatureKeyPaths.d.ts.map +1 -0
- package/dist/cjs/util/ownSignatureKeyPaths.js +24 -0
- package/dist/cjs/util/ownSignatureKeyPaths.js.map +1 -0
- package/dist/cjs/util/stubSignTransaction.d.ts +4 -0
- package/dist/cjs/util/stubSignTransaction.d.ts.map +1 -0
- package/dist/cjs/util/stubSignTransaction.js +23 -0
- package/dist/cjs/util/stubSignTransaction.js.map +1 -0
- package/dist/esm/InMemoryKeyAgent.d.ts +23 -0
- package/dist/esm/InMemoryKeyAgent.d.ts.map +1 -0
- package/dist/esm/InMemoryKeyAgent.js +106 -0
- package/dist/esm/InMemoryKeyAgent.js.map +1 -0
- package/dist/esm/KeyAgentBase.d.ts +20 -0
- package/dist/esm/KeyAgentBase.d.ts.map +1 -0
- package/dist/esm/KeyAgentBase.js +73 -0
- package/dist/esm/KeyAgentBase.js.map +1 -0
- package/dist/esm/LedgerKeyAgent.d.ts +42 -0
- package/dist/esm/LedgerKeyAgent.d.ts.map +1 -0
- package/dist/esm/LedgerKeyAgent.js +178 -0
- package/dist/esm/LedgerKeyAgent.js.map +1 -0
- package/dist/esm/TrezorKeyAgent.d.ts +29 -0
- package/dist/esm/TrezorKeyAgent.d.ts.map +1 -0
- package/dist/esm/TrezorKeyAgent.js +127 -0
- package/dist/esm/TrezorKeyAgent.js.map +1 -0
- package/dist/esm/cip8/cip30signData.d.ts +22 -0
- package/dist/esm/cip8/cip30signData.d.ts.map +1 -0
- package/dist/esm/cip8/cip30signData.js +76 -0
- package/dist/esm/cip8/cip30signData.js.map +1 -0
- package/dist/esm/cip8/index.d.ts +2 -0
- package/dist/esm/cip8/index.d.ts.map +1 -0
- package/dist/esm/cip8/index.js +2 -0
- package/dist/esm/cip8/index.js.map +1 -0
- package/dist/esm/cip8/types.d.ts +4 -0
- package/dist/esm/cip8/types.d.ts.map +1 -0
- package/dist/esm/cip8/types.js +2 -0
- package/dist/esm/cip8/types.js.map +1 -0
- package/dist/esm/cip8/util.d.ts +7 -0
- package/dist/esm/cip8/util.d.ts.map +1 -0
- package/dist/esm/cip8/util.js +7 -0
- package/dist/esm/cip8/util.js.map +1 -0
- package/dist/esm/emip3.d.ts +4 -0
- package/dist/esm/emip3.d.ts.map +1 -0
- package/dist/esm/emip3.js +39 -0
- package/dist/esm/emip3.js.map +1 -0
- package/dist/esm/errors/AuthenticationError.d.ts +6 -0
- package/dist/esm/errors/AuthenticationError.d.ts.map +1 -0
- package/dist/esm/errors/AuthenticationError.js +12 -0
- package/dist/esm/errors/AuthenticationError.js.map +1 -0
- package/dist/esm/errors/HwMappingError.d.ts +6 -0
- package/dist/esm/errors/HwMappingError.d.ts.map +1 -0
- package/dist/esm/errors/HwMappingError.js +12 -0
- package/dist/esm/errors/HwMappingError.js.map +1 -0
- package/dist/esm/errors/InvalidMnemonicError.d.ts +5 -0
- package/dist/esm/errors/InvalidMnemonicError.d.ts.map +1 -0
- package/dist/esm/errors/InvalidMnemonicError.js +9 -0
- package/dist/esm/errors/InvalidMnemonicError.js.map +1 -0
- package/dist/esm/errors/InvalidSerializableDataError.d.ts +5 -0
- package/dist/esm/errors/InvalidSerializableDataError.d.ts.map +1 -0
- package/dist/esm/errors/InvalidSerializableDataError.js +11 -0
- package/dist/esm/errors/InvalidSerializableDataError.js.map +1 -0
- package/dist/esm/errors/ProofGenerationError.d.ts +6 -0
- package/dist/esm/errors/ProofGenerationError.d.ts.map +1 -0
- package/dist/esm/errors/ProofGenerationError.js +12 -0
- package/dist/esm/errors/ProofGenerationError.js.map +1 -0
- package/dist/esm/errors/TransportError.d.ts +6 -0
- package/dist/esm/errors/TransportError.d.ts.map +1 -0
- package/dist/esm/errors/TransportError.js +12 -0
- package/dist/esm/errors/TransportError.js.map +1 -0
- package/dist/esm/errors/index.d.ts +7 -0
- package/dist/esm/errors/index.d.ts.map +1 -0
- package/dist/esm/errors/index.js +7 -0
- package/dist/esm/errors/index.js.map +1 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/restoreKeyAgent.d.ts +9 -0
- package/dist/esm/restoreKeyAgent.d.ts.map +1 -0
- package/dist/esm/restoreKeyAgent.js +27 -0
- package/dist/esm/restoreKeyAgent.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -0
- package/dist/esm/types.d.ts +127 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +40 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/util/KeyAgentTransactionSigner.d.ts +8 -0
- package/dist/esm/util/KeyAgentTransactionSigner.d.ts.map +1 -0
- package/dist/esm/util/KeyAgentTransactionSigner.js +34 -0
- package/dist/esm/util/KeyAgentTransactionSigner.js.map +1 -0
- package/dist/esm/util/bip39.d.ts +8 -0
- package/dist/esm/util/bip39.d.ts.map +1 -0
- package/dist/esm/util/bip39.js +8 -0
- package/dist/esm/util/bip39.js.map +1 -0
- package/dist/esm/util/createAsyncKeyAgent.d.ts +3 -0
- package/dist/esm/util/createAsyncKeyAgent.d.ts.map +1 -0
- package/dist/esm/util/createAsyncKeyAgent.js +22 -0
- package/dist/esm/util/createAsyncKeyAgent.js.map +1 -0
- package/dist/esm/util/index.d.ts +8 -0
- package/dist/esm/util/index.d.ts.map +1 -0
- package/dist/esm/util/index.js +8 -0
- package/dist/esm/util/index.js.map +1 -0
- package/dist/esm/util/key.d.ts +11 -0
- package/dist/esm/util/key.d.ts.map +1 -0
- package/dist/esm/util/key.js +24 -0
- package/dist/esm/util/key.js.map +1 -0
- package/dist/esm/util/mapHardwareSigningData.d.ts +38 -0
- package/dist/esm/util/mapHardwareSigningData.d.ts.map +1 -0
- package/dist/esm/util/mapHardwareSigningData.js +833 -0
- package/dist/esm/util/mapHardwareSigningData.js.map +1 -0
- package/dist/esm/util/ownSignatureKeyPaths.d.ts +4 -0
- package/dist/esm/util/ownSignatureKeyPaths.d.ts.map +1 -0
- package/dist/esm/util/ownSignatureKeyPaths.js +17 -0
- package/dist/esm/util/ownSignatureKeyPaths.js.map +1 -0
- package/dist/esm/util/stubSignTransaction.d.ts +4 -0
- package/dist/esm/util/stubSignTransaction.d.ts.map +1 -0
- package/dist/esm/util/stubSignTransaction.js +16 -0
- package/dist/esm/util/stubSignTransaction.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
import * as ledger from '@cardano-foundation/ledgerjs-hw-app-cardano';
|
|
2
|
+
import * as trezor from 'trezor-connect';
|
|
3
|
+
import { CSL, cslToCore } from '@cardano-sdk/core';
|
|
4
|
+
import { CardanoKeyConst } from '../types';
|
|
5
|
+
import { HwMappingError } from '../errors';
|
|
6
|
+
import { STAKE_KEY_DERIVATION_PATH, harden } from './key';
|
|
7
|
+
import { isNotNil } from '@cardano-sdk/util';
|
|
8
|
+
import concat from 'lodash/concat';
|
|
9
|
+
import uniq from 'lodash/uniq';
|
|
10
|
+
const sortTokensCanonically = (tokens) => {
|
|
11
|
+
tokens.sort((a, b) => {
|
|
12
|
+
const assetNameA = 'assetNameBytes' in a ? a.assetNameBytes : a.assetNameHex;
|
|
13
|
+
const assetNameB = 'assetNameBytes' in b ? b.assetNameBytes : b.assetNameHex;
|
|
14
|
+
if (assetNameA.length === assetNameB.length) {
|
|
15
|
+
return assetNameA > assetNameB ? 1 : -1;
|
|
16
|
+
}
|
|
17
|
+
else if (assetNameA.length > assetNameB.length)
|
|
18
|
+
return 1;
|
|
19
|
+
return -1;
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
const getRewardAccountKeyHash = (rewardAccount) => Buffer.from(CSL.RewardAddress.from_address(CSL.Address.from_bech32(rewardAccount.toString()))
|
|
23
|
+
.payment_cred()
|
|
24
|
+
.to_keyhash()
|
|
25
|
+
.to_bytes()).toString('hex');
|
|
26
|
+
const bytesToIp = (bytes) => {
|
|
27
|
+
if (!bytes)
|
|
28
|
+
return null;
|
|
29
|
+
if (bytes.length === 4) {
|
|
30
|
+
return bytes.join('.');
|
|
31
|
+
}
|
|
32
|
+
else if (bytes.length === 16) {
|
|
33
|
+
let ipv6 = '';
|
|
34
|
+
for (let i = 0; i < bytes.length; i += 2) {
|
|
35
|
+
ipv6 += `${bytes[i].toString(16) + bytes[i + 1].toString(16)}:`;
|
|
36
|
+
}
|
|
37
|
+
ipv6 = ipv6.slice(0, -1);
|
|
38
|
+
return ipv6;
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
};
|
|
42
|
+
const matchGroupedAddress = (knownAddresses, outputAddress) => {
|
|
43
|
+
const outputAddressBech32 = ledger.utils.bech32_encodeAddress(outputAddress);
|
|
44
|
+
return knownAddresses.find(({ address }) => address.toString() === outputAddressBech32);
|
|
45
|
+
};
|
|
46
|
+
const prepareTrezorInputs = async (inputs, inputResolver, knownAddresses) => {
|
|
47
|
+
const trezorInputs = [];
|
|
48
|
+
for (let i = 0; i < inputs.len(); i++) {
|
|
49
|
+
const input = inputs.get(i);
|
|
50
|
+
const coreInput = cslToCore.txIn(input);
|
|
51
|
+
const paymentAddress = await inputResolver.resolveInputAddress(coreInput);
|
|
52
|
+
let trezorInput = {
|
|
53
|
+
prev_hash: Buffer.from(input.transaction_id().to_bytes()).toString('hex'),
|
|
54
|
+
prev_index: input.index()
|
|
55
|
+
};
|
|
56
|
+
let paymentKeyPath = null;
|
|
57
|
+
if (paymentAddress) {
|
|
58
|
+
const knownAddress = knownAddresses.find(({ address }) => address === paymentAddress);
|
|
59
|
+
if (knownAddress) {
|
|
60
|
+
paymentKeyPath = [
|
|
61
|
+
harden(CardanoKeyConst.PURPOSE),
|
|
62
|
+
harden(CardanoKeyConst.COIN_TYPE),
|
|
63
|
+
harden(knownAddress.accountIndex),
|
|
64
|
+
knownAddress.type,
|
|
65
|
+
knownAddress.index
|
|
66
|
+
];
|
|
67
|
+
trezorInput = {
|
|
68
|
+
...trezorInput,
|
|
69
|
+
path: paymentKeyPath
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
trezorInputs.push(trezorInput);
|
|
74
|
+
}
|
|
75
|
+
return trezorInputs;
|
|
76
|
+
};
|
|
77
|
+
const prepareTrezorOutputs = (outputs, knownAddresses) => {
|
|
78
|
+
const trezorOutputs = [];
|
|
79
|
+
for (let i = 0; i < outputs.len(); i++) {
|
|
80
|
+
const output = outputs.get(i);
|
|
81
|
+
const multiAsset = output.amount().multiasset();
|
|
82
|
+
const tokenBundle = [];
|
|
83
|
+
if (multiAsset) {
|
|
84
|
+
for (let j = 0; j < multiAsset.keys().len(); j++) {
|
|
85
|
+
const policy = multiAsset.keys().get(j);
|
|
86
|
+
const assets = multiAsset.get(policy);
|
|
87
|
+
const tokens = [];
|
|
88
|
+
if (assets) {
|
|
89
|
+
for (let k = 0; k < assets.keys().len(); k++) {
|
|
90
|
+
const assetName = assets.keys().get(k);
|
|
91
|
+
const amount = assets.get(assetName);
|
|
92
|
+
if (assetName && amount) {
|
|
93
|
+
tokens.push({
|
|
94
|
+
amount: amount.to_str(),
|
|
95
|
+
assetNameBytes: Buffer.from(assetName.name()).toString('hex')
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
sortTokensCanonically(tokens);
|
|
101
|
+
tokenBundle.push({
|
|
102
|
+
policyId: Buffer.from(policy.to_bytes()).toString('hex'),
|
|
103
|
+
tokenAmounts: tokens
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const outputAddress = Buffer.from(output.address().to_bytes());
|
|
108
|
+
const ownAddress = matchGroupedAddress(knownAddresses, outputAddress);
|
|
109
|
+
const destination = ownAddress
|
|
110
|
+
? {
|
|
111
|
+
addressParameters: {
|
|
112
|
+
addressType: trezor.CardanoAddressType.BASE,
|
|
113
|
+
path: `m/${CardanoKeyConst.PURPOSE}'/${CardanoKeyConst.COIN_TYPE}'/${ownAddress.accountIndex}'/${ownAddress.type}/${ownAddress.index}`,
|
|
114
|
+
stakingPath: `m/${CardanoKeyConst.PURPOSE}'/${CardanoKeyConst.COIN_TYPE}'/${ownAddress.accountIndex}'/${STAKE_KEY_DERIVATION_PATH.role}/${STAKE_KEY_DERIVATION_PATH.index}`
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
: {
|
|
118
|
+
address: output.address().to_bech32()
|
|
119
|
+
};
|
|
120
|
+
const outputRes = {
|
|
121
|
+
...destination,
|
|
122
|
+
amount: output.amount().coin().to_str(),
|
|
123
|
+
tokenBundle
|
|
124
|
+
};
|
|
125
|
+
trezorOutputs.push(outputRes);
|
|
126
|
+
}
|
|
127
|
+
return trezorOutputs;
|
|
128
|
+
};
|
|
129
|
+
const prepareTrezorCertificates = (certificates, rewardAccountKeyPath, rewardAccountKeyHash) => {
|
|
130
|
+
let signingMode;
|
|
131
|
+
const certs = [];
|
|
132
|
+
for (let i = 0; i < certificates.len(); i++) {
|
|
133
|
+
const cert = certificates.get(i);
|
|
134
|
+
const certificate = {};
|
|
135
|
+
if (cert.kind() === 0) {
|
|
136
|
+
const credential = cert.as_stake_registration()?.stake_credential();
|
|
137
|
+
const credentialScriptHash = credential?.to_scripthash();
|
|
138
|
+
certificate.type = trezor.CardanoCertificateType.STAKE_REGISTRATION;
|
|
139
|
+
if (credential?.kind() === 0) {
|
|
140
|
+
certificate.path = rewardAccountKeyPath;
|
|
141
|
+
}
|
|
142
|
+
else if (credential && credentialScriptHash) {
|
|
143
|
+
certificate.scriptHash = Buffer.from(credentialScriptHash.to_bytes()).toString('hex');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (cert.kind() === 1) {
|
|
147
|
+
const credential = cert.as_stake_deregistration()?.stake_credential();
|
|
148
|
+
const credentialScriptHash = credential?.to_scripthash();
|
|
149
|
+
certificate.type = trezor.CardanoCertificateType.STAKE_DEREGISTRATION;
|
|
150
|
+
if (credential?.kind() === 0) {
|
|
151
|
+
certificate.path = rewardAccountKeyPath;
|
|
152
|
+
}
|
|
153
|
+
else if (credential && credentialScriptHash) {
|
|
154
|
+
certificate.scriptHash = Buffer.from(credentialScriptHash.to_bytes()).toString('hex');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (cert.kind() === 2) {
|
|
158
|
+
const delegation = cert.as_stake_delegation();
|
|
159
|
+
const delegationPoolKeyHash = delegation?.pool_keyhash();
|
|
160
|
+
const credential = delegation?.stake_credential();
|
|
161
|
+
const credentialScriptHash = credential?.to_scripthash();
|
|
162
|
+
certificate.type = trezor.CardanoCertificateType.STAKE_DELEGATION;
|
|
163
|
+
if (credential?.kind() === 0) {
|
|
164
|
+
certificate.path = rewardAccountKeyPath;
|
|
165
|
+
}
|
|
166
|
+
else if (credentialScriptHash) {
|
|
167
|
+
certificate.scriptHash = Buffer.from(credentialScriptHash.to_bytes()).toString('hex');
|
|
168
|
+
}
|
|
169
|
+
if (delegationPoolKeyHash) {
|
|
170
|
+
certificate.pool = Buffer.from(delegationPoolKeyHash.to_bytes()).toString('hex');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else if (cert.kind() === 3) {
|
|
174
|
+
const params = cert.as_pool_registration()?.pool_params();
|
|
175
|
+
if (!params) {
|
|
176
|
+
throw new HwMappingError('Missing pool registration pool parameters.');
|
|
177
|
+
}
|
|
178
|
+
certificate.type = trezor.CardanoCertificateType.STAKE_POOL_REGISTRATION;
|
|
179
|
+
const owners = params?.pool_owners();
|
|
180
|
+
const poolOwners = [];
|
|
181
|
+
if (owners) {
|
|
182
|
+
for (let j = 0; j < owners.len(); j++) {
|
|
183
|
+
const keyHash = Buffer.from(owners.get(j).to_bytes()).toString('hex');
|
|
184
|
+
if (keyHash === rewardAccountKeyHash) {
|
|
185
|
+
signingMode = trezor.CardanoTxSigningMode.POOL_REGISTRATION_AS_OWNER;
|
|
186
|
+
poolOwners.push({
|
|
187
|
+
stakingKeyPath: rewardAccountKeyPath
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
poolOwners.push({
|
|
192
|
+
stakingKeyHash: keyHash
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const relays = params?.relays();
|
|
198
|
+
const trezorRelays = [];
|
|
199
|
+
if (relays) {
|
|
200
|
+
for (let k = 0; k < relays.len(); k++) {
|
|
201
|
+
const relay = relays.get(k);
|
|
202
|
+
if (relay.kind() === 0) {
|
|
203
|
+
const singleHostAddr = relay.as_single_host_addr();
|
|
204
|
+
const type = trezor.CardanoPoolRelayType.SINGLE_HOST_IP;
|
|
205
|
+
const port = singleHostAddr?.port();
|
|
206
|
+
const ipv4Address = singleHostAddr?.ipv4() ? bytesToIp(singleHostAddr.ipv4()?.ip()) : null;
|
|
207
|
+
const ipv6Address = singleHostAddr?.ipv6() ? bytesToIp(singleHostAddr.ipv6()?.ip()) : null;
|
|
208
|
+
trezorRelays.push({
|
|
209
|
+
ipv4Address: ipv4Address || undefined,
|
|
210
|
+
ipv6Address: ipv6Address || undefined,
|
|
211
|
+
port,
|
|
212
|
+
type
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
else if (relay.kind() === 1) {
|
|
216
|
+
const type = trezor.CardanoPoolRelayType.SINGLE_HOST_NAME;
|
|
217
|
+
const singleHostName = relay.as_single_host_name();
|
|
218
|
+
if (singleHostName) {
|
|
219
|
+
const port = singleHostName.port();
|
|
220
|
+
const hostName = singleHostName.dns_name().record();
|
|
221
|
+
trezorRelays.push({
|
|
222
|
+
hostName,
|
|
223
|
+
port,
|
|
224
|
+
type
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else if (relay.kind() === 2) {
|
|
229
|
+
const type = trezor.CardanoPoolRelayType.MULTIPLE_HOST_NAME;
|
|
230
|
+
const multiHostName = relay.as_multi_host_name();
|
|
231
|
+
const hostName = multiHostName?.dns_name().record();
|
|
232
|
+
if (hostName) {
|
|
233
|
+
trezorRelays.push({
|
|
234
|
+
hostName,
|
|
235
|
+
type
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const cost = params?.cost().to_str();
|
|
242
|
+
const margin = params?.margin();
|
|
243
|
+
const pledge = params?.pledge().to_str();
|
|
244
|
+
const poolId = Buffer.from(params.operator().to_bytes()).toString('hex');
|
|
245
|
+
const poolMetadata = params.pool_metadata();
|
|
246
|
+
if (!poolMetadata) {
|
|
247
|
+
throw new HwMappingError('Missing pool metadata.');
|
|
248
|
+
}
|
|
249
|
+
const metadata = {
|
|
250
|
+
hash: Buffer.from(poolMetadata.pool_metadata_hash().to_bytes()).toString('hex'),
|
|
251
|
+
url: poolMetadata.url().url()
|
|
252
|
+
};
|
|
253
|
+
const rewardAccount = params.reward_account().to_address().to_bech32();
|
|
254
|
+
const vrfKeyHash = Buffer.from(params.vrf_keyhash().to_bytes()).toString('hex');
|
|
255
|
+
certificate.poolParameters = {
|
|
256
|
+
cost,
|
|
257
|
+
margin: {
|
|
258
|
+
denominator: margin.denominator().to_str(),
|
|
259
|
+
numerator: margin.numerator().to_str()
|
|
260
|
+
},
|
|
261
|
+
metadata,
|
|
262
|
+
owners: poolOwners,
|
|
263
|
+
pledge,
|
|
264
|
+
poolId,
|
|
265
|
+
relays: trezorRelays,
|
|
266
|
+
rewardAccount,
|
|
267
|
+
vrfKeyHash
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
certs.push(certificate);
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
certs,
|
|
274
|
+
signingMode
|
|
275
|
+
};
|
|
276
|
+
};
|
|
277
|
+
const prepareTrezorWithdrawals = (withdrawals, rewardAccountKeyPath) => {
|
|
278
|
+
const trezorWithdrawals = [];
|
|
279
|
+
for (let i = 0; i < withdrawals.keys().len(); i++) {
|
|
280
|
+
const withdrawal = {};
|
|
281
|
+
const rewardAddress = withdrawals.keys().get(i);
|
|
282
|
+
const paymentCredentials = rewardAddress.payment_cred();
|
|
283
|
+
const paymentCredentialsScriptHash = paymentCredentials.to_scripthash();
|
|
284
|
+
if (rewardAddress.payment_cred().kind() === 0) {
|
|
285
|
+
withdrawal.path = rewardAccountKeyPath;
|
|
286
|
+
}
|
|
287
|
+
else if (paymentCredentialsScriptHash) {
|
|
288
|
+
withdrawal.scriptHash = Buffer.from(paymentCredentialsScriptHash.to_bytes()).toString('hex');
|
|
289
|
+
}
|
|
290
|
+
const withdrawalAmount = withdrawals.get(rewardAddress);
|
|
291
|
+
if (!withdrawalAmount) {
|
|
292
|
+
throw new HwMappingError('Withdrawal amount is not defined.');
|
|
293
|
+
}
|
|
294
|
+
withdrawal.amount = withdrawalAmount.to_str();
|
|
295
|
+
trezorWithdrawals.push(withdrawal);
|
|
296
|
+
}
|
|
297
|
+
return trezorWithdrawals;
|
|
298
|
+
};
|
|
299
|
+
const prepareTrezorMintBundle = (mint, paymentKeyPaths, rewardAccountKeyPath) => {
|
|
300
|
+
const additionalWitnessPaths = [];
|
|
301
|
+
const mintAssetsGroup = [];
|
|
302
|
+
for (let j = 0; j < mint.keys().len(); j++) {
|
|
303
|
+
const policy = mint.keys().get(j);
|
|
304
|
+
const assets = mint.get(policy);
|
|
305
|
+
const tokens = [];
|
|
306
|
+
if (assets) {
|
|
307
|
+
for (let k = 0; k < assets.keys().len(); k++) {
|
|
308
|
+
const assetName = assets.keys().get(k);
|
|
309
|
+
const amount = assets.get(assetName);
|
|
310
|
+
const positiveAmount = amount?.as_positive()?.to_str();
|
|
311
|
+
const negativeAmount = amount?.as_negative()?.to_str();
|
|
312
|
+
if (!amount || !positiveAmount || !negativeAmount) {
|
|
313
|
+
throw new HwMappingError('Missing token amount.');
|
|
314
|
+
}
|
|
315
|
+
tokens.push({
|
|
316
|
+
amount: amount.is_positive() ? positiveAmount : `-${negativeAmount}`,
|
|
317
|
+
assetNameBytes: Buffer.from(assetName.name()).toString('hex')
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
sortTokensCanonically(tokens);
|
|
322
|
+
mintAssetsGroup.push({
|
|
323
|
+
policyId: Buffer.from(policy.to_bytes()).toString('hex'),
|
|
324
|
+
tokenAmounts: tokens
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
if (paymentKeyPaths)
|
|
328
|
+
concat(additionalWitnessPaths, paymentKeyPaths);
|
|
329
|
+
if (rewardAccountKeyPath)
|
|
330
|
+
additionalWitnessPaths.push(rewardAccountKeyPath);
|
|
331
|
+
return {
|
|
332
|
+
additionalWitnessPaths,
|
|
333
|
+
mintAssetsGroup
|
|
334
|
+
};
|
|
335
|
+
};
|
|
336
|
+
const prepareLedgerInputs = async (inputs, inputResolver, knownAddresses) => {
|
|
337
|
+
const ledgerInputs = [];
|
|
338
|
+
for (let i = 0; i < inputs.len(); i++) {
|
|
339
|
+
const input = inputs.get(i);
|
|
340
|
+
const coreInput = cslToCore.txIn(input);
|
|
341
|
+
const paymentAddress = await inputResolver.resolveInputAddress(coreInput);
|
|
342
|
+
let paymentKeyPath = null;
|
|
343
|
+
if (paymentAddress) {
|
|
344
|
+
const knownAddress = knownAddresses.find(({ address }) => address === paymentAddress);
|
|
345
|
+
if (knownAddress) {
|
|
346
|
+
paymentKeyPath = [
|
|
347
|
+
harden(CardanoKeyConst.PURPOSE),
|
|
348
|
+
harden(CardanoKeyConst.COIN_TYPE),
|
|
349
|
+
harden(knownAddress.accountIndex),
|
|
350
|
+
knownAddress.type,
|
|
351
|
+
knownAddress.index
|
|
352
|
+
];
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
ledgerInputs.push({
|
|
356
|
+
outputIndex: input.index(),
|
|
357
|
+
path: paymentKeyPath,
|
|
358
|
+
txHashHex: Buffer.from(input.transaction_id().to_bytes()).toString('hex')
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
return ledgerInputs;
|
|
362
|
+
};
|
|
363
|
+
const prepareLedgerOutputs = (outputs, knownAddresses) => {
|
|
364
|
+
const ledgerOutputs = [];
|
|
365
|
+
for (let i = 0; i < outputs.len(); i++) {
|
|
366
|
+
const output = outputs.get(i);
|
|
367
|
+
const multiAsset = output.amount().multiasset();
|
|
368
|
+
const tokenBundle = [];
|
|
369
|
+
if (multiAsset) {
|
|
370
|
+
for (let j = 0; j < multiAsset.keys().len(); j++) {
|
|
371
|
+
const policy = multiAsset.keys().get(j);
|
|
372
|
+
const assets = multiAsset.get(policy);
|
|
373
|
+
const tokens = [];
|
|
374
|
+
if (assets) {
|
|
375
|
+
for (let k = 0; k < assets.keys().len(); k++) {
|
|
376
|
+
const assetName = assets.keys().get(k);
|
|
377
|
+
const amount = assets.get(assetName);
|
|
378
|
+
if (assetName && amount) {
|
|
379
|
+
tokens.push({
|
|
380
|
+
amount: amount.to_str(),
|
|
381
|
+
assetNameHex: Buffer.from(assetName.name()).toString('hex')
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
sortTokensCanonically(tokens);
|
|
387
|
+
tokenBundle.push({
|
|
388
|
+
policyIdHex: Buffer.from(policy.to_bytes()).toString('hex'),
|
|
389
|
+
tokens
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
const outputAddress = Buffer.from(output.address().to_bytes());
|
|
394
|
+
const ownAddress = matchGroupedAddress(knownAddresses, outputAddress);
|
|
395
|
+
const destination = ownAddress
|
|
396
|
+
? {
|
|
397
|
+
params: {
|
|
398
|
+
params: {
|
|
399
|
+
spendingPath: [
|
|
400
|
+
harden(CardanoKeyConst.PURPOSE),
|
|
401
|
+
harden(CardanoKeyConst.COIN_TYPE),
|
|
402
|
+
harden(ownAddress.accountIndex),
|
|
403
|
+
ownAddress.type,
|
|
404
|
+
ownAddress.index
|
|
405
|
+
],
|
|
406
|
+
stakingPath: [
|
|
407
|
+
harden(CardanoKeyConst.PURPOSE),
|
|
408
|
+
harden(CardanoKeyConst.COIN_TYPE),
|
|
409
|
+
harden(ownAddress.accountIndex),
|
|
410
|
+
STAKE_KEY_DERIVATION_PATH.role,
|
|
411
|
+
STAKE_KEY_DERIVATION_PATH.index
|
|
412
|
+
]
|
|
413
|
+
},
|
|
414
|
+
type: ledger.AddressType.BASE_PAYMENT_KEY_STAKE_KEY
|
|
415
|
+
},
|
|
416
|
+
type: ledger.TxOutputDestinationType.DEVICE_OWNED
|
|
417
|
+
}
|
|
418
|
+
: {
|
|
419
|
+
params: {
|
|
420
|
+
addressHex: outputAddress.toString('hex')
|
|
421
|
+
},
|
|
422
|
+
type: ledger.TxOutputDestinationType.THIRD_PARTY
|
|
423
|
+
};
|
|
424
|
+
const outputDataHash = output.data_hash();
|
|
425
|
+
const datumHashHex = outputDataHash ? Buffer.from(outputDataHash.to_bytes()).toString('hex') : null;
|
|
426
|
+
const outputRes = {
|
|
427
|
+
amount: output.amount().coin().to_str(),
|
|
428
|
+
datumHashHex,
|
|
429
|
+
destination,
|
|
430
|
+
tokenBundle
|
|
431
|
+
};
|
|
432
|
+
ledgerOutputs.push(outputRes);
|
|
433
|
+
}
|
|
434
|
+
return ledgerOutputs;
|
|
435
|
+
};
|
|
436
|
+
const prepareLedgerCertificates = (certificates, knownAddresses, rewardAccountKeyPath, rewardAccountKeyHash) => {
|
|
437
|
+
let signingMode;
|
|
438
|
+
const certs = [];
|
|
439
|
+
for (let i = 0; i < certificates.len(); i++) {
|
|
440
|
+
const cert = certificates.get(i);
|
|
441
|
+
const certificate = {};
|
|
442
|
+
if (cert.kind() === 0) {
|
|
443
|
+
const credential = cert.as_stake_registration()?.stake_credential();
|
|
444
|
+
const credentialScriptHash = credential?.to_scripthash();
|
|
445
|
+
certificate.type = ledger.CertificateType.STAKE_REGISTRATION;
|
|
446
|
+
if (credential?.kind() === 0) {
|
|
447
|
+
certificate.params = {
|
|
448
|
+
stakeCredential: {
|
|
449
|
+
keyPath: rewardAccountKeyPath,
|
|
450
|
+
type: ledger.StakeCredentialParamsType.KEY_PATH
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
else if (credential && credentialScriptHash) {
|
|
455
|
+
const scriptHashHex = Buffer.from(credentialScriptHash.to_bytes()).toString('hex');
|
|
456
|
+
certificate.params = {
|
|
457
|
+
stakeCredential: {
|
|
458
|
+
scriptHashHex,
|
|
459
|
+
type: ledger.StakeCredentialParamsType.SCRIPT_HASH
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
else if (cert.kind() === 1) {
|
|
465
|
+
const credential = cert.as_stake_deregistration()?.stake_credential();
|
|
466
|
+
const credentialScriptHash = credential?.to_scripthash();
|
|
467
|
+
certificate.type = ledger.CertificateType.STAKE_DEREGISTRATION;
|
|
468
|
+
if (credential?.kind() === 0) {
|
|
469
|
+
certificate.params = {
|
|
470
|
+
stakeCredential: {
|
|
471
|
+
keyPath: rewardAccountKeyPath,
|
|
472
|
+
type: ledger.StakeCredentialParamsType.KEY_PATH
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
else if (credential && credentialScriptHash) {
|
|
477
|
+
const scriptHashHex = Buffer.from(credentialScriptHash.to_bytes()).toString('hex');
|
|
478
|
+
certificate.params = {
|
|
479
|
+
stakeCredential: {
|
|
480
|
+
scriptHashHex,
|
|
481
|
+
type: ledger.StakeCredentialParamsType.SCRIPT_HASH
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
else if (cert.kind() === 2) {
|
|
487
|
+
const delegation = cert.as_stake_delegation();
|
|
488
|
+
const delegationPoolKeyHash = delegation?.pool_keyhash();
|
|
489
|
+
const credential = delegation?.stake_credential();
|
|
490
|
+
const credentialScriptHash = credential?.to_scripthash();
|
|
491
|
+
certificate.type = ledger.CertificateType.STAKE_DELEGATION;
|
|
492
|
+
if (credential?.kind() === 0) {
|
|
493
|
+
certificate.params = {
|
|
494
|
+
stakeCredential: {
|
|
495
|
+
keyPath: rewardAccountKeyPath,
|
|
496
|
+
type: ledger.StakeCredentialParamsType.KEY_PATH
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
else if (credentialScriptHash) {
|
|
501
|
+
const scriptHashHex = Buffer.from(credentialScriptHash.to_bytes()).toString('hex');
|
|
502
|
+
certificate.params = {
|
|
503
|
+
stakeCredential: {
|
|
504
|
+
scriptHashHex,
|
|
505
|
+
type: ledger.StakeCredentialParamsType.SCRIPT_HASH
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
if (delegationPoolKeyHash) {
|
|
510
|
+
certificate.params = {
|
|
511
|
+
...certificate.params,
|
|
512
|
+
poolKeyHashHex: Buffer.from(delegationPoolKeyHash.to_bytes()).toString('hex')
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
else if (cert.kind() === 3) {
|
|
517
|
+
const params = cert.as_pool_registration()?.pool_params();
|
|
518
|
+
if (!params) {
|
|
519
|
+
throw new HwMappingError('Missing pool registration pool parameters.');
|
|
520
|
+
}
|
|
521
|
+
certificate.type = ledger.CertificateType.STAKE_POOL_REGISTRATION;
|
|
522
|
+
const owners = params?.pool_owners();
|
|
523
|
+
const poolOwners = [];
|
|
524
|
+
if (owners) {
|
|
525
|
+
for (let j = 0; j < owners.len(); j++) {
|
|
526
|
+
const keyHash = Buffer.from(owners.get(j).to_bytes()).toString('hex');
|
|
527
|
+
if (keyHash === rewardAccountKeyHash) {
|
|
528
|
+
signingMode = ledger.TransactionSigningMode.POOL_REGISTRATION_AS_OWNER;
|
|
529
|
+
poolOwners.push({
|
|
530
|
+
params: {
|
|
531
|
+
stakingPath: rewardAccountKeyPath
|
|
532
|
+
},
|
|
533
|
+
type: ledger.PoolOwnerType.DEVICE_OWNED
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
poolOwners.push({
|
|
538
|
+
params: {
|
|
539
|
+
stakingKeyHashHex: keyHash
|
|
540
|
+
},
|
|
541
|
+
type: ledger.PoolOwnerType.THIRD_PARTY
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
const relays = params?.relays();
|
|
547
|
+
const ledgerRelays = [];
|
|
548
|
+
if (relays) {
|
|
549
|
+
for (let k = 0; k < relays.len(); k++) {
|
|
550
|
+
const relay = relays.get(k);
|
|
551
|
+
if (relay.kind() === 0) {
|
|
552
|
+
const singleHostAddr = relay.as_single_host_addr();
|
|
553
|
+
const type = 0;
|
|
554
|
+
const portNumber = singleHostAddr?.port();
|
|
555
|
+
const ipv4 = singleHostAddr?.ipv4() ? bytesToIp(singleHostAddr.ipv4()?.ip()) : null;
|
|
556
|
+
const ipv6 = singleHostAddr?.ipv6() ? bytesToIp(singleHostAddr.ipv6()?.ip()) : null;
|
|
557
|
+
ledgerRelays.push({ params: { ipv4, ipv6, portNumber }, type });
|
|
558
|
+
}
|
|
559
|
+
else if (relay.kind() === 1) {
|
|
560
|
+
const type = 1;
|
|
561
|
+
const singleHostName = relay.as_single_host_name();
|
|
562
|
+
if (singleHostName) {
|
|
563
|
+
const portNumber = singleHostName.port();
|
|
564
|
+
const dnsName = singleHostName.dns_name().record();
|
|
565
|
+
ledgerRelays.push({
|
|
566
|
+
params: { dnsName, portNumber },
|
|
567
|
+
type
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
else if (relay.kind() === 2) {
|
|
572
|
+
const type = 2;
|
|
573
|
+
const multiHostName = relay.as_multi_host_name();
|
|
574
|
+
const dnsName = multiHostName?.dns_name().record();
|
|
575
|
+
if (dnsName) {
|
|
576
|
+
ledgerRelays.push({
|
|
577
|
+
params: { dnsName },
|
|
578
|
+
type
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
const cost = params?.cost().to_str();
|
|
585
|
+
const margin = params?.margin();
|
|
586
|
+
const pledge = params?.pledge().to_str();
|
|
587
|
+
const operator = Buffer.from(params.operator().to_bytes()).toString('hex');
|
|
588
|
+
let poolKey;
|
|
589
|
+
if (operator === rewardAccountKeyHash) {
|
|
590
|
+
signingMode = ledger.TransactionSigningMode.POOL_REGISTRATION_AS_OPERATOR;
|
|
591
|
+
poolKey = {
|
|
592
|
+
params: { path: rewardAccountKeyPath },
|
|
593
|
+
type: ledger.PoolKeyType.DEVICE_OWNED
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
poolKey = {
|
|
598
|
+
params: { keyHashHex: operator },
|
|
599
|
+
type: ledger.PoolKeyType.THIRD_PARTY
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
const poolMetadata = params.pool_metadata();
|
|
603
|
+
const metadata = poolMetadata
|
|
604
|
+
? {
|
|
605
|
+
metadataHashHex: Buffer.from(poolMetadata.pool_metadata_hash().to_bytes()).toString('hex'),
|
|
606
|
+
metadataUrl: poolMetadata.url().url()
|
|
607
|
+
}
|
|
608
|
+
: null;
|
|
609
|
+
const rewardAccountBytes = Buffer.from(params.reward_account().to_address().to_bytes());
|
|
610
|
+
const isDeviceOwned = knownAddresses.some(({ address }) => address.toString() === ledger.utils.bech32_encodeAddress(rewardAccountBytes));
|
|
611
|
+
const rewardAccount = isDeviceOwned
|
|
612
|
+
? {
|
|
613
|
+
params: { path: rewardAccountKeyPath },
|
|
614
|
+
type: ledger.PoolRewardAccountType.DEVICE_OWNED
|
|
615
|
+
}
|
|
616
|
+
: {
|
|
617
|
+
params: { rewardAccountHex: rewardAccountBytes.toString('hex') },
|
|
618
|
+
type: ledger.PoolRewardAccountType.THIRD_PARTY
|
|
619
|
+
};
|
|
620
|
+
const vrfKeyHashHex = Buffer.from(params.vrf_keyhash().to_bytes()).toString('hex');
|
|
621
|
+
certificate.params = {
|
|
622
|
+
cost,
|
|
623
|
+
margin: {
|
|
624
|
+
denominator: margin.denominator().to_str(),
|
|
625
|
+
numerator: margin.numerator().to_str()
|
|
626
|
+
},
|
|
627
|
+
metadata,
|
|
628
|
+
pledge,
|
|
629
|
+
poolKey,
|
|
630
|
+
poolOwners,
|
|
631
|
+
relays: ledgerRelays,
|
|
632
|
+
rewardAccount,
|
|
633
|
+
vrfKeyHashHex
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
certs.push(certificate);
|
|
637
|
+
}
|
|
638
|
+
return {
|
|
639
|
+
certs,
|
|
640
|
+
signingMode
|
|
641
|
+
};
|
|
642
|
+
};
|
|
643
|
+
const prepareLedgerWithdrawals = (withdrawals, rewardAccountKeyPath) => {
|
|
644
|
+
const ledgerWithdrawals = [];
|
|
645
|
+
for (let i = 0; i < withdrawals.keys().len(); i++) {
|
|
646
|
+
const withdrawal = { stakeCredential: {} };
|
|
647
|
+
const rewardAddress = withdrawals.keys().get(i);
|
|
648
|
+
const paymentCredentials = rewardAddress.payment_cred();
|
|
649
|
+
const paymentCredentialsScriptHash = paymentCredentials.to_scripthash();
|
|
650
|
+
if (rewardAddress.payment_cred().kind() === 0) {
|
|
651
|
+
const stakeCredential = {
|
|
652
|
+
keyPath: rewardAccountKeyPath,
|
|
653
|
+
type: ledger.StakeCredentialParamsType.KEY_PATH
|
|
654
|
+
};
|
|
655
|
+
withdrawal.stakeCredential = stakeCredential;
|
|
656
|
+
}
|
|
657
|
+
else if (paymentCredentialsScriptHash) {
|
|
658
|
+
const stakeCredential = {
|
|
659
|
+
scriptHashHex: Buffer.from(paymentCredentialsScriptHash.to_bytes()).toString('hex'),
|
|
660
|
+
type: ledger.StakeCredentialParamsType.SCRIPT_HASH
|
|
661
|
+
};
|
|
662
|
+
withdrawal.stakeCredential = stakeCredential;
|
|
663
|
+
}
|
|
664
|
+
const withdrawalAmount = withdrawals.get(rewardAddress);
|
|
665
|
+
if (!withdrawalAmount) {
|
|
666
|
+
throw new HwMappingError('Withdrawal amount is not defined.');
|
|
667
|
+
}
|
|
668
|
+
ledgerWithdrawals.push({
|
|
669
|
+
...withdrawal,
|
|
670
|
+
amount: withdrawalAmount.to_str()
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
return ledgerWithdrawals;
|
|
674
|
+
};
|
|
675
|
+
const prepareLedgerMintBundle = (mint, paymentKeyPaths, rewardAccountKeyPath) => {
|
|
676
|
+
const additionalWitnessPaths = [];
|
|
677
|
+
const mintAssetsGroup = [];
|
|
678
|
+
for (let j = 0; j < mint.keys().len(); j++) {
|
|
679
|
+
const policy = mint.keys().get(j);
|
|
680
|
+
const assets = mint.get(policy);
|
|
681
|
+
const tokens = [];
|
|
682
|
+
if (assets) {
|
|
683
|
+
for (let k = 0; k < assets.keys().len(); k++) {
|
|
684
|
+
const assetName = assets.keys().get(k);
|
|
685
|
+
const amount = assets.get(assetName);
|
|
686
|
+
const positiveAmount = amount?.as_positive()?.to_str();
|
|
687
|
+
const negativeAmount = amount?.as_negative()?.to_str();
|
|
688
|
+
if (!amount || !positiveAmount || !negativeAmount) {
|
|
689
|
+
throw new HwMappingError('Missing token amount.');
|
|
690
|
+
}
|
|
691
|
+
tokens.push({
|
|
692
|
+
amount: amount.is_positive() ? positiveAmount : `-${negativeAmount}`,
|
|
693
|
+
assetNameHex: Buffer.from(assetName.name()).toString('hex')
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
sortTokensCanonically(tokens);
|
|
698
|
+
mintAssetsGroup.push({
|
|
699
|
+
policyIdHex: Buffer.from(policy.to_bytes()).toString('hex'),
|
|
700
|
+
tokens
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
if (paymentKeyPaths)
|
|
704
|
+
concat(additionalWitnessPaths, paymentKeyPaths);
|
|
705
|
+
if (rewardAccountKeyPath)
|
|
706
|
+
additionalWitnessPaths.push(rewardAccountKeyPath);
|
|
707
|
+
return {
|
|
708
|
+
additionalWitnessPaths,
|
|
709
|
+
mintAssetsGroup
|
|
710
|
+
};
|
|
711
|
+
};
|
|
712
|
+
export const txToLedger = async ({ cslTxBody, networkId, inputResolver: inputAddressResolver, knownAddresses, protocolMagic }) => {
|
|
713
|
+
const accountAddress = knownAddresses[0];
|
|
714
|
+
const rewardAccount = accountAddress.rewardAccount;
|
|
715
|
+
const rewardAccountKeyHash = getRewardAccountKeyHash(rewardAccount);
|
|
716
|
+
const rewardAccountKeyPath = [
|
|
717
|
+
harden(CardanoKeyConst.PURPOSE),
|
|
718
|
+
harden(CardanoKeyConst.COIN_TYPE),
|
|
719
|
+
harden(accountAddress.accountIndex),
|
|
720
|
+
STAKE_KEY_DERIVATION_PATH.role,
|
|
721
|
+
STAKE_KEY_DERIVATION_PATH.index
|
|
722
|
+
];
|
|
723
|
+
const ledgerInputs = await prepareLedgerInputs(cslTxBody.inputs(), inputAddressResolver, knownAddresses);
|
|
724
|
+
const ledgerOutputs = prepareLedgerOutputs(cslTxBody.outputs(), knownAddresses);
|
|
725
|
+
const cslWithdrawals = cslTxBody.withdrawals();
|
|
726
|
+
const ledgerWithdrawals = cslWithdrawals ? prepareLedgerWithdrawals(cslWithdrawals, rewardAccountKeyPath) : null;
|
|
727
|
+
const cslCertificates = cslTxBody.certs();
|
|
728
|
+
const ledgerCertificatesData = cslCertificates
|
|
729
|
+
? prepareLedgerCertificates(cslCertificates, knownAddresses, rewardAccountKeyPath, rewardAccountKeyHash.toString())
|
|
730
|
+
: null;
|
|
731
|
+
const signingMode = ledgerCertificatesData?.signingMode || ledger.TransactionSigningMode.ORDINARY_TRANSACTION;
|
|
732
|
+
const fee = cslTxBody.fee().to_str();
|
|
733
|
+
const ttl = cslTxBody.ttl();
|
|
734
|
+
const validityStartInterval = cslTxBody.validity_start_interval();
|
|
735
|
+
const txBodyAuxDataHash = cslTxBody.auxiliary_data_hash();
|
|
736
|
+
const auxiliaryData = txBodyAuxDataHash
|
|
737
|
+
? {
|
|
738
|
+
params: {
|
|
739
|
+
hashHex: Buffer.from(txBodyAuxDataHash.to_bytes()).toString('hex')
|
|
740
|
+
},
|
|
741
|
+
type: ledger.TxAuxiliaryDataType.ARBITRARY_HASH
|
|
742
|
+
}
|
|
743
|
+
: null;
|
|
744
|
+
const cslMint = cslTxBody.multiassets();
|
|
745
|
+
let ledgerMintBundle = null;
|
|
746
|
+
if (cslMint) {
|
|
747
|
+
const paymentKeyPaths = uniq(ledgerInputs.map((ledgerInput) => ledgerInput.path).filter(isNotNil));
|
|
748
|
+
ledgerMintBundle = prepareLedgerMintBundle(cslMint, paymentKeyPaths, rewardAccountKeyPath);
|
|
749
|
+
}
|
|
750
|
+
const additionalWitnessPaths = ledgerMintBundle?.additionalWitnessPaths || [];
|
|
751
|
+
const ledgerTx = {
|
|
752
|
+
auxiliaryData,
|
|
753
|
+
certificates: ledgerCertificatesData?.certs,
|
|
754
|
+
fee,
|
|
755
|
+
inputs: ledgerInputs,
|
|
756
|
+
mint: ledgerMintBundle?.mintAssetsGroup,
|
|
757
|
+
network: {
|
|
758
|
+
networkId,
|
|
759
|
+
protocolMagic
|
|
760
|
+
},
|
|
761
|
+
outputs: ledgerOutputs,
|
|
762
|
+
ttl,
|
|
763
|
+
validityStartInterval,
|
|
764
|
+
withdrawals: ledgerWithdrawals
|
|
765
|
+
};
|
|
766
|
+
for (const key of Object.keys(ledgerTx)) {
|
|
767
|
+
const objKey = key;
|
|
768
|
+
!ledgerTx[objKey] && ledgerTx[objKey] !== 0 && delete ledgerTx[objKey];
|
|
769
|
+
}
|
|
770
|
+
return {
|
|
771
|
+
additionalWitnessPaths,
|
|
772
|
+
signingMode,
|
|
773
|
+
tx: ledgerTx
|
|
774
|
+
};
|
|
775
|
+
};
|
|
776
|
+
export const txToTrezor = async ({ cslTxBody, networkId, inputResolver: inputAddressResolver, knownAddresses, protocolMagic }) => {
|
|
777
|
+
const accountAddress = knownAddresses[0];
|
|
778
|
+
const rewardAccount = accountAddress.rewardAccount;
|
|
779
|
+
const rewardAccountKeyHash = getRewardAccountKeyHash(rewardAccount);
|
|
780
|
+
const rewardAccountKeyPath = [
|
|
781
|
+
harden(CardanoKeyConst.PURPOSE),
|
|
782
|
+
harden(CardanoKeyConst.COIN_TYPE),
|
|
783
|
+
harden(accountAddress.accountIndex),
|
|
784
|
+
STAKE_KEY_DERIVATION_PATH.role,
|
|
785
|
+
STAKE_KEY_DERIVATION_PATH.index
|
|
786
|
+
];
|
|
787
|
+
const trezorInputs = await prepareTrezorInputs(cslTxBody.inputs(), inputAddressResolver, knownAddresses);
|
|
788
|
+
const trezorOutputs = prepareTrezorOutputs(cslTxBody.outputs(), knownAddresses);
|
|
789
|
+
const cslWithdrawals = cslTxBody.withdrawals();
|
|
790
|
+
const trezorWithdrawals = cslWithdrawals ? prepareTrezorWithdrawals(cslWithdrawals, rewardAccountKeyPath) : undefined;
|
|
791
|
+
const cslCertificates = cslTxBody.certs();
|
|
792
|
+
let trezorCertificatesData;
|
|
793
|
+
if (cslCertificates) {
|
|
794
|
+
trezorCertificatesData = prepareTrezorCertificates(cslCertificates, rewardAccountKeyPath, rewardAccountKeyHash.toString());
|
|
795
|
+
}
|
|
796
|
+
const signingMode = trezorCertificatesData?.signingMode || trezor.CardanoTxSigningMode.ORDINARY_TRANSACTION;
|
|
797
|
+
const fee = cslTxBody.fee().to_str();
|
|
798
|
+
let ttl;
|
|
799
|
+
const cslTTL = cslTxBody.ttl();
|
|
800
|
+
if (cslTTL) {
|
|
801
|
+
ttl = cslTTL.toString();
|
|
802
|
+
}
|
|
803
|
+
const validityIntervalStart = cslTxBody.validity_start_interval();
|
|
804
|
+
const txBodyAuxDataHash = cslTxBody.auxiliary_data_hash();
|
|
805
|
+
let auxiliaryData;
|
|
806
|
+
if (txBodyAuxDataHash) {
|
|
807
|
+
auxiliaryData = {
|
|
808
|
+
hash: Buffer.from(txBodyAuxDataHash.to_bytes()).toString('hex')
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
const cslMint = cslTxBody.multiassets();
|
|
812
|
+
let trezorMintBundle = null;
|
|
813
|
+
if (cslMint) {
|
|
814
|
+
const paymentKeyPaths = uniq(trezorInputs.map((trezorInput) => trezorInput.path).filter(isNotNil));
|
|
815
|
+
trezorMintBundle = prepareTrezorMintBundle(cslMint, paymentKeyPaths, rewardAccountKeyPath);
|
|
816
|
+
}
|
|
817
|
+
return {
|
|
818
|
+
additionalWitnessRequests: trezorMintBundle?.additionalWitnessPaths,
|
|
819
|
+
auxiliaryData,
|
|
820
|
+
certificates: trezorCertificatesData?.certs,
|
|
821
|
+
fee,
|
|
822
|
+
inputs: trezorInputs,
|
|
823
|
+
mint: trezorMintBundle?.mintAssetsGroup,
|
|
824
|
+
networkId,
|
|
825
|
+
outputs: trezorOutputs,
|
|
826
|
+
protocolMagic,
|
|
827
|
+
signingMode,
|
|
828
|
+
ttl,
|
|
829
|
+
validityIntervalStart: validityIntervalStart?.toString(),
|
|
830
|
+
withdrawals: trezorWithdrawals
|
|
831
|
+
};
|
|
832
|
+
};
|
|
833
|
+
//# sourceMappingURL=mapHardwareSigningData.js.map
|