| 369 | } |
| 370 | |
| 371 | void WalletHDsqlite::export_wallet(const std::string &export_path, const std::string &new_password, bool view_only, |
| 372 | bool view_outgoing_addresses) const { |
| 373 | if (m_hw && !view_only) |
| 374 | throw Exception(api::WALLET_FILE_DECRYPT_ERROR, "Exporting hardware-backed wallet is not possible"); |
| 375 | |
| 376 | WalletHDsqlite other( |
| 377 | m_currency, m_log.get_logger(), export_path, new_password, std::string{}, 0, std::string{}, false); |
| 378 | |
| 379 | if (!is_view_only() && view_only) { |
| 380 | if (m_hw) { |
| 381 | SecretKey audit_key_base_secret_key; |
| 382 | PublicKey A; |
| 383 | SecretKey view_secret_key; |
| 384 | Hash view_seed; |
| 385 | Signature view_secrets_signature; |
| 386 | m_hw->export_view_only(&audit_key_base_secret_key, &view_secret_key, &view_seed, &view_secrets_signature); |
| 387 | invariant(secret_key_to_public_key(audit_key_base_secret_key, &A), ""); |
| 388 | PublicKey sH = to_bytes(P3(m_A_plus_sH) - P3(A)); |
| 389 | if (view_seed != Hash{}) { |
| 390 | other.put("view_seed", view_seed.as_binary_array(), true); |
| 391 | } else { |
| 392 | other.put("view_key", view_secret_key.as_binary_array(), true); |
| 393 | other.put("view_key_audit", audit_key_base_secret_key.as_binary_array(), true); |
| 394 | } |
| 395 | other.put("sH", sH.as_binary_array(), true); |
| 396 | other.put("view_secrets_signature", seria::to_binary(view_secrets_signature), true); |
| 397 | invariant(check_proof_H(sH, view_secrets_signature), ""); |
| 398 | } else { |
| 399 | if (view_outgoing_addresses) { // always have m_view_seed here |
| 400 | other.put("view_seed", m_view_seed.as_binary_array(), true); |
| 401 | } else { |
| 402 | other.put("view_key", m_view_secret_key.as_binary_array(), true); |
| 403 | other.put("view_key_audit", m_audit_key_base.secret_key.as_binary_array(), true); |
| 404 | } |
| 405 | auto sH = to_bytes(crypto::H * m_spend_secret_key); |
| 406 | other.put("sH", sH.as_binary_array(), true); |
| 407 | other.put("view_secrets_signature", seria::to_binary(m_view_secrets_signature), true); |
| 408 | invariant(check_proof_H(sH, m_view_secrets_signature), ""); |
| 409 | } |
| 410 | other.put("version", current_version, true); |
| 411 | other.put("coinname", CRYPTONOTE_NAME, true); |
| 412 | other.put(ADDRESS_COUNT_PREFIX, seria::to_binary(m_used_address_count), true); |
| 413 | } else if (is_view_only() && view_only) { |
| 414 | if (view_outgoing_addresses && m_view_seed != Hash{}) { |
| 415 | other.put("view_seed", m_view_seed.as_binary_array(), true); |
| 416 | } else { |
| 417 | other.put("view_key", m_view_secret_key.as_binary_array(), true); |
| 418 | other.put("view_key_audit", m_audit_key_base.secret_key.as_binary_array(), true); |
| 419 | } |
| 420 | other.put("sH", m_sH.as_binary_array(), true); |
| 421 | other.put("view_secrets_signature", seria::to_binary(m_view_secrets_signature), true); |
| 422 | other.put("version", current_version, true); |
| 423 | other.put("coinname", CRYPTONOTE_NAME, true); |
| 424 | other.put(ADDRESS_COUNT_PREFIX, seria::to_binary(m_used_address_count), true); |
| 425 | } else { |
| 426 | for (const auto &p : parameters_get()) |
| 427 | other.put(p.first, p.second, true); |
| 428 | for (const auto &el : payment_queue_get2()) |
nothing calls this directly
no test coverage detected