-
Notifications
You must be signed in to change notification settings - Fork 24
/
helpers.ts
106 lines (93 loc) · 2.93 KB
/
helpers.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import {
Bip32PublicKey,
BaseAddress,
NetworkInfo,
StakeCredential,
RewardAddress,
ByronAddress,
} from '@emurgo/cardano-serialization-lib-nodejs';
import AssetFingerprint from '@emurgo/cip14-js';
import { ParseAssetResult } from '../types/utils';
/**
* Derives an address with derivation path m/1852'/1815'/account'/role/addressIndex
* If role === 2 then it returns a stake address (m/1852'/1815'/account'/2/addressIndex)
*
* @Returns {address: string, path: number[] } Bech32 address shaped as {address: string, path: [role, addressIndex]}
* */
export const deriveAddress = (
accountPublicKey: string,
role: number,
addressIndex: number,
isTestnet: boolean,
isByron?: boolean,
): { address: string; path: [number, number] } => {
const accountKey = Bip32PublicKey.from_bytes(
Buffer.from(accountPublicKey, 'hex'),
);
const utxoPubKey = accountKey.derive(role).derive(addressIndex);
const mainStakeKey = accountKey.derive(2).derive(0);
const networkId = isTestnet
? NetworkInfo.testnet().network_id()
: NetworkInfo.mainnet().network_id();
const baseAddr = BaseAddress.new(
networkId,
StakeCredential.from_keyhash(utxoPubKey.to_raw_key().hash()),
StakeCredential.from_keyhash(mainStakeKey.to_raw_key().hash()),
);
if (role === 2 && !isByron) {
const addressSpecificStakeKey = accountKey.derive(2).derive(addressIndex);
// always return stake address
const rewardAddr = RewardAddress.new(
networkId,
StakeCredential.from_keyhash(addressSpecificStakeKey.to_raw_key().hash()),
)
.to_address()
.to_bech32();
return {
address: rewardAddr,
path: [role, addressIndex],
};
}
if (isByron) {
const protocolMagic = isTestnet
? NetworkInfo.testnet().protocol_magic()
: NetworkInfo.mainnet().protocol_magic();
const byronAddress = ByronAddress.icarus_from_key(
utxoPubKey,
protocolMagic,
);
return {
address: byronAddress.to_base58().toString(),
path: [role, addressIndex],
};
}
return {
address: baseAddr.to_address().to_bech32(),
path: [role, addressIndex],
};
};
export const hexToString = (input: string): string => {
const hex = input.toString();
let str = '';
for (let n = 0; n < hex.length; n += 2) {
str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
}
return str;
};
export const getFingerprint = (policyId: string, assetName?: string): string =>
AssetFingerprint.fromParts(
Uint8Array.from(Buffer.from(policyId, 'hex')),
Uint8Array.from(Buffer.from(assetName || '', 'hex')),
).fingerprint();
export const parseAsset = (hex: string): ParseAssetResult => {
const policyIdSize = 56;
const policyId = hex.slice(0, policyIdSize);
const assetNameInHex = hex.slice(policyIdSize);
const assetName = hexToString(assetNameInHex);
const fingerprint = getFingerprint(policyId, assetNameInHex);
return {
policyId,
assetName,
fingerprint,
};
};