@defuse-protocol/nearintents-mpp-sdk 0.1.0 → 0.1.2

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.
Files changed (2) hide show
  1. package/README.md +36 -37
  2. package/package.json +4 -3
package/README.md CHANGED
@@ -30,7 +30,7 @@ const mppx = Mppx.create({
30
30
  })
31
31
  ```
32
32
 
33
- Client (policy is the safety surface the client pays before delivery):
33
+ Client (`policy` as safety surface, the client pays before delivery):
34
34
 
35
35
  ```ts
36
36
  import { Mppx } from 'mppx/client'
@@ -61,6 +61,27 @@ configured. Without one, the client will pay any authentic challenge the
61
61
  server presents; the policy is the client's safety surface since it pays
62
62
  before delivery.
63
63
 
64
+ ## How it works
65
+
66
+ 1. The server answers an unpaid request with `402` + `WWW-Authenticate:
67
+ Payment` whose `request` carries a unique, single-use **1Click deposit
68
+ address** as `recipient`, the origin-chain leg the client pays (`amount`,
69
+ `currency`), and the merchant's destination leg in `methodDetails`.
70
+ 2. The client pays the source asset on its origin chain and retries with the
71
+ confirmed transaction hash as a `{type: "hash"}` credential.
72
+ 3. The server verifies the deposit via the 1Click status endpoint, drives the
73
+ cross-chain swap to `SUCCESS`, and returns the resource with a
74
+ `Payment-Receipt` carrying `challengeId`, `originTxHash`, and the
75
+ destination-chain delivery hash.
76
+
77
+ Quotes use `EXACT_OUTPUT`, so the merchant receives a deterministic amount of
78
+ its chosen asset on its chosen chain.
79
+
80
+ Note that settlement is not trustless: deposits are custodied by the NEAR Intents
81
+ settlement system for the duration of the swap, with automatic refunds
82
+ to `methodDetails.refundTo` on every non-success outcome.
83
+ See the spec's Trust Model section.
84
+
64
85
  ## Demo
65
86
 
66
87
  [`demo/`](demo/README.md) is a browser storefront that runs the real client in
@@ -88,14 +109,13 @@ Arbitrum account and run `pnpm example:client`, or send the deposit yourself
88
109
  and re-run with `DEPOSIT_TX_HASH=0x…`. The client refuses anything beyond its
89
110
  configured `policy.maxAmountIn` caps.
90
111
 
112
+ For operator-only live 1Click smoke testing, `examples/live-oneclick-smoke.ts`
113
+ can be run with `pnpm example:live-oneclick-smoke`. It refuses to contact the
114
+ live provider unless `LIVE_ONE_CLICK=1`, prints deposit instructions in one
115
+ invocation, then polls a separately funded deposit in a second invocation.
116
+
91
117
  ## Operational notes
92
118
 
93
- - **Trust model.** Settlement is not trustless: for the duration of the swap
94
- the deposit is custodied by the NEAR Intents settlement system
95
- (`methodDetails.settlementBackend: "near-intents"`), which either delivers
96
- the destination asset to the merchant or refunds the deposit. Comparable to
97
- entrusting a payment processor with a transfer; agents applying per-method
98
- risk policies can key off the `method` and `settlementBackend` fields.
99
119
  - **Refunds.** `methodDetails.refundTo` is a **merchant-configured** address
100
120
  on the origin chain (the server cannot know the payer before payment).
101
121
  Every non-success terminal refunds the deposit there; payers recover
@@ -118,10 +138,6 @@ configured `policy.maxAmountIn` caps.
118
138
  top-up (that is async-delivery territory, out of scope here). Backend
119
139
  aggregation of multiple deposits that reach `SUCCESS` *is* honored: any one
120
140
  of the observed origin-chain tx hashes is accepted as the credential.
121
- - **Per-origin minimums.** Bridged origins enforce minimum deposit amounts
122
- (e.g. native BTC rides the PoA bridge, minimum ≈ a few USD at the time of
123
- writing — live 1Click rejects quotes below it with `400 Amount is too low
124
- for bridge`). Micro-prices belong on fast, cheap origins like Arbitrum/Base.
125
141
  - **Slow settlements.** `verify` holds the connection at most
126
142
  `settlementTimeout` seconds, then returns **504** with a problem body —
127
143
  the credential is *not* consumed and the client re-presents the same
@@ -132,6 +148,12 @@ configured `policy.maxAmountIn` caps.
132
148
  - **After a failed settlement** the immediate 402 echoes the spent challenge
133
149
  (mppx computes the retry challenge before `verify` runs); the client's next
134
150
  request receives a fresh quote. Conformant clients re-request on 402.
151
+ - **Trust model.** Settlement is not trustless: for the duration of the swap
152
+ the deposit is custodied by the NEAR Intents settlement system
153
+ (`methodDetails.settlementBackend: "near-intents"`), which either delivers
154
+ the destination asset to the merchant or refunds the deposit. Comparable to
155
+ entrusting a payment processor with a transfer; agents applying per-method
156
+ risk policies can key off the `method` and `settlementBackend` fields.
135
157
 
136
158
  ## Observability
137
159
 
@@ -154,8 +176,7 @@ mppx.on('payment.failed', ({ error }) => logger.warn(error.type, error.message))
154
176
  ```
155
177
 
156
178
  `settlement.suspended` (backend unavailable / settlement timeout) means the
157
- credential was **not** consumed and the client will re-present it. Handler
158
- errors are swallowed — observers can never affect payment processing. The
179
+ credential was **not** consumed and the client will re-present it. The
159
180
  example and demo servers wire `onEvent` to the console, so `pnpm
160
181
  example:server` shows each payment progressing live. Everything the events
161
182
  carry (deposit addresses, tx hashes) is public on-chain data.
@@ -163,7 +184,7 @@ carry (deposit addresses, tx hashes) is public on-chain data.
163
184
  ## Advanced: the settlement core
164
185
 
165
186
  The spec's server steps 7 ("verify deposit") and 8 ("submit + await swap
166
- finality") are implemented *inside* the method's `verify()` merchants never
187
+ finality") are implemented *inside* the method's `verify()`. Merchants never
167
188
  call them directly, and the safety rails (atomic in-flight hash claim,
168
189
  consume-on-terminal, release-on-5xx) live in that sequence. This package uses
169
190
  **status observation** (spec §Verification step 3, second mode): 1Click
@@ -177,29 +198,7 @@ tooling), the underlying 1Click client is exported as the `OneClick`
177
198
  namespace: `quote`, `submitDeposit`, `getStatus`, `pollToTerminal`,
178
199
  `matchesOriginTx`, `destinationTxHash`, `terminalError`, plus the CAIP-19 ↔
179
200
  1Click asset mapping (`createAssetMap`). If you drive settlement yourself you
180
- also own replay protection — prefer re-presenting the credential to the
181
- method (the 503/504 flow) over hand-rolling steps 7–8.
182
-
183
- ## How it works
184
-
185
- 1. The server answers an unpaid request with `402` + `WWW-Authenticate:
186
- Payment` whose `request` carries a unique, single-use **1Click deposit
187
- address** as `recipient`, the origin-chain leg the client pays (`amount`,
188
- `currency`), and the merchant's destination leg in `methodDetails`.
189
- 2. The client pays the source asset on its origin chain and retries with the
190
- confirmed transaction hash as a `{type: "hash"}` credential.
191
- 3. The server verifies the deposit via the 1Click status endpoint, drives the
192
- cross-chain swap to `SUCCESS`, and returns the resource with a
193
- `Payment-Receipt` carrying `challengeId`, `originTxHash`, and the
194
- destination-chain delivery hash.
195
-
196
- Quotes use `EXACT_OUTPUT`, so the merchant receives a deterministic amount of
197
- its chosen asset on its chosen chain.
198
-
199
- Note that settlement is not trustless: deposits
200
- are custodied by the NEAR Intents settlement system for the duration of the
201
- swap, with automatic refunds to `methodDetails.refundTo` on every non-success
202
- outcome. See the spec's Trust Model section.
201
+ also own replay protection.
203
202
 
204
203
  ## Spec
205
204
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defuse-protocol/nearintents-mpp-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Reference implementation of the `nearintents` payment method for MPP (Machine Payments Protocol) — cross-chain HTTP 402 payments settled by NEAR Intents. Extends mppx.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -54,7 +54,7 @@
54
54
  "zod": "^4.4.3"
55
55
  },
56
56
  "peerDependencies": {
57
- "mppx": "0.8.12",
57
+ "mppx": "0.8.15",
58
58
  "viem": "^2.0.0"
59
59
  },
60
60
  "peerDependenciesMeta": {
@@ -66,7 +66,7 @@
66
66
  "@biomejs/biome": "^2.5.4",
67
67
  "@changesets/cli": "^2.31.1",
68
68
  "@types/node": "^26.1.1",
69
- "mppx": "0.8.12",
69
+ "mppx": "0.8.15",
70
70
  "tsx": "^4.23.1",
71
71
  "typescript": "~6.0.3",
72
72
  "viem": "^2.55.4",
@@ -81,6 +81,7 @@
81
81
  "demo:build": "pnpm -C demo/app install && pnpm -C demo/app build",
82
82
  "demo:server": "tsx --env-file-if-exists=.env demo/server/index.ts",
83
83
  "example:client": "tsx --env-file-if-exists=.env examples/client.ts",
84
+ "example:live-oneclick-smoke": "tsx --env-file-if-exists=.env examples/live-oneclick-smoke.ts",
84
85
  "example:server": "tsx --env-file-if-exists=.env examples/server.ts",
85
86
  "lint": "biome check .",
86
87
  "lint:fix": "biome check --write .",