@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 +33 -0
- package/LICENSE +7 -0
- package/README.md +97 -0
- package/dist/adapters/base-usdc.d.ts +85 -0
- package/dist/adapters/base-usdc.d.ts.map +1 -0
- package/dist/adapters/base-usdc.js +1182 -0
- package/dist/adapters/base-usdc.js.map +1 -0
- package/dist/adapters/btc.d.ts +63 -0
- package/dist/adapters/btc.d.ts.map +1 -0
- package/dist/adapters/btc.js +843 -0
- package/dist/adapters/btc.js.map +1 -0
- package/dist/adapters/stripe.d.ts +54 -0
- package/dist/adapters/stripe.d.ts.map +1 -0
- package/dist/adapters/stripe.js +696 -0
- package/dist/adapters/stripe.js.map +1 -0
- package/dist/chunks/errors-BgFC46qQ.js +45 -0
- package/dist/chunks/errors-BgFC46qQ.js.map +1 -0
- package/dist/chunks/shared-DGHSqDQT.js +392 -0
- package/dist/chunks/shared-DGHSqDQT.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/factory.d.ts +13 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/shared.d.ts +32 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/testing/conformance.d.ts +33 -0
- package/dist/testing/conformance.d.ts.map +1 -0
- package/dist/testing/conformance.js +114 -0
- package/dist/testing/conformance.js.map +1 -0
- package/dist/types.d.ts +174 -0
- package/dist/types.d.ts.map +1 -0
- package/metadata.json +30 -0
- package/package.json +88 -0
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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"}
|