@novastera-oss/nitro-metamask 0.2.7 → 0.3.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.
- package/LICENSE +21 -201
- package/NitroMetamask.podspec +1 -1
- package/README.md +75 -228
- package/android/CMakeLists.txt +3 -0
- package/android/build.gradle +24 -18
- package/android/fix-prefab.gradle +1 -1
- package/android/gradle.properties +2 -2
- package/android/src/main/java/com/margelo/nitro/nitrometamask/HybridNitroMetamask.kt +409 -0
- package/android/src/main/java/com/margelo/nitro/nitrometamask/MetamaskContextHolder.kt +4 -25
- package/android/src/main/java/com/margelo/nitro/nitrometamask/NitroMetamaskPackage.kt +36 -7
- package/ios/Bridge.h +2 -2
- package/ios/HybridNitroMetamask.swift +241 -0
- package/lib/commonjs/index.js +20 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/specs/nitro-metamask.nitro.js +6 -0
- package/lib/commonjs/specs/nitro-metamask.nitro.js.map +1 -0
- package/lib/module/index.js +16 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/specs/nitro-metamask.nitro.js +4 -0
- package/lib/module/specs/nitro-metamask.nitro.js.map +1 -0
- package/lib/typescript/src/index.d.ts +15 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/specs/nitro-metamask.nitro.d.ts +23 -0
- package/lib/typescript/src/specs/nitro-metamask.nitro.d.ts.map +1 -0
- package/nitro.json +4 -4
- package/nitrogen/generated/android/NitroMetamask+autolinking.cmake +2 -2
- package/nitrogen/generated/android/NitroMetamaskOnLoad.cpp +4 -4
- package/nitrogen/generated/android/c++/{JHybridMetamaskConnectorSpec.cpp → JHybridNitroMetamaskSpec.cpp} +31 -10
- package/nitrogen/generated/android/c++/{JHybridMetamaskConnectorSpec.hpp → JHybridNitroMetamaskSpec.hpp} +12 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrometamask/{HybridMetamaskConnectorSpec.kt → HybridNitroMetamaskSpec.kt} +14 -6
- package/nitrogen/generated/ios/NitroMetamask-Swift-Cxx-Bridge.cpp +9 -9
- package/nitrogen/generated/ios/NitroMetamask-Swift-Cxx-Bridge.hpp +38 -13
- package/nitrogen/generated/ios/NitroMetamask-Swift-Cxx-Umbrella.hpp +6 -5
- package/nitrogen/generated/ios/NitroMetamaskAutolinking.mm +3 -3
- package/nitrogen/generated/ios/NitroMetamaskAutolinking.swift +6 -6
- package/nitrogen/generated/ios/c++/{HybridMetamaskConnectorSpecSwift.cpp → HybridNitroMetamaskSpecSwift.cpp} +2 -2
- package/nitrogen/generated/ios/c++/{HybridMetamaskConnectorSpecSwift.hpp → HybridNitroMetamaskSpecSwift.hpp} +28 -13
- package/nitrogen/generated/ios/swift/HybridNitroMetamaskSpec.swift +59 -0
- package/nitrogen/generated/ios/swift/{HybridMetamaskConnectorSpec_cxx.swift → HybridNitroMetamaskSpec_cxx.swift} +55 -18
- package/nitrogen/generated/shared/c++/HybridNitroMetamaskSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/{HybridMetamaskConnectorSpec.hpp → HybridNitroMetamaskSpec.hpp} +13 -10
- package/package.json +55 -39
- package/react-native.config.js +4 -1
- package/src/index.ts +14 -5
- package/src/specs/nitro-metamask.nitro.ts +21 -0
- package/android/src/main/java/com/margelo/nitro/nitrometamask/HybridMetamaskConnector.kt +0 -126
- package/ios/HybridMetamaskConnector.swift +0 -97
- package/lib/MetamaskConnector.nitro.d.ts +0 -12
- package/lib/MetamaskConnector.nitro.js +0 -1
- package/lib/index.d.ts +0 -3
- package/lib/index.js +0 -2
- package/lib/specs/Example.nitro.d.ts +0 -0
- package/lib/specs/Example.nitro.js +0 -2
- package/nitrogen/generated/ios/swift/HybridMetamaskConnectorSpec.swift +0 -57
- package/nitrogen/generated/shared/c++/HybridMetamaskConnectorSpec.cpp +0 -22
- package/src/MetamaskConnector.nitro.ts +0 -13
- package/src/specs/Example.nitro.ts +0 -1
package/package.json
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@novastera-oss/nitro-metamask",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "lib/index",
|
|
6
|
-
"module": "lib/index",
|
|
7
|
-
"types": "lib/index.d.ts",
|
|
3
|
+
"version": "0.3.3",
|
|
4
|
+
"description": "Novastera metamask authentication with native mobile libraries",
|
|
5
|
+
"main": "./lib/commonjs/index.js",
|
|
6
|
+
"module": "./lib/module/index.js",
|
|
7
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
8
8
|
"react-native": "src/index",
|
|
9
9
|
"source": "src/index",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"typecheck": "tsc --noEmit",
|
|
12
|
+
"clean": "git clean -dfX",
|
|
13
|
+
"release": "semantic-release",
|
|
14
|
+
"build": "npm run typecheck && bob build",
|
|
15
|
+
"codegen": "nitrogen --logLevel=\"debug\" && npm run build"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"react-native",
|
|
19
|
+
"@novastera-oss/nitro-metamask",
|
|
20
|
+
"metamask",
|
|
21
|
+
"novastera"
|
|
22
|
+
],
|
|
10
23
|
"files": [
|
|
11
24
|
"src",
|
|
12
25
|
"react-native.config.js",
|
|
13
26
|
"lib",
|
|
14
27
|
"nitrogen",
|
|
28
|
+
"cpp",
|
|
29
|
+
"nitro.json",
|
|
15
30
|
"android/build.gradle",
|
|
16
|
-
"android/gradle.properties",
|
|
17
31
|
"android/fix-prefab.gradle",
|
|
32
|
+
"android/gradle.properties",
|
|
18
33
|
"android/CMakeLists.txt",
|
|
19
34
|
"android/src",
|
|
20
35
|
"ios/**/*.h",
|
|
@@ -23,53 +38,40 @@
|
|
|
23
38
|
"ios/**/*.cpp",
|
|
24
39
|
"ios/**/*.swift",
|
|
25
40
|
"app.plugin.js",
|
|
26
|
-
"nitro.json",
|
|
27
41
|
"*.podspec",
|
|
28
42
|
"README.md"
|
|
29
43
|
],
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"typecheck": "tsc --noEmit",
|
|
33
|
-
"clean": "rm -rf android/build node_modules/**/android/build lib",
|
|
34
|
-
"lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
|
|
35
|
-
"lint-ci": "eslint \"**/*.{js,ts,tsx}\" -f @jamesacarr/github-actions",
|
|
36
|
-
"typescript": "tsc",
|
|
37
|
-
"specs": "tsc --noEmit false && nitrogen --logLevel=\"debug\""
|
|
38
|
-
},
|
|
39
|
-
"keywords": [
|
|
40
|
-
"react-native",
|
|
41
|
-
"nitro"
|
|
44
|
+
"workspaces": [
|
|
45
|
+
"example"
|
|
42
46
|
],
|
|
43
|
-
"repository":
|
|
44
|
-
|
|
45
|
-
"url": "https://github.com/novastera/nitro-metamask"
|
|
46
|
-
},
|
|
47
|
-
"author": "Novastera <hassan@novastera.com>",
|
|
47
|
+
"repository": "https://github.com/darksorrow/@novastera-oss/nitro-metamask.git",
|
|
48
|
+
"author": "DarkSorrow",
|
|
48
49
|
"license": "MIT",
|
|
49
|
-
"bugs":
|
|
50
|
-
|
|
51
|
-
},
|
|
52
|
-
"homepage": "https://novastera.com",
|
|
50
|
+
"bugs": "https://github.com/darksorrow/@novastera-oss/nitro-metamask/issues",
|
|
51
|
+
"homepage": "https://github.com/darksorrow/@novastera-oss/nitro-metamask#readme",
|
|
53
52
|
"publishConfig": {
|
|
53
|
+
"access": "public",
|
|
54
54
|
"registry": "https://registry.npmjs.org/"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@
|
|
58
|
-
"@
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"nitrogen": "
|
|
63
|
-
"
|
|
64
|
-
"react": "
|
|
65
|
-
"react-native": "0.
|
|
66
|
-
"react-native-nitro-modules": "
|
|
57
|
+
"@jamesacarr/eslint-formatter-github-actions": "^0.2.0",
|
|
58
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
59
|
+
"@semantic-release/git": "^10.0.1",
|
|
60
|
+
"@types/jest": "^29.5.12",
|
|
61
|
+
"@types/react": "19.2.0",
|
|
62
|
+
"nitrogen": "0.32.0",
|
|
63
|
+
"react": "19.2.0",
|
|
64
|
+
"react-native": "0.83",
|
|
65
|
+
"react-native-builder-bob": "^0.40.17",
|
|
66
|
+
"react-native-nitro-modules": "0.32.0",
|
|
67
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
68
|
+
"semantic-release": "^25.0.2",
|
|
67
69
|
"typescript": "^5.8.3"
|
|
68
70
|
},
|
|
69
71
|
"peerDependencies": {
|
|
70
72
|
"react": "*",
|
|
71
73
|
"react-native": "*",
|
|
72
|
-
"react-native-nitro-modules": "
|
|
74
|
+
"react-native-nitro-modules": "*"
|
|
73
75
|
},
|
|
74
76
|
"eslintConfig": {
|
|
75
77
|
"root": true,
|
|
@@ -104,5 +106,19 @@
|
|
|
104
106
|
"trailingComma": "es5",
|
|
105
107
|
"useTabs": false,
|
|
106
108
|
"semi": false
|
|
109
|
+
},
|
|
110
|
+
"react-native-builder-bob": {
|
|
111
|
+
"source": "src",
|
|
112
|
+
"output": "lib",
|
|
113
|
+
"targets": [
|
|
114
|
+
"commonjs",
|
|
115
|
+
"module",
|
|
116
|
+
[
|
|
117
|
+
"typescript",
|
|
118
|
+
{
|
|
119
|
+
"project": "tsconfig.json"
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
]
|
|
107
123
|
}
|
|
108
124
|
}
|
package/react-native.config.js
CHANGED
|
@@ -10,7 +10,10 @@ module.exports = {
|
|
|
10
10
|
/**
|
|
11
11
|
* @type {import('@react-native-community/cli-types').AndroidDependencyParams}
|
|
12
12
|
*/
|
|
13
|
-
android: {
|
|
13
|
+
android: {
|
|
14
|
+
packageImportPath: 'import com.margelo.nitro.nitrometamask.NitroMetamaskPackage;',
|
|
15
|
+
packageInstance: 'new NitroMetamaskPackage()',
|
|
16
|
+
},
|
|
14
17
|
},
|
|
15
18
|
},
|
|
16
19
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { NitroModules } from 'react-native-nitro-modules'
|
|
2
|
+
import type { NitroMetamask as NitroMetamaskSpec, ConnectResult } from './specs/nitro-metamask.nitro'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
/**
|
|
5
|
+
* NitroMetamask - MetaMask connector for React Native
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { NitroMetamask } from '@novastera-oss/nitro-metamask'
|
|
10
|
+
*
|
|
11
|
+
* const result = await NitroMetamask.connect()
|
|
12
|
+
* const signature = await NitroMetamask.signMessage('Hello')
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export const NitroMetamask = NitroModules.createHybridObject<NitroMetamaskSpec>('NitroMetamask')
|
|
4
16
|
|
|
5
|
-
export
|
|
6
|
-
NitroModules.createHybridObject<MetamaskConnector>('MetamaskConnector')
|
|
7
|
-
|
|
8
|
-
export type { ConnectResult, MetamaskConnector }
|
|
17
|
+
export type { ConnectResult, NitroMetamaskSpec }
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type HybridObject } from 'react-native-nitro-modules'
|
|
2
|
+
|
|
3
|
+
export interface ConnectResult {
|
|
4
|
+
address: string
|
|
5
|
+
chainId: number
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface NitroMetamask extends HybridObject<{ ios: 'swift', android: 'kotlin' }> {
|
|
9
|
+
/**
|
|
10
|
+
* Configure the dapp URL for MetaMask SDK validation.
|
|
11
|
+
* This URL is only used for SDK validation - the deep link return is handled automatically via AndroidManifest.xml.
|
|
12
|
+
*
|
|
13
|
+
* @param dappUrl - A valid HTTP/HTTPS URL (e.g., "https://yourdomain.com").
|
|
14
|
+
* If not provided, defaults to "https://novastera.com".
|
|
15
|
+
* This is separate from the deep link scheme which is auto-detected from your manifest.
|
|
16
|
+
*/
|
|
17
|
+
configure(dappUrl?: string): void
|
|
18
|
+
connect(): Promise<ConnectResult>
|
|
19
|
+
signMessage(message: string): Promise<string>
|
|
20
|
+
connectSign(nonce: string, exp: bigint): Promise<string>
|
|
21
|
+
}
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
package com.margelo.nitro.nitrometamask
|
|
2
|
-
|
|
3
|
-
import com.margelo.nitro.core.Promise
|
|
4
|
-
import io.metamask.androidsdk.Ethereum
|
|
5
|
-
import io.metamask.androidsdk.Result
|
|
6
|
-
import io.metamask.androidsdk.DappMetadata
|
|
7
|
-
import io.metamask.androidsdk.SDKOptions
|
|
8
|
-
import io.metamask.androidsdk.EthereumRequest
|
|
9
|
-
import io.metamask.androidsdk.EthereumMethod
|
|
10
|
-
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
11
|
-
import kotlin.coroutines.resume
|
|
12
|
-
|
|
13
|
-
class HybridMetamaskConnector : HybridMetamaskConnectorSpec() {
|
|
14
|
-
// Initialize Ethereum SDK with Context, DappMetadata, and SDKOptions
|
|
15
|
-
// Based on: https://github.com/MetaMask/metamask-android-sdk
|
|
16
|
-
// Using MetamaskContextHolder for Context access (Nitro doesn't provide Context APIs)
|
|
17
|
-
// This pattern matches how other Nitro modules handle Context (VisionCamera, MMKV, etc.)
|
|
18
|
-
private val ethereum: Ethereum by lazy {
|
|
19
|
-
val context = MetamaskContextHolder.get()
|
|
20
|
-
|
|
21
|
-
val dappMetadata = DappMetadata(
|
|
22
|
-
name = "Nitro MetaMask Connector",
|
|
23
|
-
url = "https://novastera.com"
|
|
24
|
-
)
|
|
25
|
-
// SDKOptions constructor requires infuraAPIKey and readonlyRPCMap parameters
|
|
26
|
-
// They can be null for basic usage without Infura or custom RPC
|
|
27
|
-
val sdkOptions = SDKOptions(
|
|
28
|
-
infuraAPIKey = null,
|
|
29
|
-
readonlyRPCMap = null
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
Ethereum(context, dappMetadata, sdkOptions)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
override fun connect(): Promise<ConnectResult> {
|
|
36
|
-
// Use Promise.async with coroutines for best practice in Nitro modules
|
|
37
|
-
// Reference: https://nitro.margelo.com/docs/types/promises
|
|
38
|
-
return Promise.async {
|
|
39
|
-
// Convert callback-based connect() to suspend function using suspendCancellableCoroutine
|
|
40
|
-
// This handles cancellation properly when JS GC disposes the promise
|
|
41
|
-
val result = suspendCancellableCoroutine<Result> { continuation ->
|
|
42
|
-
ethereum.connect { callbackResult ->
|
|
43
|
-
if (continuation.isActive) {
|
|
44
|
-
continuation.resume(callbackResult)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
when (result) {
|
|
50
|
-
is Result.Success.Item -> {
|
|
51
|
-
// After successful connection, get account info from SDK
|
|
52
|
-
val address = ethereum.selectedAddress
|
|
53
|
-
?: throw IllegalStateException("MetaMask SDK returned no address after connection")
|
|
54
|
-
val chainIdString = ethereum.chainId
|
|
55
|
-
?: throw IllegalStateException("MetaMask SDK returned no chainId after connection")
|
|
56
|
-
|
|
57
|
-
// Parse chainId from hex string (e.g., "0x1") or decimal string to number
|
|
58
|
-
// Nitro requires chainId to be Double (number in TS maps to Double in Kotlin)
|
|
59
|
-
val chainId = try {
|
|
60
|
-
val chainIdInt = if (chainIdString.startsWith("0x") || chainIdString.startsWith("0X")) {
|
|
61
|
-
chainIdString.substring(2).toLong(16).toInt()
|
|
62
|
-
} else {
|
|
63
|
-
chainIdString.toLong().toInt()
|
|
64
|
-
}
|
|
65
|
-
chainIdInt.toDouble()
|
|
66
|
-
} catch (e: NumberFormatException) {
|
|
67
|
-
throw IllegalStateException("Invalid chainId format: $chainIdString")
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
ConnectResult(
|
|
71
|
-
address = address,
|
|
72
|
-
chainId = chainId
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
is Result.Error -> {
|
|
76
|
-
throw Exception(result.error.message ?: "Failed to connect to MetaMask")
|
|
77
|
-
}
|
|
78
|
-
else -> {
|
|
79
|
-
throw IllegalStateException("Unexpected result type from MetaMask connect")
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
override fun signMessage(message: String): Promise<String> {
|
|
86
|
-
// Use Promise.async with coroutines for best practice in Nitro modules
|
|
87
|
-
// Reference: https://nitro.margelo.com/docs/types/promises
|
|
88
|
-
return Promise.async {
|
|
89
|
-
// Use direct signMessage() method (requires connection first via connect())
|
|
90
|
-
// This is more explicit and predictable than connectSign() which forces connection
|
|
91
|
-
// Based on SDK docs: ethereum.signMessage() requires address and message
|
|
92
|
-
val address = ethereum.selectedAddress
|
|
93
|
-
?: throw IllegalStateException("No connected account. Call connect() first.")
|
|
94
|
-
|
|
95
|
-
// Create EthereumRequest for personal_sign
|
|
96
|
-
val request = EthereumRequest(
|
|
97
|
-
method = EthereumMethod.PERSONAL_SIGN.value,
|
|
98
|
-
params = listOf(address, message)
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
// Convert callback-based sendRequest() to suspend function
|
|
102
|
-
val result = suspendCancellableCoroutine<Result> { continuation ->
|
|
103
|
-
ethereum.sendRequest(request) { callbackResult ->
|
|
104
|
-
if (continuation.isActive) {
|
|
105
|
-
continuation.resume(callbackResult)
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
when (result) {
|
|
111
|
-
is Result.Success.Item -> {
|
|
112
|
-
// Extract signature from result
|
|
113
|
-
result.value as? String
|
|
114
|
-
?: throw IllegalStateException("Invalid signature response format")
|
|
115
|
-
}
|
|
116
|
-
is Result.Error -> {
|
|
117
|
-
throw Exception(result.error.message ?: "Failed to sign message")
|
|
118
|
-
}
|
|
119
|
-
else -> {
|
|
120
|
-
throw IllegalStateException("Unexpected result type from MetaMask signMessage")
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import NitroModules
|
|
2
|
-
import MetaMaskSDK
|
|
3
|
-
import Foundation
|
|
4
|
-
|
|
5
|
-
final class HybridMetamaskConnector: HybridMetamaskConnectorSpec {
|
|
6
|
-
private let sdk = MetaMaskSDK.shared
|
|
7
|
-
|
|
8
|
-
func connect() -> Promise<ConnectResult> {
|
|
9
|
-
// Use Promise.async with Swift async/await for best practice in Nitro modules
|
|
10
|
-
// Reference: https://nitro.margelo.com/docs/types/promises
|
|
11
|
-
return Promise.async {
|
|
12
|
-
// Based on MetaMask iOS SDK docs: let connectResult = await metamaskSDK.connect()
|
|
13
|
-
// Reference: https://github.com/MetaMask/metamask-ios-sdk
|
|
14
|
-
let connectResult = try await self.sdk.connect()
|
|
15
|
-
|
|
16
|
-
switch connectResult {
|
|
17
|
-
case .success:
|
|
18
|
-
// After successful connection, get account info from SDK
|
|
19
|
-
// Note: sdk.account is a String (address), not an object
|
|
20
|
-
// Reference: https://raw.githubusercontent.com/MetaMask/metamask-ios-sdk/924d91bb3e98a5383c3082d6d5ba3ddac9e1c565/README.md
|
|
21
|
-
guard let address = self.sdk.account, !address.isEmpty else {
|
|
22
|
-
throw NSError(
|
|
23
|
-
domain: "MetamaskConnector",
|
|
24
|
-
code: -1,
|
|
25
|
-
userInfo: [NSLocalizedDescriptionKey: "MetaMask SDK returned no address after connection"]
|
|
26
|
-
)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Parse chainId from hex string (e.g., "0x1") to number
|
|
30
|
-
// Nitro requires chainId to be a number, not a string, for type safety
|
|
31
|
-
guard
|
|
32
|
-
let chainIdHex = self.sdk.chainId,
|
|
33
|
-
!chainIdHex.isEmpty,
|
|
34
|
-
let chainIdInt = Int(chainIdHex.replacingOccurrences(of: "0x", with: ""), radix: 16)
|
|
35
|
-
else {
|
|
36
|
-
throw NSError(
|
|
37
|
-
domain: "MetamaskConnector",
|
|
38
|
-
code: -1,
|
|
39
|
-
userInfo: [NSLocalizedDescriptionKey: "Invalid chainId format"]
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return ConnectResult(
|
|
44
|
-
address: address,
|
|
45
|
-
chainId: Double(chainIdInt)
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
case .failure(let error):
|
|
49
|
-
throw error
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
func signMessage(message: String) -> Promise<String> {
|
|
55
|
-
// Use Promise.async with Swift async/await for best practice in Nitro modules
|
|
56
|
-
// Reference: https://nitro.margelo.com/docs/types/promises
|
|
57
|
-
return Promise.async {
|
|
58
|
-
// Use explicit sign() method (requires connection first via connect())
|
|
59
|
-
// This is more explicit and predictable than connectAndSign() which forces connection
|
|
60
|
-
// Nitro encourages explicit object state, not convenience shortcuts
|
|
61
|
-
guard let account = self.sdk.account, !account.isEmpty else {
|
|
62
|
-
throw NSError(
|
|
63
|
-
domain: "MetamaskConnector",
|
|
64
|
-
code: -1,
|
|
65
|
-
userInfo: [NSLocalizedDescriptionKey: "No connected account. Call connect() first."]
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Create EthereumRequest for personal_sign
|
|
70
|
-
// Based on MetaMask iOS SDK docs: params are [account, message]
|
|
71
|
-
// Reference: https://raw.githubusercontent.com/MetaMask/metamask-ios-sdk/924d91bb3e98a5383c3082d6d5ba3ddac9e1c565/README.md
|
|
72
|
-
let params: [String] = [account, message]
|
|
73
|
-
let request = EthereumRequest(
|
|
74
|
-
method: .personalSign,
|
|
75
|
-
params: params
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
// Make the request using the SDK's async request method
|
|
79
|
-
let result = try await self.sdk.request(request)
|
|
80
|
-
|
|
81
|
-
// Extract signature from response
|
|
82
|
-
// The signature should be a hex-encoded string (0x-prefixed)
|
|
83
|
-
if let signature = result as? String {
|
|
84
|
-
return signature
|
|
85
|
-
} else if let dict = result as? [String: Any], let sig = dict["signature"] as? String ?? dict["result"] as? String {
|
|
86
|
-
return sig
|
|
87
|
-
} else {
|
|
88
|
-
throw NSError(
|
|
89
|
-
domain: "MetamaskConnector",
|
|
90
|
-
code: -1,
|
|
91
|
-
userInfo: [NSLocalizedDescriptionKey: "Invalid signature response format"]
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
-
export interface ConnectResult {
|
|
3
|
-
address: string;
|
|
4
|
-
chainId: number;
|
|
5
|
-
}
|
|
6
|
-
export interface MetamaskConnector extends HybridObject<{
|
|
7
|
-
ios: 'swift';
|
|
8
|
-
android: 'kotlin';
|
|
9
|
-
}> {
|
|
10
|
-
connect(): Promise<ConnectResult>;
|
|
11
|
-
signMessage(message: string): Promise<string>;
|
|
12
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/index.d.ts
DELETED
package/lib/index.js
DELETED
|
File without changes
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
///
|
|
2
|
-
/// HybridMetamaskConnectorSpec.swift
|
|
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
|
-
import Foundation
|
|
9
|
-
import NitroModules
|
|
10
|
-
|
|
11
|
-
/// See ``HybridMetamaskConnectorSpec``
|
|
12
|
-
public protocol HybridMetamaskConnectorSpec_protocol: HybridObject {
|
|
13
|
-
// Properties
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// Methods
|
|
17
|
-
func connect() throws -> Promise<ConnectResult>
|
|
18
|
-
func signMessage(message: String) throws -> Promise<String>
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public extension HybridMetamaskConnectorSpec_protocol {
|
|
22
|
-
/// Default implementation of ``HybridObject.toString``
|
|
23
|
-
func toString() -> String {
|
|
24
|
-
return "[HybridObject MetamaskConnector]"
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/// See ``HybridMetamaskConnectorSpec``
|
|
29
|
-
open class HybridMetamaskConnectorSpec_base {
|
|
30
|
-
private weak var cxxWrapper: HybridMetamaskConnectorSpec_cxx? = nil
|
|
31
|
-
public init() { }
|
|
32
|
-
public func getCxxWrapper() -> HybridMetamaskConnectorSpec_cxx {
|
|
33
|
-
#if DEBUG
|
|
34
|
-
guard self is HybridMetamaskConnectorSpec else {
|
|
35
|
-
fatalError("`self` is not a `HybridMetamaskConnectorSpec`! Did you accidentally inherit from `HybridMetamaskConnectorSpec_base` instead of `HybridMetamaskConnectorSpec`?")
|
|
36
|
-
}
|
|
37
|
-
#endif
|
|
38
|
-
if let cxxWrapper = self.cxxWrapper {
|
|
39
|
-
return cxxWrapper
|
|
40
|
-
} else {
|
|
41
|
-
let cxxWrapper = HybridMetamaskConnectorSpec_cxx(self as! HybridMetamaskConnectorSpec)
|
|
42
|
-
self.cxxWrapper = cxxWrapper
|
|
43
|
-
return cxxWrapper
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* A Swift base-protocol representing the MetamaskConnector HybridObject.
|
|
50
|
-
* Implement this protocol to create Swift-based instances of MetamaskConnector.
|
|
51
|
-
* ```swift
|
|
52
|
-
* class HybridMetamaskConnector : HybridMetamaskConnectorSpec {
|
|
53
|
-
* // ...
|
|
54
|
-
* }
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
public typealias HybridMetamaskConnectorSpec = HybridMetamaskConnectorSpec_protocol & HybridMetamaskConnectorSpec_base
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
///
|
|
2
|
-
/// HybridMetamaskConnectorSpec.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 "HybridMetamaskConnectorSpec.hpp"
|
|
9
|
-
|
|
10
|
-
namespace margelo::nitro::nitrometamask {
|
|
11
|
-
|
|
12
|
-
void HybridMetamaskConnectorSpec::loadHybridMethods() {
|
|
13
|
-
// load base methods/properties
|
|
14
|
-
HybridObject::loadHybridMethods();
|
|
15
|
-
// load custom methods/properties
|
|
16
|
-
registerHybrids(this, [](Prototype& prototype) {
|
|
17
|
-
prototype.registerHybridMethod("connect", &HybridMetamaskConnectorSpec::connect);
|
|
18
|
-
prototype.registerHybridMethod("signMessage", &HybridMetamaskConnectorSpec::signMessage);
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
} // namespace margelo::nitro::nitrometamask
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { HybridObject } from 'react-native-nitro-modules'
|
|
2
|
-
|
|
3
|
-
export interface ConnectResult {
|
|
4
|
-
address: string
|
|
5
|
-
chainId: number
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface MetamaskConnector
|
|
9
|
-
extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
|
|
10
|
-
connect(): Promise<ConnectResult>
|
|
11
|
-
signMessage(message: string): Promise<string>
|
|
12
|
-
}
|
|
13
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// TODO: Export specs that extend HybridObject<...> here
|