v0.1.4 - Rename cashu wallet module API functions to remove _json suffix and keep tool-facing names consistent
This commit is contained in:
@@ -55,11 +55,11 @@ Skills compose by adoption-list order (`10123`) and trigger tags carry runtime e
|
||||
|
||||
Didactyl will support local inference, which is very privacy preserving. Remote inference does however have it's advantages, and in those cases Didactyl supports using Bitcoin Lightning and eCash inference providers.
|
||||
|
||||
## Current Status — v0.1.3
|
||||
## Current Status — v0.1.4
|
||||
|
||||
**Active build — this project is barely working. Experiment at your own risk.**
|
||||
|
||||
> Last release update: v0.1.3 — Make cashu wallet initialization unconditional and add lazy wallet readiness for first-run DM tool usage
|
||||
> Last release update: v0.1.4 — Rename cashu wallet module API functions to remove _json suffix and keep tool-facing names consistent
|
||||
|
||||
- Connects to configured relays with auto-reconnect and relay state transition logging
|
||||
- Publishes configured startup events per relay as each relay becomes connected
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "nostr_handler.h"
|
||||
@@ -226,6 +227,156 @@ static int token_proofs_total_for_mint_locked(const char* mint_url, uint64_t* ou
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dup_string_array(const char** src, int count, char*** out_arr, int* out_count) {
|
||||
if (!out_arr || !out_count) return -1;
|
||||
*out_arr = NULL;
|
||||
*out_count = 0;
|
||||
if (!src || count <= 0) return 0;
|
||||
|
||||
char** arr = (char**)calloc((size_t)count, sizeof(char*));
|
||||
if (!arr) return -1;
|
||||
|
||||
int n = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!src[i] || src[i][0] == '\0') continue;
|
||||
arr[n] = strdup(src[i]);
|
||||
if (!arr[n]) {
|
||||
for (int j = 0; j < n; j++) free(arr[j]);
|
||||
free(arr);
|
||||
return -1;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
|
||||
*out_arr = arr;
|
||||
*out_count = n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int build_nutzap_info_from_mints_locked(const char** mint_urls,
|
||||
int mint_count,
|
||||
nostr_nip61_nutzap_info_t* out_info) {
|
||||
if (!g_wallet.cfg || !out_info) return -1;
|
||||
if (!g_wallet.wallet_loaded || g_wallet.wallet.privkey[0] == '\0') return -1;
|
||||
|
||||
memset(out_info, 0, sizeof(*out_info));
|
||||
|
||||
if (g_wallet.cfg->relay_count > 0 && g_wallet.cfg->relays) {
|
||||
out_info->relay_urls = (char**)calloc((size_t)g_wallet.cfg->relay_count, sizeof(char*));
|
||||
if (!out_info->relay_urls) return -1;
|
||||
|
||||
for (int i = 0; i < g_wallet.cfg->relay_count; i++) {
|
||||
out_info->relay_urls[i] = strdup(g_wallet.cfg->relays[i] ? g_wallet.cfg->relays[i] : "");
|
||||
if (!out_info->relay_urls[i]) {
|
||||
nostr_nip61_free_nutzap_info(out_info);
|
||||
return -1;
|
||||
}
|
||||
out_info->relay_count++;
|
||||
}
|
||||
}
|
||||
|
||||
out_info->mints = (nostr_nip61_mint_entry_t*)calloc((size_t)mint_count, sizeof(nostr_nip61_mint_entry_t));
|
||||
if (!out_info->mints) {
|
||||
nostr_nip61_free_nutzap_info(out_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mint_count; i++) {
|
||||
out_info->mints[i].url = strdup(mint_urls[i]);
|
||||
if (!out_info->mints[i].url) {
|
||||
nostr_nip61_free_nutzap_info(out_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
out_info->mints[i].units = (char**)calloc(1, sizeof(char*));
|
||||
if (!out_info->mints[i].units) {
|
||||
nostr_nip61_free_nutzap_info(out_info);
|
||||
return -1;
|
||||
}
|
||||
out_info->mints[i].units[0] = strdup(g_wallet.cfg->cashu_wallet.unit[0] ? g_wallet.cfg->cashu_wallet.unit : "sat");
|
||||
if (!out_info->mints[i].units[0]) {
|
||||
nostr_nip61_free_nutzap_info(out_info);
|
||||
return -1;
|
||||
}
|
||||
out_info->mints[i].unit_count = 1;
|
||||
out_info->mint_count++;
|
||||
}
|
||||
|
||||
unsigned char wallet_priv[32] = {0};
|
||||
unsigned char wallet_pub[32] = {0};
|
||||
if (nostr_hex_to_bytes(g_wallet.wallet.privkey, wallet_priv, 32) != 0 ||
|
||||
nostr_ec_public_key_from_private_key(wallet_priv, wallet_pub) != 0) {
|
||||
nostr_nip61_free_nutzap_info(out_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nostr_bytes_to_hex(wallet_pub, 32, out_info->pubkey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_latest_public_nutzap_info(nostr_nip61_nutzap_info_t* out_info) {
|
||||
if (!out_info || !g_wallet.cfg) return -1;
|
||||
memset(out_info, 0, sizeof(*out_info));
|
||||
|
||||
cJSON* filter = cJSON_CreateObject();
|
||||
cJSON* kinds = cJSON_CreateArray();
|
||||
cJSON* authors = cJSON_CreateArray();
|
||||
if (!filter || !kinds || !authors) {
|
||||
cJSON_Delete(filter);
|
||||
cJSON_Delete(kinds);
|
||||
cJSON_Delete(authors);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cJSON_AddItemToArray(kinds, cJSON_CreateNumber((double)NOSTR_NIP61_NUTZAP_INFO_KIND));
|
||||
cJSON_AddItemToArray(authors, cJSON_CreateString(g_wallet.cfg->keys.public_key_hex));
|
||||
cJSON_AddItemToObject(filter, "kinds", kinds);
|
||||
cJSON_AddItemToObject(filter, "authors", authors);
|
||||
cJSON_AddNumberToObject(filter, "limit", 20);
|
||||
|
||||
char* events_json = nostr_handler_query_json(filter, CASHU_WALLET_QUERY_TIMEOUT_MS);
|
||||
cJSON_Delete(filter);
|
||||
if (!events_json) return -1;
|
||||
|
||||
cJSON* arr = cJSON_Parse(events_json);
|
||||
free(events_json);
|
||||
if (!arr || !cJSON_IsArray(arr)) {
|
||||
cJSON_Delete(arr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int found = 0;
|
||||
double newest_created_at = -1;
|
||||
nostr_nip61_nutzap_info_t newest;
|
||||
memset(&newest, 0, sizeof(newest));
|
||||
|
||||
int n = cJSON_GetArraySize(arr);
|
||||
for (int i = 0; i < n; i++) {
|
||||
cJSON* ev = cJSON_GetArrayItem(arr, i);
|
||||
cJSON* created_at = ev ? cJSON_GetObjectItemCaseSensitive(ev, "created_at") : NULL;
|
||||
if (!created_at || !cJSON_IsNumber(created_at)) continue;
|
||||
|
||||
nostr_nip61_nutzap_info_t parsed;
|
||||
memset(&parsed, 0, sizeof(parsed));
|
||||
if (nostr_nip61_parse_nutzap_info_event(ev, &parsed) != 0) continue;
|
||||
|
||||
if (!found || created_at->valuedouble > newest_created_at) {
|
||||
nostr_nip61_free_nutzap_info(&newest);
|
||||
newest = parsed;
|
||||
newest_created_at = created_at->valuedouble;
|
||||
found = 1;
|
||||
} else {
|
||||
nostr_nip61_free_nutzap_info(&parsed);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON_Delete(arr);
|
||||
if (!found) return -1;
|
||||
|
||||
*out_info = newest;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_init(didactyl_config_t* cfg) {
|
||||
if (!cfg) return -1;
|
||||
|
||||
@@ -415,7 +566,7 @@ int cashu_wallet_load_from_relays(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_balance_json(cJSON** out_json) {
|
||||
int cashu_wallet_balance(cJSON** out_json) {
|
||||
if (!out_json || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
(void)ensure_wallet_ready();
|
||||
|
||||
@@ -455,7 +606,7 @@ int cashu_wallet_balance_json(cJSON** out_json) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_info_json(const char* mint_url, cJSON** out_json) {
|
||||
int cashu_wallet_info(const char* mint_url, cJSON** out_json) {
|
||||
if (!out_json || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
if (ensure_wallet_ready() != 0) return -1;
|
||||
|
||||
@@ -503,7 +654,7 @@ int cashu_wallet_info_json(const char* mint_url, cJSON** out_json) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_mint_quote_json(const char* mint_url, uint64_t amount, const char* unit, cJSON** out_json) {
|
||||
int cashu_wallet_mint_quote(const char* mint_url, uint64_t amount, const char* unit, cJSON** out_json) {
|
||||
if (!out_json || amount == 0 || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
if (ensure_wallet_ready() != 0) return -1;
|
||||
|
||||
@@ -537,7 +688,7 @@ int cashu_wallet_mint_quote_json(const char* mint_url, uint64_t amount, const ch
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_mint_check_json(const char* mint_url, const char* quote_id, cJSON** out_json) {
|
||||
int cashu_wallet_mint_check(const char* mint_url, const char* quote_id, cJSON** out_json) {
|
||||
if (!out_json || !quote_id || quote_id[0] == '\0' || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
if (ensure_wallet_ready() != 0) return -1;
|
||||
|
||||
@@ -568,7 +719,7 @@ int cashu_wallet_mint_check_json(const char* mint_url, const char* quote_id, cJS
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_mint_claim_json(const char* mint_url, const char* quote_id, uint64_t amount, cJSON** out_json) {
|
||||
int cashu_wallet_mint_claim(const char* mint_url, const char* quote_id, uint64_t amount, cJSON** out_json) {
|
||||
if (!out_json || !quote_id || quote_id[0] == '\0' || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
if (ensure_wallet_ready() != 0) return -1;
|
||||
|
||||
@@ -702,7 +853,7 @@ int cashu_wallet_mint_claim_json(const char* mint_url, const char* quote_id, uin
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_melt_quote_json(const char* mint_url, const char* payment_request, const char* unit, cJSON** out_json) {
|
||||
int cashu_wallet_melt_quote(const char* mint_url, const char* payment_request, const char* unit, cJSON** out_json) {
|
||||
if (!out_json || !payment_request || payment_request[0] == '\0' || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
if (ensure_wallet_ready() != 0) return -1;
|
||||
|
||||
@@ -735,7 +886,7 @@ int cashu_wallet_melt_quote_json(const char* mint_url, const char* payment_reque
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_melt_pay_json(const char* mint_url, const char* quote_id, cJSON** out_json) {
|
||||
int cashu_wallet_melt_pay(const char* mint_url, const char* quote_id, cJSON** out_json) {
|
||||
if (!out_json || !quote_id || quote_id[0] == '\0' || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
if (ensure_wallet_ready() != 0) return -1;
|
||||
|
||||
@@ -916,7 +1067,7 @@ int cashu_wallet_melt_pay_json(const char* mint_url, const char* quote_id, cJSON
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_check_proofs_json(const char* mint_url, cJSON** out_json) {
|
||||
int cashu_wallet_check_proofs(const char* mint_url, cJSON** out_json) {
|
||||
if (!out_json || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
if (ensure_wallet_ready() != 0) return -1;
|
||||
|
||||
@@ -1016,7 +1167,7 @@ int cashu_wallet_check_proofs_json(const char* mint_url, cJSON** out_json) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_receive_token_json(const char* token_string, const char* mint_url, cJSON** out_json) {
|
||||
int cashu_wallet_receive_token(const char* token_string, const char* mint_url, cJSON** out_json) {
|
||||
if (!out_json || !token_string || token_string[0] == '\0' || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
if (ensure_wallet_ready() != 0) return -1;
|
||||
|
||||
@@ -1254,3 +1405,136 @@ int cashu_wallet_receive_token_json(const char* token_string, const char* mint_u
|
||||
cashu_free_decoded_token(&decoded);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_mints_get(cJSON** out_json) {
|
||||
if (!out_json || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
|
||||
(void)ensure_wallet_ready();
|
||||
|
||||
cJSON* root = cJSON_CreateObject();
|
||||
cJSON* wallet_mints = cJSON_CreateArray();
|
||||
cJSON* public_mints = cJSON_CreateArray();
|
||||
if (!root || !wallet_mints || !public_mints) {
|
||||
cJSON_Delete(root);
|
||||
cJSON_Delete(wallet_mints);
|
||||
cJSON_Delete(public_mints);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cJSON_AddBoolToObject(root, "success", 1);
|
||||
|
||||
pthread_mutex_lock(&g_wallet.mutex);
|
||||
int wallet_loaded = g_wallet.wallet_loaded;
|
||||
if (g_wallet.wallet_loaded && g_wallet.wallet.mint_urls) {
|
||||
for (int i = 0; i < g_wallet.wallet.mint_count; i++) {
|
||||
if (g_wallet.wallet.mint_urls[i] && g_wallet.wallet.mint_urls[i][0] != '\0') {
|
||||
cJSON_AddItemToArray(wallet_mints, cJSON_CreateString(g_wallet.wallet.mint_urls[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_wallet.mutex);
|
||||
|
||||
nostr_nip61_nutzap_info_t info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
int have_public = (load_latest_public_nutzap_info(&info) == 0);
|
||||
if (have_public) {
|
||||
for (int i = 0; i < info.mint_count; i++) {
|
||||
if (info.mints[i].url && info.mints[i].url[0] != '\0') {
|
||||
cJSON_AddItemToArray(public_mints, cJSON_CreateString(info.mints[i].url));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cJSON_AddBoolToObject(root, "wallet_loaded", wallet_loaded ? 1 : 0);
|
||||
cJSON_AddBoolToObject(root, "public_info_found", have_public ? 1 : 0);
|
||||
cJSON_AddItemToObject(root, "wallet_event_mints", wallet_mints);
|
||||
cJSON_AddItemToObject(root, "public_nutzap_mints", public_mints);
|
||||
|
||||
if (have_public) {
|
||||
cJSON_AddStringToObject(root, "wallet_pubkey", info.pubkey);
|
||||
nostr_nip61_free_nutzap_info(&info);
|
||||
}
|
||||
|
||||
*out_json = root;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cashu_wallet_mints_set(const char** wallet_mints,
|
||||
int wallet_mint_count,
|
||||
const char** public_mints,
|
||||
int public_mint_count,
|
||||
int set_wallet,
|
||||
int set_public,
|
||||
cJSON** out_json) {
|
||||
if (!out_json || !g_wallet.initialized || !g_wallet.cfg) return -1;
|
||||
if (!set_wallet && !set_public) return NOSTR_ERROR_INVALID_INPUT;
|
||||
|
||||
int wallet_updated = 0;
|
||||
int public_updated = 0;
|
||||
|
||||
if (set_wallet) {
|
||||
if (!wallet_mints || wallet_mint_count <= 0) return NOSTR_ERROR_INVALID_INPUT;
|
||||
|
||||
pthread_mutex_lock(&g_wallet.mutex);
|
||||
|
||||
nostr_nip60_wallet_data_t next_wallet;
|
||||
memset(&next_wallet, 0, sizeof(next_wallet));
|
||||
if (g_wallet.wallet_loaded && g_wallet.wallet.privkey[0] != '\0') {
|
||||
snprintf(next_wallet.privkey, sizeof(next_wallet.privkey), "%s", g_wallet.wallet.privkey);
|
||||
} else {
|
||||
unsigned char priv[32] = {0};
|
||||
unsigned char pub[32] = {0};
|
||||
if (nostr_generate_keypair(priv, pub) != NOSTR_SUCCESS) {
|
||||
pthread_mutex_unlock(&g_wallet.mutex);
|
||||
return -1;
|
||||
}
|
||||
nostr_bytes_to_hex(priv, 32, next_wallet.privkey);
|
||||
}
|
||||
|
||||
if (dup_string_array(wallet_mints, wallet_mint_count, &next_wallet.mint_urls, &next_wallet.mint_count) != 0 ||
|
||||
next_wallet.mint_count <= 0) {
|
||||
nostr_nip60_free_wallet_data(&next_wallet);
|
||||
pthread_mutex_unlock(&g_wallet.mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rc = publish_wallet_event_and_store_locked(&next_wallet, NULL);
|
||||
nostr_nip60_free_wallet_data(&next_wallet);
|
||||
pthread_mutex_unlock(&g_wallet.mutex);
|
||||
if (rc != 0) return rc;
|
||||
|
||||
wallet_updated = 1;
|
||||
}
|
||||
|
||||
if (set_public) {
|
||||
if (!public_mints || public_mint_count <= 0) return NOSTR_ERROR_INVALID_INPUT;
|
||||
|
||||
if (ensure_wallet_ready() != 0) return -1;
|
||||
|
||||
pthread_mutex_lock(&g_wallet.mutex);
|
||||
nostr_nip61_nutzap_info_t info;
|
||||
int rc = build_nutzap_info_from_mints_locked(public_mints, public_mint_count, &info);
|
||||
pthread_mutex_unlock(&g_wallet.mutex);
|
||||
if (rc != 0) return -1;
|
||||
|
||||
cJSON* ev = nostr_nip61_create_nutzap_info_event(&info, g_wallet.cfg->keys.private_key, time(NULL));
|
||||
nostr_nip61_free_nutzap_info(&info);
|
||||
if (!ev) return -1;
|
||||
|
||||
rc = publish_from_signed_event_template(ev, NULL);
|
||||
cJSON_Delete(ev);
|
||||
if (rc != 0) return rc;
|
||||
|
||||
public_updated = 1;
|
||||
}
|
||||
|
||||
cJSON* root = cJSON_CreateObject();
|
||||
if (!root) return -1;
|
||||
|
||||
cJSON_AddBoolToObject(root, "success", 1);
|
||||
cJSON_AddBoolToObject(root, "wallet_updated", wallet_updated ? 1 : 0);
|
||||
cJSON_AddBoolToObject(root, "public_updated", public_updated ? 1 : 0);
|
||||
|
||||
*out_json = root;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12,14 +12,22 @@ void cashu_wallet_cleanup(void);
|
||||
int cashu_wallet_load_from_relays(void);
|
||||
int cashu_wallet_create_new_from_config(void);
|
||||
|
||||
int cashu_wallet_balance_json(cJSON** out_json);
|
||||
int cashu_wallet_info_json(const char* mint_url, cJSON** out_json);
|
||||
int cashu_wallet_mint_quote_json(const char* mint_url, uint64_t amount, const char* unit, cJSON** out_json);
|
||||
int cashu_wallet_mint_check_json(const char* mint_url, const char* quote_id, cJSON** out_json);
|
||||
int cashu_wallet_mint_claim_json(const char* mint_url, const char* quote_id, uint64_t amount, cJSON** out_json);
|
||||
int cashu_wallet_melt_quote_json(const char* mint_url, const char* payment_request, const char* unit, cJSON** out_json);
|
||||
int cashu_wallet_melt_pay_json(const char* mint_url, const char* quote_id, cJSON** out_json);
|
||||
int cashu_wallet_check_proofs_json(const char* mint_url, cJSON** out_json);
|
||||
int cashu_wallet_receive_token_json(const char* token_string, const char* mint_url, cJSON** out_json);
|
||||
int cashu_wallet_balance(cJSON** out_json);
|
||||
int cashu_wallet_info(const char* mint_url, cJSON** out_json);
|
||||
int cashu_wallet_mint_quote(const char* mint_url, uint64_t amount, const char* unit, cJSON** out_json);
|
||||
int cashu_wallet_mint_check(const char* mint_url, const char* quote_id, cJSON** out_json);
|
||||
int cashu_wallet_mint_claim(const char* mint_url, const char* quote_id, uint64_t amount, cJSON** out_json);
|
||||
int cashu_wallet_melt_quote(const char* mint_url, const char* payment_request, const char* unit, cJSON** out_json);
|
||||
int cashu_wallet_melt_pay(const char* mint_url, const char* quote_id, cJSON** out_json);
|
||||
int cashu_wallet_check_proofs(const char* mint_url, cJSON** out_json);
|
||||
int cashu_wallet_receive_token(const char* token_string, const char* mint_url, cJSON** out_json);
|
||||
int cashu_wallet_mints_get(cJSON** out_json);
|
||||
int cashu_wallet_mints_set(const char** wallet_mints,
|
||||
int wallet_mint_count,
|
||||
const char** public_mints,
|
||||
int public_mint_count,
|
||||
int set_wallet,
|
||||
int set_public,
|
||||
cJSON** out_json);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
// Using DIDACTYL_ prefix to avoid conflicts with nostr_core_lib VERSION macros
|
||||
#define DIDACTYL_VERSION_MAJOR 0
|
||||
#define DIDACTYL_VERSION_MINOR 1
|
||||
#define DIDACTYL_VERSION_PATCH 3
|
||||
#define DIDACTYL_VERSION "v0.1.3"
|
||||
#define DIDACTYL_VERSION_PATCH 4
|
||||
#define DIDACTYL_VERSION "v0.1.4"
|
||||
|
||||
// Agent metadata
|
||||
#define DIDACTYL_NAME "Didactyl"
|
||||
|
||||
@@ -46,7 +46,7 @@ char* execute_cashu_wallet_balance(tools_context_t* ctx, const char* args_json)
|
||||
if (!args) return json_error_local("invalid arguments JSON");
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_balance_json(&out);
|
||||
int rc = cashu_wallet_balance(&out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_balance failed");
|
||||
}
|
||||
@@ -65,7 +65,7 @@ char* execute_cashu_wallet_info(tools_context_t* ctx, const char* args_json) {
|
||||
}
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_info_json(mint_url, &out);
|
||||
int rc = cashu_wallet_info(mint_url, &out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_info failed (check mint_url and mint connectivity)");
|
||||
}
|
||||
@@ -92,7 +92,7 @@ char* execute_cashu_wallet_mint_quote(tools_context_t* ctx, const char* args_jso
|
||||
}
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_mint_quote_json(mint_url, (uint64_t)amount->valuedouble, unit_s, &out);
|
||||
int rc = cashu_wallet_mint_quote(mint_url, (uint64_t)amount->valuedouble, unit_s, &out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_mint_quote failed");
|
||||
}
|
||||
@@ -117,7 +117,7 @@ char* execute_cashu_wallet_mint_check(tools_context_t* ctx, const char* args_jso
|
||||
}
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_mint_check_json(mint_url, quote_id->valuestring, &out);
|
||||
int rc = cashu_wallet_mint_check(mint_url, quote_id->valuestring, &out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_mint_check failed");
|
||||
}
|
||||
@@ -152,7 +152,7 @@ char* execute_cashu_wallet_mint_claim(tools_context_t* ctx, const char* args_jso
|
||||
}
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_mint_claim_json(mint_url, quote_id->valuestring, amount, &out);
|
||||
int rc = cashu_wallet_mint_claim(mint_url, quote_id->valuestring, amount, &out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_mint_claim failed");
|
||||
}
|
||||
@@ -179,7 +179,7 @@ char* execute_cashu_wallet_melt_quote(tools_context_t* ctx, const char* args_jso
|
||||
}
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_melt_quote_json(mint_url, payment_request->valuestring, unit_s, &out);
|
||||
int rc = cashu_wallet_melt_quote(mint_url, payment_request->valuestring, unit_s, &out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_melt_quote failed");
|
||||
}
|
||||
@@ -204,7 +204,7 @@ char* execute_cashu_wallet_melt_pay(tools_context_t* ctx, const char* args_json)
|
||||
}
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_melt_pay_json(mint_url, quote_id->valuestring, &out);
|
||||
int rc = cashu_wallet_melt_pay(mint_url, quote_id->valuestring, &out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_melt_pay failed");
|
||||
}
|
||||
@@ -223,7 +223,7 @@ char* execute_cashu_wallet_check_proofs(tools_context_t* ctx, const char* args_j
|
||||
}
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_check_proofs_json(mint_url, &out);
|
||||
int rc = cashu_wallet_check_proofs(mint_url, &out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_check_proofs failed");
|
||||
}
|
||||
@@ -244,7 +244,98 @@ char* execute_cashu_wallet_receive_token(tools_context_t* ctx, const char* args_
|
||||
const char* mint_url = (mint && cJSON_IsString(mint) && mint->valuestring) ? mint->valuestring : NULL;
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_receive_token_json(token->valuestring, mint_url, &out);
|
||||
int rc = cashu_wallet_receive_token(token->valuestring, mint_url, &out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_receive_token failed");
|
||||
}
|
||||
|
||||
char* execute_cashu_wallet_mints_get(tools_context_t* ctx, const char* args_json) {
|
||||
if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable");
|
||||
|
||||
cJSON* args = parse_args_local(args_json);
|
||||
if (!args) return json_error_local("invalid arguments JSON");
|
||||
cJSON_Delete(args);
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_mints_get(&out);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_mints_get failed");
|
||||
}
|
||||
|
||||
char* execute_cashu_wallet_mints_set(tools_context_t* ctx, const char* args_json) {
|
||||
if (!ctx || !ctx->cfg) return json_error_local("tool context unavailable");
|
||||
|
||||
cJSON* args = parse_args_local(args_json);
|
||||
if (!args) return json_error_local("invalid arguments JSON");
|
||||
|
||||
cJSON* target = cJSON_GetObjectItemCaseSensitive(args, "target");
|
||||
const char* target_s = (target && cJSON_IsString(target) && target->valuestring) ? target->valuestring : "both";
|
||||
|
||||
int set_wallet = 0;
|
||||
int set_public = 0;
|
||||
if (strcmp(target_s, "wallet") == 0) {
|
||||
set_wallet = 1;
|
||||
} else if (strcmp(target_s, "public") == 0) {
|
||||
set_public = 1;
|
||||
} else if (strcmp(target_s, "both") == 0) {
|
||||
set_wallet = 1;
|
||||
set_public = 1;
|
||||
} else {
|
||||
cJSON_Delete(args);
|
||||
return json_error_local("cashu_wallet_mints_set target must be wallet, public, or both");
|
||||
}
|
||||
|
||||
cJSON* wallet_arr = cJSON_GetObjectItemCaseSensitive(args, "wallet_mints");
|
||||
cJSON* public_arr = cJSON_GetObjectItemCaseSensitive(args, "public_mints");
|
||||
|
||||
const char* wallet_buf[32] = {0};
|
||||
int wallet_count = 0;
|
||||
if (wallet_arr) {
|
||||
if (!cJSON_IsArray(wallet_arr)) {
|
||||
cJSON_Delete(args);
|
||||
return json_error_local("wallet_mints must be an array of strings");
|
||||
}
|
||||
int n = cJSON_GetArraySize(wallet_arr);
|
||||
for (int i = 0; i < n && wallet_count < 32; i++) {
|
||||
cJSON* it = cJSON_GetArrayItem(wallet_arr, i);
|
||||
if (it && cJSON_IsString(it) && it->valuestring && it->valuestring[0] != '\0') {
|
||||
wallet_buf[wallet_count++] = it->valuestring;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* public_buf[32] = {0};
|
||||
int public_count = 0;
|
||||
if (public_arr) {
|
||||
if (!cJSON_IsArray(public_arr)) {
|
||||
cJSON_Delete(args);
|
||||
return json_error_local("public_mints must be an array of strings");
|
||||
}
|
||||
int n = cJSON_GetArraySize(public_arr);
|
||||
for (int i = 0; i < n && public_count < 32; i++) {
|
||||
cJSON* it = cJSON_GetArrayItem(public_arr, i);
|
||||
if (it && cJSON_IsString(it) && it->valuestring && it->valuestring[0] != '\0') {
|
||||
public_buf[public_count++] = it->valuestring;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (set_wallet && wallet_count <= 0) {
|
||||
cJSON_Delete(args);
|
||||
return json_error_local("cashu_wallet_mints_set requires wallet_mints when target includes wallet");
|
||||
}
|
||||
if (set_public && public_count <= 0) {
|
||||
cJSON_Delete(args);
|
||||
return json_error_local("cashu_wallet_mints_set requires public_mints when target includes public");
|
||||
}
|
||||
|
||||
cJSON* out = NULL;
|
||||
int rc = cashu_wallet_mints_set(wallet_buf,
|
||||
wallet_count,
|
||||
public_buf,
|
||||
public_count,
|
||||
set_wallet,
|
||||
set_public,
|
||||
&out);
|
||||
cJSON_Delete(args);
|
||||
return wrap_wallet_json_result(rc, out, "cashu_wallet_mints_set failed");
|
||||
}
|
||||
|
||||
@@ -259,6 +259,12 @@ char* tools_execute_legacy(tools_context_t* ctx, const char* tool_name, const ch
|
||||
if (strcmp(tool_name, "cashu_wallet_receive_token") == 0) {
|
||||
return execute_cashu_wallet_receive_token(ctx, args_json);
|
||||
}
|
||||
if (strcmp(tool_name, "cashu_wallet_mints_get") == 0) {
|
||||
return execute_cashu_wallet_mints_get(ctx, args_json);
|
||||
}
|
||||
if (strcmp(tool_name, "cashu_wallet_mints_set") == 0) {
|
||||
return execute_cashu_wallet_mints_set(ctx, args_json);
|
||||
}
|
||||
|
||||
return json_error("unknown tool");
|
||||
}
|
||||
|
||||
@@ -78,6 +78,8 @@ char* execute_cashu_wallet_melt_quote(tools_context_t* ctx, const char* args_jso
|
||||
char* execute_cashu_wallet_melt_pay(tools_context_t* ctx, const char* args_json);
|
||||
char* execute_cashu_wallet_check_proofs(tools_context_t* ctx, const char* args_json);
|
||||
char* execute_cashu_wallet_receive_token(tools_context_t* ctx, const char* args_json);
|
||||
char* execute_cashu_wallet_mints_get(tools_context_t* ctx, const char* args_json);
|
||||
char* execute_cashu_wallet_mints_set(tools_context_t* ctx, const char* args_json);
|
||||
|
||||
int memory_init(tools_context_t* ctx);
|
||||
void memory_cleanup(void);
|
||||
|
||||
@@ -1711,6 +1711,61 @@ char* tools_build_openai_schema_json_legacy(const tools_context_t* ctx) {
|
||||
cJSON_AddItemToObject(t59, "function", t59_fn);
|
||||
cJSON_AddItemToArray(tools, t59);
|
||||
|
||||
cJSON* t60 = cJSON_CreateObject();
|
||||
cJSON* t60_fn = cJSON_CreateObject();
|
||||
cJSON* t60_params = cJSON_CreateObject();
|
||||
cJSON* t60_props = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(t60, "type", "function");
|
||||
cJSON_AddStringToObject(t60_fn, "name", "cashu_wallet_mints_get");
|
||||
cJSON_AddStringToObject(t60_fn, "description", "Get wallet mints from NIP-60 wallet event and public mints from NIP-61 nutzap info");
|
||||
cJSON_AddStringToObject(t60_params, "type", "object");
|
||||
cJSON_AddItemToObject(t60_params, "properties", t60_props);
|
||||
|
||||
cJSON_AddItemToObject(t60_fn, "parameters", t60_params);
|
||||
cJSON_AddItemToObject(t60, "function", t60_fn);
|
||||
cJSON_AddItemToArray(tools, t60);
|
||||
|
||||
cJSON* t61 = cJSON_CreateObject();
|
||||
cJSON* t61_fn = cJSON_CreateObject();
|
||||
cJSON* t61_params = cJSON_CreateObject();
|
||||
cJSON* t61_props = cJSON_CreateObject();
|
||||
cJSON* t61_required = cJSON_CreateArray();
|
||||
|
||||
cJSON_AddStringToObject(t61, "type", "function");
|
||||
cJSON_AddStringToObject(t61_fn, "name", "cashu_wallet_mints_set");
|
||||
cJSON_AddStringToObject(t61_fn, "description", "Set wallet mints (NIP-60), public mints (NIP-61), or both");
|
||||
cJSON_AddStringToObject(t61_params, "type", "object");
|
||||
cJSON_AddItemToObject(t61_params, "properties", t61_props);
|
||||
cJSON_AddItemToObject(t61_params, "required", t61_required);
|
||||
|
||||
cJSON* p_wallet_ms_target = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(p_wallet_ms_target, "type", "string");
|
||||
cJSON_AddStringToObject(p_wallet_ms_target, "description", "Where to apply mint updates: wallet, public, or both");
|
||||
cJSON_AddItemToObject(t61_props, "target", p_wallet_ms_target);
|
||||
|
||||
cJSON* p_wallet_ms_wallet = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(p_wallet_ms_wallet, "type", "array");
|
||||
cJSON* p_wallet_ms_wallet_items = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(p_wallet_ms_wallet_items, "type", "string");
|
||||
cJSON_AddItemToObject(p_wallet_ms_wallet, "items", p_wallet_ms_wallet_items);
|
||||
cJSON_AddStringToObject(p_wallet_ms_wallet, "description", "Mint URLs for wallet event update");
|
||||
cJSON_AddItemToObject(t61_props, "wallet_mints", p_wallet_ms_wallet);
|
||||
|
||||
cJSON* p_wallet_ms_public = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(p_wallet_ms_public, "type", "array");
|
||||
cJSON* p_wallet_ms_public_items = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(p_wallet_ms_public_items, "type", "string");
|
||||
cJSON_AddItemToObject(p_wallet_ms_public, "items", p_wallet_ms_public_items);
|
||||
cJSON_AddStringToObject(p_wallet_ms_public, "description", "Mint URLs for public nutzap info update");
|
||||
cJSON_AddItemToObject(t61_props, "public_mints", p_wallet_ms_public);
|
||||
|
||||
cJSON_AddItemToArray(t61_required, cJSON_CreateString("target"));
|
||||
|
||||
cJSON_AddItemToObject(t61_fn, "parameters", t61_params);
|
||||
cJSON_AddItemToObject(t61, "function", t61_fn);
|
||||
cJSON_AddItemToArray(tools, t61);
|
||||
|
||||
char* out = cJSON_PrintUnformatted(tools);
|
||||
cJSON_Delete(tools);
|
||||
return out;
|
||||
|
||||
Reference in New Issue
Block a user