In this chapter we will build the import function for the Mnemonic Phrase/key/wallet file
Create the main page for importing
This page uses ATON’s SmartTabLayout, which was previously used to support ViewPager in the ATON project, but I modified it to support ViewPager2. Please refer to the SmartTabLayout class in the com.platon.aton.widge.table package.
Then create the ImportActivity class in the activity package, which inherits from the BaseActivity class. Also modify all other Activities to inherit from this class. The code of the BaseActivity class is as follows:
:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
abstract class BaseActivity: AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?){
This class is an abstract class. In onCreate, set the text color of the status bar to black, and then provide the following three abstract methods: 1, inflateUI instantiate the UI object 2, initUI initialize the UI object 3, initEvent initialize the event
The code of ImportActivity is as follow:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class ImportActivity :BaseActivity(){
private lateinit var binding: ActivityImportWalletBinding
/**
* 创建页面对象
*/
override fun inflateUI(inflater: LayoutInflater): View {
Digging supports three methods of importing wallets: helper words, wallet files, and private keys. The pages corresponding to these three import methods are as follows: res/layout/page_import_mnemonic_phrase.xml, page_import_keystore.xml, page_import_private_key.xml. Because ViewPager2 is based on the RecyclerView implementation, create the Adapter and ViewHolder. Create com.digquant.adapter package, then create ImportPageAdapter class, the code is as follows:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class ImportPageAdapter : RecyclerView.Adapter<BaseViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
// 对应的创建出三个页面对象
val inflater = LayoutInflater.from(parent.context)
if(viewType == 0){
val binding = PageImportMnemonicPhraseBinding.inflate(inflater, parent, false)
returnImportMnemonicPage(binding.root)
}elseif(viewType == 1){
val binding = PageImportKeystoreBinding.inflate(inflater, parent, false)
returnImportKeystorePage(binding.root)
}elseif(viewType == 2){
val binding = PageImportPrivateKeyBinding.inflate(inflater, parent, false)
returnImportPrivateKeyPage(binding.root)
}
throw RuntimeException("无法识别页面类型")
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int){
// 因为页面都是静态的,因此不需要动态渲染
}
/**
* 返回position作为页面类型
*/
override fun getItemViewType(position: Int): Int {
return position
}
override fun getItemCount(): Int {
// 三个页面
return3
}
}
class ImportPageAdapter : RecyclerView.Adapter<BaseViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
// 对应的创建出三个页面对象
val inflater = LayoutInflater.from(parent.context)
if (viewType == 0) {
val binding = PageImportMnemonicPhraseBinding.inflate(inflater, parent, false)
return ImportMnemonicPage(binding.root)
} else if (viewType == 1) {
val binding = PageImportKeystoreBinding.inflate(inflater, parent, false)
return ImportKeystorePage(binding.root)
} else if (viewType == 2) {
val binding = PageImportPrivateKeyBinding.inflate(inflater, parent, false)
return ImportPrivateKeyPage(binding.root)
}
throw RuntimeException("无法识别页面类型")
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
// 因为页面都是静态的,因此不需要动态渲染
}
/**
* 返回position作为页面类型
*/
override fun getItemViewType(position: Int): Int {
return position
}
override fun getItemCount(): Int {
// 三个页面
return 3
}
}
class ImportPageAdapter : RecyclerView.Adapter<BaseViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
// 对应的创建出三个页面对象
val inflater = LayoutInflater.from(parent.context)
if (viewType == 0) {
val binding = PageImportMnemonicPhraseBinding.inflate(inflater, parent, false)
return ImportMnemonicPage(binding.root)
} else if (viewType == 1) {
val binding = PageImportKeystoreBinding.inflate(inflater, parent, false)
return ImportKeystorePage(binding.root)
} else if (viewType == 2) {
val binding = PageImportPrivateKeyBinding.inflate(inflater, parent, false)
return ImportPrivateKeyPage(binding.root)
}
throw RuntimeException("无法识别页面类型")
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
// 因为页面都是静态的,因此不需要动态渲染
}
/**
* 返回position作为页面类型
*/
override fun getItemViewType(position: Int): Int {
return position
}
override fun getItemCount(): Int {
// 三个页面
return 3
}
}
The page effect is as follows:
The logic of Introducing themnemonic words
The logic for getting this class is basically the same as the logic for creating a wallet in the ImportMnemonicPage class of com.digquant.page. Because the code is relatively large, I will not post the code here. The main logic of the class is as follows:
1, The length of the wallet name is 1~20 characters 2, The password of the wallet must be more than or equal to 6 characters
Then add the ImportMnemonicWords method to com/digquant/service/WalletManager.kt with the following code:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/**
* 导入助记词
*/
fun ImportMnemonicWords(name: String, password: String, mnemonicWords: List<String>): Boolean {
// 1,把助记词组合成空格隔开的字符串
val mnemonic = mnemonicWords.joinToString(" ")
// 2.生成种子
val seed = JZMnemonicUtil.generateSeed(mnemonic, null)
The specific code is in the com.digquant.page.ImportKeystorePage class. To import a wallet file you need to determine if the password can unlock the wallet file, so the code for ImportKeyStore in the WalletManager class is as follows:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/**
* 导入钱包文件
*/
fun ImportKeyStore(
name: String,
password: String,
keystore: String
): Status {
try{
val context = DiggingApplication.context
val objectMapper = ObjectMapper()
val walletFile: WalletFile = objectMapper.readValue(
Use Credentials.create to try to unlock the wallet file with the entered password, if the entered password is incorrect, a CipherException will be thrown, as follows:
If the password entered is correct, the import is successful..
Logic for importing secret keys
The specific code is in the com.digquant.page.ImportPrivateKeyPage class, which has the following main logic:
1, The length of the wallet name is 1~20 characters 2, The password of the wallet must be greater than or equal to 6 characters 3, Determine if the secret key is empty
Then add ImportPrivateKey to the WalletManager class, with the following code:
Here remember to call Numeric.cleanHexPrefix method to take out the secret key starting with 0x, because some wallets export the secret key starting with 0x.
Well, that’s it for this chapter, next chapter we will start the build of main page.