Created
September 14, 2025 17:23
-
-
Save wcastand/4160c31062e085b043e4d78953642150 to your computer and use it in GitHub Desktop.
i just have the .zip in ./libs as a zip that the plugin will unzip
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export default { | |
| // ... | |
| plugins: [ | |
| [ | |
| "./plugins/build/react-native-wallet.plugin.js", | |
| { | |
| enableApplePayProvisioning: true, | |
| googleTapAndPaySdkPath: "./libs/tapandpay-v18.3.3.zip", | |
| }, | |
| ], | |
| ], | |
| // ... | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { execSync } from "node:child_process" | |
| import { copyFileSync, existsSync, mkdirSync, readdirSync, statSync } from "node:fs" | |
| import { extname, join, resolve } from "node:path" | |
| import { createGeneratedHeaderComment, removeGeneratedContents } from "@expo/config-plugins/build/utils/generateCode" | |
| import type { ConfigPlugin } from "expo/config-plugins" | |
| import { withInfoPlist, withProjectBuildGradle } from "expo/config-plugins" | |
| export type ReactNativeWalletConfig = { | |
| /** | |
| * Path to the Google TapAndPay SDK for Android | |
| * This should be the path to a ZIP file containing the Google TapAndPay SDK files, | |
| * or a directory containing the SDK files, or a single SDK file (.aar) | |
| */ | |
| googleTapAndPaySdkPath?: string | |
| /** | |
| * iOS Apple Pay In-App Provisioning entitlement | |
| * @default true | |
| */ | |
| enableApplePayProvisioning?: boolean | |
| } | |
| interface AppendContentsParams { | |
| src: string | |
| newSrc: string | |
| tag: string | |
| comment: string | |
| } | |
| function appendContents({ src, newSrc, tag, comment }: AppendContentsParams): { | |
| contents: string | |
| didClear: boolean | |
| didMerge: boolean | |
| } { | |
| const header = createGeneratedHeaderComment(newSrc, tag, comment) | |
| if (!src.includes(header)) { | |
| const sanitizedTarget = removeGeneratedContents(src, tag) | |
| const contentsToAdd = [header, newSrc, `${comment} @generated end ${tag}`].join("\n") | |
| return { | |
| contents: `${sanitizedTarget ?? src}\n${contentsToAdd}`, | |
| didClear: !!sanitizedTarget, | |
| didMerge: true, | |
| } | |
| } | |
| return { contents: src, didClear: false, didMerge: false } | |
| } | |
| /** | |
| * Copy Google TapAndPay SDK files to Android libs directory | |
| */ | |
| function copyGoogleTapAndPaySdk(projectRoot: string, sdkPath: string): void { | |
| const resolvedSdkPath = resolve(projectRoot, sdkPath) | |
| const androidLibsPath = join(projectRoot, "android", "libs") | |
| // Create libs directory if it doesn't exist | |
| if (!existsSync(androidLibsPath)) { | |
| mkdirSync(androidLibsPath, { recursive: true }) | |
| } | |
| // Check if SDK path exists | |
| if (!existsSync(resolvedSdkPath)) { | |
| throw new Error(`Google TapAndPay SDK path not found: ${resolvedSdkPath}`) | |
| } | |
| const fileExtension = extname(resolvedSdkPath).toLowerCase() | |
| if (fileExtension === ".zip") { | |
| // Extract ZIP file contents using system unzip command | |
| try { | |
| execSync(`unzip -o "${resolvedSdkPath}" -d "${androidLibsPath}"`, { | |
| stdio: "pipe", | |
| }) | |
| } catch (error) { | |
| throw new Error(`Failed to extract ZIP file: ${error instanceof Error ? error.message : "Unknown error"}`) | |
| } | |
| } else if (statSync(resolvedSdkPath).isDirectory()) { | |
| // Copy all files from SDK directory to libs | |
| const files = readdirSync(resolvedSdkPath) | |
| for (const file of files) { | |
| const srcFile = join(resolvedSdkPath, file) | |
| const destFile = join(androidLibsPath, file) | |
| if (statSync(srcFile).isFile()) { | |
| copyFileSync(srcFile, destFile) | |
| } | |
| } | |
| } else { | |
| // If it's a single file, copy it directly | |
| const fileName = resolvedSdkPath.split("/").pop() || "google-tap-and-pay.aar" | |
| copyFileSync(resolvedSdkPath, join(androidLibsPath, fileName)) | |
| } | |
| } | |
| /** | |
| * Config plugin for react-native-wallet | |
| * Configures native Android and iOS projects for wallet functionality | |
| */ | |
| const withReactNativeWallet: ConfigPlugin<ReactNativeWalletConfig> = ( | |
| config, | |
| { googleTapAndPaySdkPath, enableApplePayProvisioning = true } = {}, | |
| ) => { | |
| // Configure iOS | |
| let modifiedConfig = withReactNativeWalletIOS(config, { enableApplePayProvisioning }) | |
| // Configure Android | |
| modifiedConfig = withReactNativeWalletAndroid(modifiedConfig, { googleTapAndPaySdkPath }) | |
| return modifiedConfig | |
| } | |
| /** | |
| * Configure iOS for react-native-wallet | |
| */ | |
| const withReactNativeWalletIOS: ConfigPlugin<{ | |
| enableApplePayProvisioning: boolean | |
| }> = (config, { enableApplePayProvisioning }) => { | |
| if (!enableApplePayProvisioning) { | |
| return config | |
| } | |
| return withInfoPlist(config, (config) => { | |
| // Add Apple Pay In-App Provisioning entitlement | |
| // Following the structure from the documentation | |
| config.modResults["com.apple.developer.payment-pass-provisioning"] = true | |
| return config | |
| }) | |
| } | |
| /** | |
| * Configure Android for react-native-wallet | |
| */ | |
| const withReactNativeWalletAndroid: ConfigPlugin<{ | |
| googleTapAndPaySdkPath?: string | |
| }> = (config, { googleTapAndPaySdkPath }) => { | |
| if (!googleTapAndPaySdkPath) { | |
| return config | |
| } | |
| return withProjectBuildGradle(config, (config) => { | |
| // Copy Google TapAndPay SDK files to android/libs | |
| copyGoogleTapAndPaySdk(config.modRequest.projectRoot, googleTapAndPaySdkPath) | |
| if (config.modResults.language === "groovy") { | |
| // Configure gradle to use the local libs directory | |
| // This follows the pattern from react-native-wallet documentation | |
| const gradleMaven = `allprojects { | |
| repositories { | |
| google() | |
| maven { url "file://\${rootDir}/libs" } | |
| } | |
| }` | |
| config.modResults.contents = appendContents({ | |
| comment: "//", | |
| newSrc: gradleMaven, | |
| src: config.modResults.contents, | |
| tag: "react-native-wallet-libs-repository", | |
| }).contents | |
| } else { | |
| throw new Error("Cannot add react-native-wallet maven repository because the build.gradle is not groovy") | |
| } | |
| return config | |
| }) | |
| } | |
| export default withReactNativeWallet |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment