Skip to content
Draft
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/chilly-suns-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ add provisioning to card
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
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.
117 changes: 116 additions & 1 deletion 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,6 +121,110 @@ 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/assets/mea_config");
mkdirSync(path.dirname(destination), { recursive: true });
if (existsSync(source)) 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)) {
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 = "${env.MEAWALLET_ANDROID_USER}"
password = "${env.MEAWALLET_ANDROID_PASS}"
}
}`;
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);
}
return c;
},
])) satisfies ConfigPlugin,
Comment on lines +152 to +173
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if these env vars are documented anywhere
rg -i "MEAWALLET_ANDROID" --type=md --type=yaml

Repository: exactly/exa

Length of output: 37


🏁 Script executed:

#!/bin/bash
# Search for MEAWALLET_ANDROID in all files (not just md/yaml)
echo "=== All references to MEAWALLET_ANDROID ==="
rg "MEAWALLET_ANDROID" --max-count=20

echo -e "\n=== Looking for .env files ==="
fd -e env -e example -e sample

echo -e "\n=== Check README and docs ==="
fd -i readme
fd -type f -path '*/docs/*' | head -20

Repository: exactly/exa

Length of output: 491


🏁 Script executed:

#!/bin/bash
# Check README content
echo "=== README.md content ==="
cat README.md

echo -e "\n=== Looking for CI/CD config files ==="
fd -type f -path '*/.github/*'
fd -type f -name '*.yml' -o -name '*.yaml'

echo -e "\n=== Looking for setup/docs files ==="
find . -type f \( -name 'SETUP*' -o -name 'setup*' -o -name '.env*' \) | head -20

Repository: exactly/exa

Length of output: 1728


🏁 Script executed:

#!/bin/bash
# Final check for CI workflows and any remaining setup docs
echo "=== Searching for workflow files ==="
find . -type f \( -name '*.workflow' -o -name '*.yml' -o -name '*.yaml' \) 2>/dev/null | grep -E '(workflow|ci|github|build)' || echo "No workflow files found"

echo -e "\n=== Check if env vars are referenced in package.json or scripts ==="
rg "MEAWALLET" --type json --type sh

Repository: exactly/exa

Length of output: 739


🏁 Script executed:

#!/bin/bash
echo "=== mobile-beta.yaml ==="
cat ./.github/workflows/mobile-beta.yaml

echo -e "\n=== mobile-expo.yaml ==="
cat ./.github/workflows/mobile-expo.yaml

echo -e "\n=== mobile-production.yaml ==="
cat ./.github/workflows/mobile-production.yaml

Repository: exactly/exa

Length of output: 3859


Document MEAWALLET_ANDROID_USER and MEAWALLET_ANDROID_PASS in CI workflows and README.

These Maven credentials are injected into the Android build but are not documented in CI configuration or setup docs. Add these to the mobile workflow files (.github/workflows/mobile-*.yaml) and the README's development setup section to prevent build failures.

// @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
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) => {
Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"mainqueg",
"mateo-soso",
"mdpi",
"meawallet",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check how many times and in how many files "meawallet" appears.
# Expected: Should appear in multiple files across the codebase to justify global dictionary entry.

echo "=== Files containing 'meawallet' (case-insensitive) ==="
rg -i --files-with-matches 'meawallet'

echo -e "\n=== Total occurrences with context ==="
rg -i -C2 'meawallet'

echo -e "\n=== Summary ==="
echo "Total files: $(rg -i --files-with-matches 'meawallet' | wc -l)"
echo "Total occurrences: $(rg -i 'meawallet' | wc -l)"

Repository: exactly/exa

Length of output: 6095


Remove "meawallet" from the dictionary and use inline cspell:ignore annotations instead.

The term appears only as package imports in 2 source files. Per the learning guidance, one-off or limited occurrences should use inline cspell:ignore annotations on the same line as the unknown word—not pollute the global dictionary. Place cspell:ignore on the two import lines in src/components/card/useWalletProvisioning.ts and src/components/card/WalletButtons.tsx, then remove "meawallet" from this file.

"memester",
"miniapp",
"mipd",
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 @@ -202,6 +206,7 @@
},
"patchedDependencies": {
"@lifi/sdk": "patches/@lifi__sdk.patch",
"@meawallet/react-native-mpp": "patches/@meawallet__react-native-mpp.patch",
"embedded-postgres": "patches/embedded-postgres.patch",
"eslint-config-universe": "patches/eslint-config-universe.patch"
},
Expand Down
10 changes: 10 additions & 0 deletions patches/@meawallet__react-native-mpp.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
diff --git a/meawallet-react-native-mpp.podspec b/meawallet-react-native-mpp.podspec
index 05795f1b..7396ff2b 100644
--- a/meawallet-react-native-mpp.podspec
+++ b/meawallet-react-native-mpp.podspec
@@ -21,4 +21,5 @@ Pod::Spec.new do |s|
s.xcconfig = { "GCC_PREPROCESSOR_DEFINITIONS" => "REACT_NATIVE_MPP_VERSION=\"@\\\"#{s.version}\\\"\"" }

install_modules_dependencies(s)
+ s.dependency "React-RCTAppDelegate"
end
Loading
Loading