with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java, open(sys.argv[3], "w") as out_c:
opaque_structs = set()
trait_structs = set()
+ unitary_enums = set()
var_is_arr_regex = re.compile("\(\*([A-za-z_]*)\)\[([0-9]*)\]")
var_ty_regex = re.compile("([A-za-z_0-9]*)(.*)")
fn_arg = fn_arg[6:].strip()
else:
ma = var_ty_regex.match(fn_arg)
- java_ty = "long"
- c_ty = "jlong"
- fn_ty_arg = "J"
- fn_arg = ma.group(2).strip()
- rust_obj = ma.group(1).strip()
- take_by_ptr = True
+ if ma.group(1).strip() in unitary_enums:
+ java_ty = ma.group(1).strip()
+ c_ty = "jclass"
+ fn_ty_arg = "Lorg/ldk/impl/bindings$" + ma.group(1).strip() + ";"
+ fn_arg = ma.group(2).strip()
+ rust_obj = ma.group(1).strip()
+ take_by_ptr = True
+ else:
+ java_ty = "long"
+ c_ty = "jlong"
+ fn_ty_arg = "J"
+ fn_arg = ma.group(2).strip()
+ rust_obj = ma.group(1).strip()
+ take_by_ptr = True
if fn_arg.startswith(" *") or fn_arg.startswith("*"):
fn_arg = fn_arg.replace("*", "").strip()
if ty_info.rust_obj is not None:
assert(ty_info.passed_as_ptr)
if not ty_info.is_ptr:
+ if ty_info.rust_obj in unitary_enums:
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv = " + ty_info.rust_obj + "_from_java(_env, " + ty_info.var_name + ");",
+ arg_conv_name = ty_info.var_name + "_conv",
+ ret_conv = ("jclass " + ty_info.var_name + "_conv = " + ty_info.rust_obj + "_to_java(_env, ", ");"),
+ ret_conv_name = ty_info.var_name + "_conv")
base_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv = *(" + ty_info.rust_obj + "*)" + ty_info.var_name + ";";
if ty_info.rust_obj in trait_structs:
if not is_free:
# We don't have a parameter name, and don't want one (cause we're returning)
if ty_info.rust_obj is not None:
if not ty_info.is_ptr:
+ if ty_info.rust_obj in unitary_enums:
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = ty_info.rust_obj + " ret = " + ty_info.rust_obj + "_from_java(_env, " + ty_info.var_name + ");",
+ arg_conv_name = "ret",
+ ret_conv = ("jclass ret = " + ty_info.rust_obj + "_to_java(_env, ", ");"), ret_conv_name = "ret")
if ty_info.rust_obj in opaque_structs:
# If we're returning a newly-allocated struct, we don't want Rust to ever
# free, instead relying on the Java GC to lose the ref. We undo this in
out_java.write("""package org.ldk.impl;
public class bindings {
+ static native void init(java.lang.Class c);
static {
System.loadLibrary(\"lightningjni\");
+ init(java.lang.Enum.class);
}
""")
out_c.write("#include <assert.h>\n")
out_c.write("#include <string.h>\n")
out_c.write("#include <stdatomic.h>\n\n")
+
+ out_c.write("jmethodID ordinal_meth = NULL;\n")
+ out_c.write("JNIEXPORT void Java_org_ldk_impl_bindings_init(JNIEnv * env, jclass _b, jclass enum_class) {\n")
+ out_c.write("\tordinal_meth = (*env)->GetMethodID(env, enum_class, \"ordinal\", \"()I\");\n")
+ out_c.write("\tassert(ordinal_meth != NULL);\n")
+ out_c.write("}\n\n")
+
if sys.argv[4] == "false":
out_c.write("#define MALLOC(a, _) malloc(a)\n")
out_c.write("#define FREE free\n\n")
out_c.write("}\n") # TODO: rm me
in_block_comment = False
- in_block_enum = False
- cur_block_struct = None
- in_block_union = False
+ cur_block_obj = None
fn_ptr_regex = re.compile("^extern const ([A-Za-z_0-9\* ]*) \(\*(.*)\)\((.*)\);$")
fn_ret_arr_regex = re.compile("(.*) \(\*(.*)\((.*)\)\)\[([0-9]*)\];$")
assert(line_indicates_trait_regex.match(" void *(*clone)(const void *this_arg);"))
line_field_var_regex = re.compile("^ ([A-Za-z_0-9]*) ([A-Za-z_0-9]*);$")
assert(line_field_var_regex.match(" LDKMessageSendEventsProvider MessageSendEventsProvider;"))
- struct_name_regex = re.compile("^typedef (struct|enum) (MUST_USE_STRUCT )?(LDK[A-Za-z_0-9]*) {$")
+ struct_name_regex = re.compile("^typedef (struct|enum|union) (MUST_USE_STRUCT )?(LDK[A-Za-z_0-9]*) {$")
assert(struct_name_regex.match("typedef struct LDKCVecTempl_u8 {"))
assert(struct_name_regex.match("typedef enum LDKNetwork {"))
#out_java.write("\t" + line)
if line.endswith("*/\n"):
in_block_comment = False
- elif cur_block_struct is not None:
- cur_block_struct = cur_block_struct + line
+ elif cur_block_obj is not None:
+ cur_block_obj = cur_block_obj + line
if line.startswith("} "):
field_lines = []
struct_name = None
- struct_lines = cur_block_struct.split("\n")
+ obj_lines = cur_block_obj.split("\n")
is_opaque = False
+ is_unitary_enum = False
+ is_union_enum = False
+ is_union = False
trait_fn_lines = []
field_var_lines = []
- for idx, struct_line in enumerate(struct_lines):
+ for idx, struct_line in enumerate(obj_lines):
if struct_line.strip().startswith("/*"):
in_block_comment = True
if in_block_comment:
else:
struct_name_match = struct_name_regex.match(struct_line)
if struct_name_match is not None:
- struct_name = struct_name_match.group(2)
+ struct_name = struct_name_match.group(3)
+ if struct_name_match.group(1) == "enum":
+ if not struct_name.endswith("_Tag"):
+ is_unitary_enum = True
+ else:
+ is_union_enum = True
+ elif struct_name_match.group(1) == "union":
+ is_union = True
if line_indicates_opaque_regex.match(struct_line):
is_opaque = True
trait_fn_match = line_indicates_trait_regex.match(struct_line)
field_lines.append(struct_line)
assert(struct_name is not None)
- assert(len(trait_fn_lines) == 0 or not is_opaque)
+ assert(len(trait_fn_lines) == 0 or not (is_opaque or is_unitary_enum or is_union_enum or is_union))
+ assert(not is_opaque or not (len(trait_fn_lines) != 0 or is_unitary_enum or is_union_enum or is_union))
+ assert(not is_unitary_enum or not (len(trait_fn_lines) != 0 or is_opaque or is_union_enum or is_union))
+ assert(not is_union_enum or not (len(trait_fn_lines) != 0 or is_unitary_enum or is_opaque or is_union))
+ assert(not is_union or not (len(trait_fn_lines) != 0 or is_unitary_enum or is_union_enum or is_opaque))
if is_opaque:
opaque_structs.add(struct_name)
- if len(trait_fn_lines) > 0:
+ elif is_unitary_enum:
+ unitary_enums.add(struct_name)
+ out_c.write("static inline " + struct_name + " " + struct_name + "_from_java(JNIEnv *env, jclass val) {\n")
+ out_c.write("\tswitch ((*env)->CallIntMethod(env, val, ordinal_meth)) {\n")
+ ord_v = 0
+ for idx, struct_line in enumerate(field_lines):
+ if idx == 0:
+ out_java.write("\tpublic enum " + struct_name + " {\n")
+ elif idx == len(field_lines) - 3:
+ assert(struct_line.endswith("_Sentinel,"))
+ elif idx == len(field_lines) - 2:
+ out_java.write("\t}\n")
+ elif idx == len(field_lines) - 1:
+ assert(struct_line == "")
+ else:
+ out_java.write("\t" + struct_line + "\n")
+ out_c.write("\t\tcase %d: return %s;\n" % (ord_v, struct_line.strip().strip(",")))
+ ord_v = ord_v + 1
+ out_c.write("\t}\n")
+ out_c.write("\tassert(false);\n")
+ out_c.write("}\n")
+
+ ord_v = 0
+ out_c.write("static inline jclass " + struct_name + "_to_java(JNIEnv *env, " + struct_name + " val) {\n")
+ out_c.write("\t// TODO: This is pretty inefficient, we really need to cache the field IDs and class\n")
+ out_c.write("\tjclass enum_class = (*env)->FindClass(env, \"Lorg/ldk/impl/bindings$" + struct_name + ";\");\n")
+ out_c.write("\tassert(enum_class != NULL);\n")
+ out_c.write("\tswitch (val) {\n")
+ for idx, struct_line in enumerate(field_lines):
+ if idx > 0 and idx < len(field_lines) - 3:
+ variant = struct_line.strip().strip(",")
+ out_c.write("\t\tcase " + variant + ": {\n")
+ out_c.write("\t\t\tjfieldID field = (*env)->GetStaticFieldID(env, enum_class, \"" + variant + "\", \"Lorg/ldk/impl/bindings$" + struct_name + ";\");\n")
+ out_c.write("\t\t\tassert(field != NULL);\n")
+ out_c.write("\t\t\treturn (*env)->GetStaticObjectField(env, enum_class, field);\n")
+ out_c.write("\t\t}\n")
+ ord_v = ord_v + 1
+ out_c.write("\t\tdefault: assert(false);\n")
+ out_c.write("\t}\n")
+ out_c.write("}\n\n")
+ elif len(trait_fn_lines) > 0:
trait_structs.add(struct_name)
map_trait(struct_name, field_var_lines, trait_fn_lines)
- #out_java.write("/* " + "\n".join(field_lines) + "*/\n")
- cur_block_struct = None
- elif in_block_union:
- if line.startswith("} "):
- in_block_union = False
- elif in_block_enum:
- if line.startswith("} "):
- in_block_enum = False
+ cur_block_obj = None
else:
fn_ptr = fn_ptr_regex.match(line)
fn_ret_arr = fn_ret_arr_regex.match(line)
if not line.endswith("*/\n"):
in_block_comment = True
elif line.startswith("typedef enum "):
- in_block_enum = True
+ cur_block_obj = line
elif line.startswith("typedef struct "):
- cur_block_struct = line
+ cur_block_obj = line
elif line.startswith("typedef union "):
- in_block_union = True
+ cur_block_obj = line
elif line.startswith("typedef "):
pass
elif fn_ptr is not None:
package org.ldk.impl;
public class bindings {
+ static native void init(java.lang.Class c);
static {
System.loadLibrary("lightningjni");
+ init(java.lang.Enum.class);
}
public static native long LDKSecretKey_new();
+ public enum LDKChainError {
+ LDKChainError_NotSupported,
+ LDKChainError_NotWatched,
+ LDKChainError_UnknownTx,
+ }
+ public enum LDKChannelMonitorUpdateErr {
+ LDKChannelMonitorUpdateErr_TemporaryFailure,
+ LDKChannelMonitorUpdateErr_PermanentFailure,
+ }
+ public enum LDKConfirmationTarget {
+ LDKConfirmationTarget_Background,
+ LDKConfirmationTarget_Normal,
+ LDKConfirmationTarget_HighPriority,
+ }
+ public enum LDKLevel {
+ LDKLevel_Off,
+ LDKLevel_Error,
+ LDKLevel_Warn,
+ LDKLevel_Info,
+ LDKLevel_Debug,
+ LDKLevel_Trace,
+ }
+ public enum LDKNetwork {
+ LDKNetwork_Bitcoin,
+ LDKNetwork_Testnet,
+ LDKNetwork_Regtest,
+ }
+ public enum LDKSecp256k1Error {
+ LDKSecp256k1Error_IncorrectSignature,
+ LDKSecp256k1Error_InvalidMessage,
+ LDKSecp256k1Error_InvalidPublicKey,
+ LDKSecp256k1Error_InvalidSignature,
+ LDKSecp256k1Error_InvalidSecretKey,
+ LDKSecp256k1Error_InvalidRecoveryId,
+ LDKSecp256k1Error_InvalidTweak,
+ LDKSecp256k1Error_NotEnoughMemory,
+ LDKSecp256k1Error_CallbackPanicked,
+ }
public interface LDKMessageSendEventsProvider {
long get_and_clear_pending_msg_events();
}
}
public static native long LDKChainListener_new(LDKChainListener impl);
public interface LDKFeeEstimator {
- int get_est_sat_per_1000_weight(long confirmation_target);
+ int get_est_sat_per_1000_weight(LDKConfirmationTarget confirmation_target);
}
public static native long LDKFeeEstimator_new(LDKFeeEstimator impl);
public interface LDKChannelKeys {
/// extern const void (*C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free)(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ);
public static native void C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free(long arg);
/// extern const LDKCResult_C2Tuple_Scriptu64ZChainErrorZ (*CResult_C2Tuple_Scriptu64ZChainErrorZ_err)(LDKChainError);
- public static native long CResult_C2Tuple_Scriptu64ZChainErrorZ_err(long arg);
+ public static native long CResult_C2Tuple_Scriptu64ZChainErrorZ_err(LDKChainError arg);
/// extern const void (*CResult_C2Tuple_Scriptu64ZChainErrorZ_free)(LDKCResult_C2Tuple_Scriptu64ZChainErrorZ);
public static native void CResult_C2Tuple_Scriptu64ZChainErrorZ_free(long arg);
/// extern const LDKCResult_C2Tuple_Scriptu64ZChainErrorZ (*CResult_C2Tuple_Scriptu64ZChainErrorZ_ok)(LDKC2Tuple_Scriptu64Z);
/// extern const void (*CResult_NoneAPIErrorZ_free)(LDKCResult_NoneAPIErrorZ);
public static native void CResult_NoneAPIErrorZ_free(long arg);
/// extern const LDKCResult_NoneChannelMonitorUpdateErrZ (*CResult_NoneChannelMonitorUpdateErrZ_err)(LDKChannelMonitorUpdateErr);
- public static native long CResult_NoneChannelMonitorUpdateErrZ_err(long arg);
+ public static native long CResult_NoneChannelMonitorUpdateErrZ_err(LDKChannelMonitorUpdateErr arg);
/// extern const void (*CResult_NoneChannelMonitorUpdateErrZ_free)(LDKCResult_NoneChannelMonitorUpdateErrZ);
public static native void CResult_NoneChannelMonitorUpdateErrZ_free(long arg);
/// extern const LDKCResult_NoneMonitorUpdateErrorZ (*CResult_NoneMonitorUpdateErrorZ_err)(LDKMonitorUpdateError);
/// extern const LDKCResult_SignatureNoneZ (*CResult_SignatureNoneZ_ok)(LDKSignature);
public static native long CResult_SignatureNoneZ_ok(long arg);
/// extern const LDKCResult_TxCreationKeysSecpErrorZ (*CResult_TxCreationKeysSecpErrorZ_err)(LDKSecp256k1Error);
- public static native long CResult_TxCreationKeysSecpErrorZ_err(long arg);
+ public static native long CResult_TxCreationKeysSecpErrorZ_err(LDKSecp256k1Error arg);
/// extern const void (*CResult_TxCreationKeysSecpErrorZ_free)(LDKCResult_TxCreationKeysSecpErrorZ);
public static native void CResult_TxCreationKeysSecpErrorZ_free(long arg);
/// extern const LDKCResult_TxCreationKeysSecpErrorZ (*CResult_TxCreationKeysSecpErrorZ_ok)(LDKTxCreationKeys);
/// void APIError_free(LDKAPIError this_ptr);
public static native void APIError_free(long this_ptr);
/// MUST_USE_RES LDKLevel Level_max(void);
- public static native long Level_max();
+ public static native LDKLevel Level_max();
/// void Logger_free(LDKLogger this_ptr);
public static native void Logger_free(long this_ptr);
/// void ChannelHandshakeConfig_free(LDKChannelHandshakeConfig this_ptr);
/// LDKChainWatchInterface ChainWatchInterfaceUtil_as_ChainWatchInterface(const LDKChainWatchInterfaceUtil *this_arg);
public static native long ChainWatchInterfaceUtil_as_ChainWatchInterface(long this_arg);
/// MUST_USE_RES LDKChainWatchInterfaceUtil ChainWatchInterfaceUtil_new(LDKNetwork network);
- public static native long ChainWatchInterfaceUtil_new(long network);
+ public static native long ChainWatchInterfaceUtil_new(LDKNetwork network);
/// MUST_USE_RES bool ChainWatchInterfaceUtil_does_match_tx(const LDKChainWatchInterfaceUtil *this_arg, LDKTransaction tx);
public static native boolean ChainWatchInterfaceUtil_does_match_tx(long this_arg, long tx);
/// void OutPoint_free(LDKOutPoint this_ptr);
/// void KeysManager_free(LDKKeysManager this_ptr);
public static native void KeysManager_free(long this_ptr);
/// MUST_USE_RES LDKKeysManager KeysManager_new(const uint8_t (*seed)[32], LDKNetwork network, uint64_t starting_time_secs, uint32_t starting_time_nanos);
- public static native long KeysManager_new(byte[] seed, long network, long starting_time_secs, int starting_time_nanos);
+ public static native long KeysManager_new(byte[] seed, LDKNetwork network, long starting_time_secs, int starting_time_nanos);
/// MUST_USE_RES LDKInMemoryChannelKeys KeysManager_derive_channel_keys(const LDKKeysManager *this_arg, uint64_t channel_value_satoshis, uint64_t params_1, uint64_t params_2);
public static native long KeysManager_derive_channel_keys(long this_arg, long channel_value_satoshis, long params_1, long params_2);
/// LDKKeysInterface KeysManager_as_KeysInterface(const LDKKeysManager *this_arg);
/// void PaymentSendFailure_free(LDKPaymentSendFailure this_ptr);
public static native void PaymentSendFailure_free(long this_ptr);
/// MUST_USE_RES LDKChannelManager ChannelManager_new(LDKNetwork network, LDKFeeEstimator fee_est, LDKManyChannelMonitor monitor, LDKBroadcasterInterface tx_broadcaster, LDKLogger logger, LDKKeysInterface keys_manager, LDKUserConfig config, uintptr_t current_blockchain_height);
- public static native long ChannelManager_new(long network, long fee_est, long monitor, long tx_broadcaster, long logger, long keys_manager, long config, long current_blockchain_height);
+ public static native long ChannelManager_new(LDKNetwork network, long fee_est, long monitor, long tx_broadcaster, long logger, long keys_manager, long config, long current_blockchain_height);
/// MUST_USE_RES LDKCResult_NoneAPIErrorZ ChannelManager_create_channel(const LDKChannelManager *this_arg, LDKPublicKey their_network_key, uint64_t channel_value_satoshis, uint64_t push_msat, uint64_t user_id, LDKUserConfig override_config);
public static native long ChannelManager_create_channel(long this_arg, long their_network_key, long channel_value_satoshis, long push_msat, long user_id, long override_config);
/// MUST_USE_RES LDKCVec_ChannelDetailsZ ChannelManager_list_channels(const LDKChannelManager *this_arg);
#include <string.h>
#include <stdatomic.h>
+jmethodID ordinal_meth = NULL;
+JNIEXPORT void Java_org_ldk_impl_bindings_init(JNIEnv * env, jclass _b, jclass enum_class) {
+ ordinal_meth = (*env)->GetMethodID(env, enum_class, "ordinal", "()I");
+ assert(ordinal_meth != NULL);
+}
+
#include <threads.h>
static mtx_t allocation_mtx;
LDKSecretKey* key = (LDKSecretKey*)MALLOC(sizeof(LDKSecretKey), "LDKSecretKey");
return (long)key;
}
+static inline LDKChainError LDKChainError_from_java(JNIEnv *env, jclass val) {
+ switch ((*env)->CallIntMethod(env, val, ordinal_meth)) {
+ case 0: return LDKChainError_NotSupported;
+ case 1: return LDKChainError_NotWatched;
+ case 2: return LDKChainError_UnknownTx;
+ }
+ assert(false);
+}
+static inline jclass LDKChainError_to_java(JNIEnv *env, LDKChainError val) {
+ // TODO: This is pretty inefficient, we really need to cache the field IDs and class
+ jclass enum_class = (*env)->FindClass(env, "Lorg/ldk/impl/bindings$LDKChainError;");
+ assert(enum_class != NULL);
+ switch (val) {
+ case LDKChainError_NotSupported: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKChainError_NotSupported", "Lorg/ldk/impl/bindings$LDKChainError;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKChainError_NotWatched: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKChainError_NotWatched", "Lorg/ldk/impl/bindings$LDKChainError;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKChainError_UnknownTx: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKChainError_UnknownTx", "Lorg/ldk/impl/bindings$LDKChainError;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ default: assert(false);
+ }
+}
+
+static inline LDKChannelMonitorUpdateErr LDKChannelMonitorUpdateErr_from_java(JNIEnv *env, jclass val) {
+ switch ((*env)->CallIntMethod(env, val, ordinal_meth)) {
+ case 0: return LDKChannelMonitorUpdateErr_TemporaryFailure;
+ case 1: return LDKChannelMonitorUpdateErr_PermanentFailure;
+ }
+ assert(false);
+}
+static inline jclass LDKChannelMonitorUpdateErr_to_java(JNIEnv *env, LDKChannelMonitorUpdateErr val) {
+ // TODO: This is pretty inefficient, we really need to cache the field IDs and class
+ jclass enum_class = (*env)->FindClass(env, "Lorg/ldk/impl/bindings$LDKChannelMonitorUpdateErr;");
+ assert(enum_class != NULL);
+ switch (val) {
+ case LDKChannelMonitorUpdateErr_TemporaryFailure: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKChannelMonitorUpdateErr_TemporaryFailure", "Lorg/ldk/impl/bindings$LDKChannelMonitorUpdateErr;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKChannelMonitorUpdateErr_PermanentFailure: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKChannelMonitorUpdateErr_PermanentFailure", "Lorg/ldk/impl/bindings$LDKChannelMonitorUpdateErr;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ default: assert(false);
+ }
+}
+
+static inline LDKConfirmationTarget LDKConfirmationTarget_from_java(JNIEnv *env, jclass val) {
+ switch ((*env)->CallIntMethod(env, val, ordinal_meth)) {
+ case 0: return LDKConfirmationTarget_Background;
+ case 1: return LDKConfirmationTarget_Normal;
+ case 2: return LDKConfirmationTarget_HighPriority;
+ }
+ assert(false);
+}
+static inline jclass LDKConfirmationTarget_to_java(JNIEnv *env, LDKConfirmationTarget val) {
+ // TODO: This is pretty inefficient, we really need to cache the field IDs and class
+ jclass enum_class = (*env)->FindClass(env, "Lorg/ldk/impl/bindings$LDKConfirmationTarget;");
+ assert(enum_class != NULL);
+ switch (val) {
+ case LDKConfirmationTarget_Background: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKConfirmationTarget_Background", "Lorg/ldk/impl/bindings$LDKConfirmationTarget;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKConfirmationTarget_Normal: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKConfirmationTarget_Normal", "Lorg/ldk/impl/bindings$LDKConfirmationTarget;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKConfirmationTarget_HighPriority: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKConfirmationTarget_HighPriority", "Lorg/ldk/impl/bindings$LDKConfirmationTarget;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ default: assert(false);
+ }
+}
+
+static inline LDKLevel LDKLevel_from_java(JNIEnv *env, jclass val) {
+ switch ((*env)->CallIntMethod(env, val, ordinal_meth)) {
+ case 0: return LDKLevel_Off;
+ case 1: return LDKLevel_Error;
+ case 2: return LDKLevel_Warn;
+ case 3: return LDKLevel_Info;
+ case 4: return LDKLevel_Debug;
+ case 5: return LDKLevel_Trace;
+ }
+ assert(false);
+}
+static inline jclass LDKLevel_to_java(JNIEnv *env, LDKLevel val) {
+ // TODO: This is pretty inefficient, we really need to cache the field IDs and class
+ jclass enum_class = (*env)->FindClass(env, "Lorg/ldk/impl/bindings$LDKLevel;");
+ assert(enum_class != NULL);
+ switch (val) {
+ case LDKLevel_Off: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKLevel_Off", "Lorg/ldk/impl/bindings$LDKLevel;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKLevel_Error: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKLevel_Error", "Lorg/ldk/impl/bindings$LDKLevel;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKLevel_Warn: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKLevel_Warn", "Lorg/ldk/impl/bindings$LDKLevel;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKLevel_Info: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKLevel_Info", "Lorg/ldk/impl/bindings$LDKLevel;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKLevel_Debug: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKLevel_Debug", "Lorg/ldk/impl/bindings$LDKLevel;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKLevel_Trace: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKLevel_Trace", "Lorg/ldk/impl/bindings$LDKLevel;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ default: assert(false);
+ }
+}
+
+static inline LDKNetwork LDKNetwork_from_java(JNIEnv *env, jclass val) {
+ switch ((*env)->CallIntMethod(env, val, ordinal_meth)) {
+ case 0: return LDKNetwork_Bitcoin;
+ case 1: return LDKNetwork_Testnet;
+ case 2: return LDKNetwork_Regtest;
+ }
+ assert(false);
+}
+static inline jclass LDKNetwork_to_java(JNIEnv *env, LDKNetwork val) {
+ // TODO: This is pretty inefficient, we really need to cache the field IDs and class
+ jclass enum_class = (*env)->FindClass(env, "Lorg/ldk/impl/bindings$LDKNetwork;");
+ assert(enum_class != NULL);
+ switch (val) {
+ case LDKNetwork_Bitcoin: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKNetwork_Bitcoin", "Lorg/ldk/impl/bindings$LDKNetwork;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKNetwork_Testnet: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKNetwork_Testnet", "Lorg/ldk/impl/bindings$LDKNetwork;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKNetwork_Regtest: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKNetwork_Regtest", "Lorg/ldk/impl/bindings$LDKNetwork;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ default: assert(false);
+ }
+}
+
+static inline LDKSecp256k1Error LDKSecp256k1Error_from_java(JNIEnv *env, jclass val) {
+ switch ((*env)->CallIntMethod(env, val, ordinal_meth)) {
+ case 0: return LDKSecp256k1Error_IncorrectSignature;
+ case 1: return LDKSecp256k1Error_InvalidMessage;
+ case 2: return LDKSecp256k1Error_InvalidPublicKey;
+ case 3: return LDKSecp256k1Error_InvalidSignature;
+ case 4: return LDKSecp256k1Error_InvalidSecretKey;
+ case 5: return LDKSecp256k1Error_InvalidRecoveryId;
+ case 6: return LDKSecp256k1Error_InvalidTweak;
+ case 7: return LDKSecp256k1Error_NotEnoughMemory;
+ case 8: return LDKSecp256k1Error_CallbackPanicked;
+ }
+ assert(false);
+}
+static inline jclass LDKSecp256k1Error_to_java(JNIEnv *env, LDKSecp256k1Error val) {
+ // TODO: This is pretty inefficient, we really need to cache the field IDs and class
+ jclass enum_class = (*env)->FindClass(env, "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(enum_class != NULL);
+ switch (val) {
+ case LDKSecp256k1Error_IncorrectSignature: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKSecp256k1Error_IncorrectSignature", "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKSecp256k1Error_InvalidMessage: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKSecp256k1Error_InvalidMessage", "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKSecp256k1Error_InvalidPublicKey: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKSecp256k1Error_InvalidPublicKey", "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKSecp256k1Error_InvalidSignature: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKSecp256k1Error_InvalidSignature", "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKSecp256k1Error_InvalidSecretKey: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKSecp256k1Error_InvalidSecretKey", "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKSecp256k1Error_InvalidRecoveryId: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKSecp256k1Error_InvalidRecoveryId", "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKSecp256k1Error_InvalidTweak: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKSecp256k1Error_InvalidTweak", "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKSecp256k1Error_NotEnoughMemory: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKSecp256k1Error_NotEnoughMemory", "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ case LDKSecp256k1Error_CallbackPanicked: {
+ jfieldID field = (*env)->GetStaticFieldID(env, enum_class, "LDKSecp256k1Error_CallbackPanicked", "Lorg/ldk/impl/bindings$LDKSecp256k1Error;");
+ assert(field != NULL);
+ return (*env)->GetStaticObjectField(env, enum_class, field);
+ }
+ default: assert(false);
+ }
+}
+
typedef struct LDKMessageSendEventsProvider_JCalls {
atomic_size_t refcnt;
JNIEnv *env;
} LDKFeeEstimator_JCalls;
uint32_t get_est_sat_per_1000_weight_jcall(const void* this_arg, LDKConfirmationTarget confirmation_target) {
LDKFeeEstimator_JCalls *j_calls = (LDKFeeEstimator_JCalls*) this_arg;
- return (*j_calls->env)->CallIntMethod(j_calls->env, j_calls->o, j_calls->get_est_sat_per_1000_weight_meth, confirmation_target);
+ jclass confirmation_target_conv = LDKConfirmationTarget_to_java(j_calls->env, confirmation_target);
+ return (*j_calls->env)->CallIntMethod(j_calls->env, j_calls->o, j_calls->get_est_sat_per_1000_weight_meth, confirmation_target_conv);
}
static void LDKFeeEstimator_JCalls_free(void* this_arg) {
LDKFeeEstimator_JCalls *j_calls = (LDKFeeEstimator_JCalls*) this_arg;
atomic_init(&calls->refcnt, 1);
calls->env = env;
calls->o = (*env)->NewGlobalRef(env, o);
- calls->get_est_sat_per_1000_weight_meth = (*env)->GetMethodID(env, c, "get_est_sat_per_1000_weight", "(J)I");
+ calls->get_est_sat_per_1000_weight_meth = (*env)->GetMethodID(env, c, "get_est_sat_per_1000_weight", "(Lorg/ldk/impl/bindings$LDKConfirmationTarget;)I");
assert(calls->get_est_sat_per_1000_weight_meth != NULL);
LDKFeeEstimator ret = {
return C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free(arg_conv);
}
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1Scriptu64ZChainErrorZ_1err(JNIEnv * _env, jclass _b, jlong arg) {
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1Scriptu64ZChainErrorZ_1err(JNIEnv * _env, jclass _b, jclass arg) {
LDKChainError arg_conv = *(LDKChainError*)arg;
FREE((void*)arg);
LDKCResult_C2Tuple_Scriptu64ZChainErrorZ* ret = MALLOC(sizeof(LDKCResult_C2Tuple_Scriptu64ZChainErrorZ), "LDKCResult_C2Tuple_Scriptu64ZChainErrorZ");
return CResult_NoneAPIErrorZ_free(arg_conv);
}
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1NoneChannelMonitorUpdateErrZ_1err(JNIEnv * _env, jclass _b, jlong arg) {
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1NoneChannelMonitorUpdateErrZ_1err(JNIEnv * _env, jclass _b, jclass arg) {
LDKChannelMonitorUpdateErr arg_conv = *(LDKChannelMonitorUpdateErr*)arg;
FREE((void*)arg);
LDKCResult_NoneChannelMonitorUpdateErrZ* ret = MALLOC(sizeof(LDKCResult_NoneChannelMonitorUpdateErrZ), "LDKCResult_NoneChannelMonitorUpdateErrZ");
return (long)ret;
}
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1TxCreationKeysSecpErrorZ_1err(JNIEnv * _env, jclass _b, jlong arg) {
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1TxCreationKeysSecpErrorZ_1err(JNIEnv * _env, jclass _b, jclass arg) {
LDKSecp256k1Error arg_conv = *(LDKSecp256k1Error*)arg;
FREE((void*)arg);
LDKCResult_TxCreationKeysSecpErrorZ* ret = MALLOC(sizeof(LDKCResult_TxCreationKeysSecpErrorZ), "LDKCResult_TxCreationKeysSecpErrorZ");
return APIError_free(this_ptr_conv);
}
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Level_1max(JNIEnv * _env, jclass _b) {
- LDKLevel* ret = MALLOC(sizeof(LDKLevel), "LDKLevel");
- *ret = Level_max();
- return (long)ret;
+JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_Level_1max(JNIEnv * _env, jclass _b) {
+ jclass ret = LDKLevel_to_java(_env, Level_max());
+ return ret;
}
JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Logger_1free(JNIEnv * _env, jclass _b, jlong this_ptr) {
return (long)ret;
}
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChainWatchInterfaceUtil_1new(JNIEnv * _env, jclass _b, jlong network) {
- LDKNetwork network_conv = *(LDKNetwork*)network;
- FREE((void*)network);
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChainWatchInterfaceUtil_1new(JNIEnv * _env, jclass _b, jclass network) {
+ LDKNetwork network_conv = LDKNetwork_from_java(_env, network);
LDKChainWatchInterfaceUtil* ret = MALLOC(sizeof(LDKChainWatchInterfaceUtil), "LDKChainWatchInterfaceUtil");
*ret = ChainWatchInterfaceUtil_new(network_conv);
assert(!ret->_underlying_ref);
return KeysManager_free(this_ptr_conv);
}
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_KeysManager_1new(JNIEnv * _env, jclass _b, jbyteArray seed, jlong network, jlong starting_time_secs, jint starting_time_nanos) {
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_KeysManager_1new(JNIEnv * _env, jclass _b, jbyteArray seed, jclass network, jlong starting_time_secs, jint starting_time_nanos) {
unsigned char seed_arr[32];
(*_env)->GetByteArrayRegion (_env, seed, 0, 32, seed_arr);
unsigned char (*seed_ref)[32] = &seed_arr;
- LDKNetwork network_conv = *(LDKNetwork*)network;
- FREE((void*)network);
+ LDKNetwork network_conv = LDKNetwork_from_java(_env, network);
LDKKeysManager* ret = MALLOC(sizeof(LDKKeysManager), "LDKKeysManager");
*ret = KeysManager_new(seed_ref, network_conv, starting_time_secs, starting_time_nanos);
assert(!ret->_underlying_ref);
return PaymentSendFailure_free(this_ptr_conv);
}
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChannelManager_1new(JNIEnv * _env, jclass _b, jlong network, jlong fee_est, jlong monitor, jlong tx_broadcaster, jlong logger, jlong keys_manager, jlong config, jlong current_blockchain_height) {
- LDKNetwork network_conv = *(LDKNetwork*)network;
- FREE((void*)network);
+JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChannelManager_1new(JNIEnv * _env, jclass _b, jclass network, jlong fee_est, jlong monitor, jlong tx_broadcaster, jlong logger, jlong keys_manager, jlong config, jlong current_blockchain_height) {
+ LDKNetwork network_conv = LDKNetwork_from_java(_env, network);
LDKFeeEstimator fee_est_conv = *(LDKFeeEstimator*)fee_est;
LDKFeeEstimator_JCalls_clone(fee_est_conv.this_arg);
LDKManyChannelMonitor monitor_conv = *(LDKManyChannelMonitor*)monitor;
#ifdef __cplusplus
extern "C" {
#endif
+/*
+ * Class: org_ldk_impl_bindings
+ * Method: init
+ * Signature: (Ljava/lang/Class;)V
+ */
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_init
+ (JNIEnv *, jclass, jclass);
+
/*
* Class: org_ldk_impl_bindings
* Method: LDKSecretKey_new
/*
* Class: org_ldk_impl_bindings
* Method: CResult_C2Tuple_Scriptu64ZChainErrorZ_err
- * Signature: (J)J
+ * Signature: (Lorg/ldk/impl/bindings/LDKChainError;)J
*/
JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1Scriptu64ZChainErrorZ_1err
- (JNIEnv *, jclass, jlong);
+ (JNIEnv *, jclass, jobject);
/*
* Class: org_ldk_impl_bindings
/*
* Class: org_ldk_impl_bindings
* Method: CResult_NoneChannelMonitorUpdateErrZ_err
- * Signature: (J)J
+ * Signature: (Lorg/ldk/impl/bindings/LDKChannelMonitorUpdateErr;)J
*/
JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1NoneChannelMonitorUpdateErrZ_1err
- (JNIEnv *, jclass, jlong);
+ (JNIEnv *, jclass, jobject);
/*
* Class: org_ldk_impl_bindings
/*
* Class: org_ldk_impl_bindings
* Method: CResult_TxCreationKeysSecpErrorZ_err
- * Signature: (J)J
+ * Signature: (Lorg/ldk/impl/bindings/LDKSecp256k1Error;)J
*/
JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_CResult_1TxCreationKeysSecpErrorZ_1err
- (JNIEnv *, jclass, jlong);
+ (JNIEnv *, jclass, jobject);
/*
* Class: org_ldk_impl_bindings
/*
* Class: org_ldk_impl_bindings
* Method: Level_max
- * Signature: ()J
+ * Signature: ()Lorg/ldk/impl/bindings/LDKLevel;
*/
-JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_Level_1max
+JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_Level_1max
(JNIEnv *, jclass);
/*
/*
* Class: org_ldk_impl_bindings
* Method: ChainWatchInterfaceUtil_new
- * Signature: (J)J
+ * Signature: (Lorg/ldk/impl/bindings/LDKNetwork;)J
*/
JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChainWatchInterfaceUtil_1new
- (JNIEnv *, jclass, jlong);
+ (JNIEnv *, jclass, jobject);
/*
* Class: org_ldk_impl_bindings
/*
* Class: org_ldk_impl_bindings
* Method: KeysManager_new
- * Signature: ([BJJI)J
+ * Signature: ([BLorg/ldk/impl/bindings/LDKNetwork;JI)J
*/
JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_KeysManager_1new
- (JNIEnv *, jclass, jbyteArray, jlong, jlong, jint);
+ (JNIEnv *, jclass, jbyteArray, jobject, jlong, jint);
/*
* Class: org_ldk_impl_bindings
/*
* Class: org_ldk_impl_bindings
* Method: ChannelManager_new
- * Signature: (JJJJJJJJ)J
+ * Signature: (Lorg/ldk/impl/bindings/LDKNetwork;JJJJJJJ)J
*/
JNIEXPORT jlong JNICALL Java_org_ldk_impl_bindings_ChannelManager_1new
- (JNIEnv *, jclass, jlong, jlong, jlong, jlong, jlong, jlong, jlong, jlong);
+ (JNIEnv *, jclass, jobject, jlong, jlong, jlong, jlong, jlong, jlong, jlong);
/*
* Class: org_ldk_impl_bindings
long peer_manager = bindings.PeerManager_new(message_handler, our_node_secret, random_data, logger);
+ // Test Level_max() since its the only place we create a java object from a Rust-returned enum.
+ assert bindings.Level_max() == bindings.LDKLevel.LDKLevel_Trace;
+
// Note that we can't rely on finalizer order, so don't bother trying to rely on it here
bindings.Logger_free(logger);
bindings.ChannelMessageHandler_free(chan_handler);