@swype-org/deposit 0.3.26 → 0.3.32
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 +171 -0
- package/dist/{chunk-S3SPMEXQ.js → chunk-MJSD7JWR.js} +534 -98
- package/dist/chunk-MJSD7JWR.js.map +1 -0
- package/dist/index.cjs +533 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +142 -5
- package/dist/index.d.ts +142 -5
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +532 -96
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/{types-BjnQ2ux2.d.cts → types-QRkKxsoP.d.cts} +128 -1
- package/dist/{types-BjnQ2ux2.d.ts → types-QRkKxsoP.d.ts} +128 -1
- package/package.json +1 -1
- package/dist/chunk-S3SPMEXQ.js.map +0 -1
package/README.md
CHANGED
|
@@ -99,6 +99,7 @@ const deposit = new Deposit({
|
|
|
99
99
|
signerTimeoutMs: 15_000,
|
|
100
100
|
flowTimeoutMs: 300_000,
|
|
101
101
|
enableFullWidget: true,
|
|
102
|
+
presentation: 'overlay', // or 'embedded' — see below
|
|
102
103
|
debug: false,
|
|
103
104
|
});
|
|
104
105
|
```
|
|
@@ -112,6 +113,174 @@ has it enabled — disabling either turns it off. Set it to `false` to force the
|
|
|
112
113
|
hosted flow straight to the standard deposit flow regardless of merchant
|
|
113
114
|
config.
|
|
114
115
|
|
|
116
|
+
## Embedded presentation (payment-method aggregators)
|
|
117
|
+
|
|
118
|
+
By default Blink opens as a full-screen modal: a dim + blur backdrop with the
|
|
119
|
+
payment card centered on top. If you're a payment-method aggregator listing
|
|
120
|
+
Blink as one option **inside your own widget**, set
|
|
121
|
+
`presentation: 'embedded'` and Blink renders inline in an element you provide —
|
|
122
|
+
no backdrop, no page scroll lock, no Escape/backdrop dismissal (all of that
|
|
123
|
+
stays yours), and chrome-less so your panel owns the radius, background and
|
|
124
|
+
shadow.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// On widget mount. `slot` is an empty <div> inside your method panel.
|
|
128
|
+
const deposit = new Deposit({
|
|
129
|
+
signer: '/api/sign-payment',
|
|
130
|
+
merchantId: MERCHANT_ID,
|
|
131
|
+
presentation: 'embedded',
|
|
132
|
+
containerElement: slot, // required
|
|
133
|
+
embedMaxHeightPx: 640, // your panel's height budget
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Blink reports its rendered height; the SDK has already resized the iframe.
|
|
137
|
+
// Follow it to size your own panel — height with NO transition (see below).
|
|
138
|
+
deposit.on('resize', ({ heightPx, preferredWidthPx, minWidthPx }) => {
|
|
139
|
+
panel.style.height = `${heightPx}px`;
|
|
140
|
+
// Optional: size the panel's width to the flow too. These are constants
|
|
141
|
+
// (440 / 320), not measurements, so they are safe to transition.
|
|
142
|
+
panel.style.width = `${preferredWidthPx}px`;
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// When the user picks the Blink row:
|
|
146
|
+
try {
|
|
147
|
+
const { transfer } = await deposit.requestDeposit({ amount, chainId, address, token });
|
|
148
|
+
} catch (err) {
|
|
149
|
+
if (err instanceof DepositError && err.code === 'DEPOSIT_DISMISSED') {
|
|
150
|
+
showMethodList(); // user backed out of Blink
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
deposit.close(); // your own back button
|
|
155
|
+
deposit.destroy(); // widget unmount
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`close()` rejects the pending `requestDeposit()` with `DEPOSIT_DISMISSED` — the
|
|
159
|
+
same code the flow's own close control uses — so the `catch` above is the single
|
|
160
|
+
place you restore your method list. (It reports no `error` event and leaves
|
|
161
|
+
`status` on `'idle'`: you asked for this one.)
|
|
162
|
+
|
|
163
|
+
Three things to get right:
|
|
164
|
+
|
|
165
|
+
- **`containerElement` is required, must be stable across re-renders, and must
|
|
166
|
+
never be hidden with `display: none`.** Moving an iframe in the DOM reloads it,
|
|
167
|
+
throwing away the warm-up and the user's session — so render the slot once and
|
|
168
|
+
never recreate the node. When another method is selected, hide it *without
|
|
169
|
+
removing its layout*:
|
|
170
|
+
|
|
171
|
+
```css
|
|
172
|
+
/* the Blink slot while another method is showing */
|
|
173
|
+
visibility: hidden; height: 0; overflow: hidden; pointer-events: none;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`display: none` looks equivalent and is not: that subtree has no layout, so the
|
|
177
|
+
flow Blink re-warms into it after every close cannot measure itself and may
|
|
178
|
+
report no height at all. The panel then reopens blank at its budget height with
|
|
179
|
+
nothing in your console. It is timing-dependent, which is what makes it nasty —
|
|
180
|
+
closing your whole dialog tends to flip `display` in the same commit and works,
|
|
181
|
+
while a back button inside the panel does not. The SDK warns when it reveals
|
|
182
|
+
into an unrendered container; that warning is this.
|
|
183
|
+
- **Don't add a CSS transition to the height you get from `resize`.** Blink
|
|
184
|
+
animates its own height over ~300ms and reports every frame of it. A
|
|
185
|
+
transition on your side makes the panel chase each of those frames, so it
|
|
186
|
+
keeps moving after the content has settled — which shifts elements under the
|
|
187
|
+
pointer and shows up as the cursor flickering between pointer and default.
|
|
188
|
+
Apply the height directly. `preferredWidthPx` is a constant, so transitioning
|
|
189
|
+
the *width* is fine.
|
|
190
|
+
- **Embedded is a desktop presentation.** On mobile the same config presents as
|
|
191
|
+
Blink's normal full-screen sheet, because a phone-sized method panel cannot
|
|
192
|
+
hold a flow with a keypad, wallet lists, a QR code and a passkey ceremony.
|
|
193
|
+
Nothing else downgrades it: no failure in the hosted flow will drop a modal
|
|
194
|
+
over your app unannounced. Read the resolved value from `deposit.presentation`
|
|
195
|
+
(`'overlay' | 'embedded'`) — on `'overlay'` no `resize` event ever fires, so
|
|
196
|
+
collapse or skip the slot rather than leaving an empty box behind the sheet:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
// Re-read on resize; it is live until Blink builds its warm-up frame.
|
|
200
|
+
{deposit.presentation === 'embedded' && <MethodPanel />}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Brand colors
|
|
204
|
+
|
|
205
|
+
Five colors, and Blink derives its whole palette from them — surfaces, the
|
|
206
|
+
recessed and hover steps, the text ramp, borders, the button hover and label, the
|
|
207
|
+
tinted semantic surfaces — so the flow reads as part of your product rather than a
|
|
208
|
+
foreign panel inside it. Names follow Stripe's `appearance.variables`.
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const deposit = new Deposit({
|
|
212
|
+
signer: '/api/sign-payment',
|
|
213
|
+
presentation: 'embedded',
|
|
214
|
+
containerElement: slot,
|
|
215
|
+
appearance: {
|
|
216
|
+
theme: 'light',
|
|
217
|
+
variables: {
|
|
218
|
+
colorPrimary: '#0f62fe', // primary button, focus ring, selected states
|
|
219
|
+
colorBackground: '#101828', // the card surface
|
|
220
|
+
colorText: '#f7f9fc',
|
|
221
|
+
colorDanger: '#ff5c5c', // optional
|
|
222
|
+
colorBorder: '#22304a', // optional — derived from surface + text if omitted
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Worth knowing before you pick values:
|
|
229
|
+
|
|
230
|
+
- **Opaque hex only** (`#rgb` or `#rrggbb`). `rgb()`, CSS color names and 8-digit
|
|
231
|
+
hex with alpha are dropped with a console error naming the key — a solid card
|
|
232
|
+
cannot honour translucency, and an unparseable color cannot be contrast-checked.
|
|
233
|
+
- **`colorBackground` picks the light or dark base** for everything that is not
|
|
234
|
+
themeable (shadows, the scrim, semantic hues), by its own luminance. A dark
|
|
235
|
+
surface stays coherent even with `theme: 'light'`.
|
|
236
|
+
- **Contrast is enforced.** Where a derived pair would fall below WCAG AA the
|
|
237
|
+
*derived* value is substituted — never your input — and the substitution is
|
|
238
|
+
reported in the hosted flow's console. A `colorPrimary` too mid-toned for either
|
|
239
|
+
a black or a white label is reported and left alone; only you can fix that one.
|
|
240
|
+
- **Not themeable:** the type scale, weights, radii, fonts, Blink's own marks, and
|
|
241
|
+
the success/error/warning hues and authorization states.
|
|
242
|
+
|
|
243
|
+
Everything else derives, deliberately: the palette has ~35 mutually-constrained
|
|
244
|
+
tokens and five inputs cannot produce a broken combination, where thirty-five
|
|
245
|
+
reliably would.
|
|
246
|
+
|
|
247
|
+
`embedMaxHeightPx` (default: 90% of the host viewport) caps the iframe and is
|
|
248
|
+
also the basis Blink sizes its own layout against. Past that height the flow
|
|
249
|
+
scrolls internally instead of growing your panel.
|
|
250
|
+
|
|
251
|
+
Blink's screens are designed for **320–440px wide**, and the flow reports that
|
|
252
|
+
envelope on every `resize` as `minWidthPx` (320) and `preferredWidthPx` (440).
|
|
253
|
+
The iframe fills the width you give it, capped at 440 — it cannot widen your
|
|
254
|
+
panel on its own, so if you want the panel to fit the flow, size it from
|
|
255
|
+
`preferredWidthPx`. Below `minWidthPx`, fixed-width elements inside the flow
|
|
256
|
+
overflow.
|
|
257
|
+
|
|
258
|
+
Your CSP needs `frame-src https://pay.blink.cash`.
|
|
259
|
+
|
|
260
|
+
### Merchant balance
|
|
261
|
+
|
|
262
|
+
If your users hold a balance on your platform, pass it on the request and the
|
|
263
|
+
flow shows it under the deposit header — "Acme balance: $20.70" — so the user
|
|
264
|
+
tops up with their number in view:
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
await deposit.requestDeposit({
|
|
268
|
+
amount: null,
|
|
269
|
+
chainId: 8453,
|
|
270
|
+
address: userWalletAddress,
|
|
271
|
+
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
272
|
+
balance: 20.7, // USD — display only
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Display-only by design: the value is never part of the signed payload and never
|
|
277
|
+
reaches your signer, so no signer changes are needed — and it cannot affect the
|
|
278
|
+
transfer amount or destination. It must be a finite number, `>= 0` and below
|
|
279
|
+
`1e12`; the SDK floors it to whole cents (`20.789` shows as `$20.78`). Anything
|
|
280
|
+
else is dropped with a console error naming the field, and the deposit proceeds
|
|
281
|
+
without the subtitle. When you don't pass it, Blink may fall back to showing
|
|
282
|
+
the destination wallet's on-chain balance instead.
|
|
283
|
+
|
|
115
284
|
## Error Handling
|
|
116
285
|
|
|
117
286
|
Every error is a `DepositError` with a machine-readable `code`:
|
|
@@ -145,6 +314,8 @@ transfer.on('complete', (result) => { /* DepositResult */ });
|
|
|
145
314
|
transfer.on('error', (error) => { /* DepositError */ });
|
|
146
315
|
transfer.on('close', () => { /* iframe closed */ });
|
|
147
316
|
transfer.on('status-change', (status) => { /* DepositStatus */ });
|
|
317
|
+
// Embedded presentation only — the inline iframe was resized to this height.
|
|
318
|
+
transfer.on('resize', ({ heightPx }) => { /* number */ });
|
|
148
319
|
```
|
|
149
320
|
|
|
150
321
|
## Lifecycle
|