Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutli Wallet Support #544

Merged
merged 10 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
implementation "org.xmtp:android:3.0.6"
implementation "org.xmtp:android:3.0.8"
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.facebook.react:react-native:0.71.3'
implementation "com.daveanthonythomas.moshipack:moshipack:1.0.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import expo.modules.xmtpreactnativesdk.wrappers.GroupWrapper
import expo.modules.xmtpreactnativesdk.wrappers.InboxStateWrapper
import expo.modules.xmtpreactnativesdk.wrappers.MemberWrapper
import expo.modules.xmtpreactnativesdk.wrappers.PermissionPolicySetWrapper
import expo.modules.xmtpreactnativesdk.wrappers.WalletParamsWrapper
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -253,19 +254,6 @@ class XMTPModule : Module() {
}
}

AsyncFunction("revokeAllOtherInstallations") Coroutine { inboxId: String ->
withContext(Dispatchers.IO) {
logV("revokeAllOtherInstallations")
val client = clients[inboxId] ?: throw XMTPException("No client")
val reactSigner =
ReactNativeSigner(module = this@XMTPModule, address = client.address)
signer = reactSigner

client.revokeAllOtherInstallations(reactSigner)
signer = null
}
}

AsyncFunction("getInboxState") Coroutine { inboxId: String, refreshFromNetwork: Boolean ->
withContext(Dispatchers.IO) {
val client = clients[inboxId] ?: throw XMTPException("No client")
Expand Down Expand Up @@ -317,16 +305,16 @@ class XMTPModule : Module() {
}
}

AsyncFunction("create") Coroutine { address: String, hasAuthInboxCallback: Boolean?, dbEncryptionKey: List<Int>, authParams: String ->
AsyncFunction("create") Coroutine { address: String, hasAuthInboxCallback: Boolean?, dbEncryptionKey: List<Int>, authParams: String, walletParams: String ->
withContext(Dispatchers.IO) {
logV("create")
val authOptions = AuthParamsWrapper.authParamsFromJson(authParams)
val walletOptions = WalletParamsWrapper.walletParamsFromJson(walletParams)
val reactSigner = ReactNativeSigner(
module = this@XMTPModule,
address = address,
type = authOptions.walletType,
chainId = authOptions.chainId,
blockNumber = authOptions.blockNumber
type = walletOptions.walletType,
chainId = walletOptions.chainId,
blockNumber = walletOptions.blockNumber
)
signer = reactSigner
val options = clientOptions(
Expand Down Expand Up @@ -356,6 +344,66 @@ class XMTPModule : Module() {
}
}

AsyncFunction("revokeAllOtherInstallations") Coroutine { inboxId: String, walletParams: String ->
withContext(Dispatchers.IO) {
logV("revokeAllOtherInstallations")
val client = clients[inboxId] ?: throw XMTPException("No client")
val walletOptions = WalletParamsWrapper.walletParamsFromJson(walletParams)
val reactSigner =
ReactNativeSigner(
module = this@XMTPModule,
address = client.address,
type = walletOptions.walletType,
chainId = walletOptions.chainId,
blockNumber = walletOptions.blockNumber
)
signer = reactSigner

client.revokeAllOtherInstallations(reactSigner)
signer = null
}
}

AsyncFunction("addAccount") Coroutine { inboxId: String, newAddress: String, walletParams: String ->
withContext(Dispatchers.IO) {
logV("addAccount")
val client = clients[inboxId] ?: throw XMTPException("No client")
val walletOptions = WalletParamsWrapper.walletParamsFromJson(walletParams)
val reactSigner =
ReactNativeSigner(
module = this@XMTPModule,
address = newAddress,
type = walletOptions.walletType,
chainId = walletOptions.chainId,
blockNumber = walletOptions.blockNumber
)
signer = reactSigner

client.addAccount(reactSigner)
signer = null
}
}

AsyncFunction("removeAccount") Coroutine { inboxId: String, addressToRemove: String, walletParams: String ->
withContext(Dispatchers.IO) {
logV("removeAccount")
val client = clients[inboxId] ?: throw XMTPException("No client")
val walletOptions = WalletParamsWrapper.walletParamsFromJson(walletParams)
val reactSigner =
ReactNativeSigner(
module = this@XMTPModule,
address = client.address,
type = walletOptions.walletType,
chainId = walletOptions.chainId,
blockNumber = walletOptions.blockNumber
)
signer = reactSigner

client.removeAccount(reactSigner, addressToRemove)
signer = null
}
}

AsyncFunction("dropClient") Coroutine { inboxId: String ->
withContext(Dispatchers.IO) {
logV("dropClient")
Expand All @@ -366,13 +414,26 @@ class XMTPModule : Module() {

AsyncFunction("signWithInstallationKey") Coroutine { inboxId: String, message: String ->
withContext(Dispatchers.IO) {
logV("signWithInstallationKey")
val client = clients[inboxId] ?: throw XMTPException("No client")

val signature = client.signWithInstallationKey(message)
signature.map { it.toInt() and 0xFF }
}
}

AsyncFunction("verifySignature") Coroutine { inboxId: String, message: String, signature: List<Int> ->
withContext(Dispatchers.IO) {
nplasterer marked this conversation as resolved.
Show resolved Hide resolved
logV("verifySignature")
val client = clients[inboxId] ?: throw XMTPException("No client")
val signatureBytes =
signature.foldIndexed(ByteArray(signature.size)) { i, a, v ->
a.apply { set(i, v.toByte()) }
}
client.verifySignature(message, signatureBytes)
}
}

AsyncFunction("canMessage") Coroutine { inboxId: String, peerAddresses: List<String> ->
withContext(Dispatchers.IO) {
logV("canMessage")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ class AuthParamsWrapper(
val appVersion: String?,
val dbDirectory: String?,
val historySyncUrl: String?,
val walletType: WalletType = WalletType.EOA,
val chainId: Long?,
val blockNumber: Long?,
) {
companion object {
fun authParamsFromJson(authParams: String): AuthParamsWrapper {
Expand All @@ -20,6 +17,21 @@ class AuthParamsWrapper(
if (jsonOptions.has("appVersion")) jsonOptions.get("appVersion").asString else null,
if (jsonOptions.has("dbDirectory")) jsonOptions.get("dbDirectory").asString else null,
if (jsonOptions.has("historySyncUrl")) jsonOptions.get("historySyncUrl").asString else null,
)
}
}
}

class WalletParamsWrapper(
val walletType: WalletType = WalletType.EOA,
val chainId: Long?,
val blockNumber: Long?,

) {
companion object {
fun walletParamsFromJson(walletParams: String): WalletParamsWrapper {
val jsonOptions = JsonParser.parseString(walletParams).asJsonObject
return WalletParamsWrapper(
if (jsonOptions.has("walletType")) {
when (jsonOptions.get("walletType").asString) {
"SCW" -> WalletType.SCW
Expand All @@ -30,7 +42,8 @@ class AuthParamsWrapper(
},
if (jsonOptions.has("chainId")) jsonOptions.get("chainId").asLong else null,
if (jsonOptions.has("blockNumber")) jsonOptions.get("blockNumber").asLong else null,
)
)
}
}
}

60 changes: 22 additions & 38 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
PODS:
- BigInt (5.0.0)
- boost (1.76.0)
- CoinbaseWalletSDK/Client (1.0.4)
- CoinbaseWalletSDK/CrossPlatform (1.0.4):
- CoinbaseWalletSDK/Client
- CoinbaseWalletSDKExpo (1.0.10):
- CoinbaseWalletSDK/CrossPlatform (= 1.0.4)
- ExpoModulesCore
- Connect-Swift (0.12.0):
- SwiftProtobuf (~> 1.25.2)
- Connect-Swift (1.0.0):
- SwiftProtobuf (~> 1.28.2)
- CryptoSwift (1.8.3)
- CSecp256k1 (0.2.0)
- DoubleConversion (1.1.6)
- EXApplication (5.4.0):
- ExpoModulesCore
Expand Down Expand Up @@ -49,15 +50,12 @@ PODS:
- React-jsi (= 0.71.14)
- ReactCommon/turbomodule/core (= 0.71.14)
- fmt (6.2.1)
- GenericJSON (2.0.2)
- glog (0.3.5)
- GzipSwift (5.1.1)
- hermes-engine (0.71.14):
- hermes-engine/Pre-built (= 0.71.14)
- hermes-engine/Pre-built (0.71.14)
- libevent (2.1.12)
- LibXMTP (3.0.3)
- Logging (1.0.0)
- LibXMTP (3.0.7)
- MessagePacker (0.4.7)
- MMKV (2.0.0):
- MMKVCore (~> 2.0.0)
Expand Down Expand Up @@ -442,23 +440,17 @@ PODS:
- React-RCTImage
- RNSVG (13.14.0):
- React-Core
- secp256k1.swift (0.1.4)
- SwiftProtobuf (1.25.2)
- web3.swift (1.6.0):
- BigInt (~> 5.0.0)
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (3.0.6):
- Connect-Swift (= 0.12.0)
- GzipSwift
- LibXMTP (= 3.0.3)
- web3.swift
- SwiftProtobuf (1.28.2)
- XMTP (3.0.8):
- Connect-Swift (= 1.0.0)
- CryptoSwift (= 1.8.3)
- CSecp256k1 (~> 0.2)
- LibXMTP (= 3.0.7)
- XMTPReactNative (0.1.0):
- CSecp256k1 (~> 0.2)
- ExpoModulesCore
- MessagePacker
- secp256k1.swift
- XMTP (= 3.0.6)
- XMTP (= 3.0.8)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -533,22 +525,18 @@ DEPENDENCIES:

SPEC REPOS:
trunk:
- BigInt
- CoinbaseWalletSDK
- Connect-Swift
- CryptoSwift
- CSecp256k1
- fmt
- GenericJSON
- GzipSwift
- libevent
- LibXMTP
- Logging
- MessagePacker
- MMKV
- MMKVCore
- OpenSSL-Universal
- secp256k1.swift
- SwiftProtobuf
- web3.swift
- XMTP

EXTERNAL SOURCES:
Expand Down Expand Up @@ -684,11 +672,12 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
BigInt: 74b4d88367b0e819d9f77393549226d36faeb0d8
boost: 57d2868c099736d80fcd648bf211b4431e51a558
CoinbaseWalletSDK: ea1f37512bbc69ebe07416e3b29bf840f5cc3152
CoinbaseWalletSDKExpo: c79420eb009f482f768c23b6768fc5b2d7c98777
Connect-Swift: 1de2ef4a548c59ecaeb9120812dfe0d6e07a0d47
Connect-Swift: 84e043b904f63dc93a2c01c6c125da25e765b50d
CryptoSwift: 967f37cea5a3294d9cce358f78861652155be483
CSecp256k1: 2a59c03e52637ded98896a33be4b2649392cb843
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
EXApplication: 2a0d9abd4feace9c6faedfe541c1dec02e3702cd
EXConstants: f348da07e21b23d2b085e270d7b74f282df1a7d9
Expand All @@ -706,13 +695,10 @@ SPEC CHECKSUMS:
FBLazyVector: 12ea01e587c9594e7b144e1bfc86ac4d9ac28fde
FBReactNativeSpec: b6ae48e67aaba46442f84d6f9ba598ccfbe2ee66
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
GenericJSON: 79a840eeb77030962e8cf02a62d36bd413b67626
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LibXMTP: 948d39cf5b978adaa7d0f6ea5c6c0995a0b9e63f
Logging: 9ef4ecb546ad3169398d5a723bc9bea1c46bef26
LibXMTP: 1d9b9514c2b6407a82d72b203288cd5af064d787
MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02
MMKV: f7d1d5945c8765f97f39c3d121f353d46735d801
MMKVCore: c04b296010fcb1d1638f2c69405096aac12f6390
Expand Down Expand Up @@ -760,11 +746,9 @@ SPEC CHECKSUMS:
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
RNScreens: 218801c16a2782546d30bd2026bb625c0302d70f
RNSVG: d00c8f91c3cbf6d476451313a18f04d220d4f396
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 48d0c71ef732ac4d79c2942902a132bf71661029
XMTPReactNative: 406f92e777c9d2891404956309d926e7b2f25c1c
SwiftProtobuf: 4dbaffec76a39a8dc5da23b40af1a5dc01a4c02d
XMTP: f8ee66c4aacc5750ab0f67f5bb86c05cd2513185
XMTPReactNative: 8cda2ca09be81cee8c26d986db65fc6faef57bea
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,17 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/SwiftProtobuf/SwiftProtobuf.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/CryptoSwift.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SwiftProtobuf.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
Expand Down
Loading
Loading