wallet-storage
Version:
BRC100 conforming wallet, wallet storage and wallet signer components
817 lines (803 loc) • 41.6 kB
HTML
<html lang="en">
<head>
<title>Code coverage report for src/sdk/KeyDeriver.ts</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../../prettify.css" />
<link rel="stylesheet" href="../../base.css" />
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(../../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1><a href="../../index.html">All files</a> / <a href="index.html">src/sdk</a> KeyDeriver.ts</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">41.93% </span>
<span class="quiet">Statements</span>
<span class='fraction'>26/62</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">30% </span>
<span class="quiet">Branches</span>
<span class='fraction'>9/30</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">62.5% </span>
<span class="quiet">Functions</span>
<span class='fraction'>5/8</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">41.93% </span>
<span class="quiet">Lines</span>
<span class='fraction'>26/62</span>
</div>
</div>
<p class="quiet">
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
</p>
<template id="filterTemplate">
<div class="quiet">
Filter:
<input type="search" id="fileSearch">
</div>
</template>
</div>
<div class='status-line low'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
<a name='L2'></a><a href='#L2'>2</a>
<a name='L3'></a><a href='#L3'>3</a>
<a name='L4'></a><a href='#L4'>4</a>
<a name='L5'></a><a href='#L5'>5</a>
<a name='L6'></a><a href='#L6'>6</a>
<a name='L7'></a><a href='#L7'>7</a>
<a name='L8'></a><a href='#L8'>8</a>
<a name='L9'></a><a href='#L9'>9</a>
<a name='L10'></a><a href='#L10'>10</a>
<a name='L11'></a><a href='#L11'>11</a>
<a name='L12'></a><a href='#L12'>12</a>
<a name='L13'></a><a href='#L13'>13</a>
<a name='L14'></a><a href='#L14'>14</a>
<a name='L15'></a><a href='#L15'>15</a>
<a name='L16'></a><a href='#L16'>16</a>
<a name='L17'></a><a href='#L17'>17</a>
<a name='L18'></a><a href='#L18'>18</a>
<a name='L19'></a><a href='#L19'>19</a>
<a name='L20'></a><a href='#L20'>20</a>
<a name='L21'></a><a href='#L21'>21</a>
<a name='L22'></a><a href='#L22'>22</a>
<a name='L23'></a><a href='#L23'>23</a>
<a name='L24'></a><a href='#L24'>24</a>
<a name='L25'></a><a href='#L25'>25</a>
<a name='L26'></a><a href='#L26'>26</a>
<a name='L27'></a><a href='#L27'>27</a>
<a name='L28'></a><a href='#L28'>28</a>
<a name='L29'></a><a href='#L29'>29</a>
<a name='L30'></a><a href='#L30'>30</a>
<a name='L31'></a><a href='#L31'>31</a>
<a name='L32'></a><a href='#L32'>32</a>
<a name='L33'></a><a href='#L33'>33</a>
<a name='L34'></a><a href='#L34'>34</a>
<a name='L35'></a><a href='#L35'>35</a>
<a name='L36'></a><a href='#L36'>36</a>
<a name='L37'></a><a href='#L37'>37</a>
<a name='L38'></a><a href='#L38'>38</a>
<a name='L39'></a><a href='#L39'>39</a>
<a name='L40'></a><a href='#L40'>40</a>
<a name='L41'></a><a href='#L41'>41</a>
<a name='L42'></a><a href='#L42'>42</a>
<a name='L43'></a><a href='#L43'>43</a>
<a name='L44'></a><a href='#L44'>44</a>
<a name='L45'></a><a href='#L45'>45</a>
<a name='L46'></a><a href='#L46'>46</a>
<a name='L47'></a><a href='#L47'>47</a>
<a name='L48'></a><a href='#L48'>48</a>
<a name='L49'></a><a href='#L49'>49</a>
<a name='L50'></a><a href='#L50'>50</a>
<a name='L51'></a><a href='#L51'>51</a>
<a name='L52'></a><a href='#L52'>52</a>
<a name='L53'></a><a href='#L53'>53</a>
<a name='L54'></a><a href='#L54'>54</a>
<a name='L55'></a><a href='#L55'>55</a>
<a name='L56'></a><a href='#L56'>56</a>
<a name='L57'></a><a href='#L57'>57</a>
<a name='L58'></a><a href='#L58'>58</a>
<a name='L59'></a><a href='#L59'>59</a>
<a name='L60'></a><a href='#L60'>60</a>
<a name='L61'></a><a href='#L61'>61</a>
<a name='L62'></a><a href='#L62'>62</a>
<a name='L63'></a><a href='#L63'>63</a>
<a name='L64'></a><a href='#L64'>64</a>
<a name='L65'></a><a href='#L65'>65</a>
<a name='L66'></a><a href='#L66'>66</a>
<a name='L67'></a><a href='#L67'>67</a>
<a name='L68'></a><a href='#L68'>68</a>
<a name='L69'></a><a href='#L69'>69</a>
<a name='L70'></a><a href='#L70'>70</a>
<a name='L71'></a><a href='#L71'>71</a>
<a name='L72'></a><a href='#L72'>72</a>
<a name='L73'></a><a href='#L73'>73</a>
<a name='L74'></a><a href='#L74'>74</a>
<a name='L75'></a><a href='#L75'>75</a>
<a name='L76'></a><a href='#L76'>76</a>
<a name='L77'></a><a href='#L77'>77</a>
<a name='L78'></a><a href='#L78'>78</a>
<a name='L79'></a><a href='#L79'>79</a>
<a name='L80'></a><a href='#L80'>80</a>
<a name='L81'></a><a href='#L81'>81</a>
<a name='L82'></a><a href='#L82'>82</a>
<a name='L83'></a><a href='#L83'>83</a>
<a name='L84'></a><a href='#L84'>84</a>
<a name='L85'></a><a href='#L85'>85</a>
<a name='L86'></a><a href='#L86'>86</a>
<a name='L87'></a><a href='#L87'>87</a>
<a name='L88'></a><a href='#L88'>88</a>
<a name='L89'></a><a href='#L89'>89</a>
<a name='L90'></a><a href='#L90'>90</a>
<a name='L91'></a><a href='#L91'>91</a>
<a name='L92'></a><a href='#L92'>92</a>
<a name='L93'></a><a href='#L93'>93</a>
<a name='L94'></a><a href='#L94'>94</a>
<a name='L95'></a><a href='#L95'>95</a>
<a name='L96'></a><a href='#L96'>96</a>
<a name='L97'></a><a href='#L97'>97</a>
<a name='L98'></a><a href='#L98'>98</a>
<a name='L99'></a><a href='#L99'>99</a>
<a name='L100'></a><a href='#L100'>100</a>
<a name='L101'></a><a href='#L101'>101</a>
<a name='L102'></a><a href='#L102'>102</a>
<a name='L103'></a><a href='#L103'>103</a>
<a name='L104'></a><a href='#L104'>104</a>
<a name='L105'></a><a href='#L105'>105</a>
<a name='L106'></a><a href='#L106'>106</a>
<a name='L107'></a><a href='#L107'>107</a>
<a name='L108'></a><a href='#L108'>108</a>
<a name='L109'></a><a href='#L109'>109</a>
<a name='L110'></a><a href='#L110'>110</a>
<a name='L111'></a><a href='#L111'>111</a>
<a name='L112'></a><a href='#L112'>112</a>
<a name='L113'></a><a href='#L113'>113</a>
<a name='L114'></a><a href='#L114'>114</a>
<a name='L115'></a><a href='#L115'>115</a>
<a name='L116'></a><a href='#L116'>116</a>
<a name='L117'></a><a href='#L117'>117</a>
<a name='L118'></a><a href='#L118'>118</a>
<a name='L119'></a><a href='#L119'>119</a>
<a name='L120'></a><a href='#L120'>120</a>
<a name='L121'></a><a href='#L121'>121</a>
<a name='L122'></a><a href='#L122'>122</a>
<a name='L123'></a><a href='#L123'>123</a>
<a name='L124'></a><a href='#L124'>124</a>
<a name='L125'></a><a href='#L125'>125</a>
<a name='L126'></a><a href='#L126'>126</a>
<a name='L127'></a><a href='#L127'>127</a>
<a name='L128'></a><a href='#L128'>128</a>
<a name='L129'></a><a href='#L129'>129</a>
<a name='L130'></a><a href='#L130'>130</a>
<a name='L131'></a><a href='#L131'>131</a>
<a name='L132'></a><a href='#L132'>132</a>
<a name='L133'></a><a href='#L133'>133</a>
<a name='L134'></a><a href='#L134'>134</a>
<a name='L135'></a><a href='#L135'>135</a>
<a name='L136'></a><a href='#L136'>136</a>
<a name='L137'></a><a href='#L137'>137</a>
<a name='L138'></a><a href='#L138'>138</a>
<a name='L139'></a><a href='#L139'>139</a>
<a name='L140'></a><a href='#L140'>140</a>
<a name='L141'></a><a href='#L141'>141</a>
<a name='L142'></a><a href='#L142'>142</a>
<a name='L143'></a><a href='#L143'>143</a>
<a name='L144'></a><a href='#L144'>144</a>
<a name='L145'></a><a href='#L145'>145</a>
<a name='L146'></a><a href='#L146'>146</a>
<a name='L147'></a><a href='#L147'>147</a>
<a name='L148'></a><a href='#L148'>148</a>
<a name='L149'></a><a href='#L149'>149</a>
<a name='L150'></a><a href='#L150'>150</a>
<a name='L151'></a><a href='#L151'>151</a>
<a name='L152'></a><a href='#L152'>152</a>
<a name='L153'></a><a href='#L153'>153</a>
<a name='L154'></a><a href='#L154'>154</a>
<a name='L155'></a><a href='#L155'>155</a>
<a name='L156'></a><a href='#L156'>156</a>
<a name='L157'></a><a href='#L157'>157</a>
<a name='L158'></a><a href='#L158'>158</a>
<a name='L159'></a><a href='#L159'>159</a>
<a name='L160'></a><a href='#L160'>160</a>
<a name='L161'></a><a href='#L161'>161</a>
<a name='L162'></a><a href='#L162'>162</a>
<a name='L163'></a><a href='#L163'>163</a>
<a name='L164'></a><a href='#L164'>164</a>
<a name='L165'></a><a href='#L165'>165</a>
<a name='L166'></a><a href='#L166'>166</a>
<a name='L167'></a><a href='#L167'>167</a>
<a name='L168'></a><a href='#L168'>168</a>
<a name='L169'></a><a href='#L169'>169</a>
<a name='L170'></a><a href='#L170'>170</a>
<a name='L171'></a><a href='#L171'>171</a>
<a name='L172'></a><a href='#L172'>172</a>
<a name='L173'></a><a href='#L173'>173</a>
<a name='L174'></a><a href='#L174'>174</a>
<a name='L175'></a><a href='#L175'>175</a>
<a name='L176'></a><a href='#L176'>176</a>
<a name='L177'></a><a href='#L177'>177</a>
<a name='L178'></a><a href='#L178'>178</a>
<a name='L179'></a><a href='#L179'>179</a>
<a name='L180'></a><a href='#L180'>180</a>
<a name='L181'></a><a href='#L181'>181</a>
<a name='L182'></a><a href='#L182'>182</a>
<a name='L183'></a><a href='#L183'>183</a>
<a name='L184'></a><a href='#L184'>184</a>
<a name='L185'></a><a href='#L185'>185</a>
<a name='L186'></a><a href='#L186'>186</a>
<a name='L187'></a><a href='#L187'>187</a>
<a name='L188'></a><a href='#L188'>188</a>
<a name='L189'></a><a href='#L189'>189</a>
<a name='L190'></a><a href='#L190'>190</a>
<a name='L191'></a><a href='#L191'>191</a>
<a name='L192'></a><a href='#L192'>192</a>
<a name='L193'></a><a href='#L193'>193</a>
<a name='L194'></a><a href='#L194'>194</a>
<a name='L195'></a><a href='#L195'>195</a>
<a name='L196'></a><a href='#L196'>196</a>
<a name='L197'></a><a href='#L197'>197</a>
<a name='L198'></a><a href='#L198'>198</a>
<a name='L199'></a><a href='#L199'>199</a>
<a name='L200'></a><a href='#L200'>200</a>
<a name='L201'></a><a href='#L201'>201</a>
<a name='L202'></a><a href='#L202'>202</a>
<a name='L203'></a><a href='#L203'>203</a>
<a name='L204'></a><a href='#L204'>204</a>
<a name='L205'></a><a href='#L205'>205</a>
<a name='L206'></a><a href='#L206'>206</a>
<a name='L207'></a><a href='#L207'>207</a>
<a name='L208'></a><a href='#L208'>208</a>
<a name='L209'></a><a href='#L209'>209</a>
<a name='L210'></a><a href='#L210'>210</a>
<a name='L211'></a><a href='#L211'>211</a>
<a name='L212'></a><a href='#L212'>212</a>
<a name='L213'></a><a href='#L213'>213</a>
<a name='L214'></a><a href='#L214'>214</a>
<a name='L215'></a><a href='#L215'>215</a>
<a name='L216'></a><a href='#L216'>216</a>
<a name='L217'></a><a href='#L217'>217</a>
<a name='L218'></a><a href='#L218'>218</a>
<a name='L219'></a><a href='#L219'>219</a>
<a name='L220'></a><a href='#L220'>220</a>
<a name='L221'></a><a href='#L221'>221</a>
<a name='L222'></a><a href='#L222'>222</a>
<a name='L223'></a><a href='#L223'>223</a>
<a name='L224'></a><a href='#L224'>224</a>
<a name='L225'></a><a href='#L225'>225</a>
<a name='L226'></a><a href='#L226'>226</a>
<a name='L227'></a><a href='#L227'>227</a>
<a name='L228'></a><a href='#L228'>228</a>
<a name='L229'></a><a href='#L229'>229</a>
<a name='L230'></a><a href='#L230'>230</a>
<a name='L231'></a><a href='#L231'>231</a>
<a name='L232'></a><a href='#L232'>232</a>
<a name='L233'></a><a href='#L233'>233</a>
<a name='L234'></a><a href='#L234'>234</a>
<a name='L235'></a><a href='#L235'>235</a>
<a name='L236'></a><a href='#L236'>236</a>
<a name='L237'></a><a href='#L237'>237</a>
<a name='L238'></a><a href='#L238'>238</a>
<a name='L239'></a><a href='#L239'>239</a>
<a name='L240'></a><a href='#L240'>240</a>
<a name='L241'></a><a href='#L241'>241</a>
<a name='L242'></a><a href='#L242'>242</a>
<a name='L243'></a><a href='#L243'>243</a>
<a name='L244'></a><a href='#L244'>244</a>
<a name='L245'></a><a href='#L245'>245</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">28x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">28x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">13x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { PrivateKey, PublicKey, SymmetricKey, Hash, Utils, PubKeyHex } from '@bsv/sdk'
import { WalletProtocol } from './Wallet.interfaces'
export type Counterparty = PublicKey | PubKeyHex | 'self' | 'anyone'
export interface KeyDeriverApi {
/**
* The root key from which all other keys are derived.
*/
rootKey: PrivateKey
/**
* The identity of this key deriver which is normally the public key associated with the `rootKey`
*/
identityKey: string
/**
* Derives a public key based on protocol ID, key ID, and counterparty.
* @param {WalletProtocol} protocolID - The protocol ID including a security level and protocol name.
* @param {string} keyID - The key identifier.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @param {boolean} [forSelf=false] - Optional. false if undefined. Whether deriving for self.
* @returns {PublicKey} - The derived public key.
*/
derivePublicKey(protocolID: WalletProtocol, keyID: string, counterparty: Counterparty, forSelf?: boolean): PublicKey
/**
* Derives a private key based on protocol ID, key ID, and counterparty.
* @param {WalletProtocol} protocolID - The protocol ID including a security level and protocol name.
* @param {string} keyID - The key identifier.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @returns {PrivateKey} - The derived private key.
*/
derivePrivateKey(protocolID: WalletProtocol, keyID: string, counterparty: Counterparty): PrivateKey
/**
* Derives a symmetric key based on protocol ID, key ID, and counterparty.
* Note: Symmetric keys should not be derivable by everyone due to security risks.
* @param {WalletProtocol} protocolID - The protocol ID including a security level and protocol name.
* @param {string} keyID - The key identifier.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @returns {SymmetricKey} - The derived symmetric key.
* @throws {Error} - Throws an error if attempting to derive a symmetric key for 'anyone'.
*/
deriveSymmetricKey(protocolID: WalletProtocol, keyID: string, counterparty: Counterparty): SymmetricKey
/**
* Reveals the shared secret between the root key and the counterparty.
* Note: This should not be used for 'self'.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @returns {number[]} - The shared secret as a number array.
* @throws {Error} - Throws an error if attempting to reveal a shared secret for 'self'.
*/
revealCounterpartySecret(counterparty: Counterparty): number[]
/**
* Reveals the specific key association for a given protocol ID, key ID, and counterparty.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @param {WalletProtocol} protocolID - The protocol ID including a security level and protocol name.
* @param {string} keyID - The key identifier.
* @returns {number[]} - The specific key association as a number array.
*/
revealSpecificSecret(counterparty: Counterparty, protocolID: WalletProtocol, keyID: string): number[]
}
/**
* Class responsible for deriving various types of keys using a root private key.
* It supports deriving public and private keys, symmetric keys, and revealing key linkages.
*/
export class KeyDeriver implements KeyDeriverApi {
rootKey: PrivateKey
identityKey: string
/**
* Initializes the KeyDeriver instance with a root private key.
* @param {PrivateKey | 'anyone'} rootKey - The root private key or the string 'anyone'.
*/
constructor(rootKey: PrivateKey | 'anyone') {
<span class="missing-if-branch" title="if path not taken" >I</span>if (rootKey === 'anyone') {
<span class="cstat-no" title="statement not covered" > this.rootKey = new PrivateKey(1)</span>
} else {
this.rootKey = rootKey
}
this.identityKey = this.rootKey.toPublicKey().toString()
}
/**
* Derives a public key based on protocol ID, key ID, and counterparty.
* @param {WalletProtocol} protocolID - The protocol ID including a security level and protocol name.
* @param {string} keyID - The key identifier.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @param {boolean} [forSelf=false] - Whether deriving for self.
* @returns {PublicKey} - The derived public key.
*/
derivePublicKey(protocolID: WalletProtocol, keyID: string, counterparty: Counterparty, forSelf: boolean = <span class="branch-0 cbranch-no" title="branch not covered" >false)</span>: PublicKey {
counterparty = this.normalizeCounterparty(counterparty)
<span class="missing-if-branch" title="if path not taken" >I</span>if (forSelf) {
<span class="cstat-no" title="statement not covered" > return this.rootKey.deriveChild(counterparty, this.computeInvoiceNumber(protocolID, keyID)).toPublicKey()</span>
} else {
return counterparty.deriveChild(this.rootKey, this.computeInvoiceNumber(protocolID, keyID))
}
}
/**
* Derives a private key based on protocol ID, key ID, and counterparty.
* @param {WalletProtocol} protocolID - The protocol ID including a security level and protocol name.
* @param {string} keyID - The key identifier.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @returns {PrivateKey} - The derived private key.
*/
derivePrivateKey(protocolID: WalletProtocol, keyID: string, counterparty: Counterparty): PrivateKey {
counterparty = this.normalizeCounterparty(counterparty)
return this.rootKey.deriveChild(counterparty, this.computeInvoiceNumber(protocolID, keyID))
}
/**
* Derives a symmetric key based on protocol ID, key ID, and counterparty.
* Note: Symmetric keys should not be derivable by everyone due to security risks.
* @param {WalletProtocol} protocolID - The protocol ID including a security level and protocol name.
* @param {string} keyID - The key identifier.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @returns {SymmetricKey} - The derived symmetric key.
* @throws {Error} - Throws an error if attempting to derive a symmetric key for 'anyone'.
*/
<span class="fstat-no" title="function not covered" > deriveSymmetricKey(</span>protocolID: WalletProtocol, keyID: string, counterparty: Counterparty): SymmetricKey {
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (counterparty === 'anyone') {</span>
<span class="cstat-no" title="statement not covered" > throw new Error(</span>
'Symmetric keys (such as encryption keys or HMAC keys) should not be derivable by everyone, because messages would be decryptable by anyone who knows the identity public key of the user, and HMACs would be similarly forgeable.'
)
}
<span class="cstat-no" title="statement not covered" > counterparty = this.normalizeCounterparty(counterparty)</span>
const derivedPublicKey = <span class="cstat-no" title="statement not covered" >this.derivePublicKey(protocolID, keyID, counterparty)</span>
const derivedPrivateKey = <span class="cstat-no" title="statement not covered" >this.derivePrivateKey(protocolID, keyID, counterparty)</span>
<span class="cstat-no" title="statement not covered" > return new SymmetricKey(derivedPrivateKey.deriveSharedSecret(derivedPublicKey).x!.toArray())</span>
}
/**
* Reveals the shared secret between the root key and the counterparty.
* Note: This should not be used for 'self'.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @returns {number[]} - The shared secret as a number array.
* @throws {Error} - Throws an error if attempting to reveal a shared secret for 'self'.
*/
<span class="fstat-no" title="function not covered" > revealCounterpartySecret(</span>counterparty: Counterparty): number[] {
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (counterparty === 'self') {</span>
<span class="cstat-no" title="statement not covered" > throw new Error('Counterparty secrets cannot be revealed for counterparty=self.')</span>
}
<span class="cstat-no" title="statement not covered" > counterparty = this.normalizeCounterparty(counterparty)</span>
// Double-check to ensure not revealing the secret for 'self'
const self = <span class="cstat-no" title="statement not covered" >this.rootKey.toPublicKey()</span>
const keyDerivedBySelf = <span class="cstat-no" title="statement not covered" >this.rootKey.deriveChild(self, 'test').toHex()</span>
const keyDerivedByCounterparty = <span class="cstat-no" title="statement not covered" >this.rootKey.deriveChild(counterparty, 'test').toHex()</span>
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (keyDerivedBySelf === keyDerivedByCounterparty) {</span>
<span class="cstat-no" title="statement not covered" > throw new Error('Counterparty secrets cannot be revealed for counterparty=self.')</span>
}
<span class="cstat-no" title="statement not covered" > return this.rootKey.deriveSharedSecret(counterparty).encode(true) as number[]</span>
}
/**
* Reveals the specific key association for a given protocol ID, key ID, and counterparty.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @param {WalletProtocol} protocolID - The protocol ID including a security level and protocol name.
* @param {string} keyID - The key identifier.
* @returns {number[]} - The specific key association as a number array.
*/
<span class="fstat-no" title="function not covered" > revealSpecificSecret(</span>counterparty: Counterparty, protocolID: WalletProtocol, keyID: string): number[] {
<span class="cstat-no" title="statement not covered" > counterparty = this.normalizeCounterparty(counterparty)</span>
const sharedSecret = <span class="cstat-no" title="statement not covered" >this.rootKey.deriveSharedSecret(counterparty)</span>
const invoiceNumberBin = <span class="cstat-no" title="statement not covered" >Utils.toArray(this.computeInvoiceNumber(protocolID, keyID), 'utf8')</span>
<span class="cstat-no" title="statement not covered" > return Hash.sha256hmac(sharedSecret.encode(true), invoiceNumberBin)</span>
}
/**
* Normalizes the counterparty to a public key.
* @param {Counterparty} counterparty - The counterparty's public key or a predefined value ('self' or 'anyone').
* @returns {PublicKey} - The normalized counterparty public key.
* @throws {Error} - Throws an error if the counterparty is invalid.
*/
private normalizeCounterparty(counterparty: Counterparty): PublicKey {
<span class="missing-if-branch" title="if path not taken" >I</span>if (!counterparty) {
<span class="cstat-no" title="statement not covered" > throw new Error('counterparty must be self, anyone or a public key!')</span>
} else <span class="missing-if-branch" title="if path not taken" >I</span>if (counterparty === 'self') {
<span class="cstat-no" title="statement not covered" > return this.rootKey.toPublicKey()</span>
} else <span class="missing-if-branch" title="if path not taken" >I</span>if (counterparty === 'anyone') {
<span class="cstat-no" title="statement not covered" > return new PrivateKey(1).toPublicKey()</span>
} else if (typeof counterparty === 'string') {
return PublicKey.fromString(counterparty)
} else <span class="missing-if-branch" title="else path not taken" >E</span>{
<span class="cstat-no" title="statement not covered" > return counterparty</span>
}
}
/**
* Computes the invoice number based on the protocol ID and key ID.
* @param {WalletProtocol} protocolID - The protocol ID including a security level and protocol name.
* @param {string} keyID - The key identifier.
* @returns {string} - The computed invoice number.
* @throws {Error} - Throws an error if protocol ID or key ID are invalid.
*/
private computeInvoiceNumber(protocolID: WalletProtocol, keyID: string): string {
const securityLevel = protocolID[0]
<span class="missing-if-branch" title="if path not taken" >I</span>if (!Number.isInteger(securityLevel) || securityLevel < 0 || securityLevel > 2) {
<span class="cstat-no" title="statement not covered" > throw new Error('Protocol security level must be 0, 1, or 2')</span>
}
const protocolName = protocolID[1].toLowerCase().trim()
<span class="missing-if-branch" title="if path not taken" >I</span>if (keyID.length > 800) {
<span class="cstat-no" title="statement not covered" > throw new Error('Key IDs must be 800 characters or less')</span>
}
<span class="missing-if-branch" title="if path not taken" >I</span>if (keyID.length < 1) {
<span class="cstat-no" title="statement not covered" > throw new Error('Key IDs must be 1 character or more')</span>
}
<span class="missing-if-branch" title="if path not taken" >I</span>if (protocolName.length > 400) {
// Specific linkage revelation is the only protocol ID that can contain another protocol ID.
// Therefore, we allow it to be long enough to encapsulate the target protocol
<span class="cstat-no" title="statement not covered" > if (protocolName.startsWith('specific linkage revelation ')) {</span>
// The format is: 'specific linkage revelation x YYYYY'
// Where: x is the security level and YYYYY is the target protocol
// Thus, the max acceptable length is 30 + 400 = 430 bytes
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (protocolName.length > 430) {</span>
<span class="cstat-no" title="statement not covered" > throw new Error('Specific linkage revelation protocol names must be 430 characters or less')</span>
}
} else {
<span class="cstat-no" title="statement not covered" > throw new Error('Protocol names must be 400 characters or less')</span>
}
}
<span class="missing-if-branch" title="if path not taken" >I</span>if (protocolName.length < 5) {
<span class="cstat-no" title="statement not covered" > throw new Error('Protocol names must be 5 characters or more')</span>
}
<span class="missing-if-branch" title="if path not taken" >I</span>if (protocolName.includes(' ')) {
<span class="cstat-no" title="statement not covered" > throw new Error('Protocol names cannot contain multiple consecutive spaces (" ")')</span>
}
<span class="missing-if-branch" title="if path not taken" >I</span>if (!/^[a-z0-9 ]+$/g.test(protocolName)) {
<span class="cstat-no" title="statement not covered" > throw new Error('Protocol names can only contain letters, numbers and spaces')</span>
}
<span class="missing-if-branch" title="if path not taken" >I</span>if (protocolName.endsWith(' protocol')) {
<span class="cstat-no" title="statement not covered" > throw new Error('No need to end your protocol name with " protocol"')</span>
}
return `${securityLevel}-${protocolName}-${keyID}`
}
}
</pre></td></tr></table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2025-01-07T22:58:46.890Z
</div>
<script src="../../prettify.js"></script>
<script>
window.onload = function () {
prettyPrint();
};
</script>
<script src="../../sorter.js"></script>
<script src="../../block-navigation.js"></script>
</body>
</html>