| 14 | namespace quip { |
| 15 | |
| 16 | class QuipWallet::Impl { |
| 17 | public: |
| 18 | // QuipWallet ABI (minimal version with just the functions we need) |
| 19 | static const std::string abi_json; |
| 20 | |
| 21 | Impl(const std::string &rpc_url, const std::string &contract_address) |
| 22 | : rpc_url_(rpc_url), contract_address_(contract_address) { |
| 23 | curl_global_init(CURL_GLOBAL_ALL); |
| 24 | } |
| 25 | |
| 26 | ~Impl() { curl_global_cleanup(); } |
| 27 | |
| 28 | bool transferWithWinternitz(const WinternitzAddress &winternitz_address, |
| 29 | const Signature &pq_sig, |
| 30 | const Address &to_address, Amount amount) { |
| 31 | try { |
| 32 | // Get private key from environment |
| 33 | const char *env_private_key = std::getenv("PRIVATE_KEY"); |
| 34 | if (!env_private_key) { |
| 35 | throw std::runtime_error("PRIVATE_KEY environment variable not set"); |
| 36 | } |
| 37 | PrivateKey private_key = env_private_key; |
| 38 | |
| 39 | // Convert C++ types to the format expected by the ABI encoder |
| 40 | nlohmann::json nextPqOwner = { |
| 41 | {"publicSeed", toHex(winternitz_address.publicSeed)}, |
| 42 | {"publicKeyHash", toHex(winternitz_address.publicKeyHash)}}; |
| 43 | |
| 44 | // Convert signature elements to hex strings array (ABI expects bytes32[67]) |
| 45 | nlohmann::json elements = nlohmann::json::array(); |
| 46 | for (const auto &element : pq_sig) { |
| 47 | elements.push_back(toHex(element)); |
| 48 | } |
| 49 | nlohmann::json pqSig = {{"elements", elements}}; |
| 50 | |
| 51 | |
| 52 | // Create parameters for ABI encoding |
| 53 | nlohmann::json params = {nextPqOwner, pqSig, to_address, |
| 54 | std::to_string(amount)}; |
| 55 | |
| 56 | // Encode the function call using shared abiEncode function |
| 57 | std::string params_json = params.dump(); |
| 58 | std::string data = |
| 59 | abiEncode("transferWithWinternitz", abi_json, params_json); |
| 60 | |
| 61 | // Get the transfer fee |
| 62 | Amount transferFee = getTransferFee(); |
| 63 | |
| 64 | // Get account address from private key |
| 65 | std::string from_address = deriveClassicalPublicKey(private_key); |
| 66 | |
| 67 | // Get nonce |
| 68 | nlohmann::json nonce_params = {from_address, "latest"}; |
| 69 | auto nonce_response = |
| 70 | sendJsonRpc("eth_getTransactionCount", nonce_params); |
| 71 | std::string nonce_hex = nonce_response["result"]; |
| 72 | uint64_t nonce = std::stoull(nonce_hex.substr(2), nullptr, 16); |
| 73 |
nothing calls this directly
no outgoing calls
no test coverage detected