@novastera-oss/nitro-metamask 0.7.7 → 0.7.9

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.
@@ -1,8 +1,6 @@
1
- #include <fbjni/fbjni.h>
2
1
  #include <jni.h>
3
-
4
2
  #include "NitroMetamaskOnLoad.hpp"
5
3
 
6
4
  JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
7
- return facebook::jni::initialize(vm, []() { margelo::nitro::nitrometamask::registerAllNatives(); });
5
+ return margelo::nitro::nitrometamask::initialize(vm);
8
6
  }
@@ -37,9 +37,10 @@ class NitroMetamaskPackage : BaseReactPackage() {
37
37
  "NitroMetamaskPackage",
38
38
  false, // canOverrideExistingModule
39
39
  true, // needsEagerInit
40
+ true, // hasConstants
40
41
  false, // isCxxModule
41
- true, // isTurboModule
42
- ),
42
+ true // isTurboModule
43
+ )
43
44
  )
44
45
  }
45
46
  }
package/app.plugin.js CHANGED
@@ -6,109 +6,66 @@ const withMetamaskAppDelegate = (config) => {
6
6
 
7
7
  // Check if AppDelegate is Swift
8
8
  if (modResults.language === 'swift') {
9
- // Migrate stale/incorrect import if present
10
- if (modResults.contents.includes('import metamask_ios_sdk')) {
11
- modResults.contents = modResults.contents.replace(
12
- /import\s+metamask_ios_sdk/g,
13
- 'import NitroMetamask'
14
- );
15
- }
9
+ // Swift AppDelegate should not import Nitro/MetaMask modules directly.
10
+ // Cleanup legacy injected imports from previous plugin versions.
11
+ modResults.contents = modResults.contents.replace(
12
+ /^\s*import\s+metamask_ios_sdk\s*\n?/gm,
13
+ ''
14
+ );
15
+ modResults.contents = modResults.contents.replace(
16
+ /^\s*import\s+NitroMetamask\s*\n?/gm,
17
+ ''
18
+ );
16
19
 
17
- // Add NitroMetamask import if not present
18
- if (!modResults.contents.includes('import NitroMetamask')) {
19
- // Find the last import statement and add after it
20
- const importRegex = /^import\s+.*$/gm;
21
- const imports = modResults.contents.match(importRegex);
22
- if (imports && imports.length > 0) {
23
- const lastImport = imports[imports.length - 1];
24
- const lastImportIndex = modResults.contents.lastIndexOf(lastImport);
25
- modResults.contents =
26
- modResults.contents.slice(0, lastImportIndex + lastImport.length) +
27
- '\nimport NitroMetamask' +
28
- modResults.contents.slice(lastImportIndex + lastImport.length);
29
- } else {
30
- // No imports found, add at the top after the first line
31
- const firstLineIndex = modResults.contents.indexOf('\n');
32
- modResults.contents =
33
- modResults.contents.slice(0, firstLineIndex + 1) +
34
- 'import NitroMetamask\n' +
35
- modResults.contents.slice(firstLineIndex + 1);
36
- }
37
- }
20
+ // Optional migration cleanup: remove legacy injected MetaMask handler
21
+ // block if it exists in Swift AppDelegate files.
22
+ modResults.contents = modResults.contents.replace(
23
+ /\n\s*\/\/ Handle deep links from MetaMask wallet[\s\S]*?MetaMaskSDK\.sharedInstance\?\.handleUrl\(url\)[\s\S]*?return false\s*\n\s*\}/g,
24
+ ''
25
+ );
38
26
 
39
- // Check if the method already exists
40
- if (modResults.contents.includes('MetaMaskSDK.sharedInstance?.handleUrl')) {
41
- return config;
42
- }
43
-
44
- // Add the deep link handler method
45
- const deepLinkHandler = `
46
- // Handle deep links from MetaMask wallet
47
- // MetaMask returns to the app via deep link after signing/connecting
48
- // Added by @novastera-oss/nitro-metamask config plugin
49
- func application(
50
- _ app: UIApplication,
51
- open url: URL,
52
- options: [UIApplication.OpenURLOptionsKey: Any] = [:]
53
- ) -> Bool {
54
- // Check if this is a MetaMask deep link (host="mmsdk")
55
- if let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
56
- components.host == "mmsdk" {
57
- // Handle MetaMask deep link return
58
- MetaMaskSDK.sharedInstance?.handleUrl(url)
59
- return true
60
- }
61
-
62
- // Handle other deep links (e.g., React Native Linking)
63
- return false
64
- }`;
65
-
66
- // Insert before the last closing brace of the AppDelegate class
67
- // Try to find the closing brace of the class before @end or end of file
68
- const classEndPattern = /(\s+)\}(?=\s*(?:@end|$))/;
69
- const match = modResults.contents.match(classEndPattern);
70
- if (match) {
71
- const indent = match[1];
72
- const insertIndex = match.index;
73
- modResults.contents =
74
- modResults.contents.slice(0, insertIndex) +
75
- deepLinkHandler.replace(/^ /gm, indent) +
76
- '\n' + indent + '}' +
77
- modResults.contents.slice(insertIndex + match[0].length);
78
- } else {
79
- // Fallback: append before @end
27
+ return config;
28
+ } else if (modResults.language === 'objc') {
29
+ // Handle Objective-C AppDelegate
30
+ // Remove stale direct SDK import if present. Importing MetaMaskSDK headers
31
+ // in Objective-C (.m) can pull C++ headers and fail non-ObjC++ builds.
32
+ modResults.contents = modResults.contents.replace(
33
+ /^\s*#import\s+<MetaMaskSDK\/MetaMaskSDK\.h>\s*\n?/gm,
34
+ ''
35
+ );
36
+
37
+ // Migrate legacy direct call to a runtime-safe invocation in Objective-C.
38
+ if (modResults.contents.includes('[[MetaMaskSDK sharedInstance] handleUrl:url];')) {
80
39
  modResults.contents = modResults.contents.replace(
81
- /^(@end|}$)/m,
82
- deepLinkHandler + '\n$1'
40
+ /\[\[MetaMaskSDK sharedInstance\] handleUrl:url\];/g,
41
+ `Class metaMaskSDKClass = NSClassFromString(@"MetaMaskSDK");
42
+ id sharedInstance = [metaMaskSDKClass respondsToSelector:@selector(sharedInstance)]
43
+ ? [metaMaskSDKClass performSelector:@selector(sharedInstance)]
44
+ : nil;
45
+ if (sharedInstance && [sharedInstance respondsToSelector:@selector(handleUrl:)]) {
46
+ [sharedInstance performSelector:@selector(handleUrl:) withObject:url];
47
+ }`
83
48
  );
84
49
  }
85
- } else if (modResults.language === 'objc') {
86
- // Handle Objective-C AppDelegate
87
- if (modResults.contents.includes('MetaMaskSDK')) {
50
+
51
+ // Skip injection if handler already exists after migration.
52
+ if (modResults.contents.includes('[components.host isEqualToString:@"mmsdk"]')) {
88
53
  return config;
89
54
  }
90
55
 
91
- // Add import
92
- if (!modResults.contents.includes('#import <MetaMaskSDK/MetaMaskSDK.h>')) {
93
- const importRegex = /^#import\s+.*$/gm;
94
- const imports = modResults.contents.match(importRegex);
95
- if (imports && imports.length > 0) {
96
- const lastImport = imports[imports.length - 1];
97
- const lastImportIndex = modResults.contents.lastIndexOf(lastImport);
98
- modResults.contents =
99
- modResults.contents.slice(0, lastImportIndex + lastImport.length) +
100
- '\n#import <MetaMaskSDK/MetaMaskSDK.h>' +
101
- modResults.contents.slice(lastImportIndex + lastImport.length);
102
- }
103
- }
104
-
105
56
  const objcHandler = `
106
57
  - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
107
58
  // Check if this is a MetaMask deep link (host="mmsdk")
108
59
  NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
109
60
  if ([components.host isEqualToString:@"mmsdk"]) {
110
61
  // Handle MetaMask deep link return
111
- [[MetaMaskSDK sharedInstance] handleUrl:url];
62
+ Class metaMaskSDKClass = NSClassFromString(@"MetaMaskSDK");
63
+ id sharedInstance = [metaMaskSDKClass respondsToSelector:@selector(sharedInstance)]
64
+ ? [metaMaskSDKClass performSelector:@selector(sharedInstance)]
65
+ : nil;
66
+ if (sharedInstance && [sharedInstance respondsToSelector:@selector(handleUrl:)]) {
67
+ [sharedInstance performSelector:@selector(handleUrl:) withObject:url];
68
+ }
112
69
  return YES;
113
70
  }
114
71
 
@@ -0,0 +1,2 @@
1
+ declare const withMetamaskAppDelegate: any;
2
+ //# sourceMappingURL=appPlugin.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appPlugin.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/appPlugin.test.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,uBAAuB,KAAiC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@novastera-oss/nitro-metamask",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "description": "Native mobile MetaMask wallet integration for React Native. Part of Novastera CRM/ERP platform ecosystem. Provides secure authentication and message signing for Web3 mobile applications.",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/module/index.js",
@@ -0,0 +1,79 @@
1
+ jest.mock('@expo/config-plugins', () => ({
2
+ withAppDelegate: (config: any, action: (cfg: any) => any) => action(config),
3
+ }))
4
+
5
+ const withMetamaskAppDelegate = require('../../app.plugin.js')
6
+
7
+ describe('app.plugin.js', () => {
8
+ it('removes stale Swift imports and does not inject handler', () => {
9
+ const config = {
10
+ modResults: {
11
+ language: 'swift',
12
+ contents: `import UIKit
13
+ import metamask_ios_sdk
14
+ import NitroMetamask
15
+
16
+ class AppDelegate: NSObject {
17
+ }
18
+ `,
19
+ },
20
+ }
21
+
22
+ const result = withMetamaskAppDelegate(config)
23
+ const contents: string = result.modResults.contents
24
+
25
+ expect(contents).not.toContain('import metamask_ios_sdk')
26
+ expect(contents).not.toContain('import NitroMetamask')
27
+ expect(contents).not.toContain('MetaMaskSDK.sharedInstance?.handleUrl(url)')
28
+ })
29
+
30
+ it('keeps Swift AppDelegate untouched apart from cleanup', () => {
31
+ const config = {
32
+ modResults: {
33
+ language: 'swift',
34
+ contents: `import UIKit
35
+
36
+ class AppDelegate: NSObject {
37
+ }
38
+ `,
39
+ },
40
+ }
41
+
42
+ const result = withMetamaskAppDelegate(config)
43
+ const contents: string = result.modResults.contents
44
+
45
+ expect(contents).toContain('import UIKit')
46
+ expect(contents).not.toContain('import NitroMetamask')
47
+ expect(contents).not.toContain('MetaMaskSDK.sharedInstance?.handleUrl(url)')
48
+ })
49
+
50
+ it('migrates Objective-C direct SDK usage to runtime-safe calls', () => {
51
+ const config = {
52
+ modResults: {
53
+ language: 'objc',
54
+ contents: `#import "AppDelegate.h"
55
+ #import <MetaMaskSDK/MetaMaskSDK.h>
56
+
57
+ @implementation AppDelegate
58
+ - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
59
+ NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
60
+ if ([components.host isEqualToString:@"mmsdk"]) {
61
+ [[MetaMaskSDK sharedInstance] handleUrl:url];
62
+ return YES;
63
+ }
64
+ return NO;
65
+ }
66
+ @end
67
+ `,
68
+ },
69
+ }
70
+
71
+ const result = withMetamaskAppDelegate(config)
72
+ const contents: string = result.modResults.contents
73
+
74
+ expect(contents).not.toContain('#import <MetaMaskSDK/MetaMaskSDK.h>')
75
+ expect(contents).toContain('NSClassFromString(@"MetaMaskSDK")')
76
+ expect(contents).toContain('[sharedInstance performSelector:@selector(handleUrl:) withObject:url]')
77
+ expect(contents).not.toContain('[[MetaMaskSDK sharedInstance] handleUrl:url];')
78
+ })
79
+ })