@novastera-oss/nitro-metamask 0.3.3 → 0.4.2

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 (39) hide show
  1. package/README.md +73 -12
  2. package/android/src/main/java/com/margelo/nitro/nitrometamask/HybridNitroMetamask.kt +349 -175
  3. package/app.plugin.js +121 -0
  4. package/ios/HybridNitroMetamask.swift +71 -110
  5. package/lib/typescript/src/specs/nitro-metamask.nitro.d.ts +31 -6
  6. package/lib/typescript/src/specs/nitro-metamask.nitro.d.ts.map +1 -1
  7. package/nitrogen/generated/android/NitroMetamask+autolinking.cmake +2 -0
  8. package/nitrogen/generated/android/c++/JConnectResult.hpp +3 -3
  9. package/nitrogen/generated/android/c++/JConnectSignResult.hpp +65 -0
  10. package/nitrogen/generated/android/c++/JHybridNitroMetamaskSpec.cpp +48 -7
  11. package/nitrogen/generated/android/c++/JHybridNitroMetamaskSpec.hpp +4 -2
  12. package/nitrogen/generated/android/c++/JVariant_NullType_Long.cpp +26 -0
  13. package/nitrogen/generated/android/c++/JVariant_NullType_Long.hpp +69 -0
  14. package/nitrogen/generated/android/c++/JVariant_NullType_String.cpp +26 -0
  15. package/nitrogen/generated/android/c++/JVariant_NullType_String.hpp +70 -0
  16. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/ConnectResult.kt +2 -2
  17. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/ConnectSignResult.kt +44 -0
  18. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/HybridNitroMetamaskSpec.kt +11 -2
  19. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/Variant_NullType_Long.kt +59 -0
  20. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/Variant_NullType_String.kt +59 -0
  21. package/nitrogen/generated/ios/NitroMetamask-Swift-Cxx-Bridge.cpp +24 -0
  22. package/nitrogen/generated/ios/NitroMetamask-Swift-Cxx-Bridge.hpp +192 -0
  23. package/nitrogen/generated/ios/NitroMetamask-Swift-Cxx-Umbrella.hpp +5 -0
  24. package/nitrogen/generated/ios/c++/HybridNitroMetamaskSpecSwift.hpp +24 -3
  25. package/nitrogen/generated/ios/swift/ConnectResult.swift +2 -2
  26. package/nitrogen/generated/ios/swift/ConnectSignResult.swift +40 -0
  27. package/nitrogen/generated/ios/swift/Func_void_ConnectSignResult.swift +47 -0
  28. package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__int64_t_.swift +59 -0
  29. package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__std__string_.swift +59 -0
  30. package/nitrogen/generated/ios/swift/HybridNitroMetamaskSpec.swift +4 -2
  31. package/nitrogen/generated/ios/swift/HybridNitroMetamaskSpec_cxx.swift +67 -8
  32. package/nitrogen/generated/ios/swift/Variant_NullType_Int64.swift +18 -0
  33. package/nitrogen/generated/ios/swift/Variant_NullType_String.swift +18 -0
  34. package/nitrogen/generated/shared/c++/ConnectResult.hpp +5 -5
  35. package/nitrogen/generated/shared/c++/ConnectSignResult.hpp +91 -0
  36. package/nitrogen/generated/shared/c++/HybridNitroMetamaskSpec.cpp +2 -0
  37. package/nitrogen/generated/shared/c++/HybridNitroMetamaskSpec.hpp +9 -2
  38. package/package.json +18 -4
  39. package/src/specs/nitro-metamask.nitro.ts +32 -6
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;
@@ -9,9 +9,10 @@ final class HybridNitroMetamask: HybridNitroMetamaskSpec {
9
9
  // iOS SDK handles deep linking automatically via Info.plist
10
10
  private var dappUrl: String? = nil
11
11
 
12
- func configure(dappUrl: String?) {
12
+ func configure(dappUrl: String?, deepLinkScheme: String?) {
13
13
  // iOS SDK handles deep linking automatically via Info.plist
14
14
  // Store the URL for consistency with Android implementation
15
+ // deepLinkScheme is ignored on iOS as it's handled automatically
15
16
  self.dappUrl = dappUrl
16
17
  NSLog("NitroMetamask: configure: Dapp URL set to \(dappUrl ?? "default"). Deep link handled automatically via Info.plist")
17
18
  }
@@ -53,7 +54,7 @@ final class HybridNitroMetamask: HybridNitroMetamaskSpec {
53
54
 
54
55
  return ConnectResult(
55
56
  address: address,
56
- chainId: Double(chainIdInt)
57
+ chainId: Int64(chainIdInt)
57
58
  )
58
59
 
59
60
  case .failure(let error):
@@ -105,136 +106,96 @@ final class HybridNitroMetamask: HybridNitroMetamaskSpec {
105
106
  }
106
107
  }
107
108
 
108
- func connectSign(nonce: String, exp: Int64) -> Promise<String> {
109
+ func connectSign(nonce: String, exp: Int64) -> Promise<ConnectSignResult> {
109
110
  // Use Promise.async with Swift async/await for best practice in Nitro modules
110
111
  // Reference: https://nitro.margelo.com/docs/types/promises
111
- // Based on MetaMask iOS SDK: connect and sign in one call
112
+ // Based on MetaMask iOS SDK: connectAndSign(message:) convenience method
112
113
  // Reference: https://github.com/MetaMask/metamask-ios-sdk
113
114
  return Promise.async {
114
- // First, ensure we're connected
115
- var address = self.sdk.account
116
- var chainIdHex = self.sdk.chainId
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
+ ]
117
121
 
118
- // If not connected, connect first
119
- if address == nil || address?.isEmpty == true || chainIdHex == nil || chainIdHex?.isEmpty == true {
120
- let connectResult = try await self.sdk.connect()
121
-
122
- switch connectResult {
123
- case .success:
124
- address = self.sdk.account
125
- chainIdHex = self.sdk.chainId
126
-
127
- guard let account = address, !account.isEmpty else {
128
- throw NSError(
129
- domain: "MetamaskConnector",
130
- code: -1,
131
- userInfo: [NSLocalizedDescriptionKey: "MetaMask SDK returned no address after connection"]
132
- )
133
- }
134
-
135
- guard let chainId = chainIdHex, !chainId.isEmpty,
136
- let chainIdInt = Int(chainId.replacingOccurrences(of: "0x", with: ""), radix: 16) else {
137
- throw NSError(
138
- domain: "MetamaskConnector",
139
- code: -1,
140
- userInfo: [NSLocalizedDescriptionKey: "Invalid chainId format"]
141
- )
142
- }
143
-
144
- // Construct JSON message
145
- let messageDict: [String: Any] = [
146
- "address": account,
147
- "chainID": chainIdInt,
148
- "nonce": nonce,
149
- "exp": exp
150
- ]
151
-
152
- guard let jsonData = try? JSONSerialization.data(withJSONObject: messageDict),
153
- let message = String(data: jsonData, encoding: .utf8) else {
154
- throw NSError(
155
- domain: "MetamaskConnector",
156
- code: -1,
157
- userInfo: [NSLocalizedDescriptionKey: "Failed to create JSON message"]
158
- )
159
- }
160
-
161
- // Create EthereumRequest for personal_sign
162
- let params: [String] = [account, message]
163
- let request = EthereumRequest(
164
- method: .personalSign,
165
- params: params
166
- )
167
-
168
- // Make the request using the SDK's async request method
169
- let result = try await self.sdk.request(request)
170
-
171
- // Extract signature from response
172
- if let signature = result as? String {
173
- return signature
174
- } else if let dict = result as? [String: Any], let sig = dict["signature"] as? String ?? dict["result"] as? String {
175
- return sig
176
- } else {
177
- throw NSError(
178
- domain: "MetamaskConnector",
179
- code: -1,
180
- userInfo: [NSLocalizedDescriptionKey: "Invalid signature response format"]
181
- )
182
- }
183
-
184
- case .failure(let error):
185
- throw error
186
- }
187
- } else {
188
- // Already connected, construct message and sign
189
- guard let account = address, !account.isEmpty,
190
- let chainId = chainIdHex, !chainId.isEmpty,
191
- let chainIdInt = Int(chainId.replacingOccurrences(of: "0x", with: ""), radix: 16) else {
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 {
192
142
  throw NSError(
193
143
  domain: "MetamaskConnector",
194
144
  code: -1,
195
- userInfo: [NSLocalizedDescriptionKey: "Invalid connection state"]
145
+ userInfo: [NSLocalizedDescriptionKey: "Failed to retrieve address after connectSign"]
196
146
  )
197
147
  }
198
148
 
199
- // Construct JSON message
200
- let messageDict: [String: Any] = [
201
- "address": account,
202
- "chainID": chainIdInt,
203
- "nonce": nonce,
204
- "exp": Int64(exp)
205
- ]
206
-
207
- guard let jsonData = try? JSONSerialization.data(withJSONObject: messageDict),
208
- let message = String(data: jsonData, encoding: .utf8) else {
149
+ guard let chainIdHex = self.sdk.chainId, !chainIdHex.isEmpty else {
209
150
  throw NSError(
210
151
  domain: "MetamaskConnector",
211
152
  code: -1,
212
- userInfo: [NSLocalizedDescriptionKey: "Failed to create JSON message"]
153
+ userInfo: [NSLocalizedDescriptionKey: "Failed to retrieve chainId after connectSign"]
213
154
  )
214
155
  }
215
156
 
216
- // Create EthereumRequest for personal_sign
217
- let params: [String] = [account, message]
218
- let request = EthereumRequest(
219
- method: .personalSign,
220
- params: params
221
- )
222
-
223
- // Make the request using the SDK's async request method
224
- let result = try await self.sdk.request(request)
225
-
226
- // Extract signature from response
227
- if let signature = result as? String {
228
- return signature
229
- } else if let dict = result as? [String: Any], let sig = dict["signature"] as? String ?? dict["result"] as? String {
230
- return sig
231
- } else {
157
+ // Parse chainId from hex string (e.g., "0x1") to Int64
158
+ guard let chainId = Int64(chainIdHex.replacingOccurrences(of: "0x", with: ""), radix: 16) else {
232
159
  throw NSError(
233
160
  domain: "MetamaskConnector",
234
161
  code: -1,
235
- userInfo: [NSLocalizedDescriptionKey: "Invalid signature response format"]
162
+ userInfo: [NSLocalizedDescriptionKey: "Invalid chainId format: \(chainIdHex)"]
236
163
  )
237
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())
238
199
  }
239
200
  }
240
201
  }
@@ -1,23 +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
  }> {
10
15
  /**
11
- * Configure the dapp URL for MetaMask SDK validation.
12
- * This URL is only used for SDK validation - the deep link return is handled automatically via AndroidManifest.xml.
16
+ * Configure the dapp URL and deep link scheme for MetaMask SDK.
13
17
  *
14
18
  * @param dappUrl - A valid HTTP/HTTPS URL (e.g., "https://yourdomain.com").
15
19
  * If not provided, defaults to "https://novastera.com".
16
- * This is separate from the deep link scheme which is auto-detected from your manifest.
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.
17
24
  */
18
- configure(dappUrl?: string): void;
25
+ configure(dappUrl?: string, deepLinkScheme?: string): void;
19
26
  connect(): Promise<ConnectResult>;
20
27
  signMessage(message: string): Promise<string>;
21
- connectSign(nonce: string, exp: bigint): 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>;
22
47
  }
23
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;;;;;;;OAOG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC,CAAA;IACjC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC7C,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACzD"}
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,21 @@
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"
18
27
  #include <optional>
19
28
 
20
29
  namespace margelo::nitro::nitrometamask {
@@ -49,9 +58,9 @@ namespace margelo::nitro::nitrometamask {
49
58
 
50
59
 
51
60
  // Methods
52
- void JHybridNitroMetamaskSpec::configure(const std::optional<std::string>& dappUrl) {
53
- static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* dappUrl */)>("configure");
54
- method(_javaPart, dappUrl.has_value() ? jni::make_jstring(dappUrl.value()) : nullptr);
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);
55
64
  }
56
65
  std::shared_ptr<Promise<ConnectResult>> JHybridNitroMetamaskSpec::connect() {
57
66
  static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("connect");
@@ -85,14 +94,46 @@ namespace margelo::nitro::nitrometamask {
85
94
  return __promise;
86
95
  }();
87
96
  }
88
- std::shared_ptr<Promise<std::string>> JHybridNitroMetamaskSpec::connectSign(const std::string& nonce, int64_t exp) {
97
+ std::shared_ptr<Promise<ConnectSignResult>> JHybridNitroMetamaskSpec::connectSign(const std::string& nonce, int64_t exp) {
89
98
  static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* nonce */, int64_t /* exp */)>("connectSign");
90
99
  auto __result = method(_javaPart, jni::make_jstring(nonce), exp);
91
100
  return [&]() {
92
- auto __promise = Promise<std::string>::create();
101
+ auto __promise = Promise<ConnectSignResult>::create();
93
102
  __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
94
- auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
95
- __promise->resolve(__result->toStdString());
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());
96
137
  });
97
138
  __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
98
139
  jni::JniException __jniError(__throwable);
@@ -54,10 +54,12 @@ namespace margelo::nitro::nitrometamask {
54
54
 
55
55
  public:
56
56
  // Methods
57
- void configure(const std::optional<std::string>& dappUrl) override;
57
+ void configure(const std::optional<std::string>& dappUrl, const std::optional<std::string>& deepLinkScheme) override;
58
58
  std::shared_ptr<Promise<ConnectResult>> connect() override;
59
59
  std::shared_ptr<Promise<std::string>> signMessage(const std::string& message) override;
60
- std::shared_ptr<Promise<std::string>> connectSign(const std::string& nonce, int64_t exp) 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;
61
63
 
62
64
  private:
63
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