@manifoldxyz/dropkit 0.1.0 → 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/README.md +53 -5
- package/dist/index.cjs +796 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -3
- package/dist/index.d.ts +102 -3
- package/dist/index.js +764 -72
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -110,6 +110,8 @@ The adapter reads allowance and creates an approval leg when required. Manifold
|
|
|
110
110
|
| `onQuantityChange` | Receives the clamped requested quantity. The parent must update `quantity`. |
|
|
111
111
|
| `connect` | Optional `{ walletConnectProjectId }` forwarded to the shared connect widget. |
|
|
112
112
|
| `onEvent` | Optional event callback. No telemetry is sent by the package. |
|
|
113
|
+
| `crossChain` | Manifold claims only. Default on. `false` turns cross-chain minting off; `{ chains: [8453] }` narrows the pay chains. |
|
|
114
|
+
| `payChainId` | Forces the pay chain. The drop chain means a direct mint. Must be a pay chain. |
|
|
113
115
|
|
|
114
116
|
`MintButton` additionally accepts `className`, `labels`, and `children`.
|
|
115
117
|
A function child receives the full `MintState` and replaces the default button.
|
|
@@ -148,6 +150,8 @@ export function CustomMint({ config }: { config: MintConfig }) {
|
|
|
148
150
|
| `refresh` | Stable callback returning `Promise<void>`. Re-reads drop data. Queues refreshes during an attempt. |
|
|
149
151
|
| `result` | `{ txHash, explorerUrl, tokens }` after success, otherwise null. Token IDs and amounts are bigint. |
|
|
150
152
|
| `canAct` | Whether a click can act. False during an attempt, including its pre-prompt planning phase. |
|
|
153
|
+
| `route` | `{ kind: 'direct', chainId }` or `{ kind: 'relay', originChainId, amountIn, relayFee, originGas, quotedAt }`. Null before the wallet read. |
|
|
154
|
+
| `crossChain` | Inputs for `PayWithPicker`. Null when Relay cannot mint this drop for this wallet. |
|
|
151
155
|
|
|
152
156
|
`Money` is `{ value: bigint, decimals: number, symbol: string, formatted: string }`.
|
|
153
157
|
The component ships no CSS. The default button exposes `data-state`, `data-reason`, `disabled`, and `aria-busy` during asynchronous states.
|
|
@@ -174,7 +178,7 @@ A reset click never sends another transaction. Fresh drop and wallet reads must
|
|
|
174
178
|
| `sold-out` | Sold out | None |
|
|
175
179
|
| `disconnected` | Connect wallet | Open connect modal |
|
|
176
180
|
| `connecting` | Connecting… | None |
|
|
177
|
-
| `live` | Mint · {total} | Switch chain if needed, then approve and mint |
|
|
181
|
+
| `live` | Mint · {total}, or Mint · {amount} on {chain} over Relay | Switch chain if needed, then approve and mint |
|
|
178
182
|
| `ineligible` | Not eligible | None |
|
|
179
183
|
| `insufficient-funds` | Insufficient {symbol} | None |
|
|
180
184
|
| `switching-chain` | Switching network… | None |
|
|
@@ -207,10 +211,15 @@ ERC20 totals include the token price and any native fee. Gas is checked separate
|
|
|
207
211
|
| `RPC_ERROR` | `error` | Read or transaction transport failed. Supply a working RPC URL. |
|
|
208
212
|
| `CHAIN_SWITCH_FAILED` | `error` | Wallet could not switch to, or did not remain on, the configured chain. |
|
|
209
213
|
| `ALLOWLIST_UNAVAILABLE` | `error` | Required allowlist data could not be loaded. |
|
|
214
|
+
| `BRIDGE_UNAVAILABLE` | `error` | Relay could not quote or returned a route the button cannot run. Nothing was sent. |
|
|
215
|
+
| `BRIDGE_TIMEOUT` | `error` | Paid, but Relay had no final status after 10 minutes. The next click resumes the same request. |
|
|
216
|
+
| `BRIDGE_REFUNDED` | `error` | Relay could not mint and is refunding the payer. |
|
|
217
|
+
| `BRIDGE_FAILED` | `error` | Relay failed. `message` names the Relay request and says whether a refund was sent. |
|
|
210
218
|
|
|
211
219
|
## Events and lifecycle
|
|
212
220
|
|
|
213
|
-
`onEvent` receives `{ type, state, reason, chainId, quantity, config: { type, chainId, address }, txHash? }`.
|
|
221
|
+
`onEvent` receives `{ type, state, reason, chainId, quantity, config: { type, chainId, address }, route, originChainId, txHash? }`.
|
|
222
|
+
`route` is `direct` or `relay`. `originChainId` is the chain the collector pays on.
|
|
214
223
|
Types are `state`, `attempt`, `approve-submitted`, `tx-submitted`, `success`, and `error`.
|
|
215
224
|
The config address is the mint target for contract configs and the creator contract for Manifold claims.
|
|
216
225
|
Transaction events use the frozen attempt, not later props. Payloads omit payer and recipient addresses.
|
|
@@ -229,18 +238,57 @@ Receipt parsing filters mint transfers by token contract and recipient. Cancella
|
|
|
229
238
|
No direct analytics requests or `/public/instance/tx` posts are made.
|
|
230
239
|
Manifold allowlist calls are GET requests. JSON-RPC reads and wallet transactions still use their normal transports.
|
|
231
240
|
|
|
241
|
+
## Cross-chain mint (Relay)
|
|
242
|
+
|
|
243
|
+
A Manifold claim can be paid from another chain. Relay takes the payment there and calls `mintProxy` on the drop chain, minting to the recipient.
|
|
244
|
+
|
|
245
|
+
- **When:** native-priced claim on a V6/V7 extension (721 or 1155), drop on Ethereum, Base, Optimism or Shape (pay chains: Ethereum, Base, Optimism, Shape, ApeChain), or on Sepolia (pay chain: Base Sepolia). ERC20-priced drops, V8 claims and contract configs mint directly only.
|
|
246
|
+
- **Which chain pays:** the chain the wallet is on. A wallet on another pay chain with enough funds mints over Relay, even when the drop chain also has funds. A wallet on the drop chain mints directly.
|
|
247
|
+
- **Providers:** Dropkit only reads balances through the connected wallet, for the chain it is on. It never queries another chain's RPC. Relay quotes come from `api.relay.link` (no API key).
|
|
248
|
+
- **Cost:** the label shows the amount paid on the pay chain, excluding gas, e.g. `Mint · 0.00326 ETH on Base` for a 0.003 ETH mint (Relay fee ≈ 0.00026 ETH). The funds check includes gas.
|
|
249
|
+
- **Short on the wallet chain:** `Not enough ETH on Base. Pick another network to pay from.` Render `PayWithPicker` so collectors can switch.
|
|
250
|
+
- **One signature:** the collector signs one deposit on the pay chain. The button polls Relay until the mint lands on the drop chain, then reads token IDs. `result.relay` holds `{ requestId, originTxHash, originChainId }`.
|
|
251
|
+
- **Never pays twice on this page:** after a timeout, the next click resumes the same Relay request instead of paying again. Only one button per drop and wallet can prompt a payment at a time. A reload forgets it, same as claim-widgets.
|
|
252
|
+
|
|
253
|
+
`PayWithPicker` lists every pay chain with Relay's fee (`None` on the drop chain) and the balance of the wallet's current chain. Chains Relay cannot quote are hidden. Picking a row switches the wallet. It quotes every 20 seconds while mounted and renders nothing when Relay does not apply.
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
import { MintButton, PayWithPicker, type MintConfig } from '@manifoldxyz/dropkit';
|
|
257
|
+
|
|
258
|
+
export function CrossChainMint({ config }: { config: MintConfig }) {
|
|
259
|
+
return (
|
|
260
|
+
<MintButton config={config}>
|
|
261
|
+
{(m) => (
|
|
262
|
+
<>
|
|
263
|
+
<button type="button" onClick={m.mint} disabled={!m.canAct} data-state={m.state}>
|
|
264
|
+
{m.route?.kind === 'relay' ? `Mint · ${m.route.amountIn.formatted} ${m.route.amountIn.symbol}` : 'Mint'}
|
|
265
|
+
</button>
|
|
266
|
+
{m.message && <p role="status">{m.message}</p>}
|
|
267
|
+
<PayWithPicker mint={m} className="pay-with" />
|
|
268
|
+
</>
|
|
269
|
+
)}
|
|
270
|
+
</MintButton>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Rows expose `data-chain`, `data-selected`, `data-loading` and `aria-pressed`. `renderRow` replaces the row content.
|
|
276
|
+
|
|
232
277
|
## Local verification
|
|
233
278
|
|
|
234
|
-
From the repository root, use Node 24 and
|
|
279
|
+
From the repository root, use Node 24 and pnpm 10.34.5:
|
|
235
280
|
|
|
236
281
|
```sh
|
|
237
282
|
pnpm install --frozen-lockfile
|
|
238
283
|
cd packages/react/dropkit
|
|
239
|
-
pnpm
|
|
284
|
+
pnpm test # fast unit and component tests, no network
|
|
285
|
+
pnpm test:chain # adapters against a local Sepolia fork
|
|
240
286
|
pnpm run typecheck
|
|
241
287
|
pnpm run lint
|
|
242
288
|
pnpm run build
|
|
289
|
+
pnpm verify:package # packed tarball in clean React 18 and 19 consumers
|
|
243
290
|
```
|
|
244
291
|
|
|
245
|
-
|
|
292
|
+
`test:chain` requires `anvil` on `PATH` and `SEPOLIA_RPC_URL`. It forks block 11838500 and fails rather than skips when either is missing.
|
|
293
|
+
`verify:package` needs npm registry access. It type-checks every TypeScript example in this README.
|
|
246
294
|
The repository's pnpm policy enforces a seven-day release age, except for `@manifoldxyz/*` packages.
|