Skip to content
Merged
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
Binary file not shown.
11 changes: 7 additions & 4 deletions .github/workflows/deploy-kit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,20 @@ jobs:
run: bun run test:coverage

- name: Enforce server line coverage
run: node ../../scripts/assert-lcov-coverage.mjs coverage/lcov.info 90
run: node ../../scripts/assert-lcov-coverage.mjs coverage/lcov.info 90 server/

- name: Upload server coverage
- name: Enforce Convex line coverage
run: node ../../scripts/assert-lcov-coverage.mjs coverage/lcov.info 48 convex/

- name: Upload Kit coverage
uses: codecov/codecov-action@v7
with:
use_oidc: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
fail_ci_if_error: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
disable_search: true
files: coverage/lcov.info
flags: iapkit-server
name: iapkit-server
flags: iapkit
name: iapkit
network_prefix: packages/kit/
working-directory: packages/kit

Expand Down
38 changes: 32 additions & 6 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
parsers:
lcov:
partials_as_hits: true

coverage:
precision: 2
round: down
Expand Down Expand Up @@ -30,8 +34,14 @@ coverage:
target: 90%
threshold: 0%
informational: false
flags:
- iapkit-server
paths:
- "packages/kit/server/**"
iapkit-convex:
target: 48%
threshold: 0%
informational: false
paths:
- "packages/kit/convex/**"
patch:
default:
target: auto
Expand Down Expand Up @@ -59,8 +69,14 @@ coverage:
target: 90%
threshold: 0%
informational: false
flags:
- iapkit-server
paths:
- "packages/kit/server/**"
iapkit-convex:
target: 48%
threshold: 0%
informational: false
paths:
- "packages/kit/convex/**"

flags:
react-native-iap:
Expand All @@ -75,9 +91,10 @@ flags:
paths:
- "libraries/flutter_inapp_purchase/lib/**"
carryforward: true
iapkit-server:
iapkit:
paths:
- "packages/kit/server/**"
- "packages/kit/convex/**"
carryforward: true

component_management:
Expand Down Expand Up @@ -105,7 +122,13 @@ component_management:
paths:
- "packages/kit/server/**"
flag_regexes:
- "^iapkit-server$"
- "^iapkit$"
- component_id: iapkit-convex
name: IAPKit Convex
paths:
- "packages/kit/convex/**"
flag_regexes:
- "^iapkit$"

comment:
layout: "reach,diff,flags,components,files"
Expand All @@ -118,3 +141,6 @@ ignore:
- "libraries/react-native-iap/src/types.ts"
- "libraries/expo-iap/src/types.ts"
- "libraries/flutter_inapp_purchase/lib/types.dart"
- "packages/kit/convex/_generated/**"
- "packages/kit/convex/**/*.test.ts"
- "packages/kit/convex/test.setup.ts"
16 changes: 12 additions & 4 deletions knowledge/_claude-context/context.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# OpenIAP Project Context

> **Auto-generated for Claude Code**
> Last updated: 2026-08-10T16:17:58.157Z
> Last updated: 2026-08-11T08:49:51.526Z
>
> Usage: `claude --context knowledge/_claude-context/context.md`

Expand Down Expand Up @@ -4755,9 +4755,17 @@ Retention:
- Events are retained for the bounded IAPKit operational window and pruned by a
Convex cron job. They are not exposed as a public replay stream.

Meta Horizon has no inbound webhook. Its bounded polling reconciler may record
synthetic lifecycle events under the `MetaHorizonReconciler` source for the same
private state machine and retention policy.
Meta Horizon has no inbound webhook or background lifecycle lane in IAPKit.
`POST /v1/purchase/verify` performs a synchronous entitlement check only. The
`MetaHorizonReconciler` source remains schema-compatible for legacy retained
rows, but those synthetic events are excluded from current revenue rollups.

Amazon RVS also has no inbound webhook receiver in IAPKit. A bounded purchase
reconciler schedules active Amazon receipt rows for revisits on a 48-hour due
cadence, but backlog, retries, and lease recovery mean it does not guarantee
that every row is checked within 72 hours. It updates state only from
authoritative RVS outcomes and preserves the last confirmed state across
transient or malformed responses.


---
Expand Down
14 changes: 11 additions & 3 deletions knowledge/external/webhook-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ Retention:
- Events are retained for the bounded IAPKit operational window and pruned by a
Convex cron job. They are not exposed as a public replay stream.

Meta Horizon has no inbound webhook. Its bounded polling reconciler may record
synthetic lifecycle events under the `MetaHorizonReconciler` source for the same
private state machine and retention policy.
Meta Horizon has no inbound webhook or background lifecycle lane in IAPKit.
`POST /v1/purchase/verify` performs a synchronous entitlement check only. The
`MetaHorizonReconciler` source remains schema-compatible for legacy retained
rows, but those synthetic events are excluded from current revenue rollups.

Amazon RVS also has no inbound webhook receiver in IAPKit. A bounded purchase
reconciler schedules active Amazon receipt rows for revisits on a 48-hour due
cadence, but backlog, retries, and lease recovery mean it does not guarantee
that every row is checked within 72 hours. It updates state only from
authoritative RVS outcomes and preserves the last confirmed state across
transient or malformed responses.
3 changes: 3 additions & 0 deletions libraries/expo-iap/example/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ EXPO_PUBLIC_IAPKIT_API_KEY=openiap-kit_pk_your_publishable_key_here
# Required when selecting Local (IAPKit). Use your Mac's LAN IP on a device.
# Example: http://192.168.0.10:3100
EXPO_PUBLIC_IAPKIT_BASE_URL=
# Set true only for Amazon App Tester receipts after enabling the matching
# sandbox option in the IAPKit project settings.
EXPO_PUBLIC_AMAZON_RVS_SANDBOX=false
2 changes: 1 addition & 1 deletion libraries/expo-iap/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Create the ignored environment file before testing IAPKit:
cp .env.example .env
```

For hosted IAPKit, get an `openiap-kit_pk_` publishable key from the [IAPKit dashboard](https://kit.openiap.dev) and set it as `EXPO_PUBLIC_IAPKIT_API_KEY`. Expo embeds every `EXPO_PUBLIC_*` value in the app, so never use an `openiap-kit_sk_` secret admin key. For **Local (IAPKit)**, the publishable key and local server must target the same Convex deployment. Also set `EXPO_PUBLIC_IAPKIT_BASE_URL` to the device-reachable HTTP(S) origin only; do not append `/v1/purchase/verify`. A physical iPhone must use the Mac's LAN address. An Android device connected over USB can use `http://127.0.0.1:3100`: inspect `adb -s "$ANDROID_SERIAL" reverse --list`, reuse an exact `tcp:3100` mapping when present, or create it with `adb -s "$ANDROID_SERIAL" reverse --no-rebind tcp:3100 tcp:3100`. Record whether this run created the rule and remove only that rule during cleanup; if `--no-rebind` fails, use another port instead of overwriting an existing mapping.
For hosted IAPKit, get an `openiap-kit_pk_` publishable key from the [IAPKit dashboard](https://kit.openiap.dev) and set it as `EXPO_PUBLIC_IAPKIT_API_KEY`. Expo embeds every `EXPO_PUBLIC_*` value in the app, so never use an `openiap-kit_sk_` secret admin key. For **Local (IAPKit)**, the publishable key and local server must target the same Convex deployment. Also set `EXPO_PUBLIC_IAPKIT_BASE_URL` to the device-reachable HTTP(S) origin only; do not append `/v1/purchase/verify`. Set `EXPO_PUBLIC_AMAZON_RVS_SANDBOX=true` only for Amazon App Tester receipts after enabling the matching sandbox option in the IAPKit project settings. A physical iPhone must use the Mac's LAN address. An Android device connected over USB can use `http://127.0.0.1:3100`: inspect `adb -s "$ANDROID_SERIAL" reverse --list`, reuse an exact `tcp:3100` mapping when present, or create it with `adb -s "$ANDROID_SERIAL" reverse --no-rebind tcp:3100 tcp:3100`. Record whether this run created the rule and remove only that rule during cleanup; if `--no-rebind` fails, use another port instead of overwriting an existing mapping.

The Vega build scripts load the same Expo environment-file chain as the normal
Expo CLI: Debug uses `.env.development.local`, `.env.local`,
Expand Down
Loading