@walletconnect/react-native-compat 2.23.2 → 2.23.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -99,6 +99,7 @@ android {
99
99
  repositories {
100
100
  mavenCentral()
101
101
  google()
102
+ maven { url 'https://jitpack.io' }
102
103
  }
103
104
 
104
105
  def kotlin_version = getExtOrDefault("kotlinVersion")
@@ -109,6 +110,17 @@ dependencies {
109
110
  //noinspection GradleDynamicVersion
110
111
  implementation "com.facebook.react:react-native:+"
111
112
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
113
+
114
+ // Yttrium - WalletConnect Pay uniffi bindings
115
+ implementation("com.github.reown-com.yttrium:yttrium-wcpay:0.9.119") {
116
+ // Exclude JNA jar, we'll use the AAR version for Android
117
+ exclude group: 'net.java.dev.jna', module: 'jna'
118
+ }
119
+ // JNA for Android (AAR with native libraries)
120
+ implementation "net.java.dev.jna:jna:5.17.0@aar"
121
+
122
+ // Coroutines for async uniffi calls
123
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
112
124
  }
113
125
 
114
126
  if (isNewArchitectureEnabled()) {
@@ -9,10 +9,10 @@ import java.util.HashMap
9
9
 
10
10
  class RNWalletConnectModulePackage : TurboReactPackage() {
11
11
  override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
12
- return if (name == RNWalletConnectModuleModule.NAME) {
13
- RNWalletConnectModuleModule(reactContext)
14
- } else {
15
- null
12
+ return when (name) {
13
+ RNWalletConnectModuleModule.NAME -> RNWalletConnectModuleModule(reactContext)
14
+ RNWalletConnectPayModule.NAME -> RNWalletConnectPayModule(reactContext)
15
+ else -> null
16
16
  }
17
17
  }
18
18
 
@@ -20,15 +20,29 @@ class RNWalletConnectModulePackage : TurboReactPackage() {
20
20
  return ReactModuleInfoProvider {
21
21
  val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
22
22
  val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
23
+
24
+ // Existing WalletConnect module
23
25
  moduleInfos[RNWalletConnectModuleModule.NAME] = ReactModuleInfo(
24
26
  RNWalletConnectModuleModule.NAME,
25
27
  RNWalletConnectModuleModule.NAME,
26
28
  false, // canOverrideExistingModule
27
29
  false, // needsEagerInit
28
- true, // hasConstants
30
+ true, // hasConstants
29
31
  false, // isCxxModule
30
32
  isTurboModule // isTurboModule
31
33
  )
34
+
35
+ // WalletConnect Pay module
36
+ moduleInfos[RNWalletConnectPayModule.NAME] = ReactModuleInfo(
37
+ RNWalletConnectPayModule.NAME,
38
+ RNWalletConnectPayModule.NAME,
39
+ false, // canOverrideExistingModule
40
+ false, // needsEagerInit
41
+ false, // hasConstants
42
+ false, // isCxxModule
43
+ isTurboModule // isTurboModule
44
+ )
45
+
32
46
  moduleInfos
33
47
  }
34
48
  }
@@ -0,0 +1,132 @@
1
+ package com.walletconnect.reactnativemodule
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.facebook.react.bridge.ReactMethod
5
+ import com.facebook.react.bridge.Promise
6
+ import kotlinx.coroutines.*
7
+ import uniffi.yttrium_wcpay.WalletConnectPayJson
8
+
9
+ /**
10
+ * React Native module for WalletConnect Pay
11
+ * Wraps the uniffi-generated WalletConnectPayJson Rust client
12
+ */
13
+ class RNWalletConnectPayModule internal constructor(context: ReactApplicationContext) :
14
+ RNWalletConnectPaySpec(context) {
15
+
16
+ private var client: WalletConnectPayJson? = null
17
+ private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
18
+
19
+ override fun getName(): String = NAME
20
+
21
+ /**
22
+ * Initialize the Pay client with SDK configuration
23
+ * @param configJson JSON string containing SDK config:
24
+ * {
25
+ * "baseUrl": string,
26
+ * "projectId": string,
27
+ * "apiKey": string,
28
+ * "sdkName": string,
29
+ * "sdkVersion": string,
30
+ * "sdkPlatform": string,
31
+ * "bundleId": string
32
+ * }
33
+ */
34
+ @ReactMethod
35
+ override fun initialize(configJson: String) {
36
+ try {
37
+ client = WalletConnectPayJson(configJson)
38
+ } catch (e: Exception) {
39
+ // Log error but don't throw - let subsequent calls fail with "not initialized"
40
+ android.util.Log.e(NAME, "Failed to initialize Pay client: ${e.message}", e)
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Get payment options for a payment link
46
+ * @param requestJson JSON string:
47
+ * { "paymentLink": string, "accounts": string[], "includePaymentInfo"?: boolean }
48
+ * @param promise Resolves with JSON string of PaymentOptionsResponse
49
+ */
50
+ @ReactMethod
51
+ override fun getPaymentOptions(requestJson: String, promise: Promise) {
52
+ val currentClient = client
53
+ if (currentClient == null) {
54
+ promise.reject("PAY_ERROR", "Pay client not initialized. Call initialize() first.")
55
+ return
56
+ }
57
+
58
+ scope.launch {
59
+ try {
60
+ val result = currentClient.getPaymentOptions(requestJson)
61
+ promise.resolve(result)
62
+ } catch (e: Exception) {
63
+ promise.reject("PAY_ERROR", e.message ?: "Unknown error", e)
64
+ }
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Get required payment actions for a selected option
70
+ * @param requestJson JSON string:
71
+ * { "paymentId": string, "optionId": string }
72
+ * @param promise Resolves with JSON string array of Action
73
+ */
74
+ @ReactMethod
75
+ override fun getRequiredPaymentActions(requestJson: String, promise: Promise) {
76
+ val currentClient = client
77
+ if (currentClient == null) {
78
+ promise.reject("PAY_ERROR", "Pay client not initialized. Call initialize() first.")
79
+ return
80
+ }
81
+
82
+ scope.launch {
83
+ try {
84
+ val result = currentClient.getRequiredPaymentActions(requestJson)
85
+ promise.resolve(result)
86
+ } catch (e: Exception) {
87
+ promise.reject("PAY_ERROR", e.message ?: "Unknown error", e)
88
+ }
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Confirm a payment with signatures
94
+ * @param requestJson JSON string:
95
+ * {
96
+ * "paymentId": string,
97
+ * "optionId": string,
98
+ * "signatures": string[],
99
+ * "collectedData"?: [{ "id": string, "value": string }]
100
+ * }
101
+ * @param promise Resolves with JSON string of ConfirmPaymentResponse
102
+ */
103
+ @ReactMethod
104
+ override fun confirmPayment(requestJson: String, promise: Promise) {
105
+ val currentClient = client
106
+ if (currentClient == null) {
107
+ promise.reject("PAY_ERROR", "Pay client not initialized. Call initialize() first.")
108
+ return
109
+ }
110
+
111
+ scope.launch {
112
+ try {
113
+ val result = currentClient.confirmPayment(requestJson)
114
+ promise.resolve(result)
115
+ } catch (e: Exception) {
116
+ promise.reject("PAY_ERROR", e.message ?: "Unknown error", e)
117
+ }
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Clean up coroutine scope when module is destroyed
123
+ */
124
+ override fun invalidate() {
125
+ scope.cancel()
126
+ super.invalidate()
127
+ }
128
+
129
+ companion object {
130
+ const val NAME = "RNWalletConnectPay"
131
+ }
132
+ }
@@ -0,0 +1,7 @@
1
+ package com.walletconnect.reactnativemodule
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+
5
+ abstract class RNWalletConnectPaySpec internal constructor(context: ReactApplicationContext) :
6
+ NativeRNWalletConnectPaySpec(context) {
7
+ }
@@ -0,0 +1,14 @@
1
+ package com.walletconnect.reactnativemodule
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
5
+ import com.facebook.react.bridge.Promise
6
+
7
+ abstract class RNWalletConnectPaySpec internal constructor(context: ReactApplicationContext) :
8
+ ReactContextBaseJavaModule(context) {
9
+
10
+ abstract fun initialize(configJson: String)
11
+ abstract fun getPaymentOptions(requestJson: String, promise: Promise)
12
+ abstract fun getRequiredPaymentActions(requestJson: String, promise: Promise)
13
+ abstract fun confirmPayment(requestJson: String, promise: Promise)
14
+ }
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-require-imports */
2
- import { getApplicationModule } from "./module/index.ts";
2
+ import { getApplicationModule, getPayModule } from "./module/index.ts";
3
3
 
4
4
  // Polyfill TextEncode / TextDecode
5
5
  import "fast-text-encoding";
@@ -76,3 +76,18 @@ if (typeof global?.Application === "undefined") {
76
76
  console.error("react-native-compat: Application module is not available");
77
77
  }
78
78
  }
79
+
80
+ // Set up globalThis.ReactNative.NativeModules.RNWalletConnectPay for @walletconnect/pay
81
+ try {
82
+ const payModule = getPayModule();
83
+ if (payModule) {
84
+ if (typeof globalThis.ReactNative === "undefined") {
85
+ globalThis.ReactNative = { NativeModules: {} };
86
+ } else if (!globalThis.ReactNative.NativeModules) {
87
+ globalThis.ReactNative.NativeModules = {};
88
+ }
89
+ globalThis.ReactNative.NativeModules.RNWalletConnectPay = payModule;
90
+ }
91
+ } catch (e) {
92
+ // Pay module not available - this is fine, it's optional
93
+ }
@@ -0,0 +1,11 @@
1
+ #ifdef RCT_NEW_ARCH_ENABLED
2
+ #import "RNRNWalletConnectModuleSpec.h"
3
+
4
+ @interface RNWalletConnectPay : NSObject <NativeRNWalletConnectPaySpec>
5
+ #else
6
+ #import <React/RCTBridgeModule.h>
7
+
8
+ @interface RNWalletConnectPay : NSObject <RCTBridgeModule>
9
+ #endif
10
+
11
+ @end
@@ -0,0 +1,122 @@
1
+ #import "RNWalletConnectPay.h"
2
+ #import <React/RCTBridge.h>
3
+
4
+ // Import the Swift bridge - this header is auto-generated
5
+ #if __has_include(<react_native_compat/react_native_compat-Swift.h>)
6
+ #import <react_native_compat/react_native_compat-Swift.h>
7
+ #elif __has_include("react_native_compat-Swift.h")
8
+ #import "react_native_compat-Swift.h"
9
+ #else
10
+ @class RNWalletConnectPayBridge;
11
+ #endif
12
+
13
+ @implementation RNWalletConnectPay {
14
+ RNWalletConnectPayBridge *_bridge;
15
+ dispatch_queue_t _queue;
16
+ }
17
+
18
+ RCT_EXPORT_MODULE()
19
+
20
+ - (instancetype)init
21
+ {
22
+ self = [super init];
23
+ if (self) {
24
+ _queue = dispatch_queue_create("com.walletconnect.pay", DISPATCH_QUEUE_SERIAL);
25
+ _bridge = [[RNWalletConnectPayBridge alloc] init];
26
+ }
27
+ return self;
28
+ }
29
+
30
+ /**
31
+ * Initialize the Pay client with SDK configuration
32
+ * @param configJson JSON string containing SDK config
33
+ */
34
+ RCT_EXPORT_METHOD(initialize:(NSString *)configJson)
35
+ {
36
+ dispatch_async(_queue, ^{
37
+ NSError *error = nil;
38
+ [self->_bridge initialize:configJson error:&error];
39
+ if (error) {
40
+ NSLog(@"[RNWalletConnectPay] Failed to initialize: %@", error.localizedDescription);
41
+ }
42
+ });
43
+ }
44
+
45
+ /**
46
+ * Get payment options for a payment link
47
+ * @param requestJson JSON request string
48
+ * @param resolve Promise resolve callback
49
+ * @param reject Promise reject callback
50
+ */
51
+ RCT_EXPORT_METHOD(getPaymentOptions:(NSString *)requestJson
52
+ resolve:(RCTPromiseResolveBlock)resolve
53
+ reject:(RCTPromiseRejectBlock)reject)
54
+ {
55
+ dispatch_async(_queue, ^{
56
+ [self->_bridge getPaymentOptions:requestJson completion:^(NSString *result, NSError *error) {
57
+ if (error) {
58
+ reject(@"PAY_ERROR", error.localizedDescription, error);
59
+ } else {
60
+ resolve(result);
61
+ }
62
+ }];
63
+ });
64
+ }
65
+
66
+ /**
67
+ * Get required payment actions for a selected option
68
+ * @param requestJson JSON request string
69
+ * @param resolve Promise resolve callback
70
+ * @param reject Promise reject callback
71
+ */
72
+ RCT_EXPORT_METHOD(getRequiredPaymentActions:(NSString *)requestJson
73
+ resolve:(RCTPromiseResolveBlock)resolve
74
+ reject:(RCTPromiseRejectBlock)reject)
75
+ {
76
+ dispatch_async(_queue, ^{
77
+ [self->_bridge getRequiredPaymentActions:requestJson completion:^(NSString *result, NSError *error) {
78
+ if (error) {
79
+ reject(@"PAY_ERROR", error.localizedDescription, error);
80
+ } else {
81
+ resolve(result);
82
+ }
83
+ }];
84
+ });
85
+ }
86
+
87
+ /**
88
+ * Confirm a payment with signatures
89
+ * @param requestJson JSON request string
90
+ * @param resolve Promise resolve callback
91
+ * @param reject Promise reject callback
92
+ */
93
+ RCT_EXPORT_METHOD(confirmPayment:(NSString *)requestJson
94
+ resolve:(RCTPromiseResolveBlock)resolve
95
+ reject:(RCTPromiseRejectBlock)reject)
96
+ {
97
+ dispatch_async(_queue, ^{
98
+ [self->_bridge confirmPayment:requestJson completion:^(NSString *result, NSError *error) {
99
+ if (error) {
100
+ reject(@"PAY_ERROR", error.localizedDescription, error);
101
+ } else {
102
+ resolve(result);
103
+ }
104
+ }];
105
+ });
106
+ }
107
+
108
+ + (BOOL)requiresMainQueueSetup
109
+ {
110
+ return NO;
111
+ }
112
+
113
+ // Don't compile this code when we build for the old architecture.
114
+ #ifdef RCT_NEW_ARCH_ENABLED
115
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
116
+ (const facebook::react::ObjCTurboModule::InitParams &)params
117
+ {
118
+ return std::make_shared<facebook::react::NativeRNWalletConnectPaySpecJSI>(params);
119
+ }
120
+ #endif
121
+
122
+ @end
@@ -0,0 +1,71 @@
1
+ import Foundation
2
+ import YttriumWrapper
3
+
4
+ @objc public class RNWalletConnectPayBridge: NSObject {
5
+ private var client: WalletConnectPayJson?
6
+
7
+ @objc public override init() {
8
+ super.init()
9
+ }
10
+
11
+ @objc public func initialize(_ sdkConfig: String) throws {
12
+ client = try WalletConnectPayJson(sdkConfig: sdkConfig)
13
+ }
14
+
15
+ @objc public func getPaymentOptions(
16
+ _ requestJson: String,
17
+ completion: @escaping (String?, Error?) -> Void
18
+ ) {
19
+ guard let client = client else {
20
+ completion(nil, NSError(domain: "RNWalletConnectPay", code: 1, userInfo: [NSLocalizedDescriptionKey: "Pay client not initialized"]))
21
+ return
22
+ }
23
+
24
+ Task {
25
+ do {
26
+ let result = try await client.getPaymentOptions(requestJson: requestJson)
27
+ completion(result, nil)
28
+ } catch {
29
+ completion(nil, error)
30
+ }
31
+ }
32
+ }
33
+
34
+ @objc public func getRequiredPaymentActions(
35
+ _ requestJson: String,
36
+ completion: @escaping (String?, Error?) -> Void
37
+ ) {
38
+ guard let client = client else {
39
+ completion(nil, NSError(domain: "RNWalletConnectPay", code: 1, userInfo: [NSLocalizedDescriptionKey: "Pay client not initialized"]))
40
+ return
41
+ }
42
+
43
+ Task {
44
+ do {
45
+ let result = try await client.getRequiredPaymentActions(requestJson: requestJson)
46
+ completion(result, nil)
47
+ } catch {
48
+ completion(nil, error)
49
+ }
50
+ }
51
+ }
52
+
53
+ @objc public func confirmPayment(
54
+ _ requestJson: String,
55
+ completion: @escaping (String?, Error?) -> Void
56
+ ) {
57
+ guard let client = client else {
58
+ completion(nil, NSError(domain: "RNWalletConnectPay", code: 1, userInfo: [NSLocalizedDescriptionKey: "Pay client not initialized"]))
59
+ return
60
+ }
61
+
62
+ Task {
63
+ do {
64
+ let result = try await client.confirmPayment(requestJson: requestJson)
65
+ completion(result, nil)
66
+ } catch {
67
+ completion(nil, error)
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,56 @@
1
+ import type { TurboModule } from "react-native";
2
+ import { TurboModuleRegistry } from "react-native";
3
+
4
+ /**
5
+ * TurboModule spec for WalletConnect Pay native module
6
+ *
7
+ * This module wraps the uniffi-generated WalletConnectPayJson Rust client
8
+ * and provides a JSON-based interface for payment operations.
9
+ */
10
+ export interface Spec extends TurboModule {
11
+ /**
12
+ * Initialize the Pay client with SDK configuration
13
+ * @param configJson JSON string containing SDK config:
14
+ * {
15
+ * "baseUrl": string,
16
+ * "projectId": string,
17
+ * "apiKey": string,
18
+ * "sdkName": string,
19
+ * "sdkVersion": string,
20
+ * "sdkPlatform": string,
21
+ * "bundleId": string
22
+ * }
23
+ */
24
+ initialize(configJson: string): void;
25
+
26
+ /**
27
+ * Get payment options for a payment link
28
+ * @param requestJson JSON string:
29
+ * { "paymentLink": string, "accounts": string[], "includePaymentInfo"?: boolean }
30
+ * @returns Promise resolving to JSON string of PaymentOptionsResponse
31
+ */
32
+ getPaymentOptions(requestJson: string): Promise<string>;
33
+
34
+ /**
35
+ * Get required payment actions for a selected option
36
+ * @param requestJson JSON string:
37
+ * { "paymentId": string, "optionId": string }
38
+ * @returns Promise resolving to JSON string array of Action
39
+ */
40
+ getRequiredPaymentActions(requestJson: string): Promise<string>;
41
+
42
+ /**
43
+ * Confirm a payment with signatures
44
+ * @param requestJson JSON string:
45
+ * {
46
+ * "paymentId": string,
47
+ * "optionId": string,
48
+ * "signatures": string[],
49
+ * "collectedData"?: [{ "id": string, "value": string }]
50
+ * }
51
+ * @returns Promise resolving to JSON string of ConfirmPaymentResponse
52
+ */
53
+ confirmPayment(requestJson: string): Promise<string>;
54
+ }
55
+
56
+ export default TurboModuleRegistry.get<Spec>("RNWalletConnectPay");
package/module/index.ts CHANGED
@@ -6,12 +6,21 @@ const LINKING_ERROR =
6
6
  "- You rebuilt the app after installing the package\n" +
7
7
  "- If you are using Expo: install expo-application \n";
8
8
 
9
+ const PAY_LINKING_ERROR =
10
+ `The RNWalletConnectPay module doesn't seem to be linked. Make sure: \n\n` +
11
+ "- You rebuilt the app after installing the package\n" +
12
+ "- The Yttrium native dependency is properly installed\n";
13
+
9
14
  const isTurboModuleEnabled = global.__turboModuleProxy != null;
10
15
 
11
16
  const RNWalletConnectModule = isTurboModuleEnabled
12
17
  ? require("../module/NativeRNWalletConnectModule.ts").default
13
18
  : NativeModules.RNWalletConnectModule;
14
19
 
20
+ const RNWalletConnectPay = isTurboModuleEnabled
21
+ ? require("../module/NativeRNWalletConnectPay.ts").default
22
+ : NativeModules.RNWalletConnectPay;
23
+
15
24
  function getExpoModule(): any | undefined {
16
25
  try {
17
26
  const ExpoApplication = require("expo-application");
@@ -45,3 +54,36 @@ export function getApplicationModule(): any | undefined {
45
54
  }
46
55
  }
47
56
  }
57
+
58
+ /**
59
+ * Get the WalletConnect Pay native module
60
+ * @returns The RNWalletConnectPay native module or undefined if not available
61
+ */
62
+ export function getPayModule(): any | undefined {
63
+ try {
64
+ if (!RNWalletConnectPay) throw new Error();
65
+ return RNWalletConnectPay;
66
+ } catch {
67
+ return undefined;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Check if the Pay native module is available
73
+ * @returns true if the Pay module is linked and available
74
+ */
75
+ export function isPayModuleAvailable(): boolean {
76
+ return RNWalletConnectPay != null;
77
+ }
78
+
79
+ /**
80
+ * Get the WalletConnect Pay native module or throw if not available
81
+ * @throws Error if the Pay module is not linked
82
+ * @returns The RNWalletConnectPay native module
83
+ */
84
+ export function requirePayModule(): any {
85
+ if (!RNWalletConnectPay) {
86
+ throw new Error(PAY_LINKING_ERROR);
87
+ }
88
+ return RNWalletConnectPay;
89
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walletconnect/react-native-compat",
3
- "description": "Shims for WalletConnect Protocol in React Native Projects",
4
- "version": "2.23.2",
3
+ "description": "Native modules and shims for WalletConnect Protocol in React Native Projects",
4
+ "version": "2.23.3",
5
5
  "author": "WalletConnect, Inc. <walletconnect.com>",
6
6
  "homepage": "https://github.com/walletconnect/walletconnect-monorepo/",
7
7
  "license": "SEE LICENSE IN LICENSE.md",
@@ -11,10 +11,14 @@ Pod::Spec.new do |s|
11
11
  s.license = package["license"]
12
12
  s.authors = package["author"]
13
13
 
14
- s.platforms = { :ios => "11.0", :visionos => "1.0" }
14
+ s.platforms = { :ios => "13.0", :visionos => "1.0" }
15
15
  s.source = { :git => "https://github.com/walletconnect/walletconnect-monorepo.git", :tag => "#{s.version}" }
16
16
 
17
- s.source_files = "ios/**/*.{h,m,mm}"
17
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
18
+ s.swift_version = "5.0"
19
+
20
+ # Yttrium - WalletConnect Pay uniffi bindings
21
+ s.dependency "YttriumWrapper", "0.10.0"
18
22
 
19
23
  # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
20
24
  # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.