mirror of
https://github.com/aljazceru/react-native-pubky.git
synced 2025-12-17 14:44:26 +01:00
fix: add publish and resolve
Adds publish & resolve methods. Updates example app. Add npmignore. Bumps version to 0.3.0.
This commit is contained in:
2
.npmignore
Normal file
2
.npmignore
Normal file
@@ -0,0 +1,2 @@
|
||||
example/
|
||||
rust/
|
||||
@@ -11,6 +11,8 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import uniffi.pubkymobile.auth
|
||||
import uniffi.pubkymobile.parseAuthUrl
|
||||
import uniffi.pubkymobile.publish
|
||||
import uniffi.pubkymobile.resolve
|
||||
|
||||
class PubkyModule(reactContext: ReactApplicationContext) :
|
||||
ReactContextBaseJavaModule(reactContext) {
|
||||
@@ -51,6 +53,44 @@ class PubkyModule(reactContext: ReactApplicationContext) :
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun publish(recordName: String, recordContent: String, secretKey: String, promise: Promise) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
val result = publish(recordName, recordContent, secretKey)
|
||||
val array = Arguments.createArray().apply {
|
||||
result.forEach { pushString(it) }
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
promise.resolve(array)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
promise.reject("Error", e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun resolve(publicKey: String, promise: Promise) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
val result = resolve(publicKey)
|
||||
val array = Arguments.createArray().apply {
|
||||
result.forEach { pushString(it) }
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
promise.resolve(array)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
promise.reject("Error", e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val NAME = "Pubky"
|
||||
}
|
||||
|
||||
@@ -385,6 +385,10 @@ internal interface _UniFFILib : Library {
|
||||
): RustBuffer.ByValue
|
||||
fun uniffi_pubkymobile_fn_func_parse_auth_url(`url`: RustBuffer.ByValue,_uniffi_out_err: RustCallStatus,
|
||||
): RustBuffer.ByValue
|
||||
fun uniffi_pubkymobile_fn_func_publish(`recordName`: RustBuffer.ByValue,`recordContent`: RustBuffer.ByValue,`secretKey`: RustBuffer.ByValue,_uniffi_out_err: RustCallStatus,
|
||||
): RustBuffer.ByValue
|
||||
fun uniffi_pubkymobile_fn_func_resolve(`publicKey`: RustBuffer.ByValue,_uniffi_out_err: RustCallStatus,
|
||||
): RustBuffer.ByValue
|
||||
fun ffi_pubkymobile_rustbuffer_alloc(`size`: Int,_uniffi_out_err: RustCallStatus,
|
||||
): RustBuffer.ByValue
|
||||
fun ffi_pubkymobile_rustbuffer_from_bytes(`bytes`: ForeignBytes.ByValue,_uniffi_out_err: RustCallStatus,
|
||||
@@ -503,6 +507,10 @@ internal interface _UniFFILib : Library {
|
||||
): Short
|
||||
fun uniffi_pubkymobile_checksum_func_parse_auth_url(
|
||||
): Short
|
||||
fun uniffi_pubkymobile_checksum_func_publish(
|
||||
): Short
|
||||
fun uniffi_pubkymobile_checksum_func_resolve(
|
||||
): Short
|
||||
fun ffi_pubkymobile_uniffi_contract_version(
|
||||
): Int
|
||||
|
||||
@@ -526,6 +534,12 @@ private fun uniffiCheckApiChecksums(lib: _UniFFILib) {
|
||||
if (lib.uniffi_pubkymobile_checksum_func_parse_auth_url() != 29088.toShort()) {
|
||||
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
||||
}
|
||||
if (lib.uniffi_pubkymobile_checksum_func_publish() != 20156.toShort()) {
|
||||
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
||||
}
|
||||
if (lib.uniffi_pubkymobile_checksum_func_resolve() != 18303.toShort()) {
|
||||
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
|
||||
}
|
||||
}
|
||||
|
||||
// Async support
|
||||
@@ -628,3 +642,19 @@ fun `parseAuthUrl`(`url`: String): List<String> {
|
||||
}
|
||||
|
||||
|
||||
fun `publish`(`recordName`: String, `recordContent`: String, `secretKey`: String): List<String> {
|
||||
return FfiConverterSequenceString.lift(
|
||||
rustCall() { _status ->
|
||||
_UniFFILib.INSTANCE.uniffi_pubkymobile_fn_func_publish(FfiConverterString.lower(`recordName`),FfiConverterString.lower(`recordContent`),FfiConverterString.lower(`secretKey`),_status)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
fun `resolve`(`publicKey`: String): List<String> {
|
||||
return FfiConverterSequenceString.lift(
|
||||
rustCall() { _status ->
|
||||
_UniFFILib.INSTANCE.uniffi_pubkymobile_fn_func_resolve(FfiConverterString.lower(`publicKey`),_status)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1237,7 +1237,7 @@ PODS:
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- react-native-pubky (0.2.3):
|
||||
- react-native-pubky (0.3.0):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
@@ -1757,7 +1757,7 @@ SPEC CHECKSUMS:
|
||||
React-logger: 4072f39df335ca443932e0ccece41fbeb5ca8404
|
||||
React-Mapbuffer: 714f2fae68edcabfc332b754e9fbaa8cfc68fdd4
|
||||
React-microtasksnativemodule: 4943ad8f99be8ccf5a63329fa7d269816609df9e
|
||||
react-native-pubky: 71108903c771df07c623ed14196f0c49d0d49810
|
||||
react-native-pubky: 9fd2633ee974bafa9b77e0cd59e2619a0d9d708d
|
||||
React-nativeconfig: 4a9543185905fe41014c06776bf126083795aed9
|
||||
React-NativeModulesApple: 0506da59fc40d2e1e6e12a233db5e81c46face27
|
||||
React-perflogger: 3bbb82f18e9ac29a1a6931568e99d6305ef4403b
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"android": "react-native run-android",
|
||||
"ios": "bundle install && cd ios && pod install && cd ../ && react-native run-ios",
|
||||
"ios": "bundle install && cd ios && pod install && cd ../ && react-native run-ios --simulator \"iPhone 15 Pro\"",
|
||||
"start": "react-native start",
|
||||
"build:android": "react-native build-android --extra-params \"--no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a\"",
|
||||
"install-pods": "bundle install && cd ios && pod install && cd ../",
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { StyleSheet, View, Button } from 'react-native';
|
||||
import { auth, parseAuthUrl } from '@synonymdev/react-native-pubky';
|
||||
import {
|
||||
auth,
|
||||
parseAuthUrl,
|
||||
publish,
|
||||
resolve,
|
||||
} from '@synonymdev/react-native-pubky';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
@@ -9,7 +14,7 @@ export default function App() {
|
||||
onPress={async (): Promise<void> => {
|
||||
try {
|
||||
const res = await auth(
|
||||
'pubkyauth:///?caps=/pub/pubky.app/:rw,/pub/foo.bar/file:r&secret=_K8yj2nS4naHWytpECCX48XhjhGc8KAhlpnuLUiHYBI&relay=http://localhost:52244/',
|
||||
'pubkyauth:///?caps=/pub/pubky.app/:rw,/pub/foo.bar/file:r&secret=U55XnoH6vsMCpx1pxHtt8fReVg4Brvu9C0gUBuw-Jkw&relay=http://167.86.102.121:4173/',
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||
);
|
||||
if (res.isErr()) {
|
||||
@@ -39,6 +44,42 @@ export default function App() {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title={'publish'}
|
||||
onPress={async (): Promise<void> => {
|
||||
try {
|
||||
const res = await publish(
|
||||
'recordnametest',
|
||||
'recordcontenttest',
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||
);
|
||||
if (res.isErr()) {
|
||||
console.log(res.error.message);
|
||||
return;
|
||||
}
|
||||
console.log(res.value);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
title={'resolve'}
|
||||
onPress={async (): Promise<void> => {
|
||||
try {
|
||||
const res = await resolve(
|
||||
'z4e8s17cou9qmuwen8p1556jzhf1wktmzo6ijsfnri9c4hnrdfty'
|
||||
);
|
||||
if (res.isErr()) {
|
||||
console.log(res.error.message);
|
||||
return;
|
||||
}
|
||||
console.log(res.value);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,22 +4,6 @@
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>libpubkymobile.a</string>
|
||||
<key>HeadersPath</key>
|
||||
<string>Headers</string>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libpubkymobile.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>libpubkymobile.a</string>
|
||||
@@ -38,6 +22,22 @@
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>libpubkymobile.a</string>
|
||||
<key>HeadersPath</key>
|
||||
<string>Headers</string>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libpubkymobile.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
|
||||
@@ -67,6 +67,10 @@ RustBuffer uniffi_pubkymobile_fn_func_auth(RustBuffer url, RustBuffer secret_key
|
||||
);
|
||||
RustBuffer uniffi_pubkymobile_fn_func_parse_auth_url(RustBuffer url, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
RustBuffer uniffi_pubkymobile_fn_func_publish(RustBuffer record_name, RustBuffer record_content, RustBuffer secret_key, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
RustBuffer uniffi_pubkymobile_fn_func_resolve(RustBuffer public_key, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
RustBuffer ffi_pubkymobile_rustbuffer_alloc(int32_t size, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
RustBuffer ffi_pubkymobile_rustbuffer_from_bytes(ForeignBytes bytes, RustCallStatus *_Nonnull out_status
|
||||
@@ -186,6 +190,12 @@ uint16_t uniffi_pubkymobile_checksum_func_auth(void
|
||||
);
|
||||
uint16_t uniffi_pubkymobile_checksum_func_parse_auth_url(void
|
||||
|
||||
);
|
||||
uint16_t uniffi_pubkymobile_checksum_func_publish(void
|
||||
|
||||
);
|
||||
uint16_t uniffi_pubkymobile_checksum_func_resolve(void
|
||||
|
||||
);
|
||||
uint32_t ffi_pubkymobile_uniffi_contract_version(void
|
||||
|
||||
|
||||
Binary file not shown.
@@ -67,6 +67,10 @@ RustBuffer uniffi_pubkymobile_fn_func_auth(RustBuffer url, RustBuffer secret_key
|
||||
);
|
||||
RustBuffer uniffi_pubkymobile_fn_func_parse_auth_url(RustBuffer url, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
RustBuffer uniffi_pubkymobile_fn_func_publish(RustBuffer record_name, RustBuffer record_content, RustBuffer secret_key, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
RustBuffer uniffi_pubkymobile_fn_func_resolve(RustBuffer public_key, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
RustBuffer ffi_pubkymobile_rustbuffer_alloc(int32_t size, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
RustBuffer ffi_pubkymobile_rustbuffer_from_bytes(ForeignBytes bytes, RustCallStatus *_Nonnull out_status
|
||||
@@ -186,6 +190,12 @@ uint16_t uniffi_pubkymobile_checksum_func_auth(void
|
||||
);
|
||||
uint16_t uniffi_pubkymobile_checksum_func_parse_auth_url(void
|
||||
|
||||
);
|
||||
uint16_t uniffi_pubkymobile_checksum_func_publish(void
|
||||
|
||||
);
|
||||
uint16_t uniffi_pubkymobile_checksum_func_resolve(void
|
||||
|
||||
);
|
||||
uint32_t ffi_pubkymobile_uniffi_contract_version(void
|
||||
|
||||
|
||||
Binary file not shown.
10
ios/Pubky.mm
10
ios/Pubky.mm
@@ -11,6 +11,16 @@ RCT_EXTERN_METHOD(parseAuthUrl:(NSString *)url
|
||||
withResolver:(RCTPromiseResolveBlock)resolve
|
||||
withRejecter:(RCTPromiseRejectBlock)reject)
|
||||
|
||||
RCT_EXTERN_METHOD(publish:(NSString *)recordName
|
||||
recordContent:(NSString *)recordContent
|
||||
secretKey:(NSString *)secretKey
|
||||
withResolver:(RCTPromiseResolveBlock)resolve
|
||||
withRejecter:(RCTPromiseRejectBlock)reject)
|
||||
|
||||
RCT_EXTERN_METHOD(resolve:(NSString *)publicKey
|
||||
withResolver:(RCTPromiseResolveBlock)resolve
|
||||
withRejecter:(RCTPromiseRejectBlock)reject)
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup
|
||||
{
|
||||
return NO;
|
||||
|
||||
@@ -13,6 +13,7 @@ class Pubky: NSObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc(parseAuthUrl:withResolver:withRejecter:)
|
||||
func parseAuthUrl(_ url: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||
Task {
|
||||
@@ -24,4 +25,28 @@ class Pubky: NSObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc(publish:recordContent:secretKey:withResolver:withRejecter:)
|
||||
func publish(recordName: String, recordContent: String, secretKey: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||
Task {
|
||||
do {
|
||||
let result = react_native_pubky.publish(recordName: recordName, recordContent: recordContent, secretKey: secretKey)
|
||||
resolve(result)
|
||||
} catch {
|
||||
reject("publish Error", "Failed to publish", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc(resolve:withResolver:withRejecter:)
|
||||
func resolve(publicKey: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||
Task {
|
||||
do {
|
||||
let result = react_native_pubky.resolve(publicKey: publicKey)
|
||||
resolve(result)
|
||||
} catch {
|
||||
reject("resolve Error", "Failed to resolve", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,6 +376,26 @@ public func parseAuthUrl(url: String) -> [String] {
|
||||
)
|
||||
}
|
||||
|
||||
public func publish(recordName: String, recordContent: String, secretKey: String) -> [String] {
|
||||
return try! FfiConverterSequenceString.lift(
|
||||
try! rustCall() {
|
||||
uniffi_pubkymobile_fn_func_publish(
|
||||
FfiConverterString.lower(recordName),
|
||||
FfiConverterString.lower(recordContent),
|
||||
FfiConverterString.lower(secretKey),$0)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
public func resolve(publicKey: String) -> [String] {
|
||||
return try! FfiConverterSequenceString.lift(
|
||||
try! rustCall() {
|
||||
uniffi_pubkymobile_fn_func_resolve(
|
||||
FfiConverterString.lower(publicKey),$0)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private enum InitializationResult {
|
||||
case ok
|
||||
case contractVersionMismatch
|
||||
@@ -397,6 +417,12 @@ private var initializationResult: InitializationResult {
|
||||
if (uniffi_pubkymobile_checksum_func_parse_auth_url() != 29088) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_pubkymobile_checksum_func_publish() != 20156) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_pubkymobile_checksum_func_resolve() != 18303) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
|
||||
return InitializationResult.ok
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@synonymdev/react-native-pubky",
|
||||
"version": "0.2.3",
|
||||
"version": "0.3.0",
|
||||
"description": "React Native Implementation of Pubky",
|
||||
"source": "./src/index.tsx",
|
||||
"main": "./lib/commonjs/index.js",
|
||||
|
||||
23
rust/Cargo.lock
generated
23
rust/Cargo.lock
generated
@@ -386,9 +386,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.7.1"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
||||
checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
@@ -424,9 +424,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.19"
|
||||
version = "1.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800"
|
||||
checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
@@ -1566,7 +1566,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
[[package]]
|
||||
name = "pkarr"
|
||||
version = "2.2.0"
|
||||
source = "git+https://github.com/Pubky/pkarr?branch=v3#7a4575f4c60689765ba0567aa27248df2b31b2d4"
|
||||
source = "git+https://github.com/Pubky/pkarr?branch=v3#5b2f8e53735f63521b0d587167609a2cb9b8f2ab"
|
||||
dependencies = [
|
||||
"base32",
|
||||
"bytes",
|
||||
@@ -1822,6 +1822,7 @@ dependencies = [
|
||||
name = "react_native_pubky"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"hex",
|
||||
"pkarr",
|
||||
"pubky",
|
||||
@@ -2504,9 +2505,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.20"
|
||||
version = "0.22.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
|
||||
checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
@@ -2674,9 +2675,9 @@ checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.23"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
||||
checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
@@ -2951,9 +2952,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.5"
|
||||
version = "0.26.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a"
|
||||
checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
@@ -19,7 +19,8 @@ sha2 = "0.10.8"
|
||||
serde = { version = "^1.0.209", features = ["derive"] }
|
||||
tokio = "1.40.0"
|
||||
url = "2.5.2"
|
||||
pkarr = { git = "https://github.com/Pubky/pkarr", branch = "v3", package = "pkarr", features = ["async", "rand"] }
|
||||
pkarr = { git = "https://github.com/Pubky/pkarr", branch = "v3", features = ["async", "rand"] }
|
||||
pubky = { version = "0.1.0", path = "pubky/pubky" }
|
||||
pubky-common = { version = "0.1.0", path = "pubky/pubky-common" }
|
||||
pubky_homeserver = { version = "0.1.0", path = "pubky/pubky-homeserver" }
|
||||
base64 = "0.21.7"
|
||||
|
||||
92
rust/src/auth.rs
Normal file
92
rust/src/auth.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use crate::keypair::get_keypair_from_secret_key;
|
||||
use crate::{PubkyAuthDetails, Capability};
|
||||
use crate::utils::create_response_vector;
|
||||
use std::collections::HashMap;
|
||||
use pubky::PubkyClient;
|
||||
use serde_json;
|
||||
use url::Url;
|
||||
|
||||
pub async fn authorize(url: String, secret_key: String) -> Vec<String> {
|
||||
let client = PubkyClient::testnet();
|
||||
let keypair = match get_keypair_from_secret_key(&secret_key) {
|
||||
Ok(keypair) => keypair,
|
||||
Err(error) => return create_response_vector(true, error),
|
||||
};
|
||||
|
||||
// const HOMESERVER: &'static str = "8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo";
|
||||
// const URL: &'static str = "http://localhost:6287?relay=http://demo.httprelay.io/link";
|
||||
// match client.signin(&keypair).await {
|
||||
// Ok(_) => {}, // Signin successful, continue to send_auth_token
|
||||
// Err(_) => {
|
||||
// match client.signup(&keypair, &PublicKey::try_from(HOMESERVER).unwrap()).await {
|
||||
// Ok(_) => {}, // Signup successful, continue to send_auth_token
|
||||
// Err(error) => return create_response_vector(true, format!("Failed to signup: {}", error)),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
let parsed_url = match Url::parse(&url) {
|
||||
Ok(url) => url,
|
||||
Err(_) => return create_response_vector(true, "Failed to parse URL".to_string()),
|
||||
};
|
||||
|
||||
match client.send_auth_token(&keypair, parsed_url).await {
|
||||
Ok(_) => create_response_vector(false, "send_auth_token success".to_string()),
|
||||
Err(error) => create_response_vector(true, format!("send_auth_token failure: {}", error)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pubky_auth_details_to_json(details: &PubkyAuthDetails) -> Result<String, String> {
|
||||
serde_json::to_string(details).map_err(|_| "Error serializing to JSON".to_string())
|
||||
}
|
||||
|
||||
pub fn parse_pubky_auth_url(url_str: &str) -> Result<PubkyAuthDetails, String> {
|
||||
let url = Url::parse(url_str).map_err(|_| "Invalid URL".to_string())?;
|
||||
|
||||
if url.scheme() != "pubkyauth" {
|
||||
return Err("Invalid scheme, expected 'pubkyauth'".to_string());
|
||||
}
|
||||
|
||||
// Collect query pairs into a HashMap for efficient access
|
||||
let query_params: HashMap<_, _> = url.query_pairs().into_owned().collect();
|
||||
|
||||
let relay = query_params
|
||||
.get("relay")
|
||||
.cloned()
|
||||
.ok_or_else(|| "Missing relay".to_string())?;
|
||||
|
||||
let capabilities_str = query_params
|
||||
.get("capabilities")
|
||||
.or_else(|| query_params.get("caps"))
|
||||
.cloned()
|
||||
.ok_or_else(|| "Missing capabilities".to_string())?;
|
||||
|
||||
let secret = query_params
|
||||
.get("secret")
|
||||
.cloned()
|
||||
.ok_or_else(|| "Missing secret".to_string())?;
|
||||
|
||||
// Parse capabilities
|
||||
let capabilities = capabilities_str
|
||||
.split(',')
|
||||
.map(|capability| {
|
||||
let mut parts = capability.splitn(2, ':');
|
||||
let path = parts
|
||||
.next()
|
||||
.ok_or_else(|| format!("Invalid capability format in '{}'", capability))?;
|
||||
let permission = parts
|
||||
.next()
|
||||
.ok_or_else(|| format!("Invalid capability format in '{}'", capability))?;
|
||||
Ok(Capability {
|
||||
path: path.to_string(),
|
||||
permission: permission.to_string(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, String>>()?;
|
||||
|
||||
Ok(PubkyAuthDetails {
|
||||
relay,
|
||||
capabilities,
|
||||
secret,
|
||||
})
|
||||
}
|
||||
17
rust/src/keypair.rs
Normal file
17
rust/src/keypair.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use pkarr::Keypair;
|
||||
|
||||
pub fn get_keypair_from_secret_key(secret_key: &str) -> Result<Keypair, String> {
|
||||
let bytes = match hex::decode(&secret_key) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(_) => return Err("Failed to decode secret key".to_string())
|
||||
};
|
||||
|
||||
let secret_key_bytes: [u8; 32] = match bytes.try_into() {
|
||||
Ok(secret_key) => secret_key,
|
||||
Err(_) => {
|
||||
return Err("Failed to convert secret key to 32-byte array".to_string());
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Keypair::from_secret_key(&secret_key_bytes))
|
||||
}
|
||||
226
rust/src/lib.rs
226
rust/src/lib.rs
@@ -1,48 +1,138 @@
|
||||
mod types;
|
||||
mod keypair;
|
||||
mod auth;
|
||||
mod utils;
|
||||
|
||||
pub use types::*;
|
||||
pub use keypair::*;
|
||||
pub use auth::*;
|
||||
pub use utils::*;
|
||||
|
||||
uniffi::setup_scaffolding!();
|
||||
|
||||
use std::collections::HashMap;
|
||||
use base64::Engine;
|
||||
use base64::engine::general_purpose;
|
||||
use pubky::PubkyClient;
|
||||
use hex;
|
||||
use serde::Serialize;
|
||||
use url::Url;
|
||||
use tokio;
|
||||
use pkarr::{PkarrClient, SignedPacket, Keypair, dns, PublicKey};
|
||||
use pkarr::dns::rdata::RData;
|
||||
use pkarr::dns::ResourceRecord;
|
||||
use serde_json::json;
|
||||
use utils::*;
|
||||
|
||||
async fn authorize(url: String, secret_key: String) -> Vec<String> {
|
||||
let bytes = match hex::decode(&secret_key) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(_) => return create_response_vector(true, "Failed to decode secret key".to_string())
|
||||
#[uniffi::export]
|
||||
fn resolve(public_key: String) -> Vec<String> {
|
||||
let public_key = match public_key.as_str().try_into() {
|
||||
Ok(key) => key,
|
||||
Err(e) => return create_response_vector(true, format!("Invalid zbase32 encoded key: {}", e)),
|
||||
};
|
||||
let client = match PkarrClient::builder().build() {
|
||||
Ok(client) => client,
|
||||
Err(e) => return create_response_vector(true, format!("Failed to build PkarrClient: {}", e)),
|
||||
};
|
||||
|
||||
let secret_key_bytes: [u8; 32] = match bytes.try_into() {
|
||||
Ok(secret_key) => secret_key,
|
||||
Err(_) => {
|
||||
return create_response_vector(true, "Failed to convert secret key to 32-byte array".to_string());
|
||||
match client.resolve(&public_key) {
|
||||
Ok(Some(signed_packet)) => {
|
||||
// Collect references to ResourceRecords from the signed packet's answers
|
||||
let all_records: Vec<&ResourceRecord> = signed_packet.packet().answers.iter().collect();
|
||||
// Convert each ResourceRecord to a JSON value, handling errors appropriately
|
||||
let json_records: Vec<serde_json::Value> = all_records
|
||||
.iter()
|
||||
.filter_map(|record| {
|
||||
match resource_record_to_json(record) {
|
||||
Ok(json_value) => Some(json_value),
|
||||
Err(e) => {
|
||||
eprintln!("Error converting record to JSON: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let bytes = signed_packet.as_bytes();
|
||||
let public_key = &bytes[..32];
|
||||
let signature = &bytes[32..96];
|
||||
let timestamp = u64::from_be_bytes(match bytes[96..104].try_into() {
|
||||
Ok(tsbytes) => tsbytes,
|
||||
Err(_) => return create_response_vector(true, "Failed to convert timestamp bytes".to_string())
|
||||
});
|
||||
let dns_packet = &bytes[104..];
|
||||
|
||||
let json_obj = json!({
|
||||
"public_key": general_purpose::STANDARD.encode(public_key),
|
||||
"signature": general_purpose::STANDARD.encode(signature),
|
||||
"timestamp": timestamp,
|
||||
"dns_packet": general_purpose::STANDARD.encode(dns_packet),
|
||||
"records": json_records
|
||||
});
|
||||
|
||||
let json_str = serde_json::to_string(&json_obj)
|
||||
.expect("Failed to convert JSON object to string");
|
||||
|
||||
create_response_vector(false, json_str)
|
||||
},
|
||||
Ok(None) => {
|
||||
create_response_vector(true, "No signed packet found".to_string())
|
||||
}
|
||||
Err(e) => {
|
||||
create_response_vector(true, format!("Failed to resolve: {}", e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[uniffi::export]
|
||||
fn publish(record_name: String, record_content: String, secret_key: String) -> Vec<String> {
|
||||
let client = match PkarrClient::builder().build() {
|
||||
Ok(client) => client,
|
||||
Err(e) => return create_response_vector(true, format!("Failed to build PkarrClient: {}", e)),
|
||||
};
|
||||
|
||||
let keypair = match get_keypair_from_secret_key(&secret_key) {
|
||||
Ok(keypair) => keypair,
|
||||
Err(error) => return create_response_vector(true, error),
|
||||
};
|
||||
|
||||
let mut packet = dns::Packet::new_reply(0);
|
||||
|
||||
let dns_name = match dns::Name::new(&record_name) {
|
||||
Ok(name) => name,
|
||||
Err(e) => return create_response_vector(true, format!("Failed to create DNS name: {}", e)),
|
||||
};
|
||||
|
||||
let record_content_str: &str = record_content.as_str();
|
||||
|
||||
let txt_record = match record_content_str.try_into() {
|
||||
Ok(value) => RData::TXT(value),
|
||||
Err(e) => {
|
||||
return create_response_vector(true, format!("Failed to convert string to TXT record: {}", e))
|
||||
}
|
||||
};
|
||||
|
||||
let client = PubkyClient::testnet();
|
||||
let keypair = pkarr::Keypair::from_secret_key(&secret_key_bytes);
|
||||
packet.answers.push(dns::ResourceRecord::new(
|
||||
dns_name,
|
||||
dns::CLASS::IN,
|
||||
30,
|
||||
txt_record,
|
||||
));
|
||||
|
||||
// const HOMESERVER: &'static str = "8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo";
|
||||
// const URL: &'static str = "http://localhost:6287?relay=http://demo.httprelay.io/link";
|
||||
// match client.signin(&keypair).await {
|
||||
// Ok(_) => {}, // Signin successful, continue to send_auth_token
|
||||
// Err(_) => {
|
||||
// match client.signup(&keypair, &PublicKey::try_from(HOMESERVER).unwrap()).await {
|
||||
// Ok(_) => {}, // Signup successful, continue to send_auth_token
|
||||
// Err(error) => return create_response_vector(true, format!("Failed to signup: {}", error)),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
let parsed_url = match Url::parse(&url) {
|
||||
Ok(url) => url,
|
||||
Err(_) => return create_response_vector(true, "Failed to parse URL".to_string()),
|
||||
};
|
||||
|
||||
match client.send_auth_token(&keypair, parsed_url).await {
|
||||
Ok(_) => create_response_vector(false, "send_auth_token success".to_string()),
|
||||
Err(error) => create_response_vector(true, format!("send_auth_token failure: {}", error)),
|
||||
match SignedPacket::from_packet(&keypair, &packet) {
|
||||
Ok(signed_packet) => {
|
||||
match client.publish(&signed_packet) {
|
||||
Ok(()) => {
|
||||
create_response_vector(false, keypair.public_key().to_string())
|
||||
}
|
||||
Err(e) => {
|
||||
create_response_vector(true, format!("Failed to publish: {}", e))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
create_response_vector(true, format!("Failed to create signed packet: {}", e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,79 +154,3 @@ fn parse_auth_url(url: String) -> Vec<String> {
|
||||
Err(error) => create_response_vector(true, error),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct Capability {
|
||||
path: String,
|
||||
permission: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct PubkyAuthDetails {
|
||||
relay: String,
|
||||
capabilities: Vec<Capability>,
|
||||
secret: String,
|
||||
}
|
||||
|
||||
fn pubky_auth_details_to_json(details: &PubkyAuthDetails) -> Result<String, String> {
|
||||
serde_json::to_string(details).map_err(|_| "Error serializing to JSON".to_string())
|
||||
}
|
||||
|
||||
fn parse_pubky_auth_url(url_str: &str) -> Result<PubkyAuthDetails, String> {
|
||||
let url = Url::parse(url_str).map_err(|_| "Invalid URL".to_string())?;
|
||||
|
||||
if url.scheme() != "pubkyauth" {
|
||||
return Err("Invalid scheme, expected 'pubkyauth'".to_string());
|
||||
}
|
||||
|
||||
// Collect query pairs into a HashMap for efficient access
|
||||
let query_params: HashMap<_, _> = url.query_pairs().into_owned().collect();
|
||||
|
||||
let relay = query_params
|
||||
.get("relay")
|
||||
.cloned()
|
||||
.ok_or_else(|| "Missing relay".to_string())?;
|
||||
|
||||
let capabilities_str = query_params
|
||||
.get("capabilities")
|
||||
.or_else(|| query_params.get("caps"))
|
||||
.cloned()
|
||||
.ok_or_else(|| "Missing capabilities".to_string())?;
|
||||
|
||||
let secret = query_params
|
||||
.get("secret")
|
||||
.cloned()
|
||||
.ok_or_else(|| "Missing secret".to_string())?;
|
||||
|
||||
// Parse capabilities
|
||||
let capabilities = capabilities_str
|
||||
.split(',')
|
||||
.map(|capability| {
|
||||
let mut parts = capability.splitn(2, ':');
|
||||
let path = parts
|
||||
.next()
|
||||
.ok_or_else(|| format!("Invalid capability format in '{}'", capability))?;
|
||||
let permission = parts
|
||||
.next()
|
||||
.ok_or_else(|| format!("Invalid capability format in '{}'", capability))?;
|
||||
Ok(Capability {
|
||||
path: path.to_string(),
|
||||
permission: permission.to_string(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, String>>()?;
|
||||
|
||||
Ok(PubkyAuthDetails {
|
||||
relay,
|
||||
capabilities,
|
||||
secret,
|
||||
})
|
||||
}
|
||||
|
||||
fn create_response_vector(error: bool, data: String) -> Vec<String> {
|
||||
if error {
|
||||
vec!["error".to_string(), data]
|
||||
} else {
|
||||
vec!["success".to_string(), data]
|
||||
}
|
||||
}
|
||||
|
||||
14
rust/src/types.rs
Normal file
14
rust/src/types.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Capability {
|
||||
pub path: String,
|
||||
pub permission: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct PubkyAuthDetails {
|
||||
pub relay: String,
|
||||
pub capabilities: Vec<Capability>,
|
||||
pub secret: String,
|
||||
}
|
||||
203
rust/src/utils.rs
Normal file
203
rust/src/utils.rs
Normal file
@@ -0,0 +1,203 @@
|
||||
use std::error::Error;
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use serde_json::json;
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
use pkarr::dns::rdata::RData;
|
||||
use pkarr::dns::ResourceRecord;
|
||||
|
||||
pub fn create_response_vector(error: bool, data: String) -> Vec<String> {
|
||||
if error {
|
||||
vec!["error".to_string(), data]
|
||||
} else {
|
||||
vec!["success".to_string(), data]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_rdata_for_json(record: &ResourceRecord) -> serde_json::Value {
|
||||
match &record.rdata {
|
||||
RData::TXT(txt) => {
|
||||
let attributes = txt.attributes();
|
||||
let strings: Vec<String> = attributes.into_iter()
|
||||
.map(|(key, value)| {
|
||||
match value {
|
||||
Some(v) => format!("{}={}", key, v),
|
||||
None => key,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
json!({
|
||||
"type": "TXT",
|
||||
"strings": strings
|
||||
})
|
||||
},
|
||||
RData::A(a) => {
|
||||
let ipv4 = Ipv4Addr::from(a.address);
|
||||
json!({
|
||||
"type": "A",
|
||||
"address": ipv4.to_string()
|
||||
})
|
||||
},
|
||||
RData::AAAA(aaaa) => {
|
||||
let ipv6 = Ipv6Addr::from(aaaa.address);
|
||||
json!({
|
||||
"type": "AAAA",
|
||||
"address": ipv6.to_string()
|
||||
})
|
||||
},
|
||||
RData::AFSDB(afsdb) => {
|
||||
json!({
|
||||
"type": "AFSDB",
|
||||
"subtype": afsdb.subtype,
|
||||
"hostname": afsdb.hostname.to_string()
|
||||
})
|
||||
},
|
||||
RData::CAA(caa) => {
|
||||
json!({
|
||||
"type": "CAA",
|
||||
"flag": caa.flag,
|
||||
"tag": caa.tag.to_string(),
|
||||
"value": caa.value.to_string()
|
||||
})
|
||||
},
|
||||
RData::HINFO(hinfo) => {
|
||||
json!({
|
||||
"type": "HINFO",
|
||||
"cpu": hinfo.cpu.to_string(),
|
||||
"os": hinfo.os.to_string()
|
||||
})
|
||||
},
|
||||
RData::ISDN(isdn) => {
|
||||
json!({
|
||||
"type": "ISDN",
|
||||
"address": isdn.address.to_string(),
|
||||
"sa": isdn.sa.to_string()
|
||||
})
|
||||
},
|
||||
RData::LOC(loc) => {
|
||||
json!({
|
||||
"type": "LOC",
|
||||
"version": loc.version,
|
||||
"size": loc.size,
|
||||
"horizontal_precision": loc.horizontal_precision,
|
||||
"vertical_precision": loc.vertical_precision,
|
||||
"latitude": loc.latitude,
|
||||
"longitude": loc.longitude,
|
||||
"altitude": loc.altitude
|
||||
})
|
||||
},
|
||||
RData::MINFO(minfo) => {
|
||||
json!({
|
||||
"type": "MINFO",
|
||||
"rmailbox": minfo.rmailbox.to_string(),
|
||||
"emailbox": minfo.emailbox.to_string()
|
||||
})
|
||||
},
|
||||
RData::MX(mx) => {
|
||||
json!({
|
||||
"type": "MX",
|
||||
"preference": mx.preference,
|
||||
"exchange": mx.exchange.to_string()
|
||||
})
|
||||
},
|
||||
RData::NAPTR(naptr) => {
|
||||
json!({
|
||||
"type": "NAPTR",
|
||||
"order": naptr.order,
|
||||
"preference": naptr.preference,
|
||||
"flags": naptr.flags.to_string(),
|
||||
"services": naptr.services.to_string(),
|
||||
"regexp": naptr.regexp.to_string(),
|
||||
"replacement": naptr.replacement.to_string()
|
||||
})
|
||||
},
|
||||
RData::NULL(_, null_record) => {
|
||||
json!({
|
||||
"type": "NULL",
|
||||
"data": base64::encode(null_record.get_data())
|
||||
})
|
||||
},
|
||||
RData::OPT(opt) => {
|
||||
json!({
|
||||
"type": "OPT",
|
||||
"udp_packet_size": opt.udp_packet_size,
|
||||
"version": opt.version,
|
||||
"opt_codes": opt.opt_codes.iter().map(|code| {
|
||||
json!({
|
||||
"code": code.code,
|
||||
"data": base64::encode(&code.data)
|
||||
})
|
||||
}).collect::<Vec<_>>()
|
||||
})
|
||||
},
|
||||
RData::RouteThrough(rt) => {
|
||||
json!({
|
||||
"type": "RT",
|
||||
"preference": rt.preference,
|
||||
"intermediate_host": rt.intermediate_host.to_string()
|
||||
})
|
||||
},
|
||||
RData::RP(rp) => {
|
||||
json!({
|
||||
"type": "RP",
|
||||
"mbox": rp.mbox.to_string(),
|
||||
"txt": rp.txt.to_string()
|
||||
})
|
||||
},
|
||||
RData::SOA(soa) => {
|
||||
json!({
|
||||
"type": "SOA",
|
||||
"mname": soa.mname.to_string(),
|
||||
"rname": soa.rname.to_string(),
|
||||
"serial": soa.serial,
|
||||
"refresh": soa.refresh,
|
||||
"retry": soa.retry,
|
||||
"expire": soa.expire,
|
||||
"minimum": soa.minimum
|
||||
})
|
||||
},
|
||||
RData::SRV(srv) => {
|
||||
json!({
|
||||
"type": "SRV",
|
||||
"priority": srv.priority,
|
||||
"weight": srv.weight,
|
||||
"port": srv.port,
|
||||
"target": srv.target.to_string()
|
||||
})
|
||||
},
|
||||
RData::SVCB(svcb) => {
|
||||
let mut params = serde_json::Map::new();
|
||||
for (key, value) in svcb.iter_params() {
|
||||
params.insert(key.to_string(), json!(base64::encode(value)));
|
||||
}
|
||||
json!({
|
||||
"type": "SVCB",
|
||||
"priority": svcb.priority,
|
||||
"target": svcb.target.to_string(),
|
||||
"params": params
|
||||
})
|
||||
},
|
||||
RData::WKS(wks) => {
|
||||
json!({
|
||||
"type": "WKS",
|
||||
"address": Ipv4Addr::from(wks.address).to_string(),
|
||||
"protocol": wks.protocol,
|
||||
"bit_map": base64::encode(&wks.bit_map)
|
||||
})
|
||||
},
|
||||
|
||||
_ => json!({
|
||||
"type": format!("{:?}", record.rdata.type_code()),
|
||||
"data": "Unhandled record type"
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resource_record_to_json(record: &ResourceRecord) -> Result<serde_json::Value, Box<dyn Error>> {
|
||||
Ok(json!({
|
||||
"name": record.name.to_string(),
|
||||
"class": format!("{:?}", record.class),
|
||||
"ttl": record.ttl,
|
||||
"rdata": extract_rdata_for_json(record),
|
||||
"cache_flush": record.cache_flush
|
||||
}))
|
||||
}
|
||||
@@ -54,3 +54,48 @@ export async function parseAuthUrl(
|
||||
return err(JSON.stringify(e));
|
||||
}
|
||||
}
|
||||
|
||||
export async function publish(
|
||||
recordName: string,
|
||||
recordContent: string,
|
||||
secretKey: string
|
||||
): Promise<Result<string[]>> {
|
||||
try {
|
||||
const res = await Pubky.publish(recordName, recordContent, secretKey);
|
||||
if (res[0] === 'error') {
|
||||
return err(res[1]);
|
||||
}
|
||||
return ok(res[1]);
|
||||
} catch (e) {
|
||||
return err(JSON.stringify(e));
|
||||
}
|
||||
}
|
||||
|
||||
interface ITxt {
|
||||
cache_flush: boolean;
|
||||
class: string;
|
||||
name: string;
|
||||
rdata: {
|
||||
strings: string[];
|
||||
type: string;
|
||||
};
|
||||
ttl: number;
|
||||
}
|
||||
interface IDNSPacket {
|
||||
dns_packet: string;
|
||||
public_key: string;
|
||||
records: ITxt[];
|
||||
signature: string;
|
||||
timestamp: number;
|
||||
}
|
||||
export async function resolve(publicKey: string): Promise<Result<IDNSPacket>> {
|
||||
try {
|
||||
const res = await Pubky.resolve(publicKey);
|
||||
if (res[0] === 'error') {
|
||||
return err(res[1]);
|
||||
}
|
||||
return ok(JSON.parse(res[1]));
|
||||
} catch (e) {
|
||||
return err(JSON.stringify(e));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user