@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
@@ -1,146 +0,0 @@
1
- package com.nitrometamask
2
-
3
- import com.margelo.nitro.core.Promise
4
- import com.margelo.nitro.nitrometamask.HybridNitroMetamaskSpec
5
- import com.margelo.nitro.nitrometamask.ConnectResult
6
- import io.metamask.androidsdk.Ethereum
7
- import io.metamask.androidsdk.Result
8
- import io.metamask.androidsdk.DappMetadata
9
- import io.metamask.androidsdk.SDKOptions
10
- import io.metamask.androidsdk.EthereumRequest
11
- import kotlinx.coroutines.suspendCancellableCoroutine
12
- import kotlin.coroutines.resume
13
-
14
- class HybridNitroMetamask : HybridNitroMetamaskSpec() {
15
- // Initialize Ethereum SDK with Context, DappMetadata, and SDKOptions
16
- // Based on: https://github.com/MetaMask/metamask-android-sdk
17
- // Using MetamaskContextHolder for Context access (Nitro doesn't provide Context APIs)
18
- // This pattern matches how other Nitro modules handle Context (VisionCamera, MMKV, etc.)
19
- private val ethereum: Ethereum by lazy {
20
- val context = MetamaskContextHolder.get()
21
-
22
- val dappMetadata = DappMetadata(
23
- name = "Nitro MetaMask Connector",
24
- url = "https://novastera.com"
25
- )
26
- // SDKOptions constructor requires infuraAPIKey and readonlyRPCMap parameters
27
- // They can be null for basic usage without Infura or custom RPC
28
- val sdkOptions = SDKOptions(
29
- infuraAPIKey = null,
30
- readonlyRPCMap = null
31
- )
32
-
33
- Ethereum(context, dappMetadata, sdkOptions)
34
- }
35
-
36
- override fun connect(): Promise<ConnectResult> {
37
- // Use Promise.async with coroutines for best practice in Nitro modules
38
- // Reference: https://nitro.margelo.com/docs/types/promises
39
- return Promise.async {
40
- // Convert callback-based connect() to suspend function using suspendCancellableCoroutine
41
- // This handles cancellation properly when JS GC disposes the promise
42
- val result = suspendCancellableCoroutine<Result> { continuation ->
43
- ethereum.connect { callbackResult ->
44
- if (continuation.isActive) {
45
- continuation.resume(callbackResult)
46
- }
47
- }
48
- }
49
-
50
- when (result) {
51
- is Result.Success.Item -> {
52
- // After successful connection, get account info from SDK
53
- val address = ethereum.selectedAddress
54
- ?: throw IllegalStateException("MetaMask SDK returned no address after connection")
55
- val chainIdString = ethereum.chainId
56
- ?: throw IllegalStateException("MetaMask SDK returned no chainId after connection")
57
-
58
- // Parse chainId from hex string (e.g., "0x1") or decimal string to number
59
- // Nitro requires chainId to be Double (number in TS maps to Double in Kotlin)
60
- val chainId = try {
61
- val chainIdInt = if (chainIdString.startsWith("0x") || chainIdString.startsWith("0X")) {
62
- chainIdString.substring(2).toLong(16).toInt()
63
- } else {
64
- chainIdString.toLong().toInt()
65
- }
66
- chainIdInt.toDouble()
67
- } catch (e: NumberFormatException) {
68
- throw IllegalStateException("Invalid chainId format: $chainIdString")
69
- }
70
-
71
- ConnectResult(
72
- address = address,
73
- chainId = chainId
74
- )
75
- }
76
- is Result.Success.ItemMap -> {
77
- // Handle ItemMap case (shouldn't happen for connect, but make exhaustive)
78
- throw IllegalStateException("Unexpected ItemMap result from MetaMask connect")
79
- }
80
- is Result.Success.Items -> {
81
- // Handle Items case (shouldn't happen for connect, but make exhaustive)
82
- throw IllegalStateException("Unexpected Items result from MetaMask connect")
83
- }
84
- is Result.Error -> {
85
- // Result.Error contains the error directly
86
- val errorMessage = result.error?.message ?: result.error?.toString() ?: "MetaMask connection failed"
87
- throw Exception(errorMessage)
88
- }
89
- }
90
- }
91
- }
92
-
93
- override fun signMessage(message: String): Promise<String> {
94
- // Use Promise.async with coroutines for best practice in Nitro modules
95
- // Reference: https://nitro.margelo.com/docs/types/promises
96
- return Promise.async {
97
- // Verify connection state before attempting to sign
98
- // MetaMask SDK requires an active connection to sign messages
99
- val address = ethereum.selectedAddress
100
- if (address.isNullOrEmpty()) {
101
- throw IllegalStateException("No connected account. Please call connect() first to establish a connection with MetaMask.")
102
- }
103
-
104
- // Create EthereumRequest for personal_sign
105
- // Based on MetaMask Android SDK docs: params are [account, message]
106
- // Reference: https://github.com/MetaMask/metamask-android-sdk
107
- // EthereumRequest constructor expects method as String
108
- val request = EthereumRequest(
109
- method = "personal_sign",
110
- params = listOf(address, message)
111
- )
112
-
113
- // Convert callback-based sendRequest() to suspend function
114
- val result = suspendCancellableCoroutine<Result> { continuation ->
115
- ethereum.sendRequest(request) { callbackResult ->
116
- if (continuation.isActive) {
117
- continuation.resume(callbackResult)
118
- }
119
- }
120
- }
121
-
122
- when (result) {
123
- is Result.Success.Item -> {
124
- // Extract signature from response
125
- // The signature should be a hex-encoded string (0x-prefixed)
126
- val signature = result.value as? String
127
- ?: throw Exception("Invalid signature response format")
128
- signature
129
- }
130
- is Result.Success.ItemMap -> {
131
- // Handle ItemMap case (shouldn't happen for signMessage, but make exhaustive)
132
- throw IllegalStateException("Unexpected ItemMap result from MetaMask signMessage")
133
- }
134
- is Result.Success.Items -> {
135
- // Handle Items case (shouldn't happen for signMessage, but make exhaustive)
136
- throw IllegalStateException("Unexpected Items result from MetaMask signMessage")
137
- }
138
- is Result.Error -> {
139
- // Result.Error contains the error directly
140
- val errorMessage = result.error?.message ?: result.error?.toString() ?: "MetaMask signing failed"
141
- throw Exception(errorMessage)
142
- }
143
- }
144
- }
145
- }
146
- }