Skip to content

Commit

Permalink
feat: node signing
Browse files Browse the repository at this point in the history
  • Loading branch information
Jasonvdb committed Sep 19, 2023
1 parent 6f053a4 commit 495277a
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 3 deletions.
15 changes: 15 additions & 0 deletions example/Dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,21 @@ const Dev = (): ReactElement => {
setMessage('Node Restarted');
}}
/>
<Button
title={'Sign message'}
onPress={async (): Promise<void> => {
setMessage('Signing...');
const res = await ldk.nodeSign({
message: 'Hello Bitcoin',
});
if (res.isErr()) {
setMessage(res.error.message);
return;
}

setMessage(res.value);
}}
/>
</View>
</ScrollView>

Expand Down
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ PODS:
- React-jsinspector (0.70.6)
- React-logger (0.70.6):
- glog
- react-native-ldk (0.0.106):
- react-native-ldk (0.0.109):
- React
- react-native-randombytes (3.6.1):
- React-Core
Expand Down Expand Up @@ -593,7 +593,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: b4a65947391c658450151275aa406f2b8263178f
React-jsinspector: 60769e5a0a6d4b32294a2456077f59d0266f9a8b
React-logger: 1623c216abaa88974afce404dc8f479406bbc3a0
react-native-ldk: 9cbe6586e65697322126c6475547a55e2c12bf1c
react-native-ldk: 3c1cd457a2372ef3eda9fbe144f4cdf6bc1fd6c3
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-tcp-socket: c1b7297619616b4c9caae6889bcb0aba78086989
React-perflogger: 8c79399b0500a30ee8152d0f9f11beae7fc36595
Expand Down
1 change: 1 addition & 0 deletions example/ldk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export const setupLdk = async (
highPriority: 10,
normal: 5,
background: 1,
mempoolMinimum: 1,
}),
getTransactionData,
getTransactionPosition,
Expand Down
18 changes: 18 additions & 0 deletions lib/android/src/main/java/com/reactnativeldk/LdkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import org.ldk.enums.Currency
import org.ldk.enums.Network
import org.ldk.impl.bindings.get_ldk_c_bindings_version
import org.ldk.impl.bindings.get_ldk_version
import org.ldk.impl.bindings.sign
import org.ldk.structs.*
import org.ldk.structs.Result_Bolt11InvoiceParseOrSemanticErrorZ.Result_Bolt11InvoiceParseOrSemanticErrorZ_OK
import org.ldk.structs.Result_Bolt11InvoiceSignOrCreationErrorZ.Result_Bolt11InvoiceSignOrCreationErrorZ_OK
import org.ldk.structs.Result_PaymentIdPaymentErrorZ.Result_PaymentIdPaymentErrorZ_OK
import org.ldk.structs.Result_SignatureNoneZ.Result_SignatureNoneZ_OK
import org.ldk.structs.Result_StringErrorZ.Result_StringErrorZ_OK
import org.ldk.util.UInt128
import java.io.File
import java.net.InetSocketAddress
Expand Down Expand Up @@ -81,6 +84,7 @@ enum class LdkErrors {
channel_close_fail,
channel_accept_fail,
spend_outputs_fail,
failed_signing_request,
write_fail,
read_fail,
file_does_not_exist,
Expand Down Expand Up @@ -1088,6 +1092,20 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod

promise.resolve((res as Result_TransactionNoneZ.Result_TransactionNoneZ_OK).res.hexEncodedString())
}


@ReactMethod
fun nodeSign(message: String, promise: Promise) {
keysManager ?: return handleReject(promise, LdkErrors.init_keys_manager)

val res = UtilMethods.sign(message.toByteArray(Charsets.UTF_8), keysManager!!._node_secret_key)

if (!res.is_ok) {
return handleReject(promise, LdkErrors.failed_signing_request)
}

promise.resolve((res as Result_StringErrorZ_OK).res)
}
}

object LdkEventEmitter {
Expand Down
3 changes: 3 additions & 0 deletions lib/ios/Ldk.m
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ @interface RCT_EXTERN_MODULE(Ldk, NSObject)
changeDestinationScript:(NSString *)changeDestinationScript
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(nodeSign:(NSString *)message
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
@end

//MARK: Events
Expand Down
15 changes: 15 additions & 0 deletions lib/ios/Ldk.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ enum LdkErrors: String {
case channel_close_fail = "channel_close_fail"
case channel_accept_fail = "channel_accept_fail"
case spend_outputs_fail = "spend_outputs_fail"
case failed_signing_request = "failed_signing_request"
case write_fail = "write_fail"
case read_fail = "read_fail"
case file_does_not_exist = "file_does_not_exist"
Expand Down Expand Up @@ -1177,6 +1178,20 @@ class Ldk: NSObject {

return resolve(Data(res.getValue()!).hexEncodedString())
}

@objc
func nodeSign(_ message: NSString, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
guard let keysManager = keysManager else {
return handleReject(reject, .init_keys_manager)
}

let signed = Bindings.swiftSign(msg: Array(String(message).utf8), sk: keysManager.getNodeSecretKey())
if let _ = signed.getError() {
handleReject(reject, .failed_signing_request)
}

return resolve(signed.getValue()!)
}
}

//MARK: Singleton react native event emitter
Expand Down
2 changes: 1 addition & 1 deletion lib/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@synonymdev/react-native-ldk",
"title": "React Native LDK",
"version": "0.0.106",
"version": "0.0.109",
"description": "React Native wrapper for LDK",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
22 changes: 22 additions & 0 deletions lib/src/ldk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
TReconstructAndSpendOutputsReq,
THeader,
TAcceptChannelReq,
TNodeSignReq,
} from './utils/types';
import { extractPaymentRequest } from './utils/helpers';

Expand Down Expand Up @@ -1163,6 +1164,27 @@ class LDK {
return err(e);
}
}

/**
* Creates a digital signature of a message the node's secret key.
* A receiver knowing the PublicKey (e.g. the node's id) and the message can be sure that the signature was generated by the caller.
* Signatures are EC recoverable, meaning that given the message and the signature the PublicKey of the signer can be extracted.
* @param message
* @param messagePrefix
*/
async nodeSign({
message,
messagePrefix = 'Lightning Signed Message:',
}: TNodeSignReq): Promise<Result<string>> {
try {
const res = await NativeLDK.nodeSign(`${messagePrefix}${message}`);
this.writeDebugToLog('nodeSign', res);
return ok(res);
} catch (e) {
this.writeErrorToLog('nodeSign', e);
return err(e);
}
}
}

export default new LDK();
5 changes: 5 additions & 0 deletions lib/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -574,3 +574,8 @@ export type TReconstructAndSpendOutputsReq = {
feeRate: number;
changeDestinationScript: string;
};

export type TNodeSignReq = {
message: string;
messagePrefix?: string;
};

0 comments on commit 495277a

Please sign in to comment.