Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/gentle-cases-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/mobile": patch
---

✨ add wallet provisioning
5 changes: 5 additions & 0 deletions .changeset/rich-months-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/mobile": patch
---

🍱 add meawallet config assets
5 changes: 4 additions & 1 deletion .maestro/subflows/activateCard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ appId: ${APP_ID ?? "app.exactly"}
commands:
- runFlow: { file: scrollTo.yaml, env: { element: Accept and enable card } }
- tapOn: Accept and enable card
- assertVisible: Manually add your card to Apple Pay & Google Pay to make contactless payments.
- runFlow:
when: { platform: web }
commands:
- assertVisible: Manually add your card to Apple Pay & Google Pay to make contactless payments.
- tapOn: Close
- tapOn: Freeze card
- tapOn: { text: Freeze card, below: "Freeze your card?" }
Expand Down
15 changes: 15 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# isc license
#
# copyright meawallet
#
# permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby
# granted, provided that the above copyright notice and this permission notice appear in all copies.
#
# the software is provided "as is" and the author disclaims all warranties with regard to this software including
# all implied warranties of merchantability and fitness. in no event shall the author be liable for any special,
# direct, indirect, or consequential damages or any damages whatsoever resulting from loss of use, data or profits,
# whether in an action of contract, negligence or other tortious action, arising out of or in connection with the
# use or performance of this software.
@meawallet:registry=https://nexus.ext.meawallet.com/repository/react-native-mpp/
//nexus.ext.meawallet.com/repository/react-native-mpp/:username=ext-react-native-mpp
//nexus.ext.meawallet.com/repository/react-native-mpp/:_password=OXJDTVo1ZEg2dHVD
Comment thread
aguxez marked this conversation as resolved.
Comment thread
aguxez marked this conversation as resolved.
Comment thread
aguxez marked this conversation as resolved.
133 changes: 129 additions & 4 deletions app.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import type { PluginConfigType as BuildPropertiesConfig } from "expo-build-properties/build/pluginConfig";
import type { FontProps } from "expo-font/plugin/build/withFonts";

import { AndroidConfig, withAndroidManifest, withAppBuildGradle, type ConfigPlugin } from "expo/config-plugins";
import {
AndroidConfig,
IOSConfig,
withAndroidManifest,
withAppBuildGradle,
withDangerousMod,
withXcodeProject,
type ConfigPlugin,
} from "expo/config-plugins";
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import { env } from "node:process";

import metadata from "./package.json";
Expand Down Expand Up @@ -40,6 +50,7 @@ export default {
associatedDomains: [`webcredentials:${env.APP_DOMAIN ?? "sandbox.exactly.app"}`],
supportsTablet: false,
buildNumber: String(versionCode),
entitlements: { "com.apple.developer.payment-pass-provisioning": true },
infoPlist: {
ITSAppUsesNonExemptEncryption: false,
CFBundleAllowMixedLocalizations: true,
Expand Down Expand Up @@ -110,12 +121,126 @@ export default {
},
],
// @ts-expect-error inline plugin
((config) => {
const withAndroid = withDangerousMod(config, [
"android",
(c) => {
const source = path.join(c.modRequest.projectRoot, "src/assets/mea_config");
const destination = path.join(c.modRequest.projectRoot, "android/app/src/main/res/raw/mea_config");
Comment thread
aguxez marked this conversation as resolved.
if (!existsSync(source)) throw new Error("meawallet: missing src/assets/mea_config");
mkdirSync(path.dirname(destination), { recursive: true });
copyFileSync(source, destination);
return c;
},
]);
return withXcodeProject(withAndroid, (c) => {
const source = path.join(c.modRequest.projectRoot, "src/assets/mea_config");
const projectName = c.modRequest.projectName ?? "";
const destination = path.join(c.modRequest.projectRoot, "ios", projectName, "mea_config");
if (!existsSync(source)) throw new Error("meawallet: missing src/assets/mea_config");
copyFileSync(source, destination);
IOSConfig.XcodeUtils.addResourceFileToGroup({
filepath: `${projectName}/mea_config`,
groupName: projectName,
project: c.modResults, // eslint-disable-line @typescript-eslint/no-unsafe-assignment -- expo xcode project type
isBuildFile: true,
});
return c;
});
}) satisfies ConfigPlugin,
Comment thread
aguxez marked this conversation as resolved.
// @ts-expect-error inline plugin
((config) =>
withDangerousMod(config, [
"android",
(c) => {
const buildGradle = path.join(c.modRequest.projectRoot, "android/build.gradle");
const meaRepo = ` maven {
url "https://nexus.ext.meawallet.com/repository/mpp-android-group/"
credentials {
username = "ext-mpp-android"
password = "M1yeJMcuE5TiGW"
Comment thread
aguxez marked this conversation as resolved.
}
}`;
Comment thread
aguxez marked this conversation as resolved.
const contents = readFileSync(buildGradle, "utf8");
if (!contents.includes("nexus.ext.meawallet.com")) {
const replaced = contents.replace(/(allprojects[\s\S]*?repositories\s*\{)/, `$1\n${meaRepo}`); // cspell:ignore allprojects
if (replaced === contents)
throw new Error("meawallet: failed to inject maven repo into android/build.gradle");
writeFileSync(buildGradle, replaced);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
return c;
},
])) satisfies ConfigPlugin,
Comment thread
aguxez marked this conversation as resolved.
// @ts-expect-error inline plugin
((config) =>
withDangerousMod(config, [
"ios",
(c) => {
const podfile = path.join(c.modRequest.projectRoot, "ios/Podfile"); // cspell:ignore podfile Podfile OBJC RCTJS RCTUI modulemap fmodule
if (!existsSync(podfile)) return c;
const workaround = ` rctHeaders = "#{installer.sandbox.root}/Headers/Public/React-RCTAppDelegate"
Dir.mkdir(rctHeaders) unless Dir.exist?(rctHeaders)
File.write("#{rctHeaders}/React-RCTAppDelegate-umbrella.h", <<~'H')
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
#import "RCTAppDelegate.h"
#import "RCTAppSetupUtils.h"
#import "RCTArchConfiguratorProtocol.h"
#import "RCTDefaultReactNativeFactoryDelegate.h"
#import "RCTDependencyProvider.h"
#import "RCTJSRuntimeConfiguratorProtocol.h"
#import "RCTReactNativeFactory.h"
#import "RCTRootViewFactory.h"
#import "RCTUIConfiguratorProtocol.h"
H
File.write("#{rctHeaders}/React_RCTAppDelegate.modulemap", <<~MAP)
module React_RCTAppDelegate {
umbrella header "React-RCTAppDelegate-umbrella.h"
export *
module * { export * }
}
MAP
installer.pods_project.targets.each do |target|
next unless target.name == "meawallet-react-native-mpp"
target.build_configurations.each do |buildConfiguration|
flags = buildConfiguration.build_settings["OTHER_SWIFT_FLAGS"] || "$(inherited)"
next if flags.include?("React_RCTAppDelegate.modulemap")
buildConfiguration.build_settings["OTHER_SWIFT_FLAGS"] =
"#{flags} -Xcc -fmodule-map-file=\${PODS_ROOT}/Headers/Public/React-RCTAppDelegate/React_RCTAppDelegate.modulemap"
end
Comment thread
aguxez marked this conversation as resolved.
end
`;
const contents = readFileSync(podfile, "utf8");
if (!contents.includes("React_RCTAppDelegate.modulemap")) {
const replaced = contents.replace(
/(\s{4}react_native_post_install\([\s\S]*?\n\s{4}\)\n)/,
`$1${workaround}`,
);
if (replaced === contents)
throw new Error("meawallet: failed to inject react_native_post_install workaround into ios/Podfile");
writeFileSync(podfile, replaced);
}
return c;
},
])) satisfies ConfigPlugin,
// @ts-expect-error inline plugin
((config) =>
withAndroidManifest(
withAppBuildGradle(config, (c) => {
c.modResults.contents = c.modResults.contents.replace(
/defaultConfig\s*\{/,
'$& ndk { debugSymbolLevel "FULL" }',
c.modResults.contents = c.modResults.contents.replaceAll(
/(defaultConfig\s*\{)(?:\s*ndk\s*\{\s*debugSymbolLevel\s*"FULL"\s*\})+/g,
"$1",
);
if (!c.modResults.contents.includes('debugSymbolLevel "FULL"')) {
c.modResults.contents = c.modResults.contents.replace(
/release\s*\{/,
'$&\n ndk { debugSymbolLevel "FULL" }',
);
}
c.modResults.contents = c.modResults.contents.replaceAll(
'\nimplementation(enforcedPlatform("com.squareup.okhttp3:okhttp-bom:4.12.0"))',
"",
);
c.modResults.contents = c.modResults.contents.replace(
/dependencies\s*\{/,
Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"mainqueg",
"mateo-soso",
"mdpi",
"meawallet",
Comment thread
aguxez marked this conversation as resolved.
"memester",
"miniapp",
"mipd",
Expand Down
1 change: 1 addition & 0 deletions eas.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"resourceClass": "large",
"node": "24.14.1",
"pnpm": "10.33.0",
"env": { "npm_config_mpp_env": "prod" },
"android": { "image": "latest" },
"ios": { "image": "latest" }
},
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@intercom/intercom-react-native": "^9.8.0",
"@intercom/messenger-js-sdk": "^0.0.18",
"@lifi/sdk": "3.7.7",
"@meawallet/react-native-mpp": "^2.2.2",
"@peculiar/asn1-ecc": "^2.6.1",
"@peculiar/asn1-schema": "^2.6.0",
"@peculiar/webcrypto": "^1.5.0",
Expand Down Expand Up @@ -167,6 +168,9 @@
"packageManager": "pnpm@10.33.0",
"pnpm": {
"overrides": {
"@typescript-eslint/eslint-plugin": "8.58.0",
"@typescript-eslint/parser": "8.58.0",
"eslint-plugin-n": "17.24.0",
"@wagmi/core": "catalog:",
"abitype>zod": "^4.0.0",
"comlink": "$comlink",
Expand Down Expand Up @@ -203,6 +207,7 @@
},
"patchedDependencies": {
"@lifi/sdk": "patches/@lifi__sdk.patch",
"@meawallet/react-native-mpp": "patches/@meawallet__react-native-mpp.patch",
Comment thread
aguxez marked this conversation as resolved.
"embedded-postgres": "patches/embedded-postgres.patch",
"eslint-config-universe": "patches/eslint-config-universe.patch"
},
Expand Down
Loading