package Ġcom . ste ves ol ty s . seed vault . ui . recovery code Ċ Ċ import Ġandroid . app . backup . I Backup Manager Ċ import Ġandroid . os . User Handle Ċ import Ġandroid . util . Log Ċ import Ġandroidx . lifecycle . Android ViewModel Ċ import Ġcash . z . ecc . android . bip 3 9 . Mn emon ics Ċ import Ġcash . z . ecc . android . bip 3 9 . Mn emon ics . Checksum Exception Ċ import Ġcash . z . ecc . android . bip 3 9 . Mn emon ics . Invalid Word Exception Ċ import Ġcash . z . ecc . android . bip 3 9 . Mn emon ics . Word Count Exception Ċ import Ġcash . z . ecc . android . bip 3 9 . to Seed Ċ import Ġcom . ste ves ol ty s . seed vault . App Ċ import Ġcom . ste ves ol ty s . seed vault . crypto . Crypto Ċ import Ġcom . ste ves ol ty s . seed vault . crypto . Key Manager Ċ import Ġcom . ste ves ol ty s . seed vault . transport . TRANSPORT _ ID Ċ import Ġcom . ste ves ol ty s . seed vault . transport . backup . Backup Coordinator Ċ import Ġcom . ste ves ol ty s . seed vault . ui . Live Event Ċ import Ġcom . ste ves ol ty s . seed vault . ui . Mutable Live Event Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . Global Scope Ċ import Ġkotlinx . coroutines . launch Ċ import Ġorg . cal yx os . backup . storage . api . Storage Backup Ċ import Ġjava . io . IOException Ċ import Ġjava . security . Secure Random Ċ Ċ internal Ġconst Ġval ĠWORD _ NUM Ġ= Ġ 1 2 Ċ Ċ private Ġval ĠTAG Ġ= ĠRecovery Code ViewModel :: class . java . simple Name Ċ Ċ internal Ġclass ĠRecovery Code ViewModel ( ĊĠĠĠ Ġapp : ĠApp , ĊĠĠĠ Ġprivate Ġval Ġcrypto : ĠCrypto , ĊĠĠĠ Ġprivate Ġval Ġkey Manager : ĠKey Manager , ĊĠĠĠ Ġprivate Ġval Ġbackup Manager : ĠI Backup Manager , ĊĠĠĠ Ġprivate Ġval Ġbackup Coordinator : ĠBackup Coordinator , ĊĠĠĠ Ġprivate Ġval Ġstorage Backup : ĠStorage Backup Ċ ) Ġ: ĠAndroid ViewModel ( app ) Ġ{ ĊĊĠĠĠ Ġinternal Ġval Ġword List : ĠList < CharArray > Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġwe Ġuse Ġour Ġown Ġentropy Ġto Ġnot Ġhaving Ġto Ġtrust Ġthe Ġlibrary Ġto Ġuse ĠSecure Random ĊĠĠĠĠĠĠĠ Ġval Ġentropy Ġ= ĠByteArray ( Mn emon ics . Word Count . COUNT _ 1 2 . bit Length Ġ/ Ġ 8 ) ĊĠĠĠĠĠĠĠ ĠSecure Random (). next Bytes ( entropy ) ĊĠĠĠĠĠĠĠ Ġ// Ġcreate Ġthe Ġwords Ġfrom Ġthe Ġentropy ĊĠĠĠĠĠĠĠ ĠM n emon ics . Mnemonic Code ( entropy ). words ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġm Confirm Button Clicked Ġ= ĠMutable Live Event < Boolean >() ĊĠĠĠ Ġinternal Ġval Ġconfirm Button Clicked : ĠLive Event < Boolean > Ġ= Ġm Confirm Button Clicked ĊĠĠĠ Ġinternal Ġfun Ġon Confirm Button Clicked () Ġ= Ġm Confirm Button Clicked . set Event ( true ) ĊĊĠĠĠ Ġprivate Ġval Ġm Recovery Code Saved Ġ= ĠMutable Live Event < Boolean >() ĊĠĠĠ Ġinternal Ġval Ġrecovery Code Saved : ĠLive Event < Boolean > Ġ= Ġm Recovery Code Saved ĊĊĠĠĠ Ġprivate Ġval Ġm Existing Code Checked Ġ= ĠMutable Live Event < Boolean >() ĊĠĠĠ Ġinternal Ġval Ġexisting Code Checked : ĠLive Event < Boolean > Ġ= Ġm Existing Code Checked ĊĊĠĠĠ Ġinternal Ġvar Ġis Restore : ĠBoolean Ġ= Ġfalse ĊĊĠĠĠ Ġ@ Throws ( Invalid Word Exception :: class , ĠCheck sum Exception :: class ) ĊĠĠĠ Ġfun Ġvalidate And Continue ( input : ĠList < CharSequence >, Ġfor Verify ing New Code : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcode Ġ= ĠM n emon ics . Mnemonic Code ( input . to Mnemonic Chars ()) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcode . validate () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠWord Count Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠAssertionError ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġseed Ġ= Ġcode . to Seed () ĊĠĠĠĠĠĠĠ Ġif Ġ( for Verify ing New Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Manager . store Backup Key ( seed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Manager . store Main Key ( seed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Recovery Code Saved . set Event ( true ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġverified Ġ= Ġcrypto . verify Backup Key ( seed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( verified Ġ&& Ġ! key Manager . has Main Key ()) Ġkey Manager . store Main Key ( seed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Existing Code Checked . set Event ( verified ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDeletes Ġall Ġstorage Ġbackups Ġfor Ġcurrent Ġuser Ġand Ġclears Ġthe Ġstorage Ġbackup Ġcache . ĊĠĠĠĠ Ġ* ĠAlso Ġstarts Ġa Ġnew Ġapp Ġdata Ġrestore Ġset Ġand Ġinitializes Ġit . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġreason Ġis Ġthat Ġold Ġbackups Ġwon 't Ġbe Ġreadable Ġanymore Ġwith Ġthe Ġnew Ġkey . ĊĠĠĠĠ Ġ* ĠWe Ġcan 't Ġdelete Ġother Ġbackups Ġsafely , Ġbecause Ġwe Ġcan 't Ġbe Ġsure ĊĠĠĠĠ Ġ* Ġthat Ġthey Ġdon 't Ġbelong Ġto Ġa Ġdifferent Ġdevice Ġor Ġuser . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġre initialize Backup Location () Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Re - initial izing Ġbackup Ġlocation ...") ĊĠĠĠĠĠĠĠ ĠGlobal Scope . launch ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġremove Ġold Ġstorage Ġsnapshots Ġand Ġclear Ġcache ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstorage Backup . delete All Snapshots () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstorage Backup . clear Cache () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwill Ġalso Ġgenerate Ġa Ġnew Ġbackup Ġtoken Ġfor Ġthe Ġnew Ġrestore Ġset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackup Coordinator . start New Restore Set () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġinitialize Ġthe Ġnew Ġlocation ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackup Manager . initialize Transport s ForUser ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUser Handle . my UserId (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( TRANSPORT _ ID ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Error Ġstarting Ġnew ĠRestore Set ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ internal Ġfun ĠList < CharSequence >. to Mnemonic Chars (): ĠChar Array Ġ{ ĊĠĠĠ Ġreturn Ġjoin ToString (" Ġ"). toCharArray () Ċ } Ċ