@phala/pay 0.1.2 → 0.2.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/CHANGELOG.md +86 -1
- package/README.md +129 -28
- package/dist/checkout.d.ts +37 -7
- package/dist/checkout.d.ts.map +1 -1
- package/dist/checkout.js +55 -11
- package/dist/checkout.js.map +1 -1
- package/dist/client.d.ts +8 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +14 -8
- package/dist/client.js.map +1 -1
- package/dist/deposit-address.d.ts +47 -0
- package/dist/deposit-address.d.ts.map +1 -0
- package/dist/deposit-address.js +88 -0
- package/dist/deposit-address.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/payment.d.ts +43 -1
- package/dist/payment.d.ts.map +1 -1
- package/dist/payment.js +32 -10
- package/dist/payment.js.map +1 -1
- package/dist/quote.d.ts +7 -3
- package/dist/quote.d.ts.map +1 -1
- package/dist/quote.js +3 -1
- package/dist/quote.js.map +1 -1
- package/dist/react/Checkout.d.ts +11 -1
- package/dist/react/Checkout.d.ts.map +1 -1
- package/dist/react/Checkout.js +28 -37
- package/dist/react/Checkout.js.map +1 -1
- package/dist/react/DepositAddress.d.ts +31 -0
- package/dist/react/DepositAddress.d.ts.map +1 -0
- package/dist/react/DepositAddress.js +108 -0
- package/dist/react/DepositAddress.js.map +1 -0
- package/dist/react/Field.d.ts +7 -0
- package/dist/react/Field.d.ts.map +1 -0
- package/dist/react/Field.js +21 -0
- package/dist/react/Field.js.map +1 -0
- package/dist/react/appearance.d.ts +1 -1
- package/dist/react/appearance.d.ts.map +1 -1
- package/dist/react/appearance.js +3 -0
- package/dist/react/appearance.js.map +1 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/useCheckout.d.ts +3 -1
- package/dist/react/useCheckout.d.ts.map +1 -1
- package/dist/react/useCheckout.js +4 -3
- package/dist/react/useCheckout.js.map +1 -1
- package/dist/server/addresses.d.ts +78 -0
- package/dist/server/addresses.d.ts.map +1 -0
- package/dist/server/addresses.js +118 -0
- package/dist/server/addresses.js.map +1 -0
- package/dist/server/index.d.ts +12 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +12 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/sweeps.d.ts +78 -0
- package/dist/server/sweeps.d.ts.map +1 -0
- package/dist/server/sweeps.js +117 -0
- package/dist/server/sweeps.js.map +1 -0
- package/dist/server/webhook.d.ts +60 -0
- package/dist/server/webhook.d.ts.map +1 -0
- package/dist/server/webhook.js +148 -0
- package/dist/server/webhook.js.map +1 -0
- package/dist/wallet.d.ts +10 -8
- package/dist/wallet.d.ts.map +1 -1
- package/dist/wallet.js +61 -63
- package/dist/wallet.js.map +1 -1
- package/package.json +6 -1
- package/src/checkout.ts +89 -15
- package/src/client.ts +14 -8
- package/src/deposit-address.ts +138 -0
- package/src/index.ts +19 -1
- package/src/payment.ts +72 -10
- package/src/quote.ts +10 -4
- package/src/react/Checkout.tsx +72 -70
- package/src/react/DepositAddress.tsx +213 -0
- package/src/react/Field.tsx +46 -0
- package/src/react/appearance.ts +3 -0
- package/src/react/index.ts +1 -0
- package/src/react/useCheckout.ts +6 -2
- package/src/server/addresses.ts +223 -0
- package/src/server/index.ts +38 -0
- package/src/server/sweeps.ts +197 -0
- package/src/server/webhook.ts +202 -0
- package/src/wallet.ts +74 -68
package/dist/client.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { createCheckout, retrieveQuote, } from "./checkout.js";
|
|
2
2
|
/**
|
|
3
3
|
* The browser client, in the shape of Stripe.js: it holds no key, only the service origin, and
|
|
4
|
-
* works with the `client_secret` your backend got from `POST /v1/quotes
|
|
4
|
+
* works with the `client_secret` your backend got from `POST /v1/quotes` and the `address` its
|
|
5
|
+
* SDK recomputed (`expectedAddress`).
|
|
5
6
|
*
|
|
6
7
|
* const pay = new PhalaPay({ apiBase: "https://pay.example.com" });
|
|
7
|
-
* const quote = await pay.retrieveQuote(clientSecret);
|
|
8
|
-
* const session = pay.checkout(clientSecret);
|
|
8
|
+
* const quote = await pay.retrieveQuote(clientSecret, expectedAddress);
|
|
9
|
+
* const session = pay.checkout(clientSecret, { expectedAddress });
|
|
9
10
|
* session.subscribe(({ status }) => render(status));
|
|
10
11
|
*/
|
|
11
12
|
export class PhalaPay {
|
|
@@ -15,12 +16,17 @@ export class PhalaPay {
|
|
|
15
16
|
this.apiBase = options.apiBase;
|
|
16
17
|
this.#fetch = options.fetch;
|
|
17
18
|
}
|
|
18
|
-
/** Reads the quote's public view once
|
|
19
|
-
retrieveQuote(clientSecret) {
|
|
20
|
-
return retrieveQuote({
|
|
19
|
+
/** Reads the quote's public view once, refusing one whose address is not `expectedAddress`. */
|
|
20
|
+
retrieveQuote(clientSecret, expectedAddress) {
|
|
21
|
+
return retrieveQuote({
|
|
22
|
+
clientSecret,
|
|
23
|
+
expectedAddress,
|
|
24
|
+
apiBase: this.apiBase,
|
|
25
|
+
...this.#fetchOption(),
|
|
26
|
+
});
|
|
21
27
|
}
|
|
22
|
-
/** Follows the quote until it is credited, rejected, canceled, or expired. */
|
|
23
|
-
checkout(clientSecret, options
|
|
28
|
+
/** Follows the quote until it is credited, rejected, reversed, canceled, or expired. */
|
|
29
|
+
checkout(clientSecret, options) {
|
|
24
30
|
return createCheckout({
|
|
25
31
|
clientSecret,
|
|
26
32
|
apiBase: this.apiBase,
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,aAAa,GAGd,MAAM,eAAe,CAAC;AASvB
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,aAAa,GAGd,MAAM,eAAe,CAAC;AASvB;;;;;;;;;GASG;AACH,MAAM,OAAO,QAAQ;IACV,OAAO,CAAS;IAChB,MAAM,CAAsC;IAErD,YAAY,OAAwB;QAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAC9B,CAAC;IAED,+FAA+F;IAC/F,aAAa,CAAC,YAAoB,EAAE,eAAuB;QACzD,OAAO,aAAa,CAAC;YACnB,YAAY;YACZ,eAAe;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,IAAI,CAAC,YAAY,EAAE;SACvB,CAAC,CAAC;IACL,CAAC;IAED,wFAAwF;IACxF,QAAQ,CACN,YAAoB,EACpB,OAAkE;QAElE,OAAO,cAAc,CAAC;YACpB,YAAY;YACZ,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,OAAO;YACV,GAAG,IAAI,CAAC,YAAY,EAAE;SACvB,CAAC,CAAC;IACL,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IACjE,CAAC;CACF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** A payment to a deposit address as the customer's page sees it. Display only. */
|
|
2
|
+
export interface DepositAddressPayment {
|
|
3
|
+
/**
|
|
4
|
+
* `seen` (in a block, may still disappear), `confirming` (at the route's confirmation, being
|
|
5
|
+
* valued and screened), `credited`, `rejected` (contact support), or `reversed` (its
|
|
6
|
+
* transaction left the chain before finality: the payment did not happen).
|
|
7
|
+
*/
|
|
8
|
+
status: "seen" | "confirming" | "credited" | "rejected" | "reversed";
|
|
9
|
+
chain_id: number;
|
|
10
|
+
/** The token's code, or `null` for a token without a route. */
|
|
11
|
+
asset: string | null;
|
|
12
|
+
decimals: number | null;
|
|
13
|
+
/** Token amount in the smallest unit, as a decimal string. */
|
|
14
|
+
amount_atomic: string;
|
|
15
|
+
tx_hash: string;
|
|
16
|
+
/** Block confirmations while `seen`, otherwise `null`. */
|
|
17
|
+
confirmations: number | null;
|
|
18
|
+
/** Unix seconds. */
|
|
19
|
+
created: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The public view of a deposit address, as `GET /v1/deposit_addresses/{id}?client_secret=…`
|
|
23
|
+
* returns it to a browser: its payments in the last 24 hours, newest first.
|
|
24
|
+
*/
|
|
25
|
+
export interface ClientDepositAddress {
|
|
26
|
+
id: string;
|
|
27
|
+
object: "deposit_address";
|
|
28
|
+
livemode: boolean;
|
|
29
|
+
status: "active" | "retired";
|
|
30
|
+
payments: DepositAddressPayment[];
|
|
31
|
+
}
|
|
32
|
+
export interface RetrieveDepositAddressOptions {
|
|
33
|
+
/** A `client_secret` from your backend's `POST /v1/deposit_addresses` or `…/rotate`. */
|
|
34
|
+
clientSecret: string;
|
|
35
|
+
apiBase: string;
|
|
36
|
+
fetch?: typeof globalThis.fetch;
|
|
37
|
+
}
|
|
38
|
+
/** Returns the deposit address a client secret belongs to (`da_…_secret_…`), or throws. */
|
|
39
|
+
export declare function depositAddressIdFromClientSecret(clientSecret: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Reads a deposit address's public view once. Rejects with a `CheckoutError`:
|
|
42
|
+
* `invalid_client_secret` for an unknown address or secret.
|
|
43
|
+
*/
|
|
44
|
+
export declare function retrieveDepositAddress(options: RetrieveDepositAddressOptions): Promise<ClientDepositAddress>;
|
|
45
|
+
/** Validates a response body against the public deposit address view; throws on anything else. */
|
|
46
|
+
export declare function parseClientDepositAddress(value: unknown): ClientDepositAddress;
|
|
47
|
+
//# sourceMappingURL=deposit-address.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deposit-address.d.ts","sourceRoot":"","sources":["../src/deposit-address.ts"],"names":[],"mappings":"AAEA,mFAAmF;AACnF,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,6BAA6B;IAC5C,wFAAwF;IACxF,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAID,2FAA2F;AAC3F,wBAAgB,gCAAgC,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAM7E;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,oBAAoB,CAAC,CAiB/B;AAED,kGAAkG;AAClG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAmB9E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { CheckoutError, responseError } from "./checkout.js";
|
|
2
|
+
const PAYMENT_STATUSES = ["seen", "confirming", "credited", "rejected", "reversed"];
|
|
3
|
+
/** Returns the deposit address a client secret belongs to (`da_…_secret_…`), or throws. */
|
|
4
|
+
export function depositAddressIdFromClientSecret(clientSecret) {
|
|
5
|
+
const match = /^(da_[0-9a-f]{32})_secret_[0-9a-f]+$/.exec(clientSecret);
|
|
6
|
+
if (match?.[1] === undefined) {
|
|
7
|
+
throw new TypeError("clientSecret is not a deposit address client secret");
|
|
8
|
+
}
|
|
9
|
+
return match[1];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Reads a deposit address's public view once. Rejects with a `CheckoutError`:
|
|
13
|
+
* `invalid_client_secret` for an unknown address or secret.
|
|
14
|
+
*/
|
|
15
|
+
export async function retrieveDepositAddress(options) {
|
|
16
|
+
const id = depositAddressIdFromClientSecret(options.clientSecret);
|
|
17
|
+
const base = options.apiBase.replace(/\/+$/, "");
|
|
18
|
+
const url = `${base}/v1/deposit_addresses/${id}?client_secret=${encodeURIComponent(options.clientSecret)}`;
|
|
19
|
+
const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
20
|
+
// A simple GET with no custom headers, so the browser sends no CORS preflight.
|
|
21
|
+
const response = await fetchImpl(url, { cache: "no-store", credentials: "omit" });
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw responseError(response, "the address or its client secret is unknown");
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return parseClientDepositAddress(await response.json());
|
|
27
|
+
}
|
|
28
|
+
catch (cause) {
|
|
29
|
+
throw new CheckoutError("invalid_response", "unexpected response from the payment service", {
|
|
30
|
+
cause,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Validates a response body against the public deposit address view; throws on anything else. */
|
|
35
|
+
export function parseClientDepositAddress(value) {
|
|
36
|
+
const v = record(value);
|
|
37
|
+
const payments = v["payments"];
|
|
38
|
+
if (typeof v["id"] !== "string" ||
|
|
39
|
+
v["object"] !== "deposit_address" ||
|
|
40
|
+
typeof v["livemode"] !== "boolean" ||
|
|
41
|
+
(v["status"] !== "active" && v["status"] !== "retired") ||
|
|
42
|
+
!Array.isArray(payments)) {
|
|
43
|
+
throw new TypeError("response does not match the public deposit address view");
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
id: v["id"],
|
|
47
|
+
object: "deposit_address",
|
|
48
|
+
livemode: v["livemode"],
|
|
49
|
+
status: v["status"],
|
|
50
|
+
payments: payments.map(parsePayment),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function parsePayment(value) {
|
|
54
|
+
const p = record(value);
|
|
55
|
+
const status = p["status"];
|
|
56
|
+
const asset = p["asset"];
|
|
57
|
+
const decimals = p["decimals"];
|
|
58
|
+
const confirmations = p["confirmations"];
|
|
59
|
+
if (typeof status !== "string" ||
|
|
60
|
+
!PAYMENT_STATUSES.includes(status) ||
|
|
61
|
+
!Number.isSafeInteger(p["chain_id"]) ||
|
|
62
|
+
!(asset === null || typeof asset === "string") ||
|
|
63
|
+
!(decimals === null || Number.isSafeInteger(decimals)) ||
|
|
64
|
+
typeof p["amount_atomic"] !== "string" ||
|
|
65
|
+
!/^\d+$/.test(p["amount_atomic"]) ||
|
|
66
|
+
typeof p["tx_hash"] !== "string" ||
|
|
67
|
+
!(confirmations === null || Number.isSafeInteger(confirmations)) ||
|
|
68
|
+
!Number.isSafeInteger(p["created"])) {
|
|
69
|
+
throw new TypeError("payment does not match the public deposit address view");
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
status: status,
|
|
73
|
+
chain_id: p["chain_id"],
|
|
74
|
+
asset,
|
|
75
|
+
decimals: decimals,
|
|
76
|
+
amount_atomic: p["amount_atomic"],
|
|
77
|
+
tx_hash: p["tx_hash"],
|
|
78
|
+
confirmations: confirmations,
|
|
79
|
+
created: p["created"],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function record(value) {
|
|
83
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
84
|
+
throw new TypeError("response is not an object");
|
|
85
|
+
}
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=deposit-address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deposit-address.js","sourceRoot":"","sources":["../src/deposit-address.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export { CheckoutError, checkoutStatus, createCheckout, retrieveQuote, type CheckoutErrorCode, type CheckoutOptions, type CheckoutSession, type CheckoutState, type CheckoutStatus, type RetrieveQuoteOptions, } from "./checkout.js";
|
|
1
|
+
export { CheckoutError, checkoutStatus, createCheckout, retrieveQuote, type CheckoutErrorCode, type CheckoutErrorOptions, type CheckoutOptions, type CheckoutSession, type CheckoutState, type CheckoutStatus, type RetrieveQuoteOptions, } from "./checkout.js";
|
|
2
2
|
export { PhalaPay, type PhalaPayOptions } from "./client.js";
|
|
3
|
+
export { depositAddressIdFromClientSecret, parseClientDepositAddress, retrieveDepositAddress, type ClientDepositAddress, type DepositAddressPayment, type RetrieveDepositAddressOptions, } from "./deposit-address.js";
|
|
3
4
|
export { knownChain, networkName, transactionUrl } from "./chains.js";
|
|
4
5
|
export { formatAmount, formatCountdown, formatTokenAmount, tokenAmount } from "./format.js";
|
|
5
|
-
export { quoteTransfer, type TokenTransfer } from "./payment.js";
|
|
6
|
+
export { depositAddressTransfer, parseTransferUri, quoteTransfer, type DepositAddressAsset, type DepositAddressDetails, type DepositAddressNetwork, type TokenTransfer, type TransferRequest, } from "./payment.js";
|
|
6
7
|
export { parseClientQuote, quoteIdFromClientSecret, type ClientQuote } from "./quote.js";
|
|
7
8
|
export { INJECTED_WALLET_UUID, WalletError, payWithWallet, watchWallets, type EthereumProvider, type Wallet, type WalletErrorCode, type WalletInfo, } from "./wallet.js";
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EACL,gCAAgC,EAChC,yBAAyB,EACzB,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,GACnC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,MAAM,EACX,KAAK,eAAe,EACpB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export { CheckoutError, checkoutStatus, createCheckout, retrieveQuote, } from "./checkout.js";
|
|
2
2
|
export { PhalaPay } from "./client.js";
|
|
3
|
+
export { depositAddressIdFromClientSecret, parseClientDepositAddress, retrieveDepositAddress, } from "./deposit-address.js";
|
|
3
4
|
export { knownChain, networkName, transactionUrl } from "./chains.js";
|
|
4
5
|
export { formatAmount, formatCountdown, formatTokenAmount, tokenAmount } from "./format.js";
|
|
5
|
-
export { quoteTransfer } from "./payment.js";
|
|
6
|
+
export { depositAddressTransfer, parseTransferUri, quoteTransfer, } from "./payment.js";
|
|
6
7
|
export { parseClientQuote, quoteIdFromClientSecret } from "./quote.js";
|
|
7
8
|
export { INJECTED_WALLET_UUID, WalletError, payWithWallet, watchWallets, } from "./wallet.js";
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,aAAa,GAQd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAC7D,OAAO,EACL,gCAAgC,EAChC,yBAAyB,EACzB,sBAAsB,GAIvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,GAMd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAoB,MAAM,YAAY,CAAC;AACzF,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,YAAY,GAKb,MAAM,aAAa,CAAC"}
|
package/dist/payment.d.ts
CHANGED
|
@@ -5,15 +5,57 @@ export interface TokenTransfer {
|
|
|
5
5
|
chainId: number;
|
|
6
6
|
/** The token contract. */
|
|
7
7
|
token: Address;
|
|
8
|
-
/** The recipient: the quote's deposit address. */
|
|
8
|
+
/** The recipient: the quote's or the customer's deposit address. */
|
|
9
9
|
to: Address;
|
|
10
10
|
/** Token amount in the smallest unit. */
|
|
11
11
|
amount: bigint;
|
|
12
12
|
}
|
|
13
|
+
/** An EIP-681 ERC-20 transfer request whose amount the payer may choose. */
|
|
14
|
+
export type TransferRequest = Omit<TokenTransfer, "amount"> & {
|
|
15
|
+
amount: bigint | undefined;
|
|
16
|
+
};
|
|
17
|
+
/** A token a deposit address takes on one network. */
|
|
18
|
+
export interface DepositAddressAsset {
|
|
19
|
+
/** The token's code, for example `pha`. */
|
|
20
|
+
asset: string;
|
|
21
|
+
/** The ERC-20 contract. */
|
|
22
|
+
contract: string;
|
|
23
|
+
decimals: number;
|
|
24
|
+
/** The EIP-681 transfer request of this token to the network's address, without an amount. */
|
|
25
|
+
payment_uri: string;
|
|
26
|
+
}
|
|
27
|
+
/** A deposit address on one network (EVM chain), with the tokens it takes there. */
|
|
28
|
+
export interface DepositAddressNetwork {
|
|
29
|
+
chain_id: number;
|
|
30
|
+
/** The address on this chain: the same on every chain whose treasury is the same. */
|
|
31
|
+
address: string;
|
|
32
|
+
assets: DepositAddressAsset[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The fields of a deposit address that a payer's page shows: pass them from your backend's
|
|
36
|
+
* `POST /v1/deposit_addresses` response. One address takes every supported token on every
|
|
37
|
+
* supported network; any amount of a supported token sent is credited at the market rate.
|
|
38
|
+
*/
|
|
39
|
+
export interface DepositAddressDetails {
|
|
40
|
+
/** The address shared by every network, or `null` when a network's address differs. */
|
|
41
|
+
address: string | null;
|
|
42
|
+
networks: DepositAddressNetwork[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parses an EIP-681 ERC-20 transfer URI, `ethereum:<token>@<chainId>/transfer?address=<to>`, with
|
|
46
|
+
* an optional `uint256=<amount>`. Throws on anything else.
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseTransferUri(uri: string): TransferRequest;
|
|
13
49
|
/**
|
|
14
50
|
* Reads the token transfer from a quote's EIP-681 `payment_uri`, and checks that it pays exactly
|
|
15
51
|
* the quote's `amount_atomic` to the quote's `address` on the quote's chain, so the wallet, the QR
|
|
16
52
|
* code, and the manual instructions all state the same payment.
|
|
17
53
|
*/
|
|
18
54
|
export declare function quoteTransfer(quote: ClientQuote): TokenTransfer;
|
|
55
|
+
/**
|
|
56
|
+
* Reads the token transfer from a deposit address's EIP-681 `payment_uri` for one token on one
|
|
57
|
+
* network, and checks that it pays the network's address in that token on that chain and names no
|
|
58
|
+
* amount, so the QR code and the copied address and contract state the same destination.
|
|
59
|
+
*/
|
|
60
|
+
export declare function depositAddressTransfer(network: DepositAddressNetwork, asset: DepositAddressAsset): TransferRequest;
|
|
19
61
|
//# sourceMappingURL=payment.d.ts.map
|
package/dist/payment.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment.d.ts","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,
|
|
1
|
+
{"version":3,"file":"payment.d.ts","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,oEAAoE;IACpE,EAAE,EAAE,OAAO,CAAC;IACZ,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4EAA4E;AAC5E,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAE7F,sDAAsD;AACtD,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,oFAAoF;AACpF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,mBAAmB,EAAE,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,uFAAuF;IACvF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC;AAKD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAoB7D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAW/D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,mBAAmB,GACzB,eAAe,CAWjB"}
|
package/dist/payment.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { getAddress, isAddressEqual } from "viem";
|
|
2
2
|
const EIP681_TRANSFER = /^ethereum:(?:pay-)?(0x[0-9a-fA-F]{40})@([1-9][0-9]*)\/transfer\?([^#]*)$/;
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* code, and the manual instructions all state the same payment.
|
|
4
|
+
* Parses an EIP-681 ERC-20 transfer URI, `ethereum:<token>@<chainId>/transfer?address=<to>`, with
|
|
5
|
+
* an optional `uint256=<amount>`. Throws on anything else.
|
|
7
6
|
*/
|
|
8
|
-
export function
|
|
9
|
-
const match = EIP681_TRANSFER.exec(
|
|
7
|
+
export function parseTransferUri(uri) {
|
|
8
|
+
const match = EIP681_TRANSFER.exec(uri);
|
|
10
9
|
const params = new URLSearchParams(match?.[3] ?? "");
|
|
11
10
|
const to = params.get("address");
|
|
12
11
|
const amount = params.get("uint256");
|
|
@@ -14,21 +13,44 @@ export function quoteTransfer(quote) {
|
|
|
14
13
|
match[2] === undefined ||
|
|
15
14
|
to === null ||
|
|
16
15
|
!/^0x[0-9a-fA-F]{40}$/.test(to) ||
|
|
17
|
-
amount
|
|
18
|
-
!/^\d+$/.test(amount)) {
|
|
16
|
+
(amount !== null && !/^\d+$/.test(amount))) {
|
|
19
17
|
throw new TypeError("payment_uri is not an EIP-681 ERC-20 transfer");
|
|
20
18
|
}
|
|
21
|
-
|
|
19
|
+
return {
|
|
22
20
|
chainId: Number(match[2]),
|
|
23
21
|
token: getAddress(match[1]),
|
|
24
22
|
to: getAddress(to),
|
|
25
|
-
amount: BigInt(amount),
|
|
23
|
+
amount: amount === null ? undefined : BigInt(amount),
|
|
26
24
|
};
|
|
27
|
-
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Reads the token transfer from a quote's EIP-681 `payment_uri`, and checks that it pays exactly
|
|
28
|
+
* the quote's `amount_atomic` to the quote's `address` on the quote's chain, so the wallet, the QR
|
|
29
|
+
* code, and the manual instructions all state the same payment.
|
|
30
|
+
*/
|
|
31
|
+
export function quoteTransfer(quote) {
|
|
32
|
+
const transfer = parseTransferUri(quote.payment_uri);
|
|
33
|
+
if (transfer.amount === undefined ||
|
|
34
|
+
transfer.chainId !== quote.chain_id ||
|
|
28
35
|
!isAddressEqual(transfer.to, getAddress(quote.address)) ||
|
|
29
36
|
transfer.amount !== BigInt(quote.amount_atomic)) {
|
|
30
37
|
throw new TypeError("payment_uri does not match the quote");
|
|
31
38
|
}
|
|
39
|
+
return { ...transfer, amount: transfer.amount };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Reads the token transfer from a deposit address's EIP-681 `payment_uri` for one token on one
|
|
43
|
+
* network, and checks that it pays the network's address in that token on that chain and names no
|
|
44
|
+
* amount, so the QR code and the copied address and contract state the same destination.
|
|
45
|
+
*/
|
|
46
|
+
export function depositAddressTransfer(network, asset) {
|
|
47
|
+
const transfer = parseTransferUri(asset.payment_uri);
|
|
48
|
+
if (transfer.amount !== undefined ||
|
|
49
|
+
transfer.chainId !== network.chain_id ||
|
|
50
|
+
!isAddressEqual(transfer.to, getAddress(network.address)) ||
|
|
51
|
+
!isAddressEqual(transfer.token, getAddress(asset.contract))) {
|
|
52
|
+
throw new TypeError("payment_uri does not match the deposit address");
|
|
53
|
+
}
|
|
32
54
|
return transfer;
|
|
33
55
|
}
|
|
34
56
|
//# sourceMappingURL=payment.js.map
|
package/dist/payment.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment.js","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAgB,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"payment.js","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAgB,MAAM,MAAM,CAAC;AA+ChE,MAAM,eAAe,GACnB,0EAA0E,CAAC;AAE7E;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACrC,IACE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS;QACxB,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS;QACtB,EAAE,KAAK,IAAI;QACX,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAC1C,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAC;IACvE,CAAC;IACD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC;QAClB,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;KACrD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAkB;IAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACrD,IACE,QAAQ,CAAC,MAAM,KAAK,SAAS;QAC7B,QAAQ,CAAC,OAAO,KAAK,KAAK,CAAC,QAAQ;QACnC,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvD,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAC/C,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAA8B,EAC9B,KAA0B;IAE1B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACrD,IACE,QAAQ,CAAC,MAAM,KAAK,SAAS;QAC7B,QAAQ,CAAC,OAAO,KAAK,OAAO,CAAC,QAAQ;QACrC,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACzD,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAC3D,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/quote.d.ts
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
export interface ClientQuote {
|
|
5
5
|
id: string;
|
|
6
6
|
object: "quote";
|
|
7
|
+
/** `false` for a test-mode quote, paid on a testnet; the page says so. */
|
|
8
|
+
livemode: boolean;
|
|
7
9
|
/** `open` until a matching payment completes it, it expires by chain time, or it is canceled. */
|
|
8
10
|
status: "open" | "complete" | "expired" | "canceled";
|
|
9
11
|
/** Credit in the currency's minor unit (US cents). */
|
|
@@ -22,10 +24,12 @@ export interface ClientQuote {
|
|
|
22
24
|
/** Unix seconds; after this the address must no longer be shown. */
|
|
23
25
|
expires_at: number;
|
|
24
26
|
/**
|
|
25
|
-
* `seen`
|
|
26
|
-
* and screened, `credited` once it is credited
|
|
27
|
+
* `seen` once in a block (a reorg can remove it), `confirming` while a payment at the route's
|
|
28
|
+
* confirmation is valued and screened, `credited` once it is credited (about 30 seconds after
|
|
29
|
+
* paying), `rejected` when it will not be, `reversed` when a credited payment's transaction
|
|
30
|
+
* left the chain before finality (the payment did not happen).
|
|
27
31
|
*/
|
|
28
|
-
payment_status: "none" | "seen" | "confirming" | "credited" | "rejected";
|
|
32
|
+
payment_status: "none" | "seen" | "confirming" | "credited" | "rejected" | "reversed";
|
|
29
33
|
/** Block confirmations while `payment_status` is `seen`, otherwise `null`. */
|
|
30
34
|
confirmations: number | null;
|
|
31
35
|
}
|
package/dist/quote.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quote.d.ts","sourceRoot":"","sources":["../src/quote.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,iGAAiG;IACjG,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;IACrD,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB
|
|
1
|
+
{"version":3,"file":"quote.d.ts","sourceRoot":"","sources":["../src/quote.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAC;IAClB,iGAAiG;IACjG,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;IACrD,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;IACtF,8EAA8E;IAC9E,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAKD,oFAAoF;AACpF,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAMpE;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CA4C5D"}
|
package/dist/quote.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const QUOTE_STATUSES = ["open", "complete", "expired", "canceled"];
|
|
2
|
-
const PAYMENT_STATUSES = ["none", "seen", "confirming", "credited", "rejected"];
|
|
2
|
+
const PAYMENT_STATUSES = ["none", "seen", "confirming", "credited", "rejected", "reversed"];
|
|
3
3
|
/** Returns the quote id a client secret belongs to (`qt_…_secret_…`), or throws. */
|
|
4
4
|
export function quoteIdFromClientSecret(clientSecret) {
|
|
5
5
|
const match = /^(qt_[0-9a-f]+)_secret_[0-9a-f]+$/.exec(clientSecret);
|
|
@@ -17,6 +17,7 @@ export function parseClientQuote(value) {
|
|
|
17
17
|
const confirmations = v["confirmations"];
|
|
18
18
|
if (typeof v["id"] !== "string" ||
|
|
19
19
|
v["object"] !== "quote" ||
|
|
20
|
+
typeof v["livemode"] !== "boolean" ||
|
|
20
21
|
!oneOf(v["status"], QUOTE_STATUSES) ||
|
|
21
22
|
!isSafeInteger(v["amount"]) ||
|
|
22
23
|
typeof v["currency"] !== "string" ||
|
|
@@ -36,6 +37,7 @@ export function parseClientQuote(value) {
|
|
|
36
37
|
return {
|
|
37
38
|
id: v["id"],
|
|
38
39
|
object: "quote",
|
|
40
|
+
livemode: v["livemode"],
|
|
39
41
|
status: v["status"],
|
|
40
42
|
amount: v["amount"],
|
|
41
43
|
currency: v["currency"],
|
package/dist/quote.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quote.js","sourceRoot":"","sources":["../src/quote.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"quote.js","sourceRoot":"","sources":["../src/quote.ts"],"names":[],"mappings":"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"}
|
package/dist/react/Checkout.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import type { WalletClient } from "viem";
|
|
1
2
|
import type { CheckoutState } from "../checkout.js";
|
|
2
3
|
import type { ClientQuote } from "../quote.js";
|
|
3
4
|
import { type Appearance } from "./appearance.js";
|
|
4
5
|
export interface CheckoutProps {
|
|
5
6
|
/** The quote's `client_secret`, from your backend's `POST /v1/quotes`. */
|
|
6
7
|
clientSecret: string;
|
|
8
|
+
/**
|
|
9
|
+
* The quote's `address` as your backend's SDK recomputed it from the pinned forwarder
|
|
10
|
+
* (`PhalaPay(forwarder=…)` in Python). Required: when the service's quote names another
|
|
11
|
+
* address, the checkout fails closed and shows nothing to pay.
|
|
12
|
+
*/
|
|
13
|
+
expectedAddress: string;
|
|
7
14
|
/** The service origin, for example `https://topup.example.com`. */
|
|
8
15
|
apiBase: string;
|
|
9
16
|
/** Called once when the payment is credited. Fulfil from the `deposit.credited` webhook, not here. */
|
|
@@ -19,7 +26,10 @@ export interface CheckoutProps {
|
|
|
19
26
|
className?: string;
|
|
20
27
|
/** The wallet button's label; default "Pay with crypto". */
|
|
21
28
|
buttonText?: string;
|
|
29
|
+
/** Your page's connected wallet, for example wagmi's `useWalletClient().data`. When set, the
|
|
30
|
+
* wallet tab pays with it and its account instead of listing the browser's wallets. */
|
|
31
|
+
walletClient?: WalletClient | undefined;
|
|
22
32
|
}
|
|
23
33
|
/** A checkout for one quote: pay from a browser wallet, by QR code, or manually, with live status. */
|
|
24
|
-
export declare function Checkout({ clientSecret, apiBase, onSuccess, onExpire, onChange, appearance, pollInterval, className, buttonText, }: CheckoutProps): import("react").JSX.Element;
|
|
34
|
+
export declare function Checkout({ clientSecret, expectedAddress, apiBase, onSuccess, onExpire, onChange, appearance, pollInterval, className, buttonText, walletClient, }: CheckoutProps): import("react").JSX.Element;
|
|
25
35
|
//# sourceMappingURL=Checkout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkout.d.ts","sourceRoot":"","sources":["../../src/react/Checkout.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Checkout.d.ts","sourceRoot":"","sources":["../../src/react/Checkout.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAQ,YAAY,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,KAAK,EAAqB,aAAa,EAAkB,MAAM,gBAAgB,CAAC;AAIvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAQ/C,OAAO,EAA2B,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAK3E,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,sGAAsG;IACtG,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC;2FACuF;IACvF,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;2FACuF;IACvF,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CACzC;AAUD,sGAAsG;AACtG,wBAAgB,QAAQ,CAAC,EACvB,YAAY,EACZ,eAAe,EACf,OAAO,EACP,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,SAAS,EACT,UAA8B,EAC9B,YAAY,GACb,EAAE,aAAa,+BAoEf"}
|