diff --git a/.github/workflows/ci_e2e_walletkit.yaml b/.github/workflows/ci_e2e_walletkit.yaml index 7f3bfafa..f5f0b138 100644 --- a/.github/workflows/ci_e2e_walletkit.yaml +++ b/.github/workflows/ci_e2e_walletkit.yaml @@ -38,8 +38,14 @@ env: ROOT_PATH: wallets/rn_cli_wallet jobs: + check-balance: + uses: ./.github/workflows/e2e-balance-check.yml + secrets: + SLACK_FAUCETBOT_WEBHOOK_URL: ${{ secrets.SLACK_FAUCETBOT_WEBHOOK_URL }} + e2e-ios: - if: inputs.platform != 'android' + needs: check-balance + if: always() && inputs.platform != 'android' # Balance alert should not block tests name: E2E Tests - iOS runs-on: macos-latest-xlarge timeout-minutes: 60 @@ -145,17 +151,49 @@ jobs: - name: Run Maestro tests id: maestro - uses: WalletConnect/actions/maestro/run@0c9875ae33fe85fa6a4110dc46c82876d91a551d + env: + APP_ID: ${{ env.MAESTRO_APP_ID }} + WPAY_CUSTOMER_KEY_MULTI_KYC: ${{ secrets.WPAY_CUSTOMER_KEY_MULTI_KYC }} + WPAY_MERCHANT_ID_MULTI_KYC: ${{ secrets.WPAY_MERCHANT_ID_MULTI_KYC }} + WPAY_CUSTOMER_KEY_MULTI_NOKYC: ${{ secrets.WPAY_CUSTOMER_KEY_MULTI_NOKYC }} + WPAY_MERCHANT_ID_MULTI_NOKYC: ${{ secrets.WPAY_MERCHANT_ID_MULTI_NOKYC }} + WPAY_CUSTOMER_KEY_SINGLE_NOKYC: ${{ secrets.WPAY_CUSTOMER_KEY_SINGLE_NOKYC }} + WPAY_MERCHANT_ID_SINGLE_NOKYC: ${{ secrets.WPAY_MERCHANT_ID_SINGLE_NOKYC }} + run: | + xcrun simctl launch "$DEVICE_ID" "$APP_ID" || true + set +e + $HOME/.maestro/bin/maestro test \ + --env APP_ID="$APP_ID" \ + --env WPAY_CUSTOMER_KEY_SINGLE_NOKYC="$WPAY_CUSTOMER_KEY_SINGLE_NOKYC" \ + --env WPAY_MERCHANT_ID_SINGLE_NOKYC="$WPAY_MERCHANT_ID_SINGLE_NOKYC" \ + --env WPAY_CUSTOMER_KEY_MULTI_NOKYC="$WPAY_CUSTOMER_KEY_MULTI_NOKYC" \ + --env WPAY_MERCHANT_ID_MULTI_NOKYC="$WPAY_MERCHANT_ID_MULTI_NOKYC" \ + --env WPAY_CUSTOMER_KEY_MULTI_KYC="$WPAY_CUSTOMER_KEY_MULTI_KYC" \ + --env WPAY_MERCHANT_ID_MULTI_KYC="$WPAY_MERCHANT_ID_MULTI_KYC" \ + --include-tags "${{ env.MAESTRO_TAGS }}" \ + --test-output-dir maestro-artifacts \ + --debug-output "${RUNNER_TEMP}/maestro-debug" \ + .maestro/ >maestro-output.log 2>&1 + maestro_exit_code=$? + cat maestro-output.log + exit "$maestro_exit_code" + + - name: Upload Maestro artifacts + if: always() + uses: actions/upload-artifact@v4 with: - app-id: ${{ env.MAESTRO_APP_ID }} - tags: ${{ env.MAESTRO_TAGS }} - wpay-customer-key-single-nokyc: ${{ secrets.WPAY_CUSTOMER_KEY_SINGLE_NOKYC }} - wpay-merchant-id-single-nokyc: ${{ secrets.WPAY_MERCHANT_ID_SINGLE_NOKYC }} - wpay-customer-key-multi-nokyc: ${{ secrets.WPAY_CUSTOMER_KEY_MULTI_NOKYC }} - wpay-merchant-id-multi-nokyc: ${{ secrets.WPAY_MERCHANT_ID_MULTI_NOKYC }} - wpay-customer-key-multi-kyc: ${{ secrets.WPAY_CUSTOMER_KEY_MULTI_KYC }} - wpay-merchant-id-multi-kyc: ${{ secrets.WPAY_MERCHANT_ID_MULTI_KYC }} - artifact-name: maestro-ios-artifacts + name: maestro-ios-artifacts + path: | + maestro-artifacts/**/*.png + maestro-artifacts/**/*.jpg + maestro-artifacts/**/*.jpeg + maestro-artifacts/**/*.mp4 + maestro-artifacts/**/*.mov + maestro-artifacts/**/*.webm + maestro-artifacts/**/*.gif + maestro-output.log + if-no-files-found: warn + retention-days: 14 - name: Send Slack notification if: failure() @@ -207,7 +245,8 @@ jobs: } e2e-android: - if: inputs.platform != 'ios' + needs: check-balance + if: always() && inputs.platform != 'ios' # Balance alert should not block tests name: E2E Tests - Android runs-on: ubuntu-latest timeout-minutes: 60 @@ -306,9 +345,7 @@ jobs: disable-animations: true script: | adb install ${{ env.ROOT_PATH }}/android/app/build/outputs/apk/internal/app-internal.apk - $HOME/.maestro/bin/maestro test --env APP_ID="${{ env.MAESTRO_APP_ID }}" --env WPAY_CUSTOMER_KEY_MULTI_KYC="${{ secrets.WPAY_CUSTOMER_KEY_MULTI_KYC }}" --env WPAY_MERCHANT_ID_MULTI_KYC="${{ secrets.WPAY_MERCHANT_ID_MULTI_KYC }}" --env WPAY_CUSTOMER_KEY_MULTI_NOKYC="${{ secrets.WPAY_CUSTOMER_KEY_MULTI_NOKYC }}" --env WPAY_MERCHANT_ID_MULTI_NOKYC="${{ secrets.WPAY_MERCHANT_ID_MULTI_NOKYC }}" --env WPAY_CUSTOMER_KEY_SINGLE_NOKYC="${{ secrets.WPAY_CUSTOMER_KEY_SINGLE_NOKYC }}" --env WPAY_MERCHANT_ID_SINGLE_NOKYC="${{ secrets.WPAY_MERCHANT_ID_SINGLE_NOKYC }}" --include-tags "${{ env.MAESTRO_TAGS }}" --test-output-dir maestro-artifacts .maestro/ >maestro-output.log 2>&1; echo $? > maestro-exit-code - cat maestro-output.log - exit $(cat maestro-exit-code) + set +e; $HOME/.maestro/bin/maestro test --env APP_ID="${{ env.MAESTRO_APP_ID }}" --env WPAY_CUSTOMER_KEY_SINGLE_NOKYC="${{ secrets.WPAY_CUSTOMER_KEY_SINGLE_NOKYC }}" --env WPAY_MERCHANT_ID_SINGLE_NOKYC="${{ secrets.WPAY_MERCHANT_ID_SINGLE_NOKYC }}" --env WPAY_CUSTOMER_KEY_MULTI_NOKYC="${{ secrets.WPAY_CUSTOMER_KEY_MULTI_NOKYC }}" --env WPAY_MERCHANT_ID_MULTI_NOKYC="${{ secrets.WPAY_MERCHANT_ID_MULTI_NOKYC }}" --env WPAY_CUSTOMER_KEY_MULTI_KYC="${{ secrets.WPAY_CUSTOMER_KEY_MULTI_KYC }}" --env WPAY_MERCHANT_ID_MULTI_KYC="${{ secrets.WPAY_MERCHANT_ID_MULTI_KYC }}" --include-tags "${{ env.MAESTRO_TAGS }}" --test-output-dir maestro-artifacts --debug-output "${RUNNER_TEMP}/maestro-debug" .maestro/ >maestro-output.log 2>&1; maestro_exit_code=$?; cat maestro-output.log; exit "$maestro_exit_code" - name: Upload Maestro artifacts if: always() diff --git a/.github/workflows/e2e-balance-check.yml b/.github/workflows/e2e-balance-check.yml index 8dda8f4d..1e74cf70 100644 --- a/.github/workflows/e2e-balance-check.yml +++ b/.github/workflows/e2e-balance-check.yml @@ -4,6 +4,10 @@ on: schedule: - cron: '0 * * * *' # Every hour workflow_dispatch: {} + workflow_call: + secrets: + SLACK_FAUCETBOT_WEBHOOK_URL: + required: false permissions: contents: read diff --git a/wallets/rn_cli_wallet/scripts/revoke-permit2-approval.js b/wallets/rn_cli_wallet/scripts/revoke-permit2-approval.js index 9bb5410b..72d05cb7 100644 --- a/wallets/rn_cli_wallet/scripts/revoke-permit2-approval.js +++ b/wallets/rn_cli_wallet/scripts/revoke-permit2-approval.js @@ -23,13 +23,16 @@ const MIN_PRIORITY_FEE_GWEI_BY_CHAIN = { function printUsage() { const supportedChains = Object.keys(USDT_BY_CHAIN).join(', '); console.log(`Usage: - yarn permit2:revoke --chainId --walletAddress <0x...> --privateKey <0x...> --projectId [--tokenAddress <0x...>] [--minPriorityFeeGwei ] + yarn permit2:revoke --chainId --walletAddress <0x...> --privateKey <0x...> (--projectId | --rpcUrl ) [--tokenAddress <0x...>] [--minPriorityFeeGwei ] Example: yarn permit2:revoke --chainId eip155:137 --walletAddress 0xYourAddress --privateKey 0xYourPrivateKey --projectId yourProjectId + yarn permit2:revoke --chainId eip155:42161 --walletAddress 0xYourAddress --privateKey 0xYourPrivateKey --rpcUrl https://arb1.arbitrum.io/rpc Defaults: If --tokenAddress is omitted, the script uses the USDT address for the selected chain. + If --rpcUrl is provided it takes precedence over --projectId (use this for chains where the + WalletConnect Blockchain API gates methods like eth_blockNumber, e.g. Arbitrum). For Polygon (eip155:137), min priority fee defaults to 25 gwei. Supported USDT chains: ${supportedChains} `); @@ -144,7 +147,7 @@ function extractMinTipFromError(error) { function getWalletConnectRpcUrl(chainId, projectId) { if (!projectId) { - throw new Error('Missing --projectId'); + throw new Error('Missing --projectId (or pass --rpcUrl to use a custom RPC).'); } return `${WALLETCONNECT_RPC_BASE_URL}?chainId=${encodeURIComponent(chainId)}&projectId=${encodeURIComponent(projectId)}`; @@ -166,8 +169,15 @@ async function buildFeeOverrides({ from: signerAddress, }); const feeData = await provider.getFeeData(); - const latestBlock = await provider.getBlock('latest'); - const baseFeePerGas = latestBlock?.baseFeePerGas || ethers.constants.Zero; + let baseFeePerGas = ethers.constants.Zero; + try { + const latestBlock = await provider.getBlock('latest'); + baseFeePerGas = latestBlock?.baseFeePerGas || ethers.constants.Zero; + } catch (error) { + console.log( + `Skipping baseFee read (${error instanceof Error ? error.message : String(error)}); falling back to feeData.`, + ); + } const hasEip1559FeeData = !!feeData.maxFeePerGas || @@ -224,6 +234,7 @@ async function main() { args.minPriorityFeeGwei, ); const projectId = String(args.projectId || '').trim(); + const rpcUrlOverride = String(args.rpcUrl || '').trim(); if (!USDT_BY_CHAIN[chainId] && !args.tokenAddress) { throw new Error( @@ -231,7 +242,7 @@ async function main() { ); } - const rpcUrl = getWalletConnectRpcUrl(chainId, projectId); + const rpcUrl = rpcUrlOverride || getWalletConnectRpcUrl(chainId, projectId); const chainIdNumber = Number(chainId.split(':')[1]); const provider = new ethers.providers.StaticJsonRpcProvider(rpcUrl, { chainId: chainIdNumber,