错误类型1:
A、基于JavaScript运行【openWallet】的错误提示: 【MoneroRpcError: Failed to open wallet】
B、查看文件rpc命令运行错误提示:【tail -f monero-wallet-rpc.log】
情况一:提示【error:wallet_internal_error】:代表你的keys文件被其他程序打开中【被占用】可以删掉重新生成一个新的keys文件即可!
【直接测试,不经过任何代码运行】基于monero-wallet-cli直接访问钱包的错误提示:
Error: failed to load wallet: internal error: "/wallet/monero_wallet/pdvbtyne.keys" is opened by another wallet program
Error: You may want to remove the file "/wallet/monero_wallet/pdvbtyne.keys" and try again
基于【问题1-1和1-2】是一个问题,就是你的keys加密文件已被【另外一个钱包打开了】不能重复打开。解决办法【删除当前的keys】重新创建一个新的开始同步即可!
情况二:提示【not_found】:请确保--wallet-dir包含的目录存在匹配的keys文件!
错误类型二:
1、JS端提示【timed out】超时错误
2、【monero-wallet-rpc】报错:Failed to generate key derivation from tx pubkey, skipping
解决办法:请先同步你的wallet,只要同步完成了,则不会超时
基于节点同步、RPC钱包正常访问的代码参考
static async __openActiveWalletFromServer(server_storage_encryption_file_name_or_address) {
/**
* 功能:从服务器打开一个本地文件wallet
* 参数:
* server_storage_encryption_file_name:这里的文件路径必须是启动monero-wallet-rpc命令参数【--wallet-dir】指定目录下的秘钥文件
* 特殊说明:
* 1、由于此处读取文件的路径为参数【--wallet-dir】决定,请确保创建钱包加密文件的路径和【--wallet-dir】保持一致即可!
* 2、只要服务器读取【钱包加密文件】的路径和存储的路径一致,则可实现自动化创建活跃的wallet
* 3、如果Wallet未同步,则无法打开,必须先同步完成才能打开!
*/
let _server_encryption_file_name_lower = AsyncMoneroNetworkWallet.__getServerStorageEncryptionFileNameOrAddressLower(
server_storage_encryption_file_name_or_address);
return UtilError.tryCatchGlobalSupportAsync(async () => {
let _walletRPC = await moneroJS.connectToWalletRpc(
moneroConfigUniqueInstance.getRPCWalletURI(), moneroConfigUniqueInstance.walletRPC.user,
moneroConfigUniqueInstance.walletRPC.password, false);
await _walletRPC.openWallet(_server_encryption_file_name_lower, moneroConfigUniqueInstance.walletPassword);
let _walletHeight = await _walletRPC.getHeight();
console.log(`【>>==<<】walletRPC.openWallet打开成功,获取当前wallet=${await _walletRPC.getPrimaryAddress()},balance=${await _walletRPC.getBalance()},` +
`walletHeight=${_walletHeight},daemonHeight=${await AsyncMoneroNetworkWallet.getDaemonHeight()}`);
if (_walletHeight === 1) {
console.log(`【>>==<<】当前wallet=${await _walletRPC.getPrimaryAddress()}的walletHeight=${_walletHeight}【代表Wallet还没启动同步,立即开启同步中...】`);
await AsyncMoneroNetworkWallet.__syncWalletFullAndCloseWallet(_server_encryption_file_name_lower);
}
return _walletRPC;
}, async (e) => {
/**
* 1、wallet打开失败【提示超时】则必须先手动同步!
*/
e = String(e).toLowerCase();
let _coreErrPrompt = "";
let _timeoutErrorPrompt = "timed out";
if (UtilStr.checkOriginalStrExistChildStr(e, [_timeoutErrorPrompt], false)) {
_coreErrPrompt = `walletRPC.openWallet打开钱包提示【${_timeoutErrorPrompt}】wallet还未同步,立即开启同步到节点中...`;
await AsyncMoneroNetworkWallet.__syncWalletFullAndCloseWallet(_server_encryption_file_name_lower);
}
let _openFailErrorPrompt = "failed to open wallet";
if (UtilStr.checkOriginalStrExistChildStr(e, [_openFailErrorPrompt], false)) {
_coreErrPrompt = `walletRPC.openWallet打开钱包提示【${_openFailErrorPrompt}】有以下两种可能性【1、--wallet-dir包含的目录存在匹配的keys文件。2、当前wallet已被其他程序打开,被占用,可删除当前keys文件重新创建即可】`;
}
e = `${e}===>_coreErrPrompt=${_coreErrPrompt}`;
throw Error(
`【>>==<<】注:请确保->服务器端运行的monero-wallet-rpc命令参数【--wallet-dir】指定目录【加密钱包文件读取位置】存在钱包加密文件` +
`_server_encryption_file_name_lower =${_server_encryption_file_name_lower}【避免Wallet无法正常打开】本次Wallet打开失败的具体异常信息为:${e}`);
}, true);
}
static async __syncWalletFullAndCloseWallet(server_storage_encryption_file_name_or_address) {
/**
* 功能:同步wallet到节点
* 参数:
* sync_start_height:
* 1、wallet同步的起始高度【必填参数,不填会永久卡死】
* 2、如为null,则默认为Daemon节点最新高度!
*/
console.log("【>>==<<】开始执行Wallet同步节点中...");
/**
* 1、获取本地wallet基于【节点Daemon】同步!
*/
let _walletFullInstance = await UtilError.tryCatchGlobalSupportAsync(async () => {
return moneroJS.openWalletFull({
path: AsyncMoneroNetworkWallet.__getServerStorageEncryptionFilePath(
server_storage_encryption_file_name_or_address),
password: moneroConfigUniqueInstance.walletPassword,
networkType: moneroConfigUniqueInstance.currentNetworkNode,
serverUri: moneroConfigUniqueInstance.getNodeDaemonURI(),
serverUsername: moneroConfigUniqueInstance.nodeDaemon.user,
serverPassword: moneroConfigUniqueInstance.nodeDaemon.password,
});
}, (e) => {
e = String(e);
if (UtilStr.checkOriginalStrExistChildStr(e, ["input stream error"], false)) {
e = `${e}【由wallet已同步到节点,为此无法执行【moneroJS.openWalletFull】获取wallet再次同步,请使用【walletRPC.openWallet访问wallet】本次操作无效,直接跳过!`;
}
throw new Error(e);
}, true);
let _tempStr = `【>>==<<】wallet=${await _walletFullInstance.getPrimaryAddress()}`;
/**
* 1、基于V0.1.8.0开始,必须手动同步钱包,否则钱包无法打开【报错:....】
* 2、这里的_walletFullInstance.sync方法必传【syncStartHeight】参数【不传会永久卡死】这里传入创建wallet加密keys文件的恢复高度!
* 3、这里的_walletFullInstance.sync方法传入【allowConcurrentCalls=True】支持其他钱包并发同步!
*/
await _walletFullInstance.sync(new class extends moneroJS.MoneroWalletListener {
async onSyncProgress(height, startHeight, endHeight, percentDone, message) {
console.log(
`${_tempStr}正在同步中...实时同步数据:` +
`currentHeight=${height},startHeight=${startHeight},endHeight=${endHeight},percentDone=${percentDone},message=${message}`);
}
}, await _walletFullInstance.getSyncHeight(), true);
await _walletFullInstance.startSyncing(5000);
/**
* 1、钱包使用完后必须关闭,否则下一次打开钱包会报错【MoneroRpcError: Failed to open wallet】
* 2、注:同一个keys文件只能被一个钱包访问,否则就会报此错!
*/
await _walletFullInstance.close();
console.log(`${_tempStr}已启动同步中...且关闭当前钱包成功【避免占用此wallet,导致下次Open失败】`);
}