upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/main/tollgate_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/tollgate_api.c')
-rw-r--r--main/tollgate_api.c134
1 files changed, 132 insertions, 2 deletions
diff --git a/main/tollgate_api.c b/main/tollgate_api.c
index efb5cdf..e6880e0 100644
--- a/main/tollgate_api.c
+++ b/main/tollgate_api.c
@@ -3,6 +3,7 @@
3#include "config.h" 3#include "config.h"
4#include "session.h" 4#include "session.h"
5#include "firewall.h" 5#include "firewall.h"
6#include "wallet.h"
6#include "esp_log.h" 7#include "esp_log.h"
7#include "cJSON.h" 8#include "cJSON.h"
8#include "lwip/sockets.h" 9#include "lwip/sockets.h"
@@ -298,9 +299,9 @@ static esp_err_t api_post_payment(httpd_req_t *req)
298 secrets[i] = token->proofs[i].secret; 299 secrets[i] = token->proofs[i].secret;
299 } 300 }
300 session_t *session = session_create(client_ip, allotment, secrets, secret_count); 301 session_t *session = session_create(client_ip, allotment, secrets, secret_count);
301 free(states);
302 free(token);
303 if (!session) { 302 if (!session) {
303 free(states);
304 free(token);
304 cJSON *notice = create_notice("error", "session-error", "Failed to create session"); 305 cJSON *notice = create_notice("error", "session-error", "Failed to create session");
305 char *json = cJSON_PrintUnformatted(notice); 306 char *json = cJSON_PrintUnformatted(notice);
306 httpd_resp_set_status(req, "503 Service Unavailable"); 307 httpd_resp_set_status(req, "503 Service Unavailable");
@@ -317,6 +318,21 @@ static esp_err_t api_post_payment(httpd_req_t *req)
317 httpd_resp_send(req, json, strlen(json)); 318 httpd_resp_send(req, json, strlen(json));
318 cJSON_free(json); 319 cJSON_free(json);
319 cJSON_Delete(session_event); 320 cJSON_Delete(session_event);
321
322 {
323 wallet_proof_t wproofs[CASHU_MAX_PROOFS];
324 int wcount = token->proof_count > CASHU_MAX_PROOFS ? CASHU_MAX_PROOFS : token->proof_count;
325 for (int i = 0; i < wcount; i++) {
326 wproofs[i].amount = token->proofs[i].amount;
327 strncpy(wproofs[i].id, token->proofs[i].id, WALLET_KEYSET_ID_LEN - 1);
328 strncpy(wproofs[i].secret, token->proofs[i].secret, WALLET_SECRET_LEN - 1);
329 strncpy(wproofs[i].c, token->proofs[i].c, WALLET_SIG_LEN - 1);
330 }
331 wallet_add_proofs(wproofs, wcount);
332 }
333
334 free(states);
335 free(token);
320 return ESP_OK; 336 return ESP_OK;
321} 337}
322 338
@@ -363,10 +379,121 @@ static esp_err_t api_get_whoami(httpd_req_t *req)
363 return ESP_OK; 379 return ESP_OK;
364} 380}
365 381
382static esp_err_t api_get_wallet(httpd_req_t *req)
383{
384 wallet_t *w = wallet_get();
385 cJSON *root = cJSON_CreateObject();
386 cJSON_AddNumberToObject(root, "balance", (double)w->balance);
387 cJSON_AddNumberToObject(root, "proof_count", w->proof_count);
388 cJSON_AddNumberToObject(root, "keyset_count", w->keyset_count);
389
390 cJSON *proofs = cJSON_CreateArray();
391 for (int i = 0; i < w->proof_count; i++) {
392 cJSON *p = cJSON_CreateObject();
393 cJSON_AddNumberToObject(p, "amount", (double)w->proofs[i].amount);
394 cJSON_AddStringToObject(p, "id", w->proofs[i].id);
395 cJSON_AddItemToArray(proofs, p);
396 }
397 cJSON_AddItemToObject(root, "proofs", proofs);
398
399 char *json = cJSON_PrintUnformatted(root);
400 httpd_resp_set_type(req, "application/json");
401 httpd_resp_send(req, json, strlen(json));
402 cJSON_free(json);
403 cJSON_Delete(root);
404 return ESP_OK;
405}
406
407static esp_err_t api_post_wallet_swap(httpd_req_t *req)
408{
409 const tollgate_config_t *cfg = tollgate_config_get();
410
411 if (wallet_balance() == 0) {
412 httpd_resp_set_status(req, "400 Bad Request");
413 httpd_resp_set_type(req, "application/json");
414 httpd_resp_send(req, "{\"error\":\"no proofs to swap\"}", 27);
415 return ESP_OK;
416 }
417
418 wallet_print_status();
419
420 esp_err_t err = wallet_fetch_keysets(cfg->mint_url);
421 if (err != ESP_OK) {
422 httpd_resp_set_status(req, "502 Bad Gateway");
423 httpd_resp_set_type(req, "application/json");
424 httpd_resp_send(req, "{\"error\":\"keyset fetch failed\"}", 29);
425 return ESP_OK;
426 }
427
428 wallet_t *w = wallet_get();
429 err = wallet_swap_proofs(cfg->mint_url, 0, w->proof_count);
430 if (err != ESP_OK) {
431 httpd_resp_set_status(req, "502 Bad Gateway");
432 httpd_resp_set_type(req, "application/json");
433 httpd_resp_send(req, "{\"error\":\"swap failed\"}", 21);
434 return ESP_OK;
435 }
436
437 wallet_print_status();
438
439 cJSON *root = cJSON_CreateObject();
440 cJSON_AddNumberToObject(root, "balance", (double)wallet_balance());
441 cJSON_AddNumberToObject(root, "proof_count", wallet_get()->proof_count);
442 char *json = cJSON_PrintUnformatted(root);
443 httpd_resp_set_type(req, "application/json");
444 httpd_resp_send(req, json, strlen(json));
445 cJSON_free(json);
446 cJSON_Delete(root);
447 return ESP_OK;
448}
449
450static esp_err_t api_post_wallet_send(httpd_req_t *req)
451{
452 int content_len = req->content_len;
453 if (content_len <= 0 || content_len > 32) {
454 httpd_resp_set_status(req, "400 Bad Request");
455 httpd_resp_send(req, "invalid amount", 14);
456 return ESP_OK;
457 }
458
459 char body[32];
460 int total = 0;
461 while (total < content_len) {
462 int r = httpd_req_recv(req, body + total, content_len - total);
463 if (r <= 0) { httpd_resp_send_500(req); return ESP_OK; }
464 total += r;
465 }
466 body[total] = '\0';
467
468 uint64_t amount = strtoull(body, NULL, 10);
469 if (amount == 0) {
470 httpd_resp_set_status(req, "400 Bad Request");
471 httpd_resp_send(req, "invalid amount", 14);
472 return ESP_OK;
473 }
474
475 const tollgate_config_t *cfg = tollgate_config_get();
476 char token[4096];
477 esp_err_t err = wallet_send(cfg->mint_url, amount, token, sizeof(token));
478 if (err != ESP_OK) {
479 httpd_resp_set_status(req, "402 Payment Required");
480 httpd_resp_set_type(req, "text/plain");
481 httpd_resp_send(req, "insufficient balance", 20);
482 return ESP_OK;
483 }
484
485 httpd_resp_set_type(req, "text/plain");
486 httpd_resp_send(req, token, strlen(token));
487 return ESP_OK;
488}
489
366static const httpd_uri_t uri_discovery = { .uri = "/", .method = HTTP_GET, .handler = api_get_discovery }; 490static const httpd_uri_t uri_discovery = { .uri = "/", .method = HTTP_GET, .handler = api_get_discovery };
367static const httpd_uri_t uri_payment = { .uri = "/", .method = HTTP_POST, .handler = api_post_payment }; 491static const httpd_uri_t uri_payment = { .uri = "/", .method = HTTP_POST, .handler = api_post_payment };
368static const httpd_uri_t uri_usage = { .uri = "/usage", .method = HTTP_GET, .handler = api_get_usage }; 492static const httpd_uri_t uri_usage = { .uri = "/usage", .method = HTTP_GET, .handler = api_get_usage };
369static const httpd_uri_t uri_whoami = { .uri = "/whoami", .method = HTTP_GET, .handler = api_get_whoami }; 493static const httpd_uri_t uri_whoami = { .uri = "/whoami", .method = HTTP_GET, .handler = api_get_whoami };
494static const httpd_uri_t uri_wallet = { .uri = "/wallet", .method = HTTP_GET, .handler = api_get_wallet };
495static const httpd_uri_t uri_wallet_swap = { .uri = "/wallet/swap", .method = HTTP_POST, .handler = api_post_wallet_swap };
496static const httpd_uri_t uri_wallet_send = { .uri = "/wallet/send", .method = HTTP_POST, .handler = api_post_wallet_send };
370 497
371esp_err_t tollgate_api_start(void) 498esp_err_t tollgate_api_start(void)
372{ 499{
@@ -388,6 +515,9 @@ esp_err_t tollgate_api_start(void)
388 httpd_register_uri_handler(s_api_server, &uri_payment); 515 httpd_register_uri_handler(s_api_server, &uri_payment);
389 httpd_register_uri_handler(s_api_server, &uri_usage); 516 httpd_register_uri_handler(s_api_server, &uri_usage);
390 httpd_register_uri_handler(s_api_server, &uri_whoami); 517 httpd_register_uri_handler(s_api_server, &uri_whoami);
518 httpd_register_uri_handler(s_api_server, &uri_wallet);
519 httpd_register_uri_handler(s_api_server, &uri_wallet_swap);
520 httpd_register_uri_handler(s_api_server, &uri_wallet_send);
391 521
392 ESP_LOGI(TAG, "TollGate API started on port 2121"); 522 ESP_LOGI(TAG, "TollGate API started on port 2121");
393 return ESP_OK; 523 return ESP_OK;