@novastera-oss/nitro-metamask 0.7.5 → 0.7.8

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,13 +6,16 @@ const withMetamaskAppDelegate = (config) => {
6
6
 
7
7
  // Check if AppDelegate is Swift
8
8
  if (modResults.language === 'swift') {
9
- // Check if the method already exists
10
- if (modResults.contents.includes('MetaMaskSDK.sharedInstance?.handleUrl')) {
11
- return config;
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
+ );
12
15
  }
13
-
14
- // Add import if not present
15
- if (!modResults.contents.includes('import metamask_ios_sdk')) {
16
+
17
+ // Add NitroMetamask import if not present
18
+ if (!modResults.contents.includes('import NitroMetamask')) {
16
19
  // Find the last import statement and add after it
17
20
  const importRegex = /^import\s+.*$/gm;
18
21
  const imports = modResults.contents.match(importRegex);
@@ -21,17 +24,22 @@ const withMetamaskAppDelegate = (config) => {
21
24
  const lastImportIndex = modResults.contents.lastIndexOf(lastImport);
22
25
  modResults.contents =
23
26
  modResults.contents.slice(0, lastImportIndex + lastImport.length) +
24
- '\nimport metamask_ios_sdk' +
27
+ '\nimport NitroMetamask' +
25
28
  modResults.contents.slice(lastImportIndex + lastImport.length);
26
29
  } else {
27
30
  // No imports found, add at the top after the first line
28
31
  const firstLineIndex = modResults.contents.indexOf('\n');
29
32
  modResults.contents =
30
33
  modResults.contents.slice(0, firstLineIndex + 1) +
31
- 'import metamask_ios_sdk\n' +
34
+ 'import NitroMetamask\n' +
32
35
  modResults.contents.slice(firstLineIndex + 1);
33
36
  }
34
37
  }
38
+
39
+ // Check if the method already exists
40
+ if (modResults.contents.includes('MetaMaskSDK.sharedInstance?.handleUrl')) {
41
+ return config;
42
+ }
35
43
 
36
44
  // Add the deep link handler method
37
45
  const deepLinkHandler = `
@@ -76,22 +84,30 @@ const withMetamaskAppDelegate = (config) => {
76
84
  }
77
85
  } else if (modResults.language === 'objc') {
78
86
  // Handle Objective-C AppDelegate
79
- if (modResults.contents.includes('MetaMaskSDK')) {
80
- return config;
87
+ // Remove stale direct SDK import if present. Importing MetaMaskSDK headers
88
+ // in Objective-C (.m) can pull C++ headers and fail non-ObjC++ builds.
89
+ modResults.contents = modResults.contents.replace(
90
+ /^\s*#import\s+<MetaMaskSDK\/MetaMaskSDK\.h>\s*\n?/gm,
91
+ ''
92
+ );
93
+
94
+ // Migrate legacy direct call to a runtime-safe invocation in Objective-C.
95
+ if (modResults.contents.includes('[[MetaMaskSDK sharedInstance] handleUrl:url];')) {
96
+ modResults.contents = modResults.contents.replace(
97
+ /\[\[MetaMaskSDK sharedInstance\] handleUrl:url\];/g,
98
+ `Class metaMaskSDKClass = NSClassFromString(@"MetaMaskSDK");
99
+ id sharedInstance = [metaMaskSDKClass respondsToSelector:@selector(sharedInstance)]
100
+ ? [metaMaskSDKClass performSelector:@selector(sharedInstance)]
101
+ : nil;
102
+ if (sharedInstance && [sharedInstance respondsToSelector:@selector(handleUrl:)]) {
103
+ [sharedInstance performSelector:@selector(handleUrl:) withObject:url];
104
+ }`
105
+ );
81
106
  }
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
- }
107
+
108
+ // Skip injection if handler already exists after migration.
109
+ if (modResults.contents.includes('[components.host isEqualToString:@"mmsdk"]')) {
110
+ return config;
95
111
  }
96
112
 
97
113
  const objcHandler = `
@@ -100,7 +116,13 @@ const withMetamaskAppDelegate = (config) => {
100
116
  NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
101
117
  if ([components.host isEqualToString:@"mmsdk"]) {
102
118
  // Handle MetaMask deep link return
103
- [[MetaMaskSDK sharedInstance] handleUrl:url];
119
+ Class metaMaskSDKClass = NSClassFromString(@"MetaMaskSDK");
120
+ id sharedInstance = [metaMaskSDKClass respondsToSelector:@selector(sharedInstance)]
121
+ ? [metaMaskSDKClass performSelector:@selector(sharedInstance)]
122
+ : nil;
123
+ if (sharedInstance && [sharedInstance respondsToSelector:@selector(handleUrl:)]) {
124
+ [sharedInstance performSelector:@selector(handleUrl:) withObject:url];
125
+ }
104
126
  return YES;
105
127
  }
106
128
 
@@ -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.5",
3
+ "version": "0.7.8",
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,85 @@
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('replaces stale Swift import even if handler already exists', () => {
9
+ const config = {
10
+ modResults: {
11
+ language: 'swift',
12
+ contents: `import UIKit
13
+ import metamask_ios_sdk
14
+
15
+ class AppDelegate: NSObject {
16
+ func application(
17
+ _ app: UIApplication,
18
+ open url: URL,
19
+ options: [UIApplication.OpenURLOptionsKey: Any] = [:]
20
+ ) -> Bool {
21
+ MetaMaskSDK.sharedInstance?.handleUrl(url)
22
+ return true
23
+ }
24
+ }
25
+ `,
26
+ },
27
+ }
28
+
29
+ const result = withMetamaskAppDelegate(config)
30
+ const contents: string = result.modResults.contents
31
+
32
+ expect(contents).toContain('import NitroMetamask')
33
+ expect(contents).not.toContain('import metamask_ios_sdk')
34
+ expect((contents.match(/MetaMaskSDK\.sharedInstance\?\.handleUrl\(url\)/g) || []).length).toBe(1)
35
+ })
36
+
37
+ it('injects NitroMetamask Swift import when missing', () => {
38
+ const config = {
39
+ modResults: {
40
+ language: 'swift',
41
+ contents: `import UIKit
42
+
43
+ class AppDelegate: NSObject {
44
+ }
45
+ `,
46
+ },
47
+ }
48
+
49
+ const result = withMetamaskAppDelegate(config)
50
+ const contents: string = result.modResults.contents
51
+
52
+ expect(contents).toContain('import NitroMetamask')
53
+ expect(contents).toContain('MetaMaskSDK.sharedInstance?.handleUrl(url)')
54
+ })
55
+
56
+ it('migrates Objective-C direct SDK usage to runtime-safe calls', () => {
57
+ const config = {
58
+ modResults: {
59
+ language: 'objc',
60
+ contents: `#import "AppDelegate.h"
61
+ #import <MetaMaskSDK/MetaMaskSDK.h>
62
+
63
+ @implementation AppDelegate
64
+ - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
65
+ NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
66
+ if ([components.host isEqualToString:@"mmsdk"]) {
67
+ [[MetaMaskSDK sharedInstance] handleUrl:url];
68
+ return YES;
69
+ }
70
+ return NO;
71
+ }
72
+ @end
73
+ `,
74
+ },
75
+ }
76
+
77
+ const result = withMetamaskAppDelegate(config)
78
+ const contents: string = result.modResults.contents
79
+
80
+ expect(contents).not.toContain('#import <MetaMaskSDK/MetaMaskSDK.h>')
81
+ expect(contents).toContain('NSClassFromString(@"MetaMaskSDK")')
82
+ expect(contents).toContain('[sharedInstance performSelector:@selector(handleUrl:) withObject:url]')
83
+ expect(contents).not.toContain('[[MetaMaskSDK sharedInstance] handleUrl:url];')
84
+ })
85
+ })