@ledewire/browser 0.6.1 → 0.8.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 +55 -13
- package/dist/index.d.ts +1546 -46
- package/dist/index.js +465 -600
- package/dist/index.js.map +1 -1
- package/dist/ledewire.min.js +2 -2
- package/dist/ledewire.min.js.map +1 -1
- package/llms.txt +140 -28
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Browser SDK for the [LedeWire](https://api.ledewire.com/api-docs/index.html) con
|
|
|
16
16
|
// Determine what the visitor needs to do next
|
|
17
17
|
const state = await lw.checkout.state('content-id')
|
|
18
18
|
// state.checkout_state.next_required_action:
|
|
19
|
-
// 'authenticate' | 'fund_wallet' | 'purchase'
|
|
19
|
+
// 'authenticate' | 'fund_wallet' | 'purchase'
|
|
20
20
|
</script>
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -48,6 +48,8 @@ const lw = init({
|
|
|
48
48
|
| `lw.purchases` | List and create content purchases |
|
|
49
49
|
| `lw.content` | Fetch content with buyer access info |
|
|
50
50
|
| `lw.checkout` | Checkout state — what action is required next |
|
|
51
|
+
| `lw.user.spendCap` | Buyer's daily spend cap — read and update the ceiling |
|
|
52
|
+
| `lw.user.mcpKeys` | Manage buyer MCP API keys for the Ledewire MCP server |
|
|
51
53
|
| `lw.seller.content` | List, search, and get store content (API key auth) |
|
|
52
54
|
|
|
53
55
|
## Example: Fetch Google OAuth Client ID Before Sign-In
|
|
@@ -63,6 +65,11 @@ google.accounts.id.renderButton(document.getElementById('signin-btn'), { theme:
|
|
|
63
65
|
|
|
64
66
|
## Example: Full Checkout Flow
|
|
65
67
|
|
|
68
|
+
Purchases are single-use: a completed purchase does not by itself grant access
|
|
69
|
+
again later. `has_purchased` means only "has ever bought" — buying delivers the
|
|
70
|
+
content directly in the `purchases.create()` response, and that response is the
|
|
71
|
+
only place `content_body` / `content_uri` ever appear for a purchase.
|
|
72
|
+
|
|
66
73
|
```ts
|
|
67
74
|
const lw = Ledewire.init({ apiKey: 'your_api_key' })
|
|
68
75
|
|
|
@@ -76,21 +83,56 @@ switch (checkout_state.next_required_action) {
|
|
|
76
83
|
const session = await lw.wallet.createPaymentSession({ amount_cents: 500 })
|
|
77
84
|
// redirect to session.payment_url
|
|
78
85
|
break
|
|
79
|
-
case 'purchase':
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
|
|
86
|
+
case 'purchase': {
|
|
87
|
+
// Buying is how the buyer receives the content — the delivery comes back
|
|
88
|
+
// directly in this response, never from a later GET. Persist it now:
|
|
89
|
+
// there is no route that serves the same delivery again.
|
|
90
|
+
const purchase = await lw.purchases.create({ content_id: 'article-123' })
|
|
91
|
+
await saveDeliveredContent(purchase) // your own persistence, e.g. IndexedDB
|
|
92
|
+
|
|
93
|
+
if (purchase.content_body) {
|
|
94
|
+
// content_body is always plain UTF-8 text on the wire — never
|
|
95
|
+
// base64-encoded — so no decoding step is needed. What it contains
|
|
96
|
+
// depends on purchase.content.content_type.
|
|
97
|
+
if (purchase.content.content_type === 'markdown') {
|
|
98
|
+
renderMarkdown(purchase.content_body)
|
|
99
|
+
} else if (purchase.content.content_type === 'html') {
|
|
100
|
+
// Inline HTML content is seller-supplied and must be sanitised
|
|
101
|
+
// before insertion — never assign it to innerHTML directly.
|
|
102
|
+
container.innerHTML = DOMPurify.sanitize(purchase.content_body)
|
|
103
|
+
}
|
|
104
|
+
} else if (purchase.content_uri) {
|
|
105
|
+
// content_uri points at a remote resource (video, PDF, image, or
|
|
106
|
+
// remote HTML). Check the scheme before navigating or linking to it —
|
|
107
|
+
// the URI is seller-supplied and a non-http(s) scheme should not be
|
|
108
|
+
// followed automatically.
|
|
109
|
+
const uri = new URL(purchase.content_uri)
|
|
110
|
+
if (['https:', 'http:'].includes(uri.protocol)) {
|
|
111
|
+
window.location.href = purchase.content_uri
|
|
112
|
+
}
|
|
91
113
|
}
|
|
92
114
|
break
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Example: Spend Cap & MCP API Keys
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
// Every buyer starts with a default daily spend cap governing every wallet
|
|
123
|
+
// debit. Exceeding it throws SpendCapReachedError (402) from
|
|
124
|
+
// lw.purchases.create() — funding the wallet does not clear it.
|
|
125
|
+
const cap = await lw.user.spendCap.get()
|
|
126
|
+
if (cap.remaining_cents !== null && cap.remaining_cents < 500) {
|
|
127
|
+
console.warn(`Only ${cap.remaining_cents}c left before the cap resets at ${cap.resets_at}`)
|
|
93
128
|
}
|
|
129
|
+
await lw.user.spendCap.update({ daily_spend_limit_cents: 2000 }) // raise to $20/day
|
|
130
|
+
|
|
131
|
+
// MCP API keys authenticate agent requests to the Ledewire MCP server. The
|
|
132
|
+
// secret is shown once at creation — store it immediately.
|
|
133
|
+
const { key, secret } = await lw.user.mcpKeys.create({ label: 'my-agent', can_search: true })
|
|
134
|
+
const keys = await lw.user.mcpKeys.list() // secrets never included
|
|
135
|
+
await lw.user.mcpKeys.revoke(keys[0].id) // to change scopes: revoke + recreate
|
|
94
136
|
```
|
|
95
137
|
|
|
96
138
|
## Example: Seller Content Discovery
|