committed by
Daniel D’Aquino
parent
373cd71f69
commit
30ba0d72cc
@@ -1,8 +1,8 @@
|
|||||||
//
|
//
|
||||||
// nostr_bech32.c
|
// nostr_bech32.c
|
||||||
// damus
|
// damus
|
||||||
//
|
//
|
||||||
// Created by William Casarin on 2023-04-09.
|
// Created by William Casarin on 2023-04-09.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "nostr_bech32.h"
|
#include "nostr_bech32.h"
|
||||||
@@ -19,288 +19,288 @@
|
|||||||
#define TLV_KNOWN_TLVS 4
|
#define TLV_KNOWN_TLVS 4
|
||||||
|
|
||||||
struct nostr_tlv {
|
struct nostr_tlv {
|
||||||
u8 type;
|
u8 type;
|
||||||
u8 len;
|
u8 len;
|
||||||
const u8 *value;
|
const u8 *value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nostr_tlvs {
|
struct nostr_tlvs {
|
||||||
struct nostr_tlv tlvs[MAX_TLVS];
|
struct nostr_tlv tlvs[MAX_TLVS];
|
||||||
int num_tlvs;
|
int num_tlvs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int parse_nostr_tlv(struct cursor *cur, struct nostr_tlv *tlv) {
|
static int parse_nostr_tlv(struct cursor *cur, struct nostr_tlv *tlv) {
|
||||||
// get the tlv tag
|
// get the tlv tag
|
||||||
if (!pull_byte(cur, &tlv->type))
|
if (!cursor_pull_byte(cur, &tlv->type))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// unknown, fail!
|
// unknown, fail!
|
||||||
if (tlv->type >= TLV_KNOWN_TLVS)
|
if (tlv->type >= TLV_KNOWN_TLVS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// get the length
|
// get the length
|
||||||
if (!pull_byte(cur, &tlv->len))
|
if (!cursor_pull_byte(cur, &tlv->len))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// is the reported length greater then our buffer? if so fail
|
// is the reported length greater then our buffer? if so fail
|
||||||
if (cur->p + tlv->len > cur->end)
|
if (cur->p + tlv->len > cur->end)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tlv->value = cur->p;
|
tlv->value = cur->p;
|
||||||
cur->p += tlv->len;
|
cur->p += tlv->len;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nostr_tlvs(struct cursor *cur, struct nostr_tlvs *tlvs) {
|
static int parse_nostr_tlvs(struct cursor *cur, struct nostr_tlvs *tlvs) {
|
||||||
int i;
|
int i;
|
||||||
tlvs->num_tlvs = 0;
|
tlvs->num_tlvs = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAX_TLVS; i++) {
|
for (i = 0; i < MAX_TLVS; i++) {
|
||||||
if (parse_nostr_tlv(cur, &tlvs->tlvs[i])) {
|
if (parse_nostr_tlv(cur, &tlvs->tlvs[i])) {
|
||||||
tlvs->num_tlvs++;
|
tlvs->num_tlvs++;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tlvs->num_tlvs == 0)
|
if (tlvs->num_tlvs == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_tlv(struct nostr_tlvs *tlvs, u8 type, struct nostr_tlv **tlv) {
|
static int find_tlv(struct nostr_tlvs *tlvs, u8 type, struct nostr_tlv **tlv) {
|
||||||
*tlv = NULL;
|
*tlv = NULL;
|
||||||
|
|
||||||
for (int i = 0; i < tlvs->num_tlvs; i++) {
|
for (int i = 0; i < tlvs->num_tlvs; i++) {
|
||||||
if (tlvs->tlvs[i].type == type) {
|
if (tlvs->tlvs[i].type == type) {
|
||||||
*tlv = &tlvs->tlvs[i];
|
*tlv = &tlvs->tlvs[i];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nostr_bech32_type(const char *prefix, enum nostr_bech32_type *type) {
|
static int parse_nostr_bech32_type(const char *prefix, enum nostr_bech32_type *type) {
|
||||||
// Parse type
|
// Parse type
|
||||||
if (strcmp(prefix, "note") == 0) {
|
if (strcmp(prefix, "note") == 0) {
|
||||||
*type = NOSTR_BECH32_NOTE;
|
*type = NOSTR_BECH32_NOTE;
|
||||||
return 1;
|
return 1;
|
||||||
} else if (strcmp(prefix, "npub") == 0) {
|
} else if (strcmp(prefix, "npub") == 0) {
|
||||||
*type = NOSTR_BECH32_NPUB;
|
*type = NOSTR_BECH32_NPUB;
|
||||||
return 1;
|
return 1;
|
||||||
} else if (strcmp(prefix, "nsec") == 0) {
|
} else if (strcmp(prefix, "nsec") == 0) {
|
||||||
*type = NOSTR_BECH32_NSEC;
|
*type = NOSTR_BECH32_NSEC;
|
||||||
return 1;
|
return 1;
|
||||||
} else if (strcmp(prefix, "nprofile") == 0) {
|
} else if (strcmp(prefix, "nprofile") == 0) {
|
||||||
*type = NOSTR_BECH32_NPROFILE;
|
*type = NOSTR_BECH32_NPROFILE;
|
||||||
return 1;
|
return 1;
|
||||||
} else if (strcmp(prefix, "nevent") == 0) {
|
} else if (strcmp(prefix, "nevent") == 0) {
|
||||||
*type = NOSTR_BECH32_NEVENT;
|
*type = NOSTR_BECH32_NEVENT;
|
||||||
return 1;
|
return 1;
|
||||||
} else if (strcmp(prefix, "nrelay") == 0) {
|
} else if (strcmp(prefix, "nrelay") == 0) {
|
||||||
*type = NOSTR_BECH32_NRELAY;
|
*type = NOSTR_BECH32_NRELAY;
|
||||||
return 1;
|
return 1;
|
||||||
} else if (strcmp(prefix, "naddr") == 0) {
|
} else if (strcmp(prefix, "naddr") == 0) {
|
||||||
*type = NOSTR_BECH32_NADDR;
|
*type = NOSTR_BECH32_NADDR;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nostr_bech32_note(struct cursor *cur, struct bech32_note *note) {
|
static int parse_nostr_bech32_note(struct cursor *cur, struct bech32_note *note) {
|
||||||
return pull_bytes(cur, 32, ¬e->event_id);
|
return pull_bytes(cur, 32, ¬e->event_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nostr_bech32_npub(struct cursor *cur, struct bech32_npub *npub) {
|
static int parse_nostr_bech32_npub(struct cursor *cur, struct bech32_npub *npub) {
|
||||||
return pull_bytes(cur, 32, &npub->pubkey);
|
return pull_bytes(cur, 32, &npub->pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nostr_bech32_nsec(struct cursor *cur, struct bech32_nsec *nsec) {
|
static int parse_nostr_bech32_nsec(struct cursor *cur, struct bech32_nsec *nsec) {
|
||||||
return pull_bytes(cur, 32, &nsec->nsec);
|
return pull_bytes(cur, 32, &nsec->nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tlvs_to_relays(struct nostr_tlvs *tlvs, struct relays *relays) {
|
static int tlvs_to_relays(struct nostr_tlvs *tlvs, struct relays *relays) {
|
||||||
struct nostr_tlv *tlv;
|
struct nostr_tlv *tlv;
|
||||||
struct str_block *str;
|
struct str_block *str;
|
||||||
|
|
||||||
relays->num_relays = 0;
|
relays->num_relays = 0;
|
||||||
|
|
||||||
for (int i = 0; i < tlvs->num_tlvs; i++) {
|
for (int i = 0; i < tlvs->num_tlvs; i++) {
|
||||||
tlv = &tlvs->tlvs[i];
|
tlv = &tlvs->tlvs[i];
|
||||||
if (tlv->type != TLV_RELAY)
|
if (tlv->type != TLV_RELAY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (relays->num_relays + 1 > MAX_RELAYS)
|
if (relays->num_relays + 1 > MAX_RELAYS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
str = &relays->relays[relays->num_relays++];
|
str = &relays->relays[relays->num_relays++];
|
||||||
str->start = (const char*)tlv->value;
|
str->start = (const char*)tlv->value;
|
||||||
str->end = (const char*)(tlv->value + tlv->len);
|
str->end = (const char*)(tlv->value + tlv->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nostr_bech32_nevent(struct cursor *cur, struct bech32_nevent *nevent) {
|
static int parse_nostr_bech32_nevent(struct cursor *cur, struct bech32_nevent *nevent) {
|
||||||
struct nostr_tlvs tlvs;
|
struct nostr_tlvs tlvs;
|
||||||
struct nostr_tlv *tlv;
|
struct nostr_tlv *tlv;
|
||||||
|
|
||||||
if (!parse_nostr_tlvs(cur, &tlvs))
|
if (!parse_nostr_tlvs(cur, &tlvs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
|
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (tlv->len != 32)
|
if (tlv->len != 32)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nevent->event_id = tlv->value;
|
nevent->event_id = tlv->value;
|
||||||
|
|
||||||
if (find_tlv(&tlvs, TLV_AUTHOR, &tlv)) {
|
if (find_tlv(&tlvs, TLV_AUTHOR, &tlv)) {
|
||||||
nevent->pubkey = tlv->value;
|
nevent->pubkey = tlv->value;
|
||||||
} else {
|
} else {
|
||||||
nevent->pubkey = NULL;
|
nevent->pubkey = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tlvs_to_relays(&tlvs, &nevent->relays);
|
return tlvs_to_relays(&tlvs, &nevent->relays);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nostr_bech32_naddr(struct cursor *cur, struct bech32_naddr *naddr) {
|
static int parse_nostr_bech32_naddr(struct cursor *cur, struct bech32_naddr *naddr) {
|
||||||
struct nostr_tlvs tlvs;
|
struct nostr_tlvs tlvs;
|
||||||
struct nostr_tlv *tlv;
|
struct nostr_tlv *tlv;
|
||||||
|
|
||||||
if (!parse_nostr_tlvs(cur, &tlvs))
|
if (!parse_nostr_tlvs(cur, &tlvs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
|
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
naddr->identifier.start = (const char*)tlv->value;
|
naddr->identifier.start = (const char*)tlv->value;
|
||||||
naddr->identifier.end = (const char*)tlv->value + tlv->len;
|
naddr->identifier.end = (const char*)tlv->value + tlv->len;
|
||||||
|
|
||||||
if (!find_tlv(&tlvs, TLV_AUTHOR, &tlv))
|
if (!find_tlv(&tlvs, TLV_AUTHOR, &tlv))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
naddr->pubkey = tlv->value;
|
naddr->pubkey = tlv->value;
|
||||||
|
|
||||||
return tlvs_to_relays(&tlvs, &naddr->relays);
|
return tlvs_to_relays(&tlvs, &naddr->relays);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nostr_bech32_nprofile(struct cursor *cur, struct bech32_nprofile *nprofile) {
|
static int parse_nostr_bech32_nprofile(struct cursor *cur, struct bech32_nprofile *nprofile) {
|
||||||
struct nostr_tlvs tlvs;
|
struct nostr_tlvs tlvs;
|
||||||
struct nostr_tlv *tlv;
|
struct nostr_tlv *tlv;
|
||||||
|
|
||||||
if (!parse_nostr_tlvs(cur, &tlvs))
|
if (!parse_nostr_tlvs(cur, &tlvs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
|
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (tlv->len != 32)
|
if (tlv->len != 32)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nprofile->pubkey = tlv->value;
|
nprofile->pubkey = tlv->value;
|
||||||
|
|
||||||
return tlvs_to_relays(&tlvs, &nprofile->relays);
|
return tlvs_to_relays(&tlvs, &nprofile->relays);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nostr_bech32_nrelay(struct cursor *cur, struct bech32_nrelay *nrelay) {
|
static int parse_nostr_bech32_nrelay(struct cursor *cur, struct bech32_nrelay *nrelay) {
|
||||||
struct nostr_tlvs tlvs;
|
struct nostr_tlvs tlvs;
|
||||||
struct nostr_tlv *tlv;
|
struct nostr_tlv *tlv;
|
||||||
|
|
||||||
if (!parse_nostr_tlvs(cur, &tlvs))
|
if (!parse_nostr_tlvs(cur, &tlvs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
|
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nrelay->relay.start = (const char*)tlv->value;
|
nrelay->relay.start = (const char*)tlv->value;
|
||||||
nrelay->relay.end = (const char*)tlv->value + tlv->len;
|
nrelay->relay.end = (const char*)tlv->value + tlv->len;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_nostr_bech32(struct cursor *cur, struct nostr_bech32 *obj) {
|
int parse_nostr_bech32(struct cursor *cur, struct nostr_bech32 *obj) {
|
||||||
u8 *start, *end;
|
u8 *start, *end;
|
||||||
|
|
||||||
start = cur->p;
|
start = cur->p;
|
||||||
|
|
||||||
if (!consume_until_non_alphanumeric(cur, 1)) {
|
if (!consume_until_non_alphanumeric(cur, 1)) {
|
||||||
cur->p = start;
|
cur->p = start;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
end = cur->p;
|
end = cur->p;
|
||||||
|
|
||||||
size_t data_len;
|
size_t data_len;
|
||||||
size_t input_len = end - start;
|
size_t input_len = end - start;
|
||||||
if (input_len < 10 || input_len > 10000) {
|
if (input_len < 10 || input_len > 10000) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj->buffer = malloc(input_len * 2);
|
obj->buffer = malloc(input_len * 2);
|
||||||
if (!obj->buffer)
|
if (!obj->buffer)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
u8 data[input_len];
|
u8 data[input_len];
|
||||||
char prefix[input_len];
|
char prefix[input_len];
|
||||||
|
|
||||||
if (bech32_decode_len(prefix, data, &data_len, (const char*)start, input_len) == BECH32_ENCODING_NONE) {
|
if (bech32_decode_len(prefix, data, &data_len, (const char*)start, input_len) == BECH32_ENCODING_NONE) {
|
||||||
cur->p = start;
|
cur->p = start;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj->buflen = 0;
|
obj->buflen = 0;
|
||||||
if (!bech32_convert_bits(obj->buffer, &obj->buflen, 8, data, data_len, 5, 0)) {
|
if (!bech32_convert_bits(obj->buffer, &obj->buflen, 8, data, data_len, 5, 0)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parse_nostr_bech32_type(prefix, &obj->type)) {
|
if (!parse_nostr_bech32_type(prefix, &obj->type)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cursor bcur;
|
struct cursor bcur;
|
||||||
make_cursor(obj->buffer, obj->buffer + obj->buflen, &bcur);
|
make_cursor(obj->buffer, obj->buffer + obj->buflen, &bcur);
|
||||||
|
|
||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case NOSTR_BECH32_NOTE:
|
case NOSTR_BECH32_NOTE:
|
||||||
if (!parse_nostr_bech32_note(&bcur, &obj->data.note))
|
if (!parse_nostr_bech32_note(&bcur, &obj->data.note))
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
case NOSTR_BECH32_NPUB:
|
case NOSTR_BECH32_NPUB:
|
||||||
if (!parse_nostr_bech32_npub(&bcur, &obj->data.npub))
|
if (!parse_nostr_bech32_npub(&bcur, &obj->data.npub))
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
case NOSTR_BECH32_NSEC:
|
case NOSTR_BECH32_NSEC:
|
||||||
if (!parse_nostr_bech32_nsec(&bcur, &obj->data.nsec))
|
if (!parse_nostr_bech32_nsec(&bcur, &obj->data.nsec))
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
case NOSTR_BECH32_NEVENT:
|
case NOSTR_BECH32_NEVENT:
|
||||||
if (!parse_nostr_bech32_nevent(&bcur, &obj->data.nevent))
|
if (!parse_nostr_bech32_nevent(&bcur, &obj->data.nevent))
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
case NOSTR_BECH32_NADDR:
|
case NOSTR_BECH32_NADDR:
|
||||||
if (!parse_nostr_bech32_naddr(&bcur, &obj->data.naddr))
|
if (!parse_nostr_bech32_naddr(&bcur, &obj->data.naddr))
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
case NOSTR_BECH32_NPROFILE:
|
case NOSTR_BECH32_NPROFILE:
|
||||||
if (!parse_nostr_bech32_nprofile(&bcur, &obj->data.nprofile))
|
if (!parse_nostr_bech32_nprofile(&bcur, &obj->data.nprofile))
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
case NOSTR_BECH32_NRELAY:
|
case NOSTR_BECH32_NRELAY:
|
||||||
if (!parse_nostr_bech32_nrelay(&bcur, &obj->data.nrelay))
|
if (!parse_nostr_bech32_nrelay(&bcur, &obj->data.nrelay))
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
free(obj->buffer);
|
free(obj->buffer);
|
||||||
cur->p = start;
|
cur->p = start;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
//
|
//
|
||||||
// nostr_bech32.h
|
// nostr_bech32.h
|
||||||
// damus
|
// damus
|
||||||
//
|
//
|
||||||
// Created by William Casarin on 2023-04-09.
|
// Created by William Casarin on 2023-04-09.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef nostr_bech32_h
|
#ifndef nostr_bech32_h
|
||||||
@@ -15,67 +15,67 @@ typedef unsigned char u8;
|
|||||||
#define MAX_RELAYS 10
|
#define MAX_RELAYS 10
|
||||||
|
|
||||||
struct relays {
|
struct relays {
|
||||||
struct str_block relays[MAX_RELAYS];
|
struct str_block relays[MAX_RELAYS];
|
||||||
int num_relays;
|
int num_relays;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum nostr_bech32_type {
|
enum nostr_bech32_type {
|
||||||
NOSTR_BECH32_NOTE = 1,
|
NOSTR_BECH32_NOTE = 1,
|
||||||
NOSTR_BECH32_NPUB = 2,
|
NOSTR_BECH32_NPUB = 2,
|
||||||
NOSTR_BECH32_NPROFILE = 3,
|
NOSTR_BECH32_NPROFILE = 3,
|
||||||
NOSTR_BECH32_NEVENT = 4,
|
NOSTR_BECH32_NEVENT = 4,
|
||||||
NOSTR_BECH32_NRELAY = 5,
|
NOSTR_BECH32_NRELAY = 5,
|
||||||
NOSTR_BECH32_NADDR = 6,
|
NOSTR_BECH32_NADDR = 6,
|
||||||
NOSTR_BECH32_NSEC = 7,
|
NOSTR_BECH32_NSEC = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bech32_note {
|
struct bech32_note {
|
||||||
const u8 *event_id;
|
const u8 *event_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bech32_npub {
|
struct bech32_npub {
|
||||||
const u8 *pubkey;
|
const u8 *pubkey;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bech32_nsec {
|
struct bech32_nsec {
|
||||||
const u8 *nsec;
|
const u8 *nsec;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bech32_nevent {
|
struct bech32_nevent {
|
||||||
struct relays relays;
|
struct relays relays;
|
||||||
const u8 *event_id;
|
const u8 *event_id;
|
||||||
const u8 *pubkey; // optional
|
const u8 *pubkey; // optional
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bech32_nprofile {
|
struct bech32_nprofile {
|
||||||
struct relays relays;
|
struct relays relays;
|
||||||
const u8 *pubkey;
|
const u8 *pubkey;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bech32_naddr {
|
struct bech32_naddr {
|
||||||
struct relays relays;
|
struct relays relays;
|
||||||
struct str_block identifier;
|
struct str_block identifier;
|
||||||
const u8 *pubkey;
|
const u8 *pubkey;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bech32_nrelay {
|
struct bech32_nrelay {
|
||||||
struct str_block relay;
|
struct str_block relay;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct nostr_bech32 {
|
typedef struct nostr_bech32 {
|
||||||
enum nostr_bech32_type type;
|
enum nostr_bech32_type type;
|
||||||
u8 *buffer; // holds strings and tlv stuff
|
u8 *buffer; // holds strings and tlv stuff
|
||||||
size_t buflen;
|
size_t buflen;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct bech32_note note;
|
struct bech32_note note;
|
||||||
struct bech32_npub npub;
|
struct bech32_npub npub;
|
||||||
struct bech32_nsec nsec;
|
struct bech32_nsec nsec;
|
||||||
struct bech32_nevent nevent;
|
struct bech32_nevent nevent;
|
||||||
struct bech32_nprofile nprofile;
|
struct bech32_nprofile nprofile;
|
||||||
struct bech32_naddr naddr;
|
struct bech32_naddr naddr;
|
||||||
struct bech32_nrelay nrelay;
|
struct bech32_nrelay nrelay;
|
||||||
} data;
|
} data;
|
||||||
} nostr_bech32_t;
|
} nostr_bech32_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user