123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2019-2020 Nomadic Labs <contact@nomadic-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)openClient_keysopenTezos_sapling.Core.Client(* Transform a spending key to an uri, encrypted or not. *)letto_uriunencryptedcctxtsapling_key=letopenLwt_result_syntaxinifunencryptedthenlet*?sapling_uri=Tezos_signer_backends.Unencrypted.make_sapling_keysapling_keyinreturnsapling_urielseTezos_signer_backends.Encrypted.encrypt_sapling_keycctxtsapling_key(** Transform an uri into a spending key, asking for a password if the uri was
encrypted. *)letfrom_uri(cctxt:#Client_context.full)uri=Tezos_signer_backends.Encrypted.decrypt_sapling_keycctxturiletregister(cctxt:#Client_context.full)?(force=false)?(unencrypted=false)mnemonicname=letopenLwt_result_syntaxinletsk=Spending_key.of_seed@@Mnemonic.to_32_bytesmnemonicinlet*sk_uri=to_uriunencryptedcctxtskinletkey={sk=sk_uri;path=[Spending_key.child_indexsk];address_index=Viewing_key.default_index;}inlet*()=Sapling_key.add~forcecctxtnamekeyinreturn@@Viewing_key.of_skskletderive(cctxt:#Client_context.full)?(force=false)?(unencrypted=false)src_namedst_namechild_index=letopenLwt_result_syntaxinlet*k=Sapling_key.findcctxtsrc_nameinlet*src_sk=from_uricctxtk.skinletchild_index=Int32.of_intchild_indexinletdst_sk=Spending_key.derive_keysrc_skchild_indexinlet*dst_sk_uri=to_uriunencryptedcctxtdst_skinletdst_key={sk=dst_sk_uri;path=child_index::k.path;address_index=Viewing_key.default_index;}in(* TODO check this force *)let_=forceinlet*()=Sapling_key.add~force:truecctxtdst_namedst_keyinletpath=String.concat"/"(List.mapInt32.to_string(List.revdst_key.path))inreturn(path,Viewing_key.of_skdst_sk)letfind_vkcctxtname=letopenLwt_result_syntaxinlet*k=Sapling_key.findcctxtnameinlet*sk=from_uricctxtk.skinreturn(Viewing_key.of_sksk)letnew_address(cctxt:#Client_context.full)nameindex_opt=letopenLwt_result_syntaxinlet*k=Sapling_key.findcctxtnameinletindex=matchindex_optwith|None->k.address_index|Somei->Viewing_key.index_of_int64(Int64.of_inti)inlet*sk=from_uricctxtk.skinlet*vk=return(Viewing_key.of_sksk)in(* Viewing_key.new_address finds the smallest index greater or equal to
[index] that generates a correct address. *)letcorrected_index,address=Viewing_key.new_addressvkindexinlet*()=Sapling_key.updatecctxtname{kwithaddress_index=Viewing_key.index_succcorrected_index}inreturn(sk,corrected_index,address)letexport_vkcctxtname=letopenLwt_result_syntaxinlet*vk=find_vkcctxtnameinreturn(Data_encoding.Json.constructViewing_key.encodingvk)