//go:build wasm //:build wasm package registry import ( "git.smesh.lol/smesh/web/common/jsbridge/callback" "unsafe" ) // --- Identity state --- //:wasmimport bridge registry_set_seckey func wasmSetSeckey(ptr *byte, len int32, cap int32) //:wasmimport bridge registry_seckey func wasmSeckey(outPtr *int32, outLen *int32) //:wasmimport bridge registry_set_pubkey func wasmSetPubkey(ptr *byte, len int32, cap int32) //:wasmimport bridge registry_pubkey func wasmPubkey(outPtr *int32, outLen *int32) //:wasmimport bridge registry_set_has_key func wasmSetHasKey(v int32) //:wasmimport bridge registry_has_key func wasmHasKey() (n int32) func SetSeckey(hex string) { wasmSetSeckey(unsafe.StringData(hex), int32(len(hex)), int32(len(hex))) } func Seckey() (s string) { var rPtr, rLen int32 wasmSeckey(&rPtr, &rLen) if rLen <= 0 { return "" } return unsafe.String((*byte)(unsafe.Pointer(uintptr(rPtr))), rLen) } func SetPubkey(pub string) { wasmSetPubkey(unsafe.StringData(pub), int32(len(pub)), int32(len(pub))) } func Pubkey() (s string) { var rPtr, rLen int32 wasmPubkey(&rPtr, &rLen) if rLen <= 0 { return "" } return unsafe.String((*byte)(unsafe.Pointer(uintptr(rPtr))), rLen) } func SetHasKey(v bool) { if v { wasmSetHasKey(1) } else { wasmSetHasKey(0) } } func HasKey() (ok bool) { return wasmHasKey() != 0 } // --- Register extension hooks (simple signatures use callback table) --- //:wasmimport bridge registry_on_marmot_init func wasmOnMarmotInit(cbID int32) //:wasmimport bridge registry_on_marmot_send func wasmOnMarmotSend(cbID int32) //:wasmimport bridge registry_on_marmot_subscribe func wasmOnMarmotSubscribe(cbID int32) //:wasmimport bridge registry_on_marmot_publish_kp func wasmOnMarmotPublishKP(cbID int32) //:wasmimport bridge registry_on_marmot_list_groups func wasmOnMarmotListGroups(cbID int32) //:wasmimport bridge registry_on_save_dm_record func wasmOnSaveDMRecord(cbID int32) //:wasmimport bridge registry_on_broadcast_to_clients func wasmOnBroadcastToClients(cbID int32) //:wasmimport bridge registry_on_send_to_client func wasmOnSendToClient(cbID int32) func OnMarmotInit(fn func(string)) { wasmOnMarmotInit(callback.RegisterS(fn)) } func OnMarmotSend(fn func(string, string)) { wasmOnMarmotSend(callback.RegisterSS(fn)) } func OnMarmotSubscribe(fn func()) { wasmOnMarmotSubscribe(callback.Register0(fn)) } func OnMarmotPublishKP(fn func(string)) { wasmOnMarmotPublishKP(callback.RegisterS(fn)) } func OnMarmotListGroups(fn func(string)) { wasmOnMarmotListGroups(callback.RegisterS(fn)) } func OnSaveDMRecord(fn func(string)) { wasmOnSaveDMRecord(callback.RegisterS(fn)) } func OnBroadcastToClients(fn func(string)) { wasmOnBroadcastToClients(callback.RegisterS(fn)) } func OnSendToClient(fn func(string, string)) { wasmOnSendToClient(callback.RegisterSS(fn)) } // --- Hooks with nested response callbacks (custom wasmexport) --- //:wasmimport bridge registry_on_encrypt_nip04 func wasmOnEncryptNip04() //:wasmimport bridge registry_on_encrypt_nip17 func wasmOnEncryptNip17() //:wasmimport bridge registry_on_decrypt_dm func wasmOnDecryptDM() //:wasmimport bridge registry_hook_respond_s func wasmHookRespondS(reqID int32, ptr *byte, len int32, cap int32) //:wasmimport bridge registry_hook_respond_ss func wasmHookRespondSS(reqID int32, p1 *byte, l1 int32, c1 int32, p2 *byte, l2 int32, c2 int32) var hookEncryptNip04 func(string, string, func(string)) func OnEncryptNip04(fn func(string, string, func(string))) { hookEncryptNip04 = fn wasmOnEncryptNip04() } //:wasmexport __hook_encrypt_nip04 func dispatchEncryptNip04(reqID int32, pkPtr *byte, pkLen int32, ctPtr *byte, ctLen int32) { if hookEncryptNip04 == nil { return } pk := ptrToString(pkPtr, pkLen) ct := ptrToString(ctPtr, ctLen) rid := reqID hookEncryptNip04(pk, ct, func(result string) { wasmHookRespondS(rid, unsafe.StringData(result), int32(len(result)), int32(len(result))) }) } var hookEncryptNip17 func(string, string, func(string, string)) func OnEncryptNip17(fn func(string, string, func(string, string))) { hookEncryptNip17 = fn wasmOnEncryptNip17() } //:wasmexport __hook_encrypt_nip17 func dispatchEncryptNip17(reqID int32, pkPtr *byte, pkLen int32, ctPtr *byte, ctLen int32) { if hookEncryptNip17 == nil { return } pk := ptrToString(pkPtr, pkLen) ct := ptrToString(ctPtr, ctLen) rid := reqID hookEncryptNip17(pk, ct, func(a, b string) { wasmHookRespondSS(rid, unsafe.StringData(a), int32(len(a)), int32(len(a)), unsafe.StringData(b), int32(len(b)), int32(len(b)), ) }) } var hookDecryptDM func(string, func(string)) func OnDecryptDM(fn func(string, func(string))) { hookDecryptDM = fn wasmOnDecryptDM() } //:wasmexport __hook_decrypt_dm func dispatchDecryptDM(reqID int32, evPtr *byte, evLen int32) { if hookDecryptDM == nil { return } ev := ptrToString(evPtr, evLen) rid := reqID hookDecryptDM(ev, func(result string) { wasmHookRespondS(rid, unsafe.StringData(result), int32(len(result)), int32(len(result))) }) } // --- Call extension hooks --- //:wasmimport bridge registry_encrypt_nip04 func wasmEncryptNip04(pkPtr *byte, pkLen int32, pkCap int32, ctPtr *byte, ctLen int32, ctCap int32, cbID int32) //:wasmimport bridge registry_encrypt_nip17 func wasmEncryptNip17(pkPtr *byte, pkLen int32, pkCap int32, ctPtr *byte, ctLen int32, ctCap int32, cbID int32) //:wasmimport bridge registry_decrypt_dm func wasmDecryptDM(ptr *byte, len int32, cap int32, cbID int32) //:wasmimport bridge registry_make_dm_record func wasmMakeDMRecord(peerPtr *byte, peerLen int32, peerCap int32, fromPtr *byte, fromLen int32, fromCap int32, contentPtr *byte, contentLen int32, contentCap int32, ts int64, protoPtr *byte, protoLen int32, protoCap int32, eidPtr *byte, eidLen int32, eidCap int32, outPtr *int32, outLen *int32) //:wasmimport bridge registry_marmot_init func wasmMarmotInit(ptr *byte, len int32, cap int32) //:wasmimport bridge registry_marmot_send func wasmMarmotSendMsg(rPtr *byte, rLen int32, rCap int32, cPtr *byte, cLen int32, cCap int32) //:wasmimport bridge registry_marmot_subscribe func wasmMarmotSubscribeCall() //:wasmimport bridge registry_marmot_publish_kp func wasmMarmotPublishKP(ptr *byte, len int32, cap int32) //:wasmimport bridge registry_marmot_list_groups func wasmMarmotListGroupsCall(ptr *byte, len int32, cap int32) //:wasmimport bridge registry_save_dm_record func wasmSaveDMRecord(ptr *byte, len int32, cap int32) //:wasmimport bridge registry_broadcast_to_clients func wasmBroadcastToClients(ptr *byte, len int32, cap int32) //:wasmimport bridge registry_send_to_client func wasmSendToClientCall(idPtr *byte, idLen int32, idCap int32, msgPtr *byte, msgLen int32, msgCap int32) //:wasmimport bridge registry_has_hook func wasmHasHook(ptr *byte, len int32, cap int32) (n int32) //:wasmimport bridge registry_load_module func wasmLoadModule(ptr *byte, len int32, cap int32, cbID int32) func EncryptNip04(pubkey, content string, cb func(string)) { wasmEncryptNip04( unsafe.StringData(pubkey), int32(len(pubkey)), int32(len(pubkey)), unsafe.StringData(content), int32(len(content)), int32(len(content)), callback.RegisterSOnce(cb), ) } func EncryptNip17(pubkey, content string, cb func(string, string)) { wasmEncryptNip17( unsafe.StringData(pubkey), int32(len(pubkey)), int32(len(pubkey)), unsafe.StringData(content), int32(len(content)), int32(len(content)), callback.RegisterSSOnce(cb), ) } func DecryptDM(evJSON string, cb func(string)) { wasmDecryptDM(unsafe.StringData(evJSON), int32(len(evJSON)), int32(len(evJSON)), callback.RegisterSOnce(cb)) } func MakeDMRecord(peer, from, content string, ts int64, proto, eid string) (s string) { var rPtr, rLen int32 wasmMakeDMRecord( unsafe.StringData(peer), int32(len(peer)), int32(len(peer)), unsafe.StringData(from), int32(len(from)), int32(len(from)), unsafe.StringData(content), int32(len(content)), int32(len(content)), ts, unsafe.StringData(proto), int32(len(proto)), int32(len(proto)), unsafe.StringData(eid), int32(len(eid)), int32(len(eid)), &rPtr, &rLen, ) if rLen <= 0 { return "" } return unsafe.String((*byte)(unsafe.Pointer(uintptr(rPtr))), rLen) } func MarmotInit(relayURLsJSON string) { wasmMarmotInit(unsafe.StringData(relayURLsJSON), int32(len(relayURLsJSON)), int32(len(relayURLsJSON))) } func MarmotSend(recipient, content string) { wasmMarmotSendMsg( unsafe.StringData(recipient), int32(len(recipient)), int32(len(recipient)), unsafe.StringData(content), int32(len(content)), int32(len(content)), ) } func MarmotSubscribe() { wasmMarmotSubscribeCall() } func MarmotPublishKP(relayURLsJSON string) { wasmMarmotPublishKP(unsafe.StringData(relayURLsJSON), int32(len(relayURLsJSON)), int32(len(relayURLsJSON))) } func MarmotListGroups(clientID string) { wasmMarmotListGroupsCall(unsafe.StringData(clientID), int32(len(clientID)), int32(len(clientID))) } func SaveDMRecord(dmJSON string) { wasmSaveDMRecord(unsafe.StringData(dmJSON), int32(len(dmJSON)), int32(len(dmJSON))) } func BroadcastToClients(msg string) { wasmBroadcastToClients(unsafe.StringData(msg), int32(len(msg)), int32(len(msg))) } func SendToClient(clientID, msg string) { wasmSendToClientCall( unsafe.StringData(clientID), int32(len(clientID)), int32(len(clientID)), unsafe.StringData(msg), int32(len(msg)), int32(len(msg)), ) } func HasHook(name string) (ok bool) { return wasmHasHook(unsafe.StringData(name), int32(len(name)), int32(len(name))) != 0 } func LoadModule(name string, cb func()) { wasmLoadModule(unsafe.StringData(name), int32(len(name)), int32(len(name)), callback.Register0Once(cb)) } func ptrToString(ptr *byte, length int32) (s string) { if ptr == nil || length <= 0 { return "" } return unsafe.String(ptr, length) }