@mysten-incubation/suipay 0.0.0-stage → 0.2.0-dev.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 +103 -2
- package/dist/index.d.ts +2942 -0
- package/dist/index.js +10970 -0
- package/package.json +45 -3
package/README.md
CHANGED
|
@@ -1,3 +1,104 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @mysten-incubation/suipay
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Embeddable SuiPay client for app developers. Quote a 402 resource and pay it
|
|
4
|
+
from a spend-account grant. This package does **not** bake hosted gateway URLs
|
|
5
|
+
— pass `gatewayUrl` yourself.
|
|
6
|
+
|
|
7
|
+
## 30-second quickstart
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { createClient } from '@mysten-incubation/suipay';
|
|
11
|
+
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
|
|
12
|
+
|
|
13
|
+
const keypair = Ed25519Keypair.fromSecretKey(/* 32-byte seed */);
|
|
14
|
+
|
|
15
|
+
const client = await createClient({
|
|
16
|
+
gatewayUrl: process.env.SUIPAY_GATEWAY_URL!,
|
|
17
|
+
keypair,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const url = 'https://gateway.example/v1/image/generate';
|
|
21
|
+
const result = await client.pay(url, {
|
|
22
|
+
json: { prompt: 'a small red circle' },
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`pay` quotes that POST, then pays the quoted price. You do not pass atomic
|
|
27
|
+
units. `result.quote` is the price it agreed to, and `result.paid` says whether
|
|
28
|
+
settlement finished.
|
|
29
|
+
|
|
30
|
+
`createClient` throws if `gatewayUrl` or `keypair` is missing. The key must
|
|
31
|
+
already have a live spend-account grant on that gateway. A body makes the
|
|
32
|
+
request POST; a GET resource is `pay(url, { method: 'GET' })`. To show the
|
|
33
|
+
price before spending, call `quote` first and pass it back:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const quote = await client.quote(url, { body: JSON.stringify({ prompt: '...' }) });
|
|
37
|
+
const result = await client.pay(url, { quote });
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Passing `quote` pins `payTo` and replays that quote's method, body, and
|
|
41
|
+
content type. A later offer cannot swap the recipient or the coin. `maxAmount`
|
|
42
|
+
can only tighten the quoted price, not raise it. A different body or content
|
|
43
|
+
type is refused before anything is signed.
|
|
44
|
+
|
|
45
|
+
## Errors — branch on `code`
|
|
46
|
+
|
|
47
|
+
A caller mistake caught before anything is quoted or signed (a missing
|
|
48
|
+
`gatewayUrl`, a URL off the gateway origin, `json` and `body` together) is
|
|
49
|
+
**thrown** as a `SuiPayError`. A failed quote throws one too. Once a payment
|
|
50
|
+
is attempted, `pay` **returns** the result instead: a failed or ambiguous
|
|
51
|
+
`PayResult` carries `code`, `paymentState`, `retryable`, `nextAction`,
|
|
52
|
+
`detail`, and `txDigest` / `paymentId` / `challengeId` when known.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { SuiPayError, toErrorFields } from '@mysten-incubation/suipay';
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const result = await client.pay(url, { json: { prompt: 'a small red circle' } });
|
|
59
|
+
if (result.status !== 'ok') {
|
|
60
|
+
// Money first: `paymentState` always agrees with `paid`.
|
|
61
|
+
if (result.paymentState !== 'not_charged') {
|
|
62
|
+
console.log('do not pay again; reconcile', result.paymentId);
|
|
63
|
+
} else if (result.retryable) {
|
|
64
|
+
console.log('safe to retry');
|
|
65
|
+
} else {
|
|
66
|
+
console.log(result.code, result.nextAction); // branch on code, never on detail
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} catch (err) {
|
|
70
|
+
const fields = err instanceof SuiPayError ? err : toErrorFields(err);
|
|
71
|
+
console.log(fields.code, fields.nextAction);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`status` keeps its meaning: `failed` only when nothing was charged,
|
|
76
|
+
`ambiguous` when money moved or may have. `ErrorCode`, `PaymentState` and
|
|
77
|
+
`NextAction` are exported, so a `switch` over `ErrorCode` can be exhaustive.
|
|
78
|
+
|
|
79
|
+
## Which package?
|
|
80
|
+
|
|
81
|
+
| Install | Use it when |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| `@mysten-incubation/suipay` | An app needs `quote` + `pay` against a 402. This barrel. |
|
|
84
|
+
| `@mysten-incubation/suipay-buyer` | You need the typed `/v1` control plane, connection manifests, or `createPayer` directly. |
|
|
85
|
+
| `@mysten-incubation/suipay-mcp` | An MCP host (Claude, Codex, …) should log in, discover, and pay. |
|
|
86
|
+
|
|
87
|
+
Sellers copy `apps/seller-template` (and `@suipay/seller-runtime` inside the
|
|
88
|
+
repo). There is **no** published seller SDK.
|
|
89
|
+
|
|
90
|
+
Do not publish or depend on `@cmdoss/suipay-core` or `@cmdoss/suipay-sdk`.
|
|
91
|
+
Those stay private; this tarball bundles what it needs.
|
|
92
|
+
|
|
93
|
+
## Build (this repo)
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pnpm --filter @mysten-incubation/suipay test
|
|
97
|
+
pnpm --filter @mysten-incubation/suipay build
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Publishing is the `release-npm` workflow: merge to `dev` publishes
|
|
101
|
+
`@mysten-incubation/suipay@<version>-dev.N` with dist-tag `dev` (OIDC, pack gate,
|
|
102
|
+
provenance). `latest` is a gated dispatch from `main` (`dry_run` default
|
|
103
|
+
true). Do not `npm publish` from a laptop. See
|
|
104
|
+
[`docs/guide/npm-release.md`](../../docs/guide/npm-release.md).
|