Skip to content

Commit

Permalink
Merge pull request #520 from xmtp/np/create-key-bundle-signer
Browse files Browse the repository at this point in the history
Add ability to create from key bundle with signer
  • Loading branch information
nplasterer authored Nov 1, 2024
2 parents c08ebf8 + 99194d6 commit 794fd86
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ class XMTPModule : Module() {
"sign",
"authed",
"authedV3",
"bundleAuthed",
"preCreateIdentityCallback",
"preEnableIdentityCallback",
"preAuthenticateToInboxCallback",
Expand Down Expand Up @@ -410,6 +411,34 @@ class XMTPModule : Module() {
}
}

AsyncFunction("createFromKeyBundleWithSigner") Coroutine { address: String, keyBundle: String, dbEncryptionKey: List<Int>?, authParams: String ->
withContext(Dispatchers.IO) {
logV("createFromKeyBundleWithSigner")
try {
val options = clientOptions(
dbEncryptionKey,
authParams
)
val bundle =
PrivateKeyOuterClass.PrivateKeyBundle.parseFrom(
Base64.decode(
keyBundle,
NO_WRAP
)
)
val reactSigner = ReactNativeSigner(module = this@XMTPModule, address = address)
signer = reactSigner
val client = Client().buildFromBundle(bundle = bundle, options = options, account = reactSigner)
clients[client.inboxId] = client
ContentJson.Companion
signer = null
sendEvent("bundleAuthed", ClientWrapper.encodeToObj(client))
} catch (e: Exception) {
throw XMTPException("Failed to create client: $e")
}
}
}

AsyncFunction("createV3") Coroutine { address: String, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean?, hasAuthInboxCallback: Boolean?, dbEncryptionKey: List<Int>?, authParams: String ->
withContext(Dispatchers.IO) {
logV("createV3")
Expand Down
14 changes: 7 additions & 7 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ PODS:
- hermes-engine/Pre-built (= 0.71.14)
- hermes-engine/Pre-built (0.71.14)
- libevent (2.1.12)
- LibXMTP (0.5.10)
- LibXMTP (0.6.0)
- Logging (1.0.0)
- MessagePacker (0.4.7)
- MMKV (2.0.0):
Expand Down Expand Up @@ -449,16 +449,16 @@ PODS:
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (0.16.0):
- XMTP (0.16.1):
- Connect-Swift (= 0.12.0)
- GzipSwift
- LibXMTP (= 0.5.10)
- LibXMTP (= 0.6.0)
- web3.swift
- XMTPReactNative (0.1.0):
- ExpoModulesCore
- MessagePacker
- secp256k1.swift
- XMTP (= 0.16.0)
- XMTP (= 0.16.1)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -711,7 +711,7 @@ SPEC CHECKSUMS:
GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LibXMTP: 3b64b0b1e4157ff73c37cde60fe943f89e6f8693
LibXMTP: 059c6d51b2c59419941ecff600aa586bbe083673
Logging: 9ef4ecb546ad3169398d5a723bc9bea1c46bef26
MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02
MMKV: f7d1d5945c8765f97f39c3d121f353d46735d801
Expand Down Expand Up @@ -763,8 +763,8 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 18d555dbf5afd3dcafa11b108042f9673da3c6b9
XMTPReactNative: cd8be3d8547d116005f3d0f4f207f19c7b34d035
XMTP: b2c2bcb0ddd6fbdb4820cac7be8a694c0f797425
XMTPReactNative: 0b3b70a875bcb3defc24f051f69c35b257037c08
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd
Expand Down
70 changes: 35 additions & 35 deletions example/ios/xmtpreactnativesdkexample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
9453E5BA4D9E60C6B21EAF55 /* libPods-xmtpreactnativesdkexample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A15D051C53AD0CEEBB4113F5 /* libPods-xmtpreactnativesdkexample.a */; };
54E6B19EA8330AD1B859A861 /* libPods-xmtpreactnativesdkexample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14DAE522F34BCEFD44E396D2 /* libPods-xmtpreactnativesdkexample.a */; };
A6A5DB882A00551E001DF8C2 /* xmtpreactnativesdkexampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6A5DB872A00551E001DF8C2 /* xmtpreactnativesdkexampleUITests.swift */; };
B18059E884C0ABDD17F3DC3D /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */; };
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
Expand All @@ -36,15 +36,15 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = xmtpreactnativesdkexample/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = xmtpreactnativesdkexample/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = xmtpreactnativesdkexample/main.m; sourceTree = "<group>"; };
74E1B7F7695132E36345D810 /* Pods-xmtpreactnativesdkexample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-xmtpreactnativesdkexample.release.xcconfig"; path = "Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample.release.xcconfig"; sourceTree = "<group>"; };
A15D051C53AD0CEEBB4113F5 /* libPods-xmtpreactnativesdkexample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-xmtpreactnativesdkexample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
14DAE522F34BCEFD44E396D2 /* libPods-xmtpreactnativesdkexample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-xmtpreactnativesdkexample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
62E6C2FC52DB7774BD32A867 /* Pods-xmtpreactnativesdkexample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-xmtpreactnativesdkexample.release.xcconfig"; path = "Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample.release.xcconfig"; sourceTree = "<group>"; };
6941C3A2B2A07289AC69DB6E /* Pods-xmtpreactnativesdkexample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-xmtpreactnativesdkexample.debug.xcconfig"; path = "Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample.debug.xcconfig"; sourceTree = "<group>"; };
A6A5DB852A00551E001DF8C2 /* xmtpreactnativesdkexampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = xmtpreactnativesdkexampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
A6A5DB872A00551E001DF8C2 /* xmtpreactnativesdkexampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = xmtpreactnativesdkexampleUITests.swift; sourceTree = "<group>"; };
A6AE8C832A49F1F300BD4E8B /* libMessagePack.swift.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libMessagePack.swift.a; sourceTree = BUILT_PRODUCTS_DIR; };
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = xmtpreactnativesdkexample/SplashScreen.storyboard; sourceTree = "<group>"; };
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
ED9CBB83C05BBF316FC66508 /* Pods-xmtpreactnativesdkexample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-xmtpreactnativesdkexample.debug.xcconfig"; path = "Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample.debug.xcconfig"; sourceTree = "<group>"; };
FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-xmtpreactnativesdkexample/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
FDF0078FD601458DA88B0565 /* noop-file.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = "noop-file.swift"; path = "xmtpreactnativesdkexample/noop-file.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand All @@ -54,7 +54,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9453E5BA4D9E60C6B21EAF55 /* libPods-xmtpreactnativesdkexample.a in Frameworks */,
54E6B19EA8330AD1B859A861 /* libPods-xmtpreactnativesdkexample.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -89,7 +89,7 @@
children = (
A6AE8C832A49F1F300BD4E8B /* libMessagePack.swift.a */,
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
A15D051C53AD0CEEBB4113F5 /* libPods-xmtpreactnativesdkexample.a */,
14DAE522F34BCEFD44E396D2 /* libPods-xmtpreactnativesdkexample.a */,
);
name = Frameworks;
sourceTree = "<group>";
Expand Down Expand Up @@ -154,8 +154,8 @@
D65327D7A22EEC0BE12398D9 /* Pods */ = {
isa = PBXGroup;
children = (
ED9CBB83C05BBF316FC66508 /* Pods-xmtpreactnativesdkexample.debug.xcconfig */,
74E1B7F7695132E36345D810 /* Pods-xmtpreactnativesdkexample.release.xcconfig */,
6941C3A2B2A07289AC69DB6E /* Pods-xmtpreactnativesdkexample.debug.xcconfig */,
62E6C2FC52DB7774BD32A867 /* Pods-xmtpreactnativesdkexample.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
Expand All @@ -175,14 +175,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "xmtpreactnativesdkexample" */;
buildPhases = (
1A3E35BABB8B52C80119AEF4 /* [CP] Check Pods Manifest.lock */,
F7C2F8448A1C8A1337F9DFBF /* [CP] Check Pods Manifest.lock */,
FD10A7F022414F080027D42C /* Start Packager */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
0A30FD7A4347963420162925 /* [CP] Embed Pods Frameworks */,
E72368AA4D83F2FC000573E5 /* [CP] Copy Pods Resources */,
4BAC9E432DE97602D88F93F8 /* [CP] Embed Pods Frameworks */,
0241AAAE331A2389D024FC03 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand Down Expand Up @@ -286,7 +286,27 @@
shellPath = /bin/sh;
shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" $PROJECT_ROOT ios relative | tail -n 1)\"\nfi\n\n`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n\n";
};
0A30FD7A4347963420162925 /* [CP] Embed Pods Frameworks */ = {
0241AAAE331A2389D024FC03 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample-resources.sh\"\n";
showEnvVarsInLog = 0;
};
4BAC9E432DE97602D88F93F8 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand All @@ -306,7 +326,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
1A3E35BABB8B52C80119AEF4 /* [CP] Check Pods Manifest.lock */ = {
F7C2F8448A1C8A1337F9DFBF /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand All @@ -328,26 +348,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
E72368AA4D83F2FC000573E5 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-xmtpreactnativesdkexample/Pods-xmtpreactnativesdkexample-resources.sh\"\n";
showEnvVarsInLog = 0;
};
FD10A7F022414F080027D42C /* Start Packager */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down Expand Up @@ -402,7 +402,7 @@
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = ED9CBB83C05BBF316FC66508 /* Pods-xmtpreactnativesdkexample.debug.xcconfig */;
baseConfigurationReference = 6941C3A2B2A07289AC69DB6E /* Pods-xmtpreactnativesdkexample.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
Expand Down Expand Up @@ -435,7 +435,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 74E1B7F7695132E36345D810 /* Pods-xmtpreactnativesdkexample.release.xcconfig */;
baseConfigurationReference = 62E6C2FC52DB7774BD32A867 /* Pods-xmtpreactnativesdkexample.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
Expand Down
81 changes: 61 additions & 20 deletions example/src/tests/groupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,37 +57,86 @@ test('can revoke all other installations', async () => {
])
const alixWallet = Wallet.createRandom()

// create a v3 client
const alix = await Client.create(alixWallet, {
env: 'local',
appVersion: 'Testing/0.0.0',
enableV3: true,
dbEncryptionKey: keyBytes,
})

await alix.deleteLocalDatabase()

// create a v2 client
const alix2 = await Client.create(alixWallet, {
env: 'local',
})

const keyBundle = await alix2.exportKeyBundle()

// create from keybundle a v3 client
const alixKeyBundle = await Client.createFromKeyBundle(
keyBundle,
{
env: 'local',
appVersion: 'Testing/0.0.0',
enableV3: true,
dbEncryptionKey: keyBytes,
},
alixWallet
)

const inboxState = await alixKeyBundle.inboxState(true)
assert(
inboxState.installations.length === 2,
`installations length should be 2 but was ${inboxState.installations.length}`
)

const alix3 = await Client.create(alixWallet, {
env: 'local',
appVersion: 'Testing/0.0.0',
enableV3: true,
dbEncryptionKey: keyBytes,
})

const inboxState = await alix2.inboxState(true)
const keyBundle2 = await alix3.exportKeyBundle()

const alixKeyBundle2 = await Client.createFromKeyBundle(
keyBundle2,
{
env: 'local',
appVersion: 'Testing/0.0.0',
enableV3: true,
dbEncryptionKey: keyBytes,
},
alixWallet
)

await alix3.deleteLocalDatabase()

const alix4 = await Client.create(alixWallet, {
env: 'local',
appVersion: 'Testing/0.0.0',
enableV3: true,
dbEncryptionKey: keyBytes,
})

const inboxState2 = await alix4.inboxState(true)
assert(
inboxState.installations.length === 2,
`installations length should be 2 but was ${inboxState.installations.length}`
inboxState2.installations.length === 3,
`installations length should be 3 but was ${inboxState2.installations.length}`
)

await alix2.revokeAllOtherInstallations(alixWallet)
await alix4.revokeAllOtherInstallations(alixWallet)

const inboxState2 = await alix2.inboxState(true)
const inboxState3 = await alix4.inboxState(true)
assert(
inboxState2.installations.length === 1,
`installations length should be 1 but was ${inboxState2.installations.length}`
inboxState3.installations.length === 1,
`installations length should be 1 but was ${inboxState3.installations.length}`
)

assert(
inboxState2.installations[0].createdAt !== undefined,
inboxState3.installations[0].createdAt !== undefined,
`installations createdAt should not be undefined`
)
return true
Expand Down Expand Up @@ -2290,19 +2339,11 @@ test('can sync all groups', async () => {
}

// First syncAllGroups after removal will still sync each group to set group inactive
// For some reason on Android (RN only), first syncAllGroups already returns 0
const numGroupsSynced2 = await bo.conversations.syncAllGroups()
if (Platform.OS === 'ios') {
assert(
numGroupsSynced2 === 50,
`should have synced 50 groups but synced ${numGroupsSynced2}`
)
} else {
assert(
numGroupsSynced2 === 0,
`should have synced 0 groups but synced ${numGroupsSynced2}`
)
}
assert(
numGroupsSynced2 === 50,
`should have synced 50 groups but synced ${numGroupsSynced2}`
)

// Next syncAllGroups will not sync inactive groups
const numGroupsSynced3 = await bo.conversations.syncAllGroups()
Expand Down
10 changes: 10 additions & 0 deletions example/src/tests/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,16 @@ test('can load a client from env "2k lens convos" private key', async () => {
env: 'local',
})

const keyBundle = await xmtpClient.exportKeyBundle()

await Client.createFromKeyBundle(
keyBundle,
{
env: 'local',
},
signer
)

return true
})

Expand Down
Loading

0 comments on commit 794fd86

Please sign in to comment.