@bitpal/checkout 0.8.0 → 0.9.0
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/README.md +4 -1
- package/dist/index.cjs +28 -8
- package/dist/index.d.cts +22 -4
- package/dist/index.d.ts +22 -4
- package/dist/index.js +28 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -208,7 +208,7 @@ app.get('/report', x402({
|
|
|
208
208
|
apiKey: process.env.BITPAL_API_KEY, // bp_test_… or bp_live_…
|
|
209
209
|
payTo: '0xYourPayoutWallet',
|
|
210
210
|
network: 'base', // test key → 'base-sepolia'
|
|
211
|
-
amount: '
|
|
211
|
+
amount: '1.00', // human-readable — no decimals math
|
|
212
212
|
}), (req, res) => {
|
|
213
213
|
res.json({ report: '…' }); // req.x402Payment has the txHash
|
|
214
214
|
});
|
|
@@ -267,6 +267,9 @@ if (res.status === 402) {
|
|
|
267
267
|
| Base | USDC | `base` |
|
|
268
268
|
| Base Sepolia | USDC | `base-sepolia` |
|
|
269
269
|
|
|
270
|
+
Amounts are human-readable (`'1.00'`), the same model as `line_items[].amount` — the server converts.
|
|
271
|
+
Pass `amountAtomic` instead if you already have raw units.
|
|
272
|
+
|
|
270
273
|
EOA signers only — smart-contract wallets cannot sign EIP-3009 authorizations. Amounts are exact:
|
|
271
274
|
over- and underpayment are both rejected, and this lane has no refund path. Authorizations are valid
|
|
272
275
|
for 90–3600 seconds (the server's floor is 60s; the extra 30s absorbs clock skew and round trips).
|
package/dist/index.cjs
CHANGED
|
@@ -315,12 +315,23 @@ var BitPalCheckoutClient = class {
|
|
|
315
315
|
);
|
|
316
316
|
}
|
|
317
317
|
/* ─── Fees ─── */
|
|
318
|
-
/**
|
|
318
|
+
/**
|
|
319
|
+
* 수수료 미리보기 — `/v1/checkout/fee-preview`.
|
|
320
|
+
*
|
|
321
|
+
* `amount` 는 **사람 표기**다("100", "0.5") — line item / Price / x402 와 같은 모델이라
|
|
322
|
+
* decimals 를 계산할 필요가 없다. raw μUSD 를 직접 넣으려면 `amountAtomic` 을 쓴다(상호 배타).
|
|
323
|
+
* 응답은 계속 atomic 이다(계산 결과라 정밀도가 곧 계약이다).
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* const { data } = await bp.checkout.previewFee('100'); // $100
|
|
327
|
+
* const { data } = await bp.checkout.previewFee({ amountAtomic: '100000000' });
|
|
328
|
+
*/
|
|
319
329
|
async previewFee(amount) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
330
|
+
const qs = typeof amount === "string" ? `amount=${encodeURIComponent(amount)}` : `amount_atomic=${encodeURIComponent(amount.amountAtomic)}`;
|
|
331
|
+
if (typeof amount === "string" && !/^(0|[1-9]\d*)(\.\d{1,6})?$/.test(amount)) {
|
|
332
|
+
throw new Error('[BitPal] previewFee: amount must be a decimal string like "100" or "0.5" (max 6 decimals). For raw \u03BCUSD use { amountAtomic }.');
|
|
333
|
+
}
|
|
334
|
+
return this.request("GET", `/v1/checkout/fee-preview?${qs}`);
|
|
324
335
|
}
|
|
325
336
|
};
|
|
326
337
|
var BitPalError = class extends Error {
|
|
@@ -476,8 +487,16 @@ var X402Gate = class {
|
|
|
476
487
|
if (!/^0x[a-fA-F0-9]{40}$/.test(opts.payTo)) {
|
|
477
488
|
throw new Error("[BitPal] x402: payTo must be a 0x EVM address (your registered payout wallet).");
|
|
478
489
|
}
|
|
479
|
-
|
|
480
|
-
|
|
490
|
+
const hasHuman = opts.amount != null;
|
|
491
|
+
const hasAtomic = opts.amountAtomic != null;
|
|
492
|
+
if (hasHuman === hasAtomic) {
|
|
493
|
+
throw new Error('[BitPal] x402: provide exactly one of `amount` ("0.1") or `amountAtomic` ("100000").');
|
|
494
|
+
}
|
|
495
|
+
if (hasHuman && !/^(0|[1-9]\d*)(\.\d{1,6})?$/.test(opts.amount)) {
|
|
496
|
+
throw new Error('[BitPal] x402: amount must be a decimal string like "0.1" or "29" (max 6 decimals).');
|
|
497
|
+
}
|
|
498
|
+
if (hasAtomic && !/^\d+$/.test(opts.amountAtomic)) {
|
|
499
|
+
throw new Error('[BitPal] x402: amountAtomic must be an integer string (USDC 6dp, $1 = "1000000").');
|
|
481
500
|
}
|
|
482
501
|
const timeoutSeconds = opts.maxTimeoutSeconds ?? DEFAULT_MAX_TIMEOUT_SECONDS;
|
|
483
502
|
if (timeoutSeconds < MIN_VALIDITY_SECONDS || timeoutSeconds > MAX_VALIDITY_SECONDS) {
|
|
@@ -495,7 +514,8 @@ var X402Gate = class {
|
|
|
495
514
|
async requirements(resource) {
|
|
496
515
|
return this.request("POST", "/v1/x402/requirements", {
|
|
497
516
|
payTo: this.opts.payTo,
|
|
498
|
-
|
|
517
|
+
// 사람 표기 → atomic 변환은 **서버가** 한다. SDK 가 decimals 를 알 필요가 없다.
|
|
518
|
+
...this.opts.amount != null ? { amount: this.opts.amount } : { amountAtomic: this.opts.amountAtomic },
|
|
499
519
|
resource,
|
|
500
520
|
...this.opts.network ? { network: this.opts.network } : {},
|
|
501
521
|
...this.opts.asset ? { asset: this.opts.asset } : {},
|
package/dist/index.d.cts
CHANGED
|
@@ -556,8 +556,20 @@ declare class BitPalCheckoutClient {
|
|
|
556
556
|
* 통지되므로, 서버 사이드 확정은 webhook 을 신뢰(폴링은 buyer UX 용).
|
|
557
557
|
*/
|
|
558
558
|
getStatus(sessionId: string): Promise<ApiResponse<SessionStatus>>;
|
|
559
|
-
/**
|
|
560
|
-
|
|
559
|
+
/**
|
|
560
|
+
* 수수료 미리보기 — `/v1/checkout/fee-preview`.
|
|
561
|
+
*
|
|
562
|
+
* `amount` 는 **사람 표기**다("100", "0.5") — line item / Price / x402 와 같은 모델이라
|
|
563
|
+
* decimals 를 계산할 필요가 없다. raw μUSD 를 직접 넣으려면 `amountAtomic` 을 쓴다(상호 배타).
|
|
564
|
+
* 응답은 계속 atomic 이다(계산 결과라 정밀도가 곧 계약이다).
|
|
565
|
+
*
|
|
566
|
+
* @example
|
|
567
|
+
* const { data } = await bp.checkout.previewFee('100'); // $100
|
|
568
|
+
* const { data } = await bp.checkout.previewFee({ amountAtomic: '100000000' });
|
|
569
|
+
*/
|
|
570
|
+
previewFee(amount: string | {
|
|
571
|
+
amountAtomic: string;
|
|
572
|
+
}): Promise<ApiResponse<FeePreview>>;
|
|
561
573
|
}
|
|
562
574
|
declare class BitPalError extends Error {
|
|
563
575
|
readonly statusCode: number;
|
|
@@ -785,8 +797,14 @@ interface X402GateOptions {
|
|
|
785
797
|
apiKey: string;
|
|
786
798
|
/** 정산 지갑. 콘솔에 등록한 payout 주소와 같은 값이어야 한다. */
|
|
787
799
|
payTo: string;
|
|
788
|
-
/**
|
|
789
|
-
|
|
800
|
+
/**
|
|
801
|
+
* 호출 1건당 받을 총액. **사람 표기 문자열**이다 — `'0.1'`, `'1'`, `'29.00'`.
|
|
802
|
+
* 체인·토큰 decimals 를 계산할 필요가 없다(체크아웃 `line_items[].amount` 와 같은 모델).
|
|
803
|
+
* 수수료는 이 금액에서 차감된다. raw atomic 을 직접 넣으려면 `amountAtomic` 을 쓴다(상호 배타).
|
|
804
|
+
*/
|
|
805
|
+
amount?: string;
|
|
806
|
+
/** raw atomic 정수 문자열(고급). USDC 6dp 기준 $1 = `'1000000'`. `amount` 와 상호 배타. */
|
|
807
|
+
amountAtomic?: string;
|
|
790
808
|
/** 생략 시 API 키 모드의 기본 자산(현재 Base / Base Sepolia). */
|
|
791
809
|
network?: string;
|
|
792
810
|
/** 기본 `'USDC'`. */
|
package/dist/index.d.ts
CHANGED
|
@@ -556,8 +556,20 @@ declare class BitPalCheckoutClient {
|
|
|
556
556
|
* 통지되므로, 서버 사이드 확정은 webhook 을 신뢰(폴링은 buyer UX 용).
|
|
557
557
|
*/
|
|
558
558
|
getStatus(sessionId: string): Promise<ApiResponse<SessionStatus>>;
|
|
559
|
-
/**
|
|
560
|
-
|
|
559
|
+
/**
|
|
560
|
+
* 수수료 미리보기 — `/v1/checkout/fee-preview`.
|
|
561
|
+
*
|
|
562
|
+
* `amount` 는 **사람 표기**다("100", "0.5") — line item / Price / x402 와 같은 모델이라
|
|
563
|
+
* decimals 를 계산할 필요가 없다. raw μUSD 를 직접 넣으려면 `amountAtomic` 을 쓴다(상호 배타).
|
|
564
|
+
* 응답은 계속 atomic 이다(계산 결과라 정밀도가 곧 계약이다).
|
|
565
|
+
*
|
|
566
|
+
* @example
|
|
567
|
+
* const { data } = await bp.checkout.previewFee('100'); // $100
|
|
568
|
+
* const { data } = await bp.checkout.previewFee({ amountAtomic: '100000000' });
|
|
569
|
+
*/
|
|
570
|
+
previewFee(amount: string | {
|
|
571
|
+
amountAtomic: string;
|
|
572
|
+
}): Promise<ApiResponse<FeePreview>>;
|
|
561
573
|
}
|
|
562
574
|
declare class BitPalError extends Error {
|
|
563
575
|
readonly statusCode: number;
|
|
@@ -785,8 +797,14 @@ interface X402GateOptions {
|
|
|
785
797
|
apiKey: string;
|
|
786
798
|
/** 정산 지갑. 콘솔에 등록한 payout 주소와 같은 값이어야 한다. */
|
|
787
799
|
payTo: string;
|
|
788
|
-
/**
|
|
789
|
-
|
|
800
|
+
/**
|
|
801
|
+
* 호출 1건당 받을 총액. **사람 표기 문자열**이다 — `'0.1'`, `'1'`, `'29.00'`.
|
|
802
|
+
* 체인·토큰 decimals 를 계산할 필요가 없다(체크아웃 `line_items[].amount` 와 같은 모델).
|
|
803
|
+
* 수수료는 이 금액에서 차감된다. raw atomic 을 직접 넣으려면 `amountAtomic` 을 쓴다(상호 배타).
|
|
804
|
+
*/
|
|
805
|
+
amount?: string;
|
|
806
|
+
/** raw atomic 정수 문자열(고급). USDC 6dp 기준 $1 = `'1000000'`. `amount` 와 상호 배타. */
|
|
807
|
+
amountAtomic?: string;
|
|
790
808
|
/** 생략 시 API 키 모드의 기본 자산(현재 Base / Base Sepolia). */
|
|
791
809
|
network?: string;
|
|
792
810
|
/** 기본 `'USDC'`. */
|
package/dist/index.js
CHANGED
|
@@ -256,12 +256,23 @@ var BitPalCheckoutClient = class {
|
|
|
256
256
|
);
|
|
257
257
|
}
|
|
258
258
|
/* ─── Fees ─── */
|
|
259
|
-
/**
|
|
259
|
+
/**
|
|
260
|
+
* 수수료 미리보기 — `/v1/checkout/fee-preview`.
|
|
261
|
+
*
|
|
262
|
+
* `amount` 는 **사람 표기**다("100", "0.5") — line item / Price / x402 와 같은 모델이라
|
|
263
|
+
* decimals 를 계산할 필요가 없다. raw μUSD 를 직접 넣으려면 `amountAtomic` 을 쓴다(상호 배타).
|
|
264
|
+
* 응답은 계속 atomic 이다(계산 결과라 정밀도가 곧 계약이다).
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* const { data } = await bp.checkout.previewFee('100'); // $100
|
|
268
|
+
* const { data } = await bp.checkout.previewFee({ amountAtomic: '100000000' });
|
|
269
|
+
*/
|
|
260
270
|
async previewFee(amount) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
271
|
+
const qs = typeof amount === "string" ? `amount=${encodeURIComponent(amount)}` : `amount_atomic=${encodeURIComponent(amount.amountAtomic)}`;
|
|
272
|
+
if (typeof amount === "string" && !/^(0|[1-9]\d*)(\.\d{1,6})?$/.test(amount)) {
|
|
273
|
+
throw new Error('[BitPal] previewFee: amount must be a decimal string like "100" or "0.5" (max 6 decimals). For raw \u03BCUSD use { amountAtomic }.');
|
|
274
|
+
}
|
|
275
|
+
return this.request("GET", `/v1/checkout/fee-preview?${qs}`);
|
|
265
276
|
}
|
|
266
277
|
};
|
|
267
278
|
var BitPalError = class extends Error {
|
|
@@ -417,8 +428,16 @@ var X402Gate = class {
|
|
|
417
428
|
if (!/^0x[a-fA-F0-9]{40}$/.test(opts.payTo)) {
|
|
418
429
|
throw new Error("[BitPal] x402: payTo must be a 0x EVM address (your registered payout wallet).");
|
|
419
430
|
}
|
|
420
|
-
|
|
421
|
-
|
|
431
|
+
const hasHuman = opts.amount != null;
|
|
432
|
+
const hasAtomic = opts.amountAtomic != null;
|
|
433
|
+
if (hasHuman === hasAtomic) {
|
|
434
|
+
throw new Error('[BitPal] x402: provide exactly one of `amount` ("0.1") or `amountAtomic` ("100000").');
|
|
435
|
+
}
|
|
436
|
+
if (hasHuman && !/^(0|[1-9]\d*)(\.\d{1,6})?$/.test(opts.amount)) {
|
|
437
|
+
throw new Error('[BitPal] x402: amount must be a decimal string like "0.1" or "29" (max 6 decimals).');
|
|
438
|
+
}
|
|
439
|
+
if (hasAtomic && !/^\d+$/.test(opts.amountAtomic)) {
|
|
440
|
+
throw new Error('[BitPal] x402: amountAtomic must be an integer string (USDC 6dp, $1 = "1000000").');
|
|
422
441
|
}
|
|
423
442
|
const timeoutSeconds = opts.maxTimeoutSeconds ?? DEFAULT_MAX_TIMEOUT_SECONDS;
|
|
424
443
|
if (timeoutSeconds < MIN_VALIDITY_SECONDS || timeoutSeconds > MAX_VALIDITY_SECONDS) {
|
|
@@ -436,7 +455,8 @@ var X402Gate = class {
|
|
|
436
455
|
async requirements(resource) {
|
|
437
456
|
return this.request("POST", "/v1/x402/requirements", {
|
|
438
457
|
payTo: this.opts.payTo,
|
|
439
|
-
|
|
458
|
+
// 사람 표기 → atomic 변환은 **서버가** 한다. SDK 가 decimals 를 알 필요가 없다.
|
|
459
|
+
...this.opts.amount != null ? { amount: this.opts.amount } : { amountAtomic: this.opts.amountAtomic },
|
|
440
460
|
resource,
|
|
441
461
|
...this.opts.network ? { network: this.opts.network } : {},
|
|
442
462
|
...this.opts.asset ? { asset: this.opts.asset } : {},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitpal/checkout",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "BitPal Checkout SDK — non-custodial crypto checkout: create sessions, issue per-order deposit addresses, poll status, verify signed webhooks, and charge per API call with x402.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|