@happyvertical/payments 0.74.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENT.md ADDED
@@ -0,0 +1,33 @@
1
+ # @happyvertical/payments
2
+
3
+ <!-- BEGIN AGENT:GENERATED -->
4
+ ## Purpose
5
+ Payment backend abstraction with adapters for Base USDC, BTCPay Server, and Stripe
6
+
7
+ ## Package Map
8
+ - Package: `@happyvertical/payments`
9
+ - Hierarchy path: `@happyvertical/sdk > packages > payments`
10
+ - Workspace position: `20 of 30` local packages
11
+ - Internal dependencies: none
12
+ - Internal dependents: none
13
+ - Knowledge graph files: `AGENT.md`, `metadata.json`, `ecosystem-manifest.json`
14
+
15
+ ## Build & Test
16
+ ```bash
17
+ pnpm --filter @happyvertical/payments build
18
+ pnpm --filter @happyvertical/payments test
19
+ pnpm --filter @happyvertical/payments clean
20
+ ```
21
+
22
+ ## Agent Correction Loops
23
+ - If Vite or TypeScript reports missing packages, run `pnpm install` at the repo root and rerun `pnpm --filter @happyvertical/payments build`.
24
+ - If tests or exports fail after API, type, or bundle changes, run `pnpm --filter @happyvertical/payments clean` followed by `pnpm --filter @happyvertical/payments build` and `pnpm --filter @happyvertical/payments test`.
25
+ - If failures span multiple packages or Turborepo ordering looks wrong, run `pnpm build` and `pnpm typecheck` from the repo root before retrying package-scoped commands.
26
+
27
+ ## Ecosystem Relationships
28
+ - Provides: Payment backend abstraction with adapters for Base USDC, BTCPay Server, and Stripe
29
+ - Implements: none
30
+ - Requires: @noble/curves, @noble/hashes, @scure/bip32
31
+ - Stability: stable (Primary package surface is described as implemented and production-oriented.)
32
+ <!-- END AGENT:GENERATED -->
33
+
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright <2025> <Happy Vertical Corporation>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # @happyvertical/payments
2
+
3
+ Multi-backend payment provider abstraction for crypto and fiat checkout.
4
+
5
+ The root import exposes the shared `PaymentBackend` contract, common types,
6
+ errors, and dynamic factory:
7
+
8
+ ```ts
9
+ import { createPaymentBackend } from '@happyvertical/payments';
10
+
11
+ const payments = await createPaymentBackend({
12
+ type: 'stripe',
13
+ secretKey: process.env.STRIPE_SECRET_KEY!,
14
+ successUrl: 'https://example.com/pay/success',
15
+ cancelUrl: 'https://example.com/pay/cancel',
16
+ });
17
+ ```
18
+
19
+ Adapters are also available as selective subpath exports:
20
+
21
+ ```ts
22
+ import { BaseUsdcAdapter } from '@happyvertical/payments/base-usdc';
23
+ import { BtcAdapter } from '@happyvertical/payments/btc';
24
+ import { StripeAdapter } from '@happyvertical/payments/stripe';
25
+ ```
26
+
27
+ ## Adapters
28
+
29
+ - `BaseUsdcAdapter`: USDC on Base via JSON-RPC, deterministic xpub child
30
+ addresses, x402 proof verification, and injected signer payouts.
31
+ - `BtcAdapter`: BTCPay Server invoice, polling/webhook status, tiered
32
+ confirmation policy, and unsigned PSBT payout creation.
33
+ - `StripeAdapter`: Stripe Checkout URL settlement, webhook verification,
34
+ refunds, and Stripe Connect transfers.
35
+
36
+ The package does not depend on SMRT or a database. Consumers own quote
37
+ persistence, webhook routing, and operational policy.
38
+
39
+ Public payment amounts follow Stripe's convention: `amount` is an integer in
40
+ the smallest currency unit, paired with a `currency` code. For example,
41
+ `{ amount: 1234, currency: 'USD' }` means USD 12.34. Crypto settlement uses the
42
+ same rule at the public boundary: `{ amount: 10000, currency: 'BTC' }` means
43
+ 10,000 satoshis, and `{ amount: 1000000, currency: 'USDC' }` means 1 USDC.
44
+ Adapters convert those integers to provider-specific decimal strings or atomic
45
+ unit strings internally when a protocol requires it.
46
+
47
+ Stripe-compatible whole-unit currencies that still have two-decimal ISO minor
48
+ units, such as `ISK` and `UGX`, must be passed in whole-unit increments:
49
+ `{ amount: 500, currency: 'UGX' }` means UGX 5.00, and `amount` must be evenly
50
+ divisible by 100.
51
+
52
+ ## Operational Notes
53
+
54
+ ### Migration Notes
55
+
56
+ Webhook parsing now requires configured secrets. Callers that previously parsed
57
+ Stripe or BTCPay webhooks without `webhookSecret` must configure the provider
58
+ secret or handle trusted test fixtures outside `parseWebhookEvent`.
59
+
60
+ Webhook parsing is fail-closed. `StripeAdapter.parseWebhookEvent` and
61
+ `BtcAdapter.parseWebhookEvent` require a configured `webhookSecret` and a valid
62
+ signature. BTCPay webhook payloads must include `deliveryId`; the exported
63
+ `BtcpayWebhookEvent.deliveryId` type is required. Duplicate webhook detection is
64
+ bounded, in-memory replay protection for the current adapter instance;
65
+ production webhook handlers should still persist Stripe event ids and BTCPay
66
+ delivery ids before applying side effects, especially across restarts or
67
+ multiple replicas.
68
+
69
+ Base x402 receipt replay protection is also bounded and in-memory. Persist the
70
+ accepted transaction id in the application layer if a verified x402 proof
71
+ unlocks durable access.
72
+
73
+ `StripeAdapter` sends Checkout Sessions with Stripe API-compatible expiry
74
+ values only. Expiries outside Stripe's 30 minute to 24 hour Checkout window are
75
+ rejected instead of being silently clamped.
76
+
77
+ `BtcAdapter` defaults to the BTCPay on-chain method id `BTC-CHAIN` while still
78
+ matching exact `BTC` and `BITCOIN` aliases.
79
+
80
+ `BaseUsdcAdapter` records `metadata.searchStartBlock` on created payment
81
+ options. Persist it with quote state and pass it back as
82
+ `PaymentStatusContext.searchStartBlock` after process restarts so old transfers
83
+ cannot satisfy a new quote. Stateless `getStatus` calls that provide an amount
84
+ must also provide `searchStartBlock` unless the adapter was configured with
85
+ `fromBlock`. Long-lived unpaid quotes may force `eth_getLogs` ranges that exceed
86
+ some RPC provider limits; use an archive provider, provider-supported range, or
87
+ application-level batching for old `searchStartBlock` values. Cumulative
88
+ split-transfer matching is disabled by default; enable
89
+ `allowCumulativeTransferMatching` only when every quote receives a unique deposit
90
+ address and the search start block is persisted. When quote currency is `USD`,
91
+ Base settlement assumes a 1:1 USD-to-USDC amount; callers that need live FX or
92
+ spread handling should convert to `USDC` amounts before creating payment
93
+ options.
94
+
95
+ `pollPaymentStatus` emits `event: 'timeout'` when polling times out. The
96
+ associated `status` remains the last observed status, or `pending` if no status
97
+ was observed, rather than being coerced to `failed`.
@@ -0,0 +1,85 @@
1
+ import { FetchLike } from '../shared.js';
2
+ import { CreatePaymentOptionInput, PaymentBackend, PaymentBackendCapabilities, PaymentEvent, PaymentOption, PaymentStatusContext, PaymentStatusResult, PayoutResult, RefundPaymentInput, RefundResult, SendPayoutInput, VerifyX402ProofInput, WatchPaymentInput, X402VerificationResult } from '../types.js';
3
+ export declare const BASE_USDC_BACKEND_ID = "base-usdc";
4
+ export declare const BASE_MAINNET_CHAIN_ID = 8453;
5
+ export declare const BASE_MAINNET_CAIP2 = "eip155:8453";
6
+ export declare const BASE_USDC_CONTRACT = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
7
+ export declare const USDC_DECIMALS = 6;
8
+ export interface BaseUsdcAddressDeriverInput {
9
+ quoteId: string;
10
+ index: number;
11
+ indexes: number[];
12
+ path: string;
13
+ }
14
+ export interface BaseUsdcSendTransactionInput {
15
+ destination: string;
16
+ amount: number;
17
+ amountAtomic: string;
18
+ currency: 'USDC';
19
+ tokenAddress: string;
20
+ memo?: string;
21
+ quoteId?: string;
22
+ idempotencyKey?: string;
23
+ metadata?: Record<string, string | number | boolean | null | undefined>;
24
+ }
25
+ export interface BaseUsdcAdapterOptions {
26
+ rpcUrl: string;
27
+ fetch?: FetchLike;
28
+ usdcContractAddress?: string;
29
+ masterXpub?: string;
30
+ derivationPathPrefix?: string;
31
+ addressDeriver?: (input: BaseUsdcAddressDeriverInput) => string | Promise<string>;
32
+ addressIndexForQuote?: (quoteId: string) => number;
33
+ fromBlock?: string | number | bigint;
34
+ confirmations?: number;
35
+ pollIntervalMs?: number;
36
+ maxStoredPaymentOptions?: number;
37
+ /**
38
+ * Opt in only when each quote has a unique deposit address and the
39
+ * returned metadata.searchStartBlock is persisted with quote state.
40
+ */
41
+ allowCumulativeTransferMatching?: boolean;
42
+ x402FacilitatorUrl?: string;
43
+ sendTransaction?: (input: BaseUsdcSendTransactionInput) => Promise<{
44
+ transactionId: string;
45
+ raw?: unknown;
46
+ }>;
47
+ }
48
+ export declare class BaseUsdcAdapter implements PaymentBackend {
49
+ private readonly options;
50
+ readonly capabilities: PaymentBackendCapabilities;
51
+ private readonly fetch;
52
+ private readonly rpcUrl;
53
+ private readonly usdcContractAddress;
54
+ private readonly confirmations;
55
+ private readonly configuredFromBlock;
56
+ private readonly masterXpub;
57
+ private readonly derivationPathPrefix;
58
+ private readonly x402FacilitatorUrl;
59
+ private readonly maxStoredPaymentOptions;
60
+ private readonly allowCumulativeTransferMatching;
61
+ private readonly optionsByQuote;
62
+ private readonly seenX402TransactionIds;
63
+ private rpcId;
64
+ constructor(options: BaseUsdcAdapterOptions);
65
+ createPaymentOption(input: CreatePaymentOptionInput): Promise<PaymentOption>;
66
+ watchPayment(input: WatchPaymentInput): AsyncIterable<PaymentEvent>;
67
+ getStatus(quoteId: string, payTo: string, context?: PaymentStatusContext): Promise<PaymentStatusResult>;
68
+ verifyX402Proof(input: VerifyX402ProofInput): Promise<X402VerificationResult>;
69
+ sendPayout(input: SendPayoutInput): Promise<PayoutResult>;
70
+ refundPayment(input: RefundPaymentInput): Promise<RefundResult>;
71
+ private deriveAddress;
72
+ private getTransferLogs;
73
+ private getDefaultFromBlock;
74
+ private getCurrentBlockNumber;
75
+ private rpc;
76
+ private verifyX402Receipt;
77
+ private verifyWithFacilitator;
78
+ }
79
+ export declare function deriveBaseUsdcAddress(input: {
80
+ masterXpub: string;
81
+ path: string;
82
+ }): Promise<string>;
83
+ export declare function quoteIdToDerivationIndex(quoteId: string): number;
84
+ export declare function quoteIdToDerivationIndexes(quoteId: string): number[];
85
+ //# sourceMappingURL=base-usdc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-usdc.d.ts","sourceRoot":"","sources":["../../src/adapters/base-usdc.ts"],"names":[],"mappings":"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"}