@novastera-oss/nitro-metamask 0.3.2 → 0.4.1

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.
Files changed (44) hide show
  1. package/README.md +124 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/com/margelo/nitro/nitrometamask/HybridNitroMetamask.kt +583 -0
  4. package/android/src/main/java/com/{nitrometamask → margelo/nitro/nitrometamask}/MetamaskContextHolder.kt +1 -1
  5. package/android/src/main/java/com/{nitrometamask → margelo/nitro/nitrometamask}/NitroMetamaskPackage.kt +1 -1
  6. package/app.plugin.js +121 -0
  7. package/ios/HybridNitroMetamask.swift +107 -1
  8. package/lib/typescript/src/specs/nitro-metamask.nitro.d.ts +36 -1
  9. package/lib/typescript/src/specs/nitro-metamask.nitro.d.ts.map +1 -1
  10. package/nitrogen/generated/android/NitroMetamask+autolinking.cmake +2 -0
  11. package/nitrogen/generated/android/c++/JConnectResult.hpp +3 -3
  12. package/nitrogen/generated/android/c++/JConnectSignResult.hpp +65 -0
  13. package/nitrogen/generated/android/c++/JHybridNitroMetamaskSpec.cpp +62 -0
  14. package/nitrogen/generated/android/c++/JHybridNitroMetamaskSpec.hpp +4 -0
  15. package/nitrogen/generated/android/c++/JVariant_NullType_Long.cpp +26 -0
  16. package/nitrogen/generated/android/c++/JVariant_NullType_Long.hpp +69 -0
  17. package/nitrogen/generated/android/c++/JVariant_NullType_String.cpp +26 -0
  18. package/nitrogen/generated/android/c++/JVariant_NullType_String.hpp +70 -0
  19. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/ConnectResult.kt +2 -2
  20. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/ConnectSignResult.kt +44 -0
  21. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/HybridNitroMetamaskSpec.kt +17 -0
  22. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/Variant_NullType_Long.kt +59 -0
  23. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/Variant_NullType_String.kt +59 -0
  24. package/nitrogen/generated/ios/NitroMetamask-Swift-Cxx-Bridge.cpp +24 -0
  25. package/nitrogen/generated/ios/NitroMetamask-Swift-Cxx-Bridge.hpp +217 -0
  26. package/nitrogen/generated/ios/NitroMetamask-Swift-Cxx-Umbrella.hpp +6 -0
  27. package/nitrogen/generated/ios/c++/HybridNitroMetamaskSpecSwift.hpp +37 -1
  28. package/nitrogen/generated/ios/swift/ConnectResult.swift +2 -2
  29. package/nitrogen/generated/ios/swift/ConnectSignResult.swift +40 -0
  30. package/nitrogen/generated/ios/swift/Func_void_ConnectSignResult.swift +47 -0
  31. package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__int64_t_.swift +59 -0
  32. package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__std__string_.swift +59 -0
  33. package/nitrogen/generated/ios/swift/HybridNitroMetamaskSpec.swift +4 -0
  34. package/nitrogen/generated/ios/swift/HybridNitroMetamaskSpec_cxx.swift +96 -0
  35. package/nitrogen/generated/ios/swift/Variant_NullType_Int64.swift +18 -0
  36. package/nitrogen/generated/ios/swift/Variant_NullType_String.swift +18 -0
  37. package/nitrogen/generated/shared/c++/ConnectResult.hpp +5 -5
  38. package/nitrogen/generated/shared/c++/ConnectSignResult.hpp +91 -0
  39. package/nitrogen/generated/shared/c++/HybridNitroMetamaskSpec.cpp +4 -0
  40. package/nitrogen/generated/shared/c++/HybridNitroMetamaskSpec.hpp +11 -1
  41. package/package.json +4 -3
  42. package/react-native.config.js +1 -1
  43. package/src/specs/nitro-metamask.nitro.ts +37 -1
  44. package/android/src/main/java/com/nitrometamask/HybridNitroMetamask.kt +0 -146
package/app.plugin.js ADDED
@@ -0,0 +1,121 @@
1
+ const { withAppDelegate } = require('@expo/config-plugins');
2
+
3
+ const withMetamaskAppDelegate = (config) => {
4
+ return withAppDelegate(config, (config) => {
5
+ const { modResults } = config;
6
+
7
+ // Check if AppDelegate is Swift
8
+ if (modResults.language === 'swift') {
9
+ // Check if the method already exists
10
+ if (modResults.contents.includes('MetaMaskSDK.shared.handleUrl')) {
11
+ return config;
12
+ }
13
+
14
+ // Add import if not present
15
+ if (!modResults.contents.includes('import MetaMaskSDK')) {
16
+ // Find the last import statement and add after it
17
+ const importRegex = /^import\s+.*$/gm;
18
+ const imports = modResults.contents.match(importRegex);
19
+ if (imports && imports.length > 0) {
20
+ const lastImport = imports[imports.length - 1];
21
+ const lastImportIndex = modResults.contents.lastIndexOf(lastImport);
22
+ modResults.contents =
23
+ modResults.contents.slice(0, lastImportIndex + lastImport.length) +
24
+ '\nimport MetaMaskSDK' +
25
+ modResults.contents.slice(lastImportIndex + lastImport.length);
26
+ } else {
27
+ // No imports found, add at the top after the first line
28
+ const firstLineIndex = modResults.contents.indexOf('\n');
29
+ modResults.contents =
30
+ modResults.contents.slice(0, firstLineIndex + 1) +
31
+ 'import MetaMaskSDK\n' +
32
+ modResults.contents.slice(firstLineIndex + 1);
33
+ }
34
+ }
35
+
36
+ // Add the deep link handler method
37
+ const deepLinkHandler = `
38
+ // Handle deep links from MetaMask wallet
39
+ // MetaMask returns to the app via deep link after signing/connecting
40
+ // Added by @novastera-oss/nitro-metamask config plugin
41
+ func application(
42
+ _ app: UIApplication,
43
+ open url: URL,
44
+ options: [UIApplication.OpenURLOptionsKey: Any] = [:]
45
+ ) -> Bool {
46
+ // Check if this is a MetaMask deep link (host="mmsdk")
47
+ if let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
48
+ components.host == "mmsdk" {
49
+ // Handle MetaMask deep link return
50
+ MetaMaskSDK.shared.handleUrl(url)
51
+ return true
52
+ }
53
+
54
+ // Handle other deep links (e.g., React Native Linking)
55
+ return false
56
+ }`;
57
+
58
+ // Insert before the last closing brace of the AppDelegate class
59
+ // Try to find the closing brace of the class before @end or end of file
60
+ const classEndPattern = /(\s+)\}(?=\s*(?:@end|$))/;
61
+ const match = modResults.contents.match(classEndPattern);
62
+ if (match) {
63
+ const indent = match[1];
64
+ const insertIndex = match.index;
65
+ modResults.contents =
66
+ modResults.contents.slice(0, insertIndex) +
67
+ deepLinkHandler.replace(/^ /gm, indent) +
68
+ '\n' + indent + '}' +
69
+ modResults.contents.slice(insertIndex + match[0].length);
70
+ } else {
71
+ // Fallback: append before @end
72
+ modResults.contents = modResults.contents.replace(
73
+ /^(@end|}$)/m,
74
+ deepLinkHandler + '\n$1'
75
+ );
76
+ }
77
+ } else if (modResults.language === 'objc') {
78
+ // Handle Objective-C AppDelegate
79
+ if (modResults.contents.includes('MetaMaskSDK')) {
80
+ return config;
81
+ }
82
+
83
+ // Add import
84
+ if (!modResults.contents.includes('#import <MetaMaskSDK/MetaMaskSDK.h>')) {
85
+ const importRegex = /^#import\s+.*$/gm;
86
+ const imports = modResults.contents.match(importRegex);
87
+ if (imports && imports.length > 0) {
88
+ const lastImport = imports[imports.length - 1];
89
+ const lastImportIndex = modResults.contents.lastIndexOf(lastImport);
90
+ modResults.contents =
91
+ modResults.contents.slice(0, lastImportIndex + lastImport.length) +
92
+ '\n#import <MetaMaskSDK/MetaMaskSDK.h>' +
93
+ modResults.contents.slice(lastImportIndex + lastImport.length);
94
+ }
95
+ }
96
+
97
+ const objcHandler = `
98
+ - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
99
+ // Check if this is a MetaMask deep link (host="mmsdk")
100
+ NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
101
+ if ([components.host isEqualToString:@"mmsdk"]) {
102
+ // Handle MetaMask deep link return
103
+ [[MetaMaskSDK sharedInstance] handleUrl:url];
104
+ return YES;
105
+ }
106
+
107
+ // Handle other deep links
108
+ return NO;
109
+ }`;
110
+
111
+ modResults.contents = modResults.contents.replace(
112
+ /^(@end|}$)/m,
113
+ objcHandler + '\n$1'
114
+ );
115
+ }
116
+
117
+ return config;
118
+ });
119
+ };
120
+
121
+ module.exports = withMetamaskAppDelegate;
@@ -4,6 +4,18 @@ import Foundation
4
4
 
5
5
  final class HybridNitroMetamask: HybridNitroMetamaskSpec {
6
6
  private let sdk = MetaMaskSDK.shared
7
+
8
+ // Configurable dapp URL - stored for consistency with Android
9
+ // iOS SDK handles deep linking automatically via Info.plist
10
+ private var dappUrl: String? = nil
11
+
12
+ func configure(dappUrl: String?, deepLinkScheme: String?) {
13
+ // iOS SDK handles deep linking automatically via Info.plist
14
+ // Store the URL for consistency with Android implementation
15
+ // deepLinkScheme is ignored on iOS as it's handled automatically
16
+ self.dappUrl = dappUrl
17
+ NSLog("NitroMetamask: configure: Dapp URL set to \(dappUrl ?? "default"). Deep link handled automatically via Info.plist")
18
+ }
7
19
 
8
20
  func connect() -> Promise<ConnectResult> {
9
21
  // Use Promise.async with Swift async/await for best practice in Nitro modules
@@ -42,7 +54,7 @@ final class HybridNitroMetamask: HybridNitroMetamaskSpec {
42
54
 
43
55
  return ConnectResult(
44
56
  address: address,
45
- chainId: Double(chainIdInt)
57
+ chainId: Int64(chainIdInt)
46
58
  )
47
59
 
48
60
  case .failure(let error):
@@ -93,4 +105,98 @@ final class HybridNitroMetamask: HybridNitroMetamaskSpec {
93
105
  }
94
106
  }
95
107
  }
108
+
109
+ func connectSign(nonce: String, exp: Int64) -> Promise<ConnectSignResult> {
110
+ // Use Promise.async with Swift async/await for best practice in Nitro modules
111
+ // Reference: https://nitro.margelo.com/docs/types/promises
112
+ // Based on MetaMask iOS SDK: connectAndSign(message:) convenience method
113
+ // Reference: https://github.com/MetaMask/metamask-ios-sdk
114
+ return Promise.async {
115
+ // Construct JSON message with only nonce and exp
116
+ // We don't include address or chainID - just encrypt nonce and exp
117
+ let messageDict: [String: Any] = [
118
+ "nonce": nonce,
119
+ "exp": exp
120
+ ]
121
+
122
+ guard let jsonData = try? JSONSerialization.data(withJSONObject: messageDict),
123
+ let message = String(data: jsonData, encoding: .utf8) else {
124
+ throw NSError(
125
+ domain: "MetamaskConnector",
126
+ code: -1,
127
+ userInfo: [NSLocalizedDescriptionKey: "Failed to create JSON message"]
128
+ )
129
+ }
130
+
131
+ NSLog("NitroMetamask: connectSign: Constructed message with nonce and exp: \(message)")
132
+
133
+ // Use the SDK's connectAndSign convenience method - it will connect if needed and sign the message
134
+ // This is the recommended approach per MetaMask iOS SDK documentation
135
+ // Reference: https://github.com/MetaMask/metamask-ios-sdk
136
+ let connectSignResult = try await self.sdk.connectAndSign(message: message)
137
+
138
+ switch connectSignResult {
139
+ case .success(let signature):
140
+ // After connectSign completes, get the address and chainId from the SDK
141
+ guard let address = self.sdk.account, !address.isEmpty else {
142
+ throw NSError(
143
+ domain: "MetamaskConnector",
144
+ code: -1,
145
+ userInfo: [NSLocalizedDescriptionKey: "Failed to retrieve address after connectSign"]
146
+ )
147
+ }
148
+
149
+ guard let chainIdHex = self.sdk.chainId, !chainIdHex.isEmpty else {
150
+ throw NSError(
151
+ domain: "MetamaskConnector",
152
+ code: -1,
153
+ userInfo: [NSLocalizedDescriptionKey: "Failed to retrieve chainId after connectSign"]
154
+ )
155
+ }
156
+
157
+ // Parse chainId from hex string (e.g., "0x1") to Int64
158
+ guard let chainId = Int64(chainIdHex.replacingOccurrences(of: "0x", with: ""), radix: 16) else {
159
+ throw NSError(
160
+ domain: "MetamaskConnector",
161
+ code: -1,
162
+ userInfo: [NSLocalizedDescriptionKey: "Invalid chainId format: \(chainIdHex)"]
163
+ )
164
+ }
165
+
166
+ NSLog("NitroMetamask: connectSign: Signature received successfully, address=\(address), chainId=\(chainId)")
167
+
168
+ // Return ConnectSignResult with signature, address, and chainId
169
+ return ConnectSignResult(signature: signature, address: address, chainId: chainId)
170
+
171
+ case .failure(let error):
172
+ throw error
173
+ }
174
+ }
175
+ }
176
+
177
+ func getAddress() -> Promise<Variant_NullType_String> {
178
+ return Promise.async {
179
+ if let account = self.sdk.account, !account.isEmpty {
180
+ return Variant_NullType_String.second(account)
181
+ } else {
182
+ return Variant_NullType_String.first(NullType())
183
+ }
184
+ }
185
+ }
186
+
187
+ func getChainId() -> Promise<Variant_NullType_Int64> {
188
+ return Promise.async {
189
+ guard let chainIdHex = self.sdk.chainId, !chainIdHex.isEmpty else {
190
+ return Variant_NullType_Int64.first(NullType())
191
+ }
192
+
193
+ // Parse chainId from hex string (e.g., "0x1") to Int64 (bigint maps to Int64 in Swift)
194
+ if let chainIdInt = Int64(chainIdHex.replacingOccurrences(of: "0x", with: ""), radix: 16) {
195
+ return Variant_NullType_Int64.second(chainIdInt)
196
+ } else {
197
+ NSLog("NitroMetamask: Invalid chainId format: \(chainIdHex)")
198
+ return Variant_NullType_Int64.first(NullType())
199
+ }
200
+ }
201
+ }
96
202
  }
@@ -1,13 +1,48 @@
1
1
  import { type HybridObject } from 'react-native-nitro-modules';
2
2
  export interface ConnectResult {
3
3
  address: string;
4
- chainId: number;
4
+ chainId: bigint;
5
+ }
6
+ export interface ConnectSignResult {
7
+ signature: string;
8
+ address: string;
9
+ chainId: bigint;
5
10
  }
6
11
  export interface NitroMetamask extends HybridObject<{
7
12
  ios: 'swift';
8
13
  android: 'kotlin';
9
14
  }> {
15
+ /**
16
+ * Configure the dapp URL and deep link scheme for MetaMask SDK.
17
+ *
18
+ * @param dappUrl - A valid HTTP/HTTPS URL (e.g., "https://yourdomain.com").
19
+ * If not provided, defaults to "https://novastera.com".
20
+ * This is used for SDK validation.
21
+ * @param deepLinkScheme - The deep link scheme from your AndroidManifest.xml (e.g., "nitrometamask").
22
+ * If not provided, the library will attempt to auto-detect it.
23
+ * This is used to return to your app after MetaMask operations.
24
+ */
25
+ configure(dappUrl?: string, deepLinkScheme?: string): void;
10
26
  connect(): Promise<ConnectResult>;
11
27
  signMessage(message: string): Promise<string>;
28
+ /**
29
+ * Connect to MetaMask (if not already connected) and sign a message containing nonce and expiration.
30
+ * Returns the signature along with the address and chainId that were used to sign.
31
+ *
32
+ * @param nonce - A unique nonce for this signing request
33
+ * @param exp - Expiration timestamp (as bigint)
34
+ * @returns Promise resolving to ConnectSignResult containing signature, address, and chainId
35
+ */
36
+ connectSign(nonce: string, exp: bigint): Promise<ConnectSignResult>;
37
+ /**
38
+ * Get the currently connected wallet address.
39
+ * Returns null if not connected.
40
+ */
41
+ getAddress(): Promise<string | null>;
42
+ /**
43
+ * Get the current chain ID.
44
+ * Returns null if not connected.
45
+ */
46
+ getChainId(): Promise<bigint | null>;
12
47
  }
13
48
  //# sourceMappingURL=nitro-metamask.nitro.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nitro-metamask.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/nitro-metamask.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;IACtF,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC,CAAA;IACjC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CAC9C"}
1
+ {"version":3,"file":"nitro-metamask.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/nitro-metamask.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;IACtF;;;;;;;;;OASG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1D,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC,CAAA;IACjC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC7C;;;;;;;OAOG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACnE;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACpC;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CACrC"}
@@ -36,6 +36,8 @@ target_sources(
36
36
  ../nitrogen/generated/shared/c++/HybridNitroMetamaskSpec.cpp
37
37
  # Android-specific Nitrogen C++ sources
38
38
  ../nitrogen/generated/android/c++/JHybridNitroMetamaskSpec.cpp
39
+ ../nitrogen/generated/android/c++/JVariant_NullType_String.cpp
40
+ ../nitrogen/generated/android/c++/JVariant_NullType_Long.cpp
39
41
  )
40
42
 
41
43
  # From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
@@ -33,8 +33,8 @@ namespace margelo::nitro::nitrometamask {
33
33
  static const auto clazz = javaClassStatic();
34
34
  static const auto fieldAddress = clazz->getField<jni::JString>("address");
35
35
  jni::local_ref<jni::JString> address = this->getFieldValue(fieldAddress);
36
- static const auto fieldChainId = clazz->getField<double>("chainId");
37
- double chainId = this->getFieldValue(fieldChainId);
36
+ static const auto fieldChainId = clazz->getField<int64_t>("chainId");
37
+ int64_t chainId = this->getFieldValue(fieldChainId);
38
38
  return ConnectResult(
39
39
  address->toStdString(),
40
40
  chainId
@@ -47,7 +47,7 @@ namespace margelo::nitro::nitrometamask {
47
47
  */
48
48
  [[maybe_unused]]
49
49
  static jni::local_ref<JConnectResult::javaobject> fromCpp(const ConnectResult& value) {
50
- using JSignature = JConnectResult(jni::alias_ref<jni::JString>, double);
50
+ using JSignature = JConnectResult(jni::alias_ref<jni::JString>, int64_t);
51
51
  static const auto clazz = javaClassStatic();
52
52
  static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
53
53
  return create(
@@ -0,0 +1,65 @@
1
+ ///
2
+ /// JConnectSignResult.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include "ConnectSignResult.hpp"
12
+
13
+ #include <string>
14
+
15
+ namespace margelo::nitro::nitrometamask {
16
+
17
+ using namespace facebook;
18
+
19
+ /**
20
+ * The C++ JNI bridge between the C++ struct "ConnectSignResult" and the the Kotlin data class "ConnectSignResult".
21
+ */
22
+ struct JConnectSignResult final: public jni::JavaClass<JConnectSignResult> {
23
+ public:
24
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitrometamask/ConnectSignResult;";
25
+
26
+ public:
27
+ /**
28
+ * Convert this Java/Kotlin-based struct to the C++ struct ConnectSignResult by copying all values to C++.
29
+ */
30
+ [[maybe_unused]]
31
+ [[nodiscard]]
32
+ ConnectSignResult toCpp() const {
33
+ static const auto clazz = javaClassStatic();
34
+ static const auto fieldSignature = clazz->getField<jni::JString>("signature");
35
+ jni::local_ref<jni::JString> signature = this->getFieldValue(fieldSignature);
36
+ static const auto fieldAddress = clazz->getField<jni::JString>("address");
37
+ jni::local_ref<jni::JString> address = this->getFieldValue(fieldAddress);
38
+ static const auto fieldChainId = clazz->getField<int64_t>("chainId");
39
+ int64_t chainId = this->getFieldValue(fieldChainId);
40
+ return ConnectSignResult(
41
+ signature->toStdString(),
42
+ address->toStdString(),
43
+ chainId
44
+ );
45
+ }
46
+
47
+ public:
48
+ /**
49
+ * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
50
+ */
51
+ [[maybe_unused]]
52
+ static jni::local_ref<JConnectSignResult::javaobject> fromCpp(const ConnectSignResult& value) {
53
+ using JSignature = JConnectSignResult(jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, int64_t);
54
+ static const auto clazz = javaClassStatic();
55
+ static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
56
+ return create(
57
+ clazz,
58
+ jni::make_jstring(value.signature),
59
+ jni::make_jstring(value.address),
60
+ value.chainId
61
+ );
62
+ }
63
+ };
64
+
65
+ } // namespace margelo::nitro::nitrometamask
@@ -9,12 +9,22 @@
9
9
 
10
10
  // Forward declaration of `ConnectResult` to properly resolve imports.
11
11
  namespace margelo::nitro::nitrometamask { struct ConnectResult; }
12
+ // Forward declaration of `ConnectSignResult` to properly resolve imports.
13
+ namespace margelo::nitro::nitrometamask { struct ConnectSignResult; }
12
14
 
13
15
  #include "ConnectResult.hpp"
14
16
  #include <NitroModules/Promise.hpp>
15
17
  #include <NitroModules/JPromise.hpp>
16
18
  #include "JConnectResult.hpp"
17
19
  #include <string>
20
+ #include "ConnectSignResult.hpp"
21
+ #include "JConnectSignResult.hpp"
22
+ #include <NitroModules/Null.hpp>
23
+ #include <variant>
24
+ #include "JVariant_NullType_String.hpp"
25
+ #include <NitroModules/JNull.hpp>
26
+ #include "JVariant_NullType_Long.hpp"
27
+ #include <optional>
18
28
 
19
29
  namespace margelo::nitro::nitrometamask {
20
30
 
@@ -48,6 +58,10 @@ namespace margelo::nitro::nitrometamask {
48
58
 
49
59
 
50
60
  // Methods
61
+ void JHybridNitroMetamaskSpec::configure(const std::optional<std::string>& dappUrl, const std::optional<std::string>& deepLinkScheme) {
62
+ static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* dappUrl */, jni::alias_ref<jni::JString> /* deepLinkScheme */)>("configure");
63
+ method(_javaPart, dappUrl.has_value() ? jni::make_jstring(dappUrl.value()) : nullptr, deepLinkScheme.has_value() ? jni::make_jstring(deepLinkScheme.value()) : nullptr);
64
+ }
51
65
  std::shared_ptr<Promise<ConnectResult>> JHybridNitroMetamaskSpec::connect() {
52
66
  static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("connect");
53
67
  auto __result = method(_javaPart);
@@ -80,5 +94,53 @@ namespace margelo::nitro::nitrometamask {
80
94
  return __promise;
81
95
  }();
82
96
  }
97
+ std::shared_ptr<Promise<ConnectSignResult>> JHybridNitroMetamaskSpec::connectSign(const std::string& nonce, int64_t exp) {
98
+ static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* nonce */, int64_t /* exp */)>("connectSign");
99
+ auto __result = method(_javaPart, jni::make_jstring(nonce), exp);
100
+ return [&]() {
101
+ auto __promise = Promise<ConnectSignResult>::create();
102
+ __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
103
+ auto __result = jni::static_ref_cast<JConnectSignResult>(__boxedResult);
104
+ __promise->resolve(__result->toCpp());
105
+ });
106
+ __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
107
+ jni::JniException __jniError(__throwable);
108
+ __promise->reject(std::make_exception_ptr(__jniError));
109
+ });
110
+ return __promise;
111
+ }();
112
+ }
113
+ std::shared_ptr<Promise<std::variant<nitro::NullType, std::string>>> JHybridNitroMetamaskSpec::getAddress() {
114
+ static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getAddress");
115
+ auto __result = method(_javaPart);
116
+ return [&]() {
117
+ auto __promise = Promise<std::variant<nitro::NullType, std::string>>::create();
118
+ __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
119
+ auto __result = jni::static_ref_cast<JVariant_NullType_String>(__boxedResult);
120
+ __promise->resolve(__result->toCpp());
121
+ });
122
+ __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
123
+ jni::JniException __jniError(__throwable);
124
+ __promise->reject(std::make_exception_ptr(__jniError));
125
+ });
126
+ return __promise;
127
+ }();
128
+ }
129
+ std::shared_ptr<Promise<std::variant<nitro::NullType, int64_t>>> JHybridNitroMetamaskSpec::getChainId() {
130
+ static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getChainId");
131
+ auto __result = method(_javaPart);
132
+ return [&]() {
133
+ auto __promise = Promise<std::variant<nitro::NullType, int64_t>>::create();
134
+ __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
135
+ auto __result = jni::static_ref_cast<JVariant_NullType_Long>(__boxedResult);
136
+ __promise->resolve(__result->toCpp());
137
+ });
138
+ __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
139
+ jni::JniException __jniError(__throwable);
140
+ __promise->reject(std::make_exception_ptr(__jniError));
141
+ });
142
+ return __promise;
143
+ }();
144
+ }
83
145
 
84
146
  } // namespace margelo::nitro::nitrometamask
@@ -54,8 +54,12 @@ namespace margelo::nitro::nitrometamask {
54
54
 
55
55
  public:
56
56
  // Methods
57
+ void configure(const std::optional<std::string>& dappUrl, const std::optional<std::string>& deepLinkScheme) override;
57
58
  std::shared_ptr<Promise<ConnectResult>> connect() override;
58
59
  std::shared_ptr<Promise<std::string>> signMessage(const std::string& message) override;
60
+ std::shared_ptr<Promise<ConnectSignResult>> connectSign(const std::string& nonce, int64_t exp) override;
61
+ std::shared_ptr<Promise<std::variant<nitro::NullType, std::string>>> getAddress() override;
62
+ std::shared_ptr<Promise<std::variant<nitro::NullType, int64_t>>> getChainId() override;
59
63
 
60
64
  private:
61
65
  friend HybridBase;
@@ -0,0 +1,26 @@
1
+ ///
2
+ /// JVariant_NullType_Long.cpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #include "JVariant_NullType_Long.hpp"
9
+
10
+ namespace margelo::nitro::nitrometamask {
11
+ /**
12
+ * Converts JVariant_NullType_Long to std::variant<nitro::NullType, int64_t>
13
+ */
14
+ std::variant<nitro::NullType, int64_t> JVariant_NullType_Long::toCpp() const {
15
+ if (isInstanceOf(JVariant_NullType_Long_impl::First::javaClassStatic())) {
16
+ // It's a `nitro::NullType`
17
+ auto jniValue = static_cast<const JVariant_NullType_Long_impl::First*>(this)->getValue();
18
+ return nitro::null;
19
+ } else if (isInstanceOf(JVariant_NullType_Long_impl::Second::javaClassStatic())) {
20
+ // It's a `int64_t`
21
+ auto jniValue = static_cast<const JVariant_NullType_Long_impl::Second*>(this)->getValue();
22
+ return jniValue;
23
+ }
24
+ throw std::invalid_argument("Variant is unknown Kotlin instance!");
25
+ }
26
+ } // namespace margelo::nitro::nitrometamask
@@ -0,0 +1,69 @@
1
+ ///
2
+ /// JVariant_NullType_Long.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include <variant>
12
+
13
+ #include <NitroModules/Null.hpp>
14
+ #include <variant>
15
+ #include <NitroModules/JNull.hpp>
16
+
17
+ namespace margelo::nitro::nitrometamask {
18
+
19
+ using namespace facebook;
20
+
21
+ /**
22
+ * The C++ JNI bridge between the C++ std::variant and the Java class "Variant_NullType_Long".
23
+ */
24
+ class JVariant_NullType_Long: public jni::JavaClass<JVariant_NullType_Long> {
25
+ public:
26
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitrometamask/Variant_NullType_Long;";
27
+
28
+ static jni::local_ref<JVariant_NullType_Long> create_0(jni::alias_ref<JNull> value) {
29
+ static const auto method = javaClassStatic()->getStaticMethod<JVariant_NullType_Long(jni::alias_ref<JNull>)>("create");
30
+ return method(javaClassStatic(), value);
31
+ }
32
+ static jni::local_ref<JVariant_NullType_Long> create_1(int64_t value) {
33
+ static const auto method = javaClassStatic()->getStaticMethod<JVariant_NullType_Long(int64_t)>("create");
34
+ return method(javaClassStatic(), value);
35
+ }
36
+
37
+ static jni::local_ref<JVariant_NullType_Long> fromCpp(const std::variant<nitro::NullType, int64_t>& variant) {
38
+ switch (variant.index()) {
39
+ case 0: return create_0(JNull::null());
40
+ case 1: return create_1(std::get<1>(variant));
41
+ default: throw std::invalid_argument("Variant holds unknown index! (" + std::to_string(variant.index()) + ")");
42
+ }
43
+ }
44
+
45
+ [[nodiscard]] std::variant<nitro::NullType, int64_t> toCpp() const;
46
+ };
47
+
48
+ namespace JVariant_NullType_Long_impl {
49
+ class First final: public jni::JavaClass<First, JVariant_NullType_Long> {
50
+ public:
51
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitrometamask/Variant_NullType_Long$First;";
52
+
53
+ [[nodiscard]] jni::local_ref<JNull> getValue() const {
54
+ static const auto field = javaClassStatic()->getField<JNull>("value");
55
+ return getFieldValue(field);
56
+ }
57
+ };
58
+
59
+ class Second final: public jni::JavaClass<Second, JVariant_NullType_Long> {
60
+ public:
61
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitrometamask/Variant_NullType_Long$Second;";
62
+
63
+ [[nodiscard]] int64_t getValue() const {
64
+ static const auto field = javaClassStatic()->getField<int64_t>("value");
65
+ return getFieldValue(field);
66
+ }
67
+ };
68
+ } // namespace JVariant_NullType_Long_impl
69
+ } // namespace margelo::nitro::nitrometamask
@@ -0,0 +1,26 @@
1
+ ///
2
+ /// JVariant_NullType_String.cpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #include "JVariant_NullType_String.hpp"
9
+
10
+ namespace margelo::nitro::nitrometamask {
11
+ /**
12
+ * Converts JVariant_NullType_String to std::variant<nitro::NullType, std::string>
13
+ */
14
+ std::variant<nitro::NullType, std::string> JVariant_NullType_String::toCpp() const {
15
+ if (isInstanceOf(JVariant_NullType_String_impl::First::javaClassStatic())) {
16
+ // It's a `nitro::NullType`
17
+ auto jniValue = static_cast<const JVariant_NullType_String_impl::First*>(this)->getValue();
18
+ return nitro::null;
19
+ } else if (isInstanceOf(JVariant_NullType_String_impl::Second::javaClassStatic())) {
20
+ // It's a `std::string`
21
+ auto jniValue = static_cast<const JVariant_NullType_String_impl::Second*>(this)->getValue();
22
+ return jniValue->toStdString();
23
+ }
24
+ throw std::invalid_argument("Variant is unknown Kotlin instance!");
25
+ }
26
+ } // namespace margelo::nitro::nitrometamask