lnsocket

A minimal C library for connecting to the lightning network
git clone git://jb55.com/lnsocket
Log | Files | Refs | Submodules | README | LICENSE

rpc.c (2319B)


      1 
      2 #include <stdlib.h>
      3 
      4 #include "lnsocket.h"
      5 #include "endian.h"
      6 #include "typedefs.h"
      7 #include "commando.h"
      8 
      9 #include <stdio.h>
     10 #include <assert.h>
     11 
     12 #include <sys/select.h>
     13 
     14 int usage()
     15 {
     16 	printf("lnrpc <nodeid> <ip/hostname> <method> <rune> [params (json string)]\n\n");
     17 	printf("currently supports commando for clightning, but potentially more rpc types in the future!\n");
     18 	return 0;
     19 }
     20 
     21 int main(int argc, const char *argv[])
     22 {
     23 	static u8 msgbuf[4096];
     24 	u8 *buf;
     25 	struct lnsocket *ln;
     26 	fd_set set;
     27 	struct timeval timeout = {0};
     28 
     29 	char *timeout_str;
     30 	u16 len, msgtype;
     31 	int ok = 1;
     32 	int socket, rv;
     33 	int verbose = getenv("VERBOSE") != 0;
     34 	//int verbose = 1;
     35 
     36 	timeout_str = getenv("LNRPC_TIMEOUT");
     37 	int timeout_ms = timeout_str ? atoi(timeout_str) : 5000;
     38 
     39 	timeout.tv_sec = timeout_ms / 1000;
     40 	timeout.tv_usec = (timeout_ms % 1000) * 1000;
     41 
     42 	FD_ZERO(&set); /* clear the set */
     43 
     44 	if (argc < 5)
     45 		return usage();
     46 
     47 	ln = lnsocket_create();
     48 	assert(ln);
     49 
     50 	lnsocket_genkey(ln);
     51 
     52 	const char *nodeid = argv[1];
     53 	const char *host = argv[2];
     54 	const char *method = argv[3];
     55 	const char *rune = argv[4];
     56 	const char *params = argc < 6 ? argv[5] : NULL;
     57 
     58 	if (!(ok = lnsocket_connect(ln, nodeid, host)))
     59 		goto done;
     60 
     61 	if (!(ok = lnsocket_fd(ln, &socket)))
     62 		goto done;
     63 
     64 	FD_SET(socket, &set); /* add our file descriptor to the set */
     65 
     66 	if (!(ok = lnsocket_perform_init(ln)))
     67 		goto done;
     68 
     69 	if (verbose)
     70 		fprintf(stderr, "init success\n");
     71 
     72 	if (!(ok = len = commando_make_rpc_msg(method, params, rune, 1, msgbuf, sizeof(msgbuf))))
     73 		goto done;
     74 
     75 	if (!(ok = lnsocket_write(ln, msgbuf, len)))
     76 		goto done;
     77 
     78 	if (verbose)
     79 		fprintf(stderr, "waiting for response...\n");
     80 
     81 	while (1) {
     82 		rv = select(socket + 1, &set, NULL, NULL, &timeout);
     83 
     84 		if (rv == -1) {
     85 			perror("select");
     86 			ok = 0;
     87 			goto done;
     88 		} else if (rv == 0) {
     89 			fprintf(stderr, "error: rpc request timeout\n");
     90 			ok = 0;
     91 			goto done;
     92 		}
     93 
     94 		if (!(ok = lnsocket_recv(ln, &msgtype, &buf, &len)))
     95 			goto done;
     96 
     97 		switch (msgtype) {
     98 		case COMMANDO_REPLY_TERM:
     99 			printf("%.*s\n", len - 8, buf + 8);
    100 			goto done;
    101 		case COMMANDO_REPLY_CONTINUES:
    102 			printf("%.*s", len - 8, buf + 8);
    103 			continue;
    104 		default:
    105 			// ignore extra interleaved messages which can happen
    106 			continue;
    107 		}
    108 	}
    109 
    110 done:
    111 	lnsocket_print_errors(ln);
    112 	lnsocket_destroy(ln);
    113 	return !ok;
    114 }