@phala/pay 0.4.0 → 0.6.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 +17 -7
- package/dist/deposit-address.d.ts +14 -1
- package/dist/deposit-address.d.ts.map +1 -1
- package/dist/deposit-address.js +18 -0
- package/dist/deposit-address.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/quote.d.ts +2 -1
- package/dist/quote.d.ts.map +1 -1
- package/dist/quote.js.map +1 -1
- package/dist/react/DepositAddress.d.ts +2 -1
- package/dist/react/DepositAddress.d.ts.map +1 -1
- package/dist/react/DepositAddress.js +33 -8
- package/dist/react/DepositAddress.js.map +1 -1
- package/package.json +2 -3
- package/src/deposit-address.ts +36 -1
- package/src/index.ts +1 -0
- package/src/quote.ts +2 -1
- package/src/react/DepositAddress.tsx +41 -12
- package/CHANGELOG.md +0 -192
package/README.md
CHANGED
|
@@ -11,6 +11,9 @@ Python SDK (`phala-pay`) and fulfils from the signed `deposit.credited` webhook.
|
|
|
11
11
|
npm install @phala/pay viem
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
`@phala/pay` shares the service's version: pin the one equal to your operator's service version
|
|
15
|
+
([compatibility](../../docs/integration.md#compatibility)).
|
|
16
|
+
|
|
14
17
|
Peer dependencies: `viem` 2, and `react` 18 or 19 for `@phala/pay/react`. Browser wallets are
|
|
15
18
|
found with EIP-6963 through [mipd](https://github.com/wevm/mipd), wagmi's discovery store (with a
|
|
16
19
|
`window.ethereum` fallback for wallets that do not announce themselves). If your page already
|
|
@@ -88,12 +91,13 @@ to offer your own way to fund that wallet.
|
|
|
88
91
|
To resume after a reload, keep the client secret in the browser (for example `localStorage`, per
|
|
89
92
|
signed-in account) until the status is `credited`, `expired`, `canceled`, or `error`. Tell a
|
|
90
93
|
payer who is waiting that the payment is credited in about the quote's `typical_credit_seconds`
|
|
91
|
-
(30 seconds on Ethereum, about
|
|
94
|
+
(30 seconds on Ethereum, about 7 seconds on Base, 15 minutes under a `finalized` policy) and the
|
|
92
95
|
credit arrives on its own.
|
|
93
96
|
|
|
94
|
-
A credit is made before Ethereum finality (about 15 minutes). In the rare case that a reorg
|
|
95
|
-
the payment
|
|
96
|
-
|
|
97
|
+
A credit is made before Ethereum finality (about 15 minutes). In the rare case that a reorg proves
|
|
98
|
+
the payment replaced, your backend receives `deposit.reversed` and claws the credit back as for
|
|
99
|
+
`deposit.refunded`; a payment gone with its nonce unspent instead stays credited and not final,
|
|
100
|
+
and the operator is alerted. The checkout itself only reflects the quote.
|
|
97
101
|
|
|
98
102
|
The payment options disappear once a payment is seen, and at `expires_at`. A payment of a different
|
|
99
103
|
amount, or after expiry, is still credited, at the market price instead of the quote's: the
|
|
@@ -152,7 +156,9 @@ import { DepositAddress } from "@phala/pay/react";
|
|
|
152
156
|
|
|
153
157
|
With `clientSecret` and `apiBase` it reads the address's public view every three seconds and lists
|
|
154
158
|
its payments of the last 24 hours: "1.5 PHA received on Sepolia, 1 confirmation" within about a
|
|
155
|
-
block of the transfer, then "credited" (or rejected or reversed). Display only.
|
|
159
|
+
block of the transfer, then "credited" (or rejected or reversed). Display only. It also states each
|
|
160
|
+
network's typical credit time from the view's `typical_credit_seconds` ("usually in about 30 seconds
|
|
161
|
+
on Sepolia and about 7 seconds on Base Sepolia"); until the view is loaded it names no time.
|
|
156
162
|
|
|
157
163
|
`depositAddressTransfer(network, asset)` reads and checks one token's amount-less EIP-681
|
|
158
164
|
`payment_uri` without React.
|
|
@@ -274,5 +280,9 @@ EIP-6963 wallet backed by the node (and again through a viem `WalletClient` pass
|
|
|
274
280
|
|
|
275
281
|
## Releases
|
|
276
282
|
|
|
277
|
-
|
|
278
|
-
(environment `npm`) with trusted publishing and provenance
|
|
283
|
+
`@phala/pay` is released with the service: the `v<version>` tag's Release workflow publishes it to
|
|
284
|
+
npm (environment `npm`) with trusted publishing and provenance
|
|
285
|
+
([CONTRIBUTING.md, "Releasing"](../../CONTRIBUTING.md#releasing)). Its changes are in the top-level
|
|
286
|
+
[CHANGELOG.md](https://github.com/Phala-Network/phala-pay/blob/main/CHANGELOG.md), under "JS SDK";
|
|
287
|
+
[its releases before v0.5.0](https://github.com/Phala-Network/phala-pay/blob/main/sdk/js/CHANGELOG.md),
|
|
288
|
+
versioned on their own, stay in `sdk/js`.
|
|
@@ -18,15 +18,28 @@ export interface DepositAddressPayment {
|
|
|
18
18
|
/** Unix seconds. */
|
|
19
19
|
created: number;
|
|
20
20
|
}
|
|
21
|
+
/** A deposit address on one network, as the customer's page sees it. */
|
|
22
|
+
export interface ClientDepositAddressNetwork {
|
|
23
|
+
chain_id: number;
|
|
24
|
+
/** The forwarder address to pay on this chain. */
|
|
25
|
+
address: string;
|
|
26
|
+
/**
|
|
27
|
+
* Typical seconds from payment to credit at the confirmation this chain's payments are credited
|
|
28
|
+
* at: about 30 on Ethereum (two blocks), 7 on an OP-stack chain (three blocks), 300 under a
|
|
29
|
+
* `safe` policy, 900 at finality.
|
|
30
|
+
*/
|
|
31
|
+
typical_credit_seconds: number;
|
|
32
|
+
}
|
|
21
33
|
/**
|
|
22
34
|
* 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.
|
|
35
|
+
* returns it to a browser: its networks, and its payments in the last 24 hours, newest first.
|
|
24
36
|
*/
|
|
25
37
|
export interface ClientDepositAddress {
|
|
26
38
|
id: string;
|
|
27
39
|
object: "deposit_address";
|
|
28
40
|
livemode: boolean;
|
|
29
41
|
status: "active" | "retired";
|
|
42
|
+
networks: ClientDepositAddressNetwork[];
|
|
30
43
|
payments: DepositAddressPayment[];
|
|
31
44
|
}
|
|
32
45
|
export interface RetrieveDepositAddressOptions {
|
|
@@ -1 +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,
|
|
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,wEAAwE;AACxE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,CAAC;CAChC;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,2BAA2B,EAAE,CAAC;IACxC,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,CAsB9E"}
|
package/dist/deposit-address.js
CHANGED
|
@@ -34,11 +34,13 @@ export async function retrieveDepositAddress(options) {
|
|
|
34
34
|
/** Validates a response body against the public deposit address view; throws on anything else. */
|
|
35
35
|
export function parseClientDepositAddress(value) {
|
|
36
36
|
const v = record(value);
|
|
37
|
+
const networks = v["networks"];
|
|
37
38
|
const payments = v["payments"];
|
|
38
39
|
if (typeof v["id"] !== "string" ||
|
|
39
40
|
v["object"] !== "deposit_address" ||
|
|
40
41
|
typeof v["livemode"] !== "boolean" ||
|
|
41
42
|
(v["status"] !== "active" && v["status"] !== "retired") ||
|
|
43
|
+
!Array.isArray(networks) ||
|
|
42
44
|
!Array.isArray(payments)) {
|
|
43
45
|
throw new TypeError("response does not match the public deposit address view");
|
|
44
46
|
}
|
|
@@ -47,9 +49,25 @@ export function parseClientDepositAddress(value) {
|
|
|
47
49
|
object: "deposit_address",
|
|
48
50
|
livemode: v["livemode"],
|
|
49
51
|
status: v["status"],
|
|
52
|
+
networks: networks.map(parseNetwork),
|
|
50
53
|
payments: payments.map(parsePayment),
|
|
51
54
|
};
|
|
52
55
|
}
|
|
56
|
+
function parseNetwork(value) {
|
|
57
|
+
const n = record(value);
|
|
58
|
+
const seconds = n["typical_credit_seconds"];
|
|
59
|
+
if (!Number.isSafeInteger(n["chain_id"]) ||
|
|
60
|
+
typeof n["address"] !== "string" ||
|
|
61
|
+
!Number.isSafeInteger(seconds) ||
|
|
62
|
+
seconds < 0) {
|
|
63
|
+
throw new TypeError("network does not match the public deposit address view");
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
chain_id: n["chain_id"],
|
|
67
|
+
address: n["address"],
|
|
68
|
+
typical_credit_seconds: seconds,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
53
71
|
function parsePayment(value) {
|
|
54
72
|
const p = record(value);
|
|
55
73
|
const status = p["status"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deposit-address.js","sourceRoot":"","sources":["../src/deposit-address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
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,6 +1,6 @@
|
|
|
1
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
|
+
export { depositAddressIdFromClientSecret, parseClientDepositAddress, retrieveDepositAddress, type ClientDepositAddress, type ClientDepositAddressNetwork, type DepositAddressPayment, type RetrieveDepositAddressOptions, } from "./deposit-address.js";
|
|
4
4
|
export { knownChain, networkName, transactionUrl } from "./chains.js";
|
|
5
5
|
export { formatAmount, formatCountdown, formatTokenAmount, tokenAmount } from "./format.js";
|
|
6
6
|
export { depositAddressTransfer, parseTransferUri, quoteTransfer, type DepositAddressAsset, type DepositAddressDetails, type DepositAddressNetwork, type TokenTransfer, type TransferRequest, } from "./payment.js";
|
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,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"}
|
|
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,2BAA2B,EAChC,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.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,GAQd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAC7D,OAAO,EACL,gCAAgC,EAChC,yBAAyB,EACzB,sBAAsB,
|
|
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,GAKvB,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/quote.d.ts
CHANGED
|
@@ -40,7 +40,8 @@ export interface ClientQuote {
|
|
|
40
40
|
amount_credited: number | null;
|
|
41
41
|
/**
|
|
42
42
|
* Typical seconds from paying to the credit at the confirmation this quote's payments need:
|
|
43
|
-
* 30 on Ethereum (two blocks),
|
|
43
|
+
* 30 on Ethereum (two blocks), 7 on an OP-stack chain (three blocks), about 300 under a `safe`
|
|
44
|
+
* policy, 900 at finality.
|
|
44
45
|
*/
|
|
45
46
|
typical_credit_seconds: number;
|
|
46
47
|
}
|
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,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAC;IAClB,iGAAiG;IACjG,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;IACrD,iEAAiE;IACjE,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;IAC7B;;;;OAIG;IACH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B
|
|
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,iEAAiE;IACjE,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;IAC7B;;;;OAIG;IACH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAKD,oFAAoF;AACpF,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAMpE;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAiD5D"}
|
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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"}
|
|
@@ -10,7 +10,8 @@ export interface DepositAddressProps {
|
|
|
10
10
|
/**
|
|
11
11
|
* The `client_secret` of the same response. With `apiBase`, the component follows the
|
|
12
12
|
* address's payments and shows each one within about a block of arriving: received with its
|
|
13
|
-
* confirmations, then credited
|
|
13
|
+
* confirmations, then credited, and states each network's typical credit time. Display only;
|
|
14
|
+
* credit from your `deposit.credited` webhook.
|
|
14
15
|
*/
|
|
15
16
|
clientSecret?: string;
|
|
16
17
|
/** The service origin, for example `https://pay.example.com`; needed with `clientSecret`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DepositAddress.d.ts","sourceRoot":"","sources":["../../src/react/DepositAddress.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DepositAddress.d.ts","sourceRoot":"","sources":["../../src/react/DepositAddress.tsx"],"names":[],"mappings":"AAYA,OAAO,EAA0B,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAA2B,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAI3E,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,cAAc,EAAE,qBAAqB,CAAC;IACtC,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAC7B,cAAc,EACd,OAAO,EACP,KAAK,EACL,YAAY,EACZ,OAAO,EACP,YAAY,EACZ,UAAU,EACV,SAAS,GACV,EAAE,mBAAmB,+BA2FrB"}
|
|
@@ -5,6 +5,7 @@ import { formatUnits } from "viem";
|
|
|
5
5
|
import { networkName } from "../chains.js";
|
|
6
6
|
import { retrieveDepositAddress, } from "../deposit-address.js";
|
|
7
7
|
import { CheckoutError, pollDelay } from "../checkout.js";
|
|
8
|
+
import { formatWait } from "../format.js";
|
|
8
9
|
import { depositAddressTransfer } from "../payment.js";
|
|
9
10
|
import { STYLES, appearanceStyle } from "./appearance.js";
|
|
10
11
|
import { Field } from "./Field.js";
|
|
@@ -18,7 +19,8 @@ import { QrCode } from "./QrCode.js";
|
|
|
18
19
|
*/
|
|
19
20
|
export function DepositAddress({ depositAddress, chainId, asset, clientSecret, apiBase, pollInterval, appearance, className, }) {
|
|
20
21
|
const { networks } = depositAddress;
|
|
21
|
-
const
|
|
22
|
+
const view = useClientView(clientSecret, apiBase, pollInterval ?? 3000);
|
|
23
|
+
const payments = view?.payments ?? [];
|
|
22
24
|
const [selectedChain, setSelectedChain] = useState(chainId ?? networks[0]?.chain_id);
|
|
23
25
|
const [selectedAsset, setSelectedAsset] = useState(asset);
|
|
24
26
|
const network = networks.find((candidate) => candidate.chain_id === selectedChain) ?? networks[0];
|
|
@@ -39,14 +41,14 @@ export function DepositAddress({ depositAddress, chainId, asset, clientSecret, a
|
|
|
39
41
|
setSelectedChain(each.chain_id);
|
|
40
42
|
}, children: networkName(each.chain_id) }, each.chain_id))) })), network.assets.length > 1 && (_jsx("div", { className: "pp-tabs", role: "tablist", "aria-label": "Token", children: network.assets.map((each) => (_jsx("button", { type: "button", role: "tab", className: "pp-tab", "aria-selected": each.asset === token.asset, onClick: () => {
|
|
41
43
|
setSelectedAsset(each.asset);
|
|
42
|
-
}, children: each.asset.toUpperCase() }, each.asset))) })), _jsx("div", { className: "pp-qr-panel", children: _jsx(QrCode, { value: token.payment_uri, label: `Deposit address for ${symbol} on ${name}` }) }), _jsxs("dl", { className: "pp-fields", children: [_jsx(Field, { label: "Network", value: `${name} (chain ID ${network.chain_id})` }), _jsx(Field, { label: `Token (${symbol}) contract`, value: contract, copy: true }), _jsx(Field, { label: "Deposit address", value: to, copy: true })] }), payments.length > 0 && (_jsx("ul", { className: "pp-payments", "aria-live": "polite", "aria-label": "Payments", children: payments.map((payment) => (_jsx("li", { children: paymentMessage(payment) }, `${payment.chain_id}:${payment.tx_hash}:${payment.created}`))) })), _jsxs("p", { className: "pp-message", children: ["Send only ", tokens.join(", "), " on ", networks.map((each) => networkName(each.chain_id)).join(", "), ".
|
|
44
|
+
}, children: each.asset.toUpperCase() }, each.asset))) })), _jsx("div", { className: "pp-qr-panel", children: _jsx(QrCode, { value: token.payment_uri, label: `Deposit address for ${symbol} on ${name}` }) }), _jsxs("dl", { className: "pp-fields", children: [_jsx(Field, { label: "Network", value: `${name} (chain ID ${network.chain_id})` }), _jsx(Field, { label: `Token (${symbol}) contract`, value: contract, copy: true }), _jsx(Field, { label: "Deposit address", value: to, copy: true })] }), payments.length > 0 && (_jsx("ul", { className: "pp-payments", "aria-live": "polite", "aria-label": "Payments", children: payments.map((payment) => (_jsx("li", { children: paymentMessage(payment) }, `${payment.chain_id}:${payment.tx_hash}:${payment.created}`))) })), _jsxs("p", { className: "pp-message", children: ["Send only ", tokens.join(", "), " on ", networks.map((each) => networkName(each.chain_id)).join(", "), ". ", creditMessage(networks.map((each) => each.chain_id), view), " Other tokens and networks are not credited. You can reuse this address."] })] }));
|
|
43
45
|
}
|
|
44
|
-
/** The address's
|
|
45
|
-
function
|
|
46
|
+
/** The address's public view, read every `interval` while mounted; `null` without a secret. */
|
|
47
|
+
function useClientView(clientSecret, apiBase, interval) {
|
|
46
48
|
const key = clientSecret === undefined || apiBase === undefined ? "" : `${apiBase} ${clientSecret}`;
|
|
47
49
|
const [current, setCurrent] = useState({
|
|
48
50
|
key: "",
|
|
49
|
-
|
|
51
|
+
view: null,
|
|
50
52
|
});
|
|
51
53
|
useEffect(() => {
|
|
52
54
|
if (clientSecret === undefined || apiBase === undefined) {
|
|
@@ -61,7 +63,7 @@ function usePayments(clientSecret, apiBase, interval) {
|
|
|
61
63
|
const view = await retrieveDepositAddress({ clientSecret, apiBase });
|
|
62
64
|
failures = 0;
|
|
63
65
|
if (!stopped) {
|
|
64
|
-
setCurrent({ key,
|
|
66
|
+
setCurrent({ key, view });
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
catch (error) {
|
|
@@ -82,8 +84,31 @@ function usePayments(clientSecret, apiBase, interval) {
|
|
|
82
84
|
clearTimeout(timer);
|
|
83
85
|
};
|
|
84
86
|
}, [key, clientSecret, apiBase, interval]);
|
|
85
|
-
// Another address starts without the previous one's
|
|
86
|
-
return current.key === key && key !== "" ? current.
|
|
87
|
+
// Another address starts without the previous one's view.
|
|
88
|
+
return current.key === key && key !== "" ? current.view : null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* When a payment on each of `chainIds` is credited, from `view`'s typical credit times, for
|
|
92
|
+
* example "usually in about 30 seconds on Ethereum and about 7 seconds on Base". Before the view
|
|
93
|
+
* is loaded it names no time.
|
|
94
|
+
*/
|
|
95
|
+
function creditMessage(chainIds, view) {
|
|
96
|
+
const names = new Map();
|
|
97
|
+
for (const network of view?.networks ?? []) {
|
|
98
|
+
if (chainIds.includes(network.chain_id)) {
|
|
99
|
+
const seconds = network.typical_credit_seconds;
|
|
100
|
+
names.set(seconds, [...(names.get(seconds) ?? []), networkName(network.chain_id)]);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (names.size === 0) {
|
|
104
|
+
return "Any amount is credited at the market rate once it is confirmed on its network.";
|
|
105
|
+
}
|
|
106
|
+
const list = new Intl.ListFormat("en", { type: "conjunction" });
|
|
107
|
+
const [only, ...others] = names.keys();
|
|
108
|
+
const usually = only !== undefined && others.length === 0
|
|
109
|
+
? formatWait(only)
|
|
110
|
+
: list.format([...names].map(([seconds, on]) => `${formatWait(seconds)} on ${list.format(on)}`));
|
|
111
|
+
return `Any amount is credited at the market rate when it arrives, usually in ${usually}.`;
|
|
87
112
|
}
|
|
88
113
|
function paymentMessage(payment) {
|
|
89
114
|
const amount = payment.asset === null || payment.decimals === null
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DepositAddress.js","sourceRoot":"","sources":["../../src/react/DepositAddress.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EACL,sBAAsB,
|
|
1
|
+
{"version":3,"file":"DepositAddress.js","sourceRoot":"","sources":["../../src/react/DepositAddress.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phala/pay",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Phala Pay checkout: a framework-agnostic client and React bindings",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"crypto",
|
|
@@ -40,8 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"files": [
|
|
42
42
|
"dist",
|
|
43
|
-
"src"
|
|
44
|
-
"CHANGELOG.md"
|
|
43
|
+
"src"
|
|
45
44
|
],
|
|
46
45
|
"publishConfig": {
|
|
47
46
|
"access": "public"
|
package/src/deposit-address.ts
CHANGED
|
@@ -21,15 +21,29 @@ export interface DepositAddressPayment {
|
|
|
21
21
|
created: number;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/** A deposit address on one network, as the customer's page sees it. */
|
|
25
|
+
export interface ClientDepositAddressNetwork {
|
|
26
|
+
chain_id: number;
|
|
27
|
+
/** The forwarder address to pay on this chain. */
|
|
28
|
+
address: string;
|
|
29
|
+
/**
|
|
30
|
+
* Typical seconds from payment to credit at the confirmation this chain's payments are credited
|
|
31
|
+
* at: about 30 on Ethereum (two blocks), 7 on an OP-stack chain (three blocks), 300 under a
|
|
32
|
+
* `safe` policy, 900 at finality.
|
|
33
|
+
*/
|
|
34
|
+
typical_credit_seconds: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
24
37
|
/**
|
|
25
38
|
* The public view of a deposit address, as `GET /v1/deposit_addresses/{id}?client_secret=…`
|
|
26
|
-
* returns it to a browser: its payments in the last 24 hours, newest first.
|
|
39
|
+
* returns it to a browser: its networks, and its payments in the last 24 hours, newest first.
|
|
27
40
|
*/
|
|
28
41
|
export interface ClientDepositAddress {
|
|
29
42
|
id: string;
|
|
30
43
|
object: "deposit_address";
|
|
31
44
|
livemode: boolean;
|
|
32
45
|
status: "active" | "retired";
|
|
46
|
+
networks: ClientDepositAddressNetwork[];
|
|
33
47
|
payments: DepositAddressPayment[];
|
|
34
48
|
}
|
|
35
49
|
|
|
@@ -79,12 +93,14 @@ export async function retrieveDepositAddress(
|
|
|
79
93
|
/** Validates a response body against the public deposit address view; throws on anything else. */
|
|
80
94
|
export function parseClientDepositAddress(value: unknown): ClientDepositAddress {
|
|
81
95
|
const v = record(value);
|
|
96
|
+
const networks = v["networks"];
|
|
82
97
|
const payments = v["payments"];
|
|
83
98
|
if (
|
|
84
99
|
typeof v["id"] !== "string" ||
|
|
85
100
|
v["object"] !== "deposit_address" ||
|
|
86
101
|
typeof v["livemode"] !== "boolean" ||
|
|
87
102
|
(v["status"] !== "active" && v["status"] !== "retired") ||
|
|
103
|
+
!Array.isArray(networks) ||
|
|
88
104
|
!Array.isArray(payments)
|
|
89
105
|
) {
|
|
90
106
|
throw new TypeError("response does not match the public deposit address view");
|
|
@@ -94,10 +110,29 @@ export function parseClientDepositAddress(value: unknown): ClientDepositAddress
|
|
|
94
110
|
object: "deposit_address",
|
|
95
111
|
livemode: v["livemode"],
|
|
96
112
|
status: v["status"],
|
|
113
|
+
networks: networks.map(parseNetwork),
|
|
97
114
|
payments: payments.map(parsePayment),
|
|
98
115
|
};
|
|
99
116
|
}
|
|
100
117
|
|
|
118
|
+
function parseNetwork(value: unknown): ClientDepositAddressNetwork {
|
|
119
|
+
const n = record(value);
|
|
120
|
+
const seconds = n["typical_credit_seconds"];
|
|
121
|
+
if (
|
|
122
|
+
!Number.isSafeInteger(n["chain_id"]) ||
|
|
123
|
+
typeof n["address"] !== "string" ||
|
|
124
|
+
!Number.isSafeInteger(seconds) ||
|
|
125
|
+
(seconds as number) < 0
|
|
126
|
+
) {
|
|
127
|
+
throw new TypeError("network does not match the public deposit address view");
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
chain_id: n["chain_id"] as number,
|
|
131
|
+
address: n["address"],
|
|
132
|
+
typical_credit_seconds: seconds as number,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
101
136
|
function parsePayment(value: unknown): DepositAddressPayment {
|
|
102
137
|
const p = record(value);
|
|
103
138
|
const status = p["status"];
|
package/src/index.ts
CHANGED
package/src/quote.ts
CHANGED
|
@@ -40,7 +40,8 @@ export interface ClientQuote {
|
|
|
40
40
|
amount_credited: number | null;
|
|
41
41
|
/**
|
|
42
42
|
* Typical seconds from paying to the credit at the confirmation this quote's payments need:
|
|
43
|
-
* 30 on Ethereum (two blocks),
|
|
43
|
+
* 30 on Ethereum (two blocks), 7 on an OP-stack chain (three blocks), about 300 under a `safe`
|
|
44
|
+
* policy, 900 at finality.
|
|
44
45
|
*/
|
|
45
46
|
typical_credit_seconds: number;
|
|
46
47
|
}
|
|
@@ -5,9 +5,11 @@ import { formatUnits } from "viem";
|
|
|
5
5
|
import { networkName } from "../chains.js";
|
|
6
6
|
import {
|
|
7
7
|
retrieveDepositAddress,
|
|
8
|
+
type ClientDepositAddress,
|
|
8
9
|
type DepositAddressPayment,
|
|
9
10
|
} from "../deposit-address.js";
|
|
10
11
|
import { CheckoutError, pollDelay } from "../checkout.js";
|
|
12
|
+
import { formatWait } from "../format.js";
|
|
11
13
|
import { depositAddressTransfer, type DepositAddressDetails } from "../payment.js";
|
|
12
14
|
import { STYLES, appearanceStyle, type Appearance } from "./appearance.js";
|
|
13
15
|
import { Field } from "./Field.js";
|
|
@@ -23,7 +25,8 @@ export interface DepositAddressProps {
|
|
|
23
25
|
/**
|
|
24
26
|
* The `client_secret` of the same response. With `apiBase`, the component follows the
|
|
25
27
|
* address's payments and shows each one within about a block of arriving: received with its
|
|
26
|
-
* confirmations, then credited
|
|
28
|
+
* confirmations, then credited, and states each network's typical credit time. Display only;
|
|
29
|
+
* credit from your `deposit.credited` webhook.
|
|
27
30
|
*/
|
|
28
31
|
clientSecret?: string;
|
|
29
32
|
/** The service origin, for example `https://pay.example.com`; needed with `clientSecret`. */
|
|
@@ -52,7 +55,8 @@ export function DepositAddress({
|
|
|
52
55
|
className,
|
|
53
56
|
}: DepositAddressProps) {
|
|
54
57
|
const { networks } = depositAddress;
|
|
55
|
-
const
|
|
58
|
+
const view = useClientView(clientSecret, apiBase, pollInterval ?? 3000);
|
|
59
|
+
const payments = view?.payments ?? [];
|
|
56
60
|
const [selectedChain, setSelectedChain] = useState(chainId ?? networks[0]?.chain_id);
|
|
57
61
|
const [selectedAsset, setSelectedAsset] = useState(asset);
|
|
58
62
|
const network = networks.find((candidate) => candidate.chain_id === selectedChain) ?? networks[0];
|
|
@@ -135,23 +139,23 @@ export function DepositAddress({
|
|
|
135
139
|
)}
|
|
136
140
|
<p className="pp-message">
|
|
137
141
|
Send only {tokens.join(", ")} on {networks.map((each) => networkName(each.chain_id)).join(", ")}
|
|
138
|
-
.
|
|
139
|
-
|
|
142
|
+
. {creditMessage(networks.map((each) => each.chain_id), view)} Other tokens and networks are not
|
|
143
|
+
credited. You can reuse this address.
|
|
140
144
|
</p>
|
|
141
145
|
</div>
|
|
142
146
|
);
|
|
143
147
|
}
|
|
144
148
|
|
|
145
|
-
/** The address's
|
|
146
|
-
function
|
|
149
|
+
/** The address's public view, read every `interval` while mounted; `null` without a secret. */
|
|
150
|
+
function useClientView(
|
|
147
151
|
clientSecret: string | undefined,
|
|
148
152
|
apiBase: string | undefined,
|
|
149
153
|
interval: number,
|
|
150
|
-
):
|
|
154
|
+
): ClientDepositAddress | null {
|
|
151
155
|
const key = clientSecret === undefined || apiBase === undefined ? "" : `${apiBase} ${clientSecret}`;
|
|
152
|
-
const [current, setCurrent] = useState<{ key: string;
|
|
156
|
+
const [current, setCurrent] = useState<{ key: string; view: ClientDepositAddress | null }>({
|
|
153
157
|
key: "",
|
|
154
|
-
|
|
158
|
+
view: null,
|
|
155
159
|
});
|
|
156
160
|
useEffect(() => {
|
|
157
161
|
if (clientSecret === undefined || apiBase === undefined) {
|
|
@@ -166,7 +170,7 @@ function usePayments(
|
|
|
166
170
|
const view = await retrieveDepositAddress({ clientSecret, apiBase });
|
|
167
171
|
failures = 0;
|
|
168
172
|
if (!stopped) {
|
|
169
|
-
setCurrent({ key,
|
|
173
|
+
setCurrent({ key, view });
|
|
170
174
|
}
|
|
171
175
|
} catch (error) {
|
|
172
176
|
failures += 1;
|
|
@@ -186,8 +190,33 @@ function usePayments(
|
|
|
186
190
|
clearTimeout(timer);
|
|
187
191
|
};
|
|
188
192
|
}, [key, clientSecret, apiBase, interval]);
|
|
189
|
-
// Another address starts without the previous one's
|
|
190
|
-
return current.key === key && key !== "" ? current.
|
|
193
|
+
// Another address starts without the previous one's view.
|
|
194
|
+
return current.key === key && key !== "" ? current.view : null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* When a payment on each of `chainIds` is credited, from `view`'s typical credit times, for
|
|
199
|
+
* example "usually in about 30 seconds on Ethereum and about 7 seconds on Base". Before the view
|
|
200
|
+
* is loaded it names no time.
|
|
201
|
+
*/
|
|
202
|
+
function creditMessage(chainIds: number[], view: ClientDepositAddress | null): string {
|
|
203
|
+
const names = new Map<number, string[]>();
|
|
204
|
+
for (const network of view?.networks ?? []) {
|
|
205
|
+
if (chainIds.includes(network.chain_id)) {
|
|
206
|
+
const seconds = network.typical_credit_seconds;
|
|
207
|
+
names.set(seconds, [...(names.get(seconds) ?? []), networkName(network.chain_id)]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (names.size === 0) {
|
|
211
|
+
return "Any amount is credited at the market rate once it is confirmed on its network.";
|
|
212
|
+
}
|
|
213
|
+
const list = new Intl.ListFormat("en", { type: "conjunction" });
|
|
214
|
+
const [only, ...others] = names.keys();
|
|
215
|
+
const usually =
|
|
216
|
+
only !== undefined && others.length === 0
|
|
217
|
+
? formatWait(only)
|
|
218
|
+
: list.format([...names].map(([seconds, on]) => `${formatWait(seconds)} on ${list.format(on)}`));
|
|
219
|
+
return `Any amount is credited at the market rate when it arrives, usually in ${usually}.`;
|
|
191
220
|
}
|
|
192
221
|
|
|
193
222
|
function paymentMessage(payment: DepositAddressPayment): string {
|
package/CHANGELOG.md
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to `@phala/pay` are recorded here. The format follows
|
|
4
|
-
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
|
|
5
|
-
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
-
|
|
7
|
-
## [Unreleased]
|
|
8
|
-
|
|
9
|
-
## [0.4.0] - 2026-10-01
|
|
10
|
-
|
|
11
|
-
### Added
|
|
12
|
-
|
|
13
|
-
- `payWithWallet` reads the account's token balance before sending and, when it is below the
|
|
14
|
-
quote's amount, sends nothing and throws `WalletError` with the new code
|
|
15
|
-
`insufficient_balance`: the transfer would revert and still cost gas. `<Checkout>` shows the
|
|
16
|
-
error's message (what the wallet holds and what the quote needs). A wallet that cannot read the
|
|
17
|
-
balance still pays.
|
|
18
|
-
- `<Checkout onWalletError>`: called with the `WalletError` and the wallet it tried (the chosen
|
|
19
|
-
browser wallet's provider, or `walletClient`) when the wallet tab could not send the payment, for
|
|
20
|
-
example to offer your own way to fund that wallet on `insufficient_balance`.
|
|
21
|
-
- `ClientQuote.amount_credited`, what a credited payment credited in cents (it differs from
|
|
22
|
-
`amount` for a payment of another amount or a late one), and `ClientQuote.typical_credit_seconds`,
|
|
23
|
-
the typical credit time at the quote's confirmation.
|
|
24
|
-
|
|
25
|
-
### Changed (breaking)
|
|
26
|
-
|
|
27
|
-
- `parseClientQuote`, and so `<Checkout>` and `createCheckout`, require `amount_credited` (an
|
|
28
|
-
integer or `null`) and `typical_credit_seconds`, which the service sends from v0.3.4: upgrade
|
|
29
|
-
the service before the SDK.
|
|
30
|
-
|
|
31
|
-
### Fixed
|
|
32
|
-
|
|
33
|
-
- `<Checkout>` showed the quoted amount as credited ("Payment credited: $25.00" for a $25 quote
|
|
34
|
-
paid with $10). It now shows what was credited and, when that differs from the quote, says so
|
|
35
|
-
("Payment credited: $10.00 of $25.00"); `onSuccess(quote)` carries it as `amount_credited`.
|
|
36
|
-
- `<Checkout>` told a payer "crediting in about 30 seconds" on every chain. It now states the
|
|
37
|
-
quote's typical wait: about 5 minutes at Base's `safe` block, 15 minutes under a `finalized`
|
|
38
|
-
policy.
|
|
39
|
-
|
|
40
|
-
## [0.3.0] - 2026-10-01
|
|
41
|
-
|
|
42
|
-
### Changed (breaking)
|
|
43
|
-
|
|
44
|
-
- `constructEvent` takes webhook public keys only in Standard Webhooks' `whpk_` form (`whpk_` and
|
|
45
|
-
the standard base64 of the key), as `GET /v1/attestation` lists them; a hex or bare base64 key
|
|
46
|
-
is refused.
|
|
47
|
-
- `parseClientQuote` requires `confirmations`, an integer or `null`, as the service always sends
|
|
48
|
-
it.
|
|
49
|
-
- `constructEvent` requires the event's `actor` and `request` (`null` or the causing request), as
|
|
50
|
-
the service always sends them, and refuses an envelope without them; `WebhookEvent.actor` and
|
|
51
|
-
`request` are no longer optional.
|
|
52
|
-
|
|
53
|
-
### Fixed
|
|
54
|
-
|
|
55
|
-
- `constructEvent` returns the event's `request` (the causing API request's `id` and
|
|
56
|
-
`idempotency_key`, or `null`), as `WebhookEvent` declares; it was dropped. A malformed `request`
|
|
57
|
-
is refused like any malformed event.
|
|
58
|
-
|
|
59
|
-
## [0.2.0] - 2026-09-29
|
|
60
|
-
|
|
61
|
-
### Changed (breaking)
|
|
62
|
-
|
|
63
|
-
- `quoteAddress(forwarder, quote, treasury, account)` takes the treasury explicitly, like
|
|
64
|
-
`depositAddress`; it no longer reads the quote's own `treasury`, which a compromised service
|
|
65
|
-
could set to an attacker's with that treasury's valid address.
|
|
66
|
-
|
|
67
|
-
- `quoteSalt(account, clientReferenceId, quoteId)` replaces `lockSalt`: a quote's address salt is
|
|
68
|
-
tagged `"quote"` (design D3; it was `"lock"`), so `quoteAddress` recomputes the service's
|
|
69
|
-
addresses again.
|
|
70
|
-
|
|
71
|
-
- `<Checkout expectedAddress>` is required, as are `expectedAddress` in `createCheckout`,
|
|
72
|
-
`useCheckout`, `PhalaPay.checkout(clientSecret, { expectedAddress })`, and the second argument of
|
|
73
|
-
`retrieveQuote`/`PhalaPay.retrieveQuote`: the address your backend recomputed. A quote naming
|
|
74
|
-
another address fails closed with `CheckoutError` `address_mismatch`; the component shows
|
|
75
|
-
nothing to pay.
|
|
76
|
-
- `ClientQuote` has `livemode` (the checkout shows "Test mode") and `payment_status: "reversed"`;
|
|
77
|
-
`CheckoutStatus` gains `reversed`, with "reversed" copy.
|
|
78
|
-
|
|
79
|
-
### Added
|
|
80
|
-
|
|
81
|
-
- `verifyQuoteAddress(pins, quote)` and `verifyDepositAddress(pins, address)` in
|
|
82
|
-
`@phala/pay/server` recompute an address from `AddressPins` you configure (`account`, `factory`,
|
|
83
|
-
`implementation`, `treasuries` per chain), never from the response's treasury, and throw
|
|
84
|
-
`AddressMismatchError`; in live mode a chain without a pinned treasury fails closed, and test mode
|
|
85
|
-
falls back to the response's treasury with a console warning.
|
|
86
|
-
|
|
87
|
-
- `CheckoutError.requestId` (the failed response's `Request-Id`) and, for `rate_limited`,
|
|
88
|
-
`retryAfter` (its `Retry-After`, in seconds), which `createCheckout` and `<DepositAddress>` wait
|
|
89
|
-
before reading again.
|
|
90
|
-
- `WebhookEvent.request` (the request that caused the event, or `null` for the service's
|
|
91
|
-
workers) and the documented `data.previous_attributes` of `*.updated` events.
|
|
92
|
-
|
|
93
|
-
- `<DepositAddress clientSecret apiBase pollInterval?>` follows the address's payments and shows
|
|
94
|
-
each within about a block of arriving ("1.5 PHA received on Sepolia, 1 confirmation"), then
|
|
95
|
-
credited, rejected, or reversed; `retrieveDepositAddress`, `parseClientDepositAddress`, and
|
|
96
|
-
`depositAddressIdFromClientSecret` read the same public view.
|
|
97
|
-
- `@phala/pay/server`, which takes no secret key: `constructEvent(payload, headers, publicKeys,
|
|
98
|
-
{ expectedAccount, expectedLivemode })` verifies Standard Webhooks `v1a` deliveries with
|
|
99
|
-
WebCrypto (Node 20+, Deno, Bun, edge runtimes), failing closed for another account or mode;
|
|
100
|
-
`forwarderAddress`, `quoteSalt`, `depositAddressSalt`, `quoteAddress`, and `depositAddress`
|
|
101
|
-
recompute addresses; `flushTransaction`, `flushTransactions`, `safeBatch`, and `batchChecksum`
|
|
102
|
-
build sweeps offline, with the Transaction Builder's `BatchFile` type.
|
|
103
|
-
|
|
104
|
-
- `<DepositAddress depositAddress chainId? asset?>` (`@phala/pay/react`): a customer's persistent
|
|
105
|
-
deposit address, one address for all supported tokens and networks. The payer picks a network
|
|
106
|
-
and a token; it shows a QR code of that token's EIP-681 request, the token contract and address
|
|
107
|
-
to copy (each network's own address where they differ), and "send only supported tokens; any
|
|
108
|
-
amount, credited at the market rate when it arrives" copy. `depositAddressTransfer(network,
|
|
109
|
-
asset)` reads and checks one token's amount-less `payment_uri`, and `parseTransferUri(uri)` is
|
|
110
|
-
the EIP-681 ERC-20 transfer parser `quoteTransfer` uses.
|
|
111
|
-
|
|
112
|
-
- `<Checkout walletClient>` and `payWithWallet(walletClient, quote)`: pay with the page's own viem
|
|
113
|
-
`WalletClient`, such as wagmi's `useWalletClient()` (RainbowKit, ConnectKit, AppKit). The wallet
|
|
114
|
-
tab then uses its account and switches its chain, without listing the browser's wallets.
|
|
115
|
-
|
|
116
|
-
### Changed
|
|
117
|
-
|
|
118
|
-
- `<Checkout>` copy for fast credit: a seen payment reads "Payment received, N confirmations.
|
|
119
|
-
Crediting in about 30 seconds"; `confirming` and `credited` are documented for crediting at the
|
|
120
|
-
route's confirmation (two blocks on Ethereum) instead of finality.
|
|
121
|
-
- `watchWallets` discovers EIP-6963 wallets through [mipd](https://github.com/wevm/mipd), wagmi's
|
|
122
|
-
discovery store, now a dependency; the `window.ethereum` fallback stays. Wallet errors are
|
|
123
|
-
classified with viem's `UserRejectedRequestError` and `SwitchChainError`.
|
|
124
|
-
|
|
125
|
-
## [0.1.2] - 2026-09-27
|
|
126
|
-
|
|
127
|
-
### Added
|
|
128
|
-
|
|
129
|
-
- `CheckoutError.requestId` (the failed response's `Request-Id`) and, for `rate_limited`,
|
|
130
|
-
`retryAfter` (its `Retry-After`, in seconds), which `createCheckout` and `<DepositAddress>` wait
|
|
131
|
-
before reading again.
|
|
132
|
-
- `WebhookEvent.request` (the request that caused the event, or `null` for the service's
|
|
133
|
-
workers) and the documented `data.previous_attributes` of `*.updated` events.
|
|
134
|
-
|
|
135
|
-
- `<Checkout onChange>`: called once per status change with `{ status, quote, error }`, like
|
|
136
|
-
Stripe Elements' `onChange`, so the page can react to `seen` or `confirming` without its own
|
|
137
|
-
polling.
|
|
138
|
-
|
|
139
|
-
### Fixed
|
|
140
|
-
|
|
141
|
-
- The transaction link in `<Checkout>` uses the text color with an underline instead of
|
|
142
|
-
`colorPrimary`, so it stays readable with a light brand color.
|
|
143
|
-
|
|
144
|
-
## [0.1.1] - 2026-09-27
|
|
145
|
-
|
|
146
|
-
### Added
|
|
147
|
-
|
|
148
|
-
- `CheckoutError.requestId` (the failed response's `Request-Id`) and, for `rate_limited`,
|
|
149
|
-
`retryAfter` (its `Retry-After`, in seconds), which `createCheckout` and `<DepositAddress>` wait
|
|
150
|
-
before reading again.
|
|
151
|
-
- `WebhookEvent.request` (the request that caused the event, or `null` for the service's
|
|
152
|
-
workers) and the documented `data.previous_attributes` of `*.updated` events.
|
|
153
|
-
|
|
154
|
-
- `appearance.variables.accessibleColorOnColorPrimary` (`--pp-accessible-color-on-color-primary`,
|
|
155
|
-
default `#ffffff`): the color of text on a `colorPrimary` background, such as the pay button's
|
|
156
|
-
label, so a light brand primary stays readable. Same name and meaning as Stripe's current
|
|
157
|
-
Appearance API variable.
|
|
158
|
-
|
|
159
|
-
### Fixed
|
|
160
|
-
|
|
161
|
-
- `<Checkout>` shows the full transaction hash after a wallet payment, wrapping in monospace,
|
|
162
|
-
instead of truncating it, so a payer can verify every character; a long token amount wraps
|
|
163
|
-
instead of overflowing.
|
|
164
|
-
|
|
165
|
-
## [0.1.0] - 2026-09-27
|
|
166
|
-
|
|
167
|
-
### Added
|
|
168
|
-
|
|
169
|
-
- `CheckoutError.requestId` (the failed response's `Request-Id`) and, for `rate_limited`,
|
|
170
|
-
`retryAfter` (its `Retry-After`, in seconds), which `createCheckout` and `<DepositAddress>` wait
|
|
171
|
-
before reading again.
|
|
172
|
-
- `WebhookEvent.request` (the request that caused the event, or `null` for the service's
|
|
173
|
-
workers) and the documented `data.previous_attributes` of `*.updated` events.
|
|
174
|
-
|
|
175
|
-
- `PhalaPay({ apiBase })`: `retrieveQuote(clientSecret)` reads a quote's public view
|
|
176
|
-
(`GET /v1/quotes/{id}?client_secret=…`) and `checkout(clientSecret)` follows it, exposing the
|
|
177
|
-
payer-facing status (also `createCheckout` and `retrieveQuote`).
|
|
178
|
-
- `watchWallets` (EIP-6963, `window.ethereum` fallback) and `payWithWallet`: pay a quote's EIP-681
|
|
179
|
-
ERC-20 transfer from a browser wallet, switching or adding the chain.
|
|
180
|
-
- `@phala/pay/react`: `<Checkout>` with wallet ("Pay with crypto", `buttonText`), QR code, and
|
|
181
|
-
manual payment, live status, and Stripe-style `appearance`; `useCheckout`.
|
|
182
|
-
- `formatTokenAmount(quote, locale?)` shows the exact token amount grouped for the locale and
|
|
183
|
-
without trailing zeros (`1,273.9185`); `tokenAmount(quote)` is the plain decimal a wallet
|
|
184
|
-
accepts, which `<Checkout>`'s "Exact amount" copies.
|
|
185
|
-
|
|
186
|
-
[unreleased]: https://github.com/Phala-Network/phala-pay/compare/sdk-js-v0.4.0...HEAD
|
|
187
|
-
[0.4.0]: https://github.com/Phala-Network/phala-pay/compare/sdk-js-v0.3.0...sdk-js-v0.4.0
|
|
188
|
-
[0.3.0]: https://github.com/Phala-Network/phala-pay/compare/sdk-js-v0.2.0...sdk-js-v0.3.0
|
|
189
|
-
[0.2.0]: https://github.com/Phala-Network/phala-pay/compare/sdk-js-v0.1.2...sdk-js-v0.2.0
|
|
190
|
-
[0.1.2]: https://github.com/Phala-Network/phala-pay/compare/sdk-js-v0.1.1...sdk-js-v0.1.2
|
|
191
|
-
[0.1.1]: https://github.com/Phala-Network/phala-pay/compare/sdk-js-v0.1.0...sdk-js-v0.1.1
|
|
192
|
-
[0.1.0]: https://github.com/Phala-Network/phala-pay/releases/tag/sdk-js-v0.1.0
|