sovads-sdk 1.0.9 → 1.1.1
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 +229 -93
- package/dist/index.d.ts +490 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2067 -81
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
#
|
|
1
|
+
# sovads-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/sovads-sdk)
|
|
4
|
+
[](https://github.com/sovseas/sovads/blob/main/sdk/LICENSE)
|
|
5
|
+
|
|
6
|
+
Publisher SDK for the [SovAds](https://ads.sovseas.xyz) ad network. Ships
|
|
7
|
+
seven modular surfaces (Banner, Sidebar, Popup, BottomBar, Overlay,
|
|
8
|
+
Interstitial, NativeCard) plus an opt-in **attached CTA** system that lets a
|
|
9
|
+
single ad carry up to two on-page tasks (visit-url, sign-message, poll) and
|
|
10
|
+
reward viewers for completing them.
|
|
11
|
+
|
|
12
|
+
- Zero peer dependencies. Works in any HTML page or framework (React, Vue,
|
|
13
|
+
Svelte, plain `<script type="module">`).
|
|
14
|
+
- Full TypeScript types.
|
|
15
|
+
- Backward compatible — every existing positional call site keeps working;
|
|
16
|
+
attached CTAs are strictly opt-in.
|
|
17
|
+
|
|
18
|
+
---
|
|
4
19
|
|
|
5
20
|
## Installation
|
|
6
21
|
|
|
@@ -12,138 +27,259 @@ pnpm add sovads-sdk@latest
|
|
|
12
27
|
yarn add sovads-sdk@latest
|
|
13
28
|
```
|
|
14
29
|
|
|
15
|
-
|
|
30
|
+
CDN / no-bundler usage:
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<script type="module">
|
|
34
|
+
import { SovAds, Banner } from 'https://ads.sovseas.xyz/api/v1/sdk'
|
|
35
|
+
const sovads = new SovAds({ debug: true })
|
|
36
|
+
await new Banner(sovads, 'banner').render()
|
|
37
|
+
</script>
|
|
38
|
+
```
|
|
16
39
|
|
|
17
|
-
|
|
40
|
+
---
|
|
18
41
|
|
|
19
|
-
|
|
20
|
-
|
|
42
|
+
## Quick start
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { SovAds, Banner, Popup, Sidebar, BottomBar } from 'sovads-sdk'
|
|
21
46
|
|
|
22
|
-
// Initialize SDK
|
|
23
47
|
const sovads = new SovAds({
|
|
24
|
-
apiUrl
|
|
25
|
-
|
|
26
|
-
|
|
48
|
+
// apiUrl defaults to https://ads.sovseas.xyz in production builds; override
|
|
49
|
+
// for self-hosting or local dev.
|
|
50
|
+
apiUrl: 'https://ads.sovseas.xyz',
|
|
51
|
+
debug: false,
|
|
52
|
+
// Optional — auto-detected from the page origin if omitted.
|
|
53
|
+
siteId: 'your-site-id',
|
|
54
|
+
// Optional — viewer wallet for reward attribution.
|
|
55
|
+
walletAddress: '0x...',
|
|
27
56
|
})
|
|
28
57
|
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
await banner.render()
|
|
58
|
+
// 1. Inline banner
|
|
59
|
+
await new Banner(sovads, 'banner-container').render()
|
|
32
60
|
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
await popup.show() // Shows after 3 seconds by default
|
|
61
|
+
// 2. Sidebar
|
|
62
|
+
await new Sidebar(sovads, 'sidebar-container').render()
|
|
36
63
|
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
await bottomBar.show()
|
|
64
|
+
// 3. Popup (modal, with frequency cap)
|
|
65
|
+
await new Popup(sovads).show()
|
|
40
66
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
await sidebar.render()
|
|
67
|
+
// 4. Bottom bar (sticky, dismissible)
|
|
68
|
+
await new BottomBar(sovads).show()
|
|
44
69
|
```
|
|
45
70
|
|
|
46
|
-
|
|
71
|
+
---
|
|
47
72
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
banner.render()
|
|
71
|
-
sidebar.render()
|
|
72
|
-
</script>
|
|
73
|
-
</body>
|
|
74
|
-
</html>
|
|
73
|
+
## Attached CTAs (v1.1+)
|
|
74
|
+
|
|
75
|
+
A campaign can attach up to **2 tasks** to its banner. The SDK renders them
|
|
76
|
+
inline beneath the media. Reward issuance and HMAC-signed verification are
|
|
77
|
+
handled server-side; the SDK only mounts UI and reports submissions.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { Banner } from 'sovads-sdk'
|
|
81
|
+
|
|
82
|
+
const banner = new Banner(sovads, 'banner-container', {
|
|
83
|
+
attached: true, // ask the server for attached tasks
|
|
84
|
+
clickTarget: 'button', // optional: route click-through through an
|
|
85
|
+
// explicit "Learn more" button (recommended)
|
|
86
|
+
onCtaComplete: (ev) => {
|
|
87
|
+
if (ev.ok) {
|
|
88
|
+
console.log('rewarded', ev.awarded) // { points, gs, bonusPointsInLieuOfGs? }
|
|
89
|
+
} else if (ev.needsSignature) {
|
|
90
|
+
// SIGN_MESSAGE task — your wallet code should sign ev.needsSignature.message
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
})
|
|
94
|
+
await banner.render()
|
|
75
95
|
```
|
|
76
96
|
|
|
77
|
-
|
|
97
|
+
Supported task kinds:
|
|
78
98
|
|
|
79
|
-
|
|
99
|
+
| Kind | What the viewer does |
|
|
100
|
+
| --------------- | ------------------------------------------ |
|
|
101
|
+
| `VISIT_URL` | Clicks through and dwells `minDwellMs`. |
|
|
102
|
+
| `SIGN_MESSAGE` | Signs a short message with their wallet. |
|
|
103
|
+
| `POLL` | Picks one of up to 4 options. |
|
|
80
104
|
|
|
81
|
-
|
|
105
|
+
If the campaign has no attached tasks, or you don't pass `attached: true`, the
|
|
106
|
+
SDK falls back to the classic banner-only experience.
|
|
82
107
|
|
|
83
|
-
|
|
108
|
+
### Pure-CTA unit (no media)
|
|
84
109
|
|
|
85
|
-
|
|
86
|
-
|
|
110
|
+
For a CTA-only slot (e.g. an inline poll under an article):
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { CtaUnit } from 'sovads-sdk'
|
|
114
|
+
|
|
115
|
+
await new CtaUnit(sovads, 'poll-here').render({
|
|
116
|
+
layout: 'auto', // 'stack' | 'inline' | 'auto' (inline at 2 tasks)
|
|
117
|
+
onCtaComplete: (ev) => { /* … */ },
|
|
118
|
+
})
|
|
87
119
|
```
|
|
88
120
|
|
|
89
|
-
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## API reference
|
|
124
|
+
|
|
125
|
+
### `new SovAds(config?: SovAdsConfig)`
|
|
126
|
+
|
|
127
|
+
| Field | Type | Default | Notes |
|
|
128
|
+
| --------------------------- | -------------------------- | ----------------------------- | ------------------------------------------------------------------------------------ |
|
|
129
|
+
| `apiUrl` | `string` | `https://ads.sovseas.xyz` | API origin. Set to your local server in dev. |
|
|
130
|
+
| `siteId` | `string` | auto-detected | Publisher site ID. |
|
|
131
|
+
| `apiKey` / `apiSecret` | `string` | — | Enables HMAC-signed tracking. |
|
|
132
|
+
| `debug` | `boolean` | `false` | Verbose console logging. |
|
|
133
|
+
| `consumerId` | `string` | — | Target a specific advertiser slug. |
|
|
134
|
+
| `walletAddress` | `string` | — | Viewer wallet for reward attribution. |
|
|
135
|
+
| `refreshInterval` | `number` (seconds) | `0` (off) | Auto-refresh interval for Banner / Sidebar. |
|
|
136
|
+
| `lazyLoad` | `boolean` | `true` | Use IntersectionObserver to defer load until in-viewport. |
|
|
137
|
+
| `rotationEnabled` | `boolean` | `true` | Rotate between ads when refreshing. |
|
|
138
|
+
| `popupMinIntervalMinutes` | `number` | `30` | Min minutes between popup / overlay impressions per viewer. |
|
|
139
|
+
| `popupSessionMax` | `number` | `1` | Hard cap on popup / overlay impressions per browser session. |
|
|
140
|
+
| `disclosureLabel` | `boolean \| string` | `true` (`"Sponsored"`) | Force a custom label (e.g. `"Ad"`) or `false` to suppress (not recommended). |
|
|
141
|
+
| `advertiserName` | `string` | — | Appended to the disclosure: `"Sponsored · {advertiserName}"`. |
|
|
142
|
+
|
|
143
|
+
### `Banner`
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
new Banner(sovads, containerId, slotConfig?: SlotConfig)
|
|
147
|
+
banner.render(consumerId?: string, forceRefresh?: boolean): Promise<void>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`SlotConfig`: `{ placementId?, size?, attached?, onCtaComplete?, clickTarget?, disclosureLabel? }`.
|
|
90
151
|
|
|
91
|
-
|
|
92
|
-
- `debug?: boolean` - Enable debug logging (default: `false`)
|
|
93
|
-
- `siteId?: string` - Site ID (optional, will auto-detect)
|
|
94
|
-
- `consumerId?: string` - Consumer ID for targeting specific advertisers
|
|
152
|
+
### `Sidebar`
|
|
95
153
|
|
|
96
|
-
|
|
154
|
+
```ts
|
|
155
|
+
new Sidebar(sovads, containerId, slotConfig?: SlotConfig)
|
|
156
|
+
sidebar.render(consumerId?: string, forceRefresh?: boolean): Promise<void>
|
|
157
|
+
```
|
|
97
158
|
|
|
98
|
-
|
|
159
|
+
### `Popup`
|
|
99
160
|
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
|
|
161
|
+
```ts
|
|
162
|
+
new Popup(sovads)
|
|
163
|
+
popup.show(consumerIdOrOpts?: string | PopupShowOptions): Promise<void>
|
|
164
|
+
popup.hide(): void
|
|
103
165
|
```
|
|
104
166
|
|
|
105
|
-
|
|
167
|
+
`PopupShowOptions`: `{ consumerId?, delay? (ms, default 3000), attached?, onCtaComplete?, clickTarget?, disclosureLabel? }`.
|
|
106
168
|
|
|
107
|
-
|
|
169
|
+
### `BottomBar`
|
|
108
170
|
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
171
|
+
```ts
|
|
172
|
+
new BottomBar(sovads)
|
|
173
|
+
bottomBar.show(consumerIdOrOpts?: string | BottomBarShowOptions): Promise<void>
|
|
174
|
+
bottomBar.hide(): void
|
|
113
175
|
```
|
|
114
176
|
|
|
115
|
-
|
|
177
|
+
Defaults to `clickTarget: 'button'` to suppress accidental bar-wide clicks.
|
|
178
|
+
|
|
179
|
+
### `Overlay` / `Interstitial`
|
|
180
|
+
|
|
181
|
+
`Overlay` is a full-viewport modal with backdrop dismiss. `Interstitial`
|
|
182
|
+
extends it with its own frequency-cap counter so the two surfaces never
|
|
183
|
+
share a budget.
|
|
116
184
|
|
|
117
|
-
|
|
185
|
+
```ts
|
|
186
|
+
new Overlay(sovads)
|
|
187
|
+
overlay.show(opts?: OverlayShowOptions): Promise<void>
|
|
188
|
+
overlay.hide(): void
|
|
118
189
|
|
|
119
|
-
|
|
120
|
-
const bottomBar = new BottomBar(sovads: SovAds)
|
|
121
|
-
await bottomBar.show(consumerId?: string)
|
|
122
|
-
bottomBar.hide()
|
|
190
|
+
new Interstitial(sovads) // same API
|
|
123
191
|
```
|
|
124
192
|
|
|
125
|
-
|
|
193
|
+
`OverlayShowOptions`: `{ consumerId?, attached?, onCtaComplete?, clickTarget?, disclosureLabel?, dismissOnBackdrop? (default true), dismissOnEscape? (default true) }`.
|
|
126
194
|
|
|
127
|
-
|
|
195
|
+
### `NativeCard`
|
|
128
196
|
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
|
|
197
|
+
```ts
|
|
198
|
+
new NativeCard(sovads, containerId)
|
|
199
|
+
card.render(consumerIdOrOpts?: string | NativeCardRenderOptions): Promise<void>
|
|
132
200
|
```
|
|
133
201
|
|
|
202
|
+
### `CtaUnit`
|
|
203
|
+
|
|
204
|
+
Pure CTA panel (no media). See [Attached CTAs](#attached-ctas-v11) above.
|
|
205
|
+
|
|
206
|
+
### Other exports
|
|
207
|
+
|
|
208
|
+
- `SDK_VERSION` — runtime version string, kept in sync with `package.json`.
|
|
209
|
+
- `mountMedia`, `mountCtaPanel`, `renderAttachedCtas` — low-level building blocks for custom layouts.
|
|
210
|
+
- `buildRewardBadge`, `buildDisclosureBadge` — drop-in UI primitives.
|
|
211
|
+
- `toStreamingEmbed`, `buildStreamingIframe` — helpers for video creatives.
|
|
212
|
+
- Types: `SovAdsConfig`, `AdComponent`, `AttachedTask`, `AttachedTaskKind`, `AttachedPollOption`, `AttachedCtaCompleteEvent`, `SlotConfig`, `PopupShowOptions`, `BottomBarShowOptions`, `OverlayShowOptions`, `NativeCardRenderOptions`, `CtaUnitRenderOptions`, `AdSurface`.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Styling
|
|
217
|
+
|
|
218
|
+
Every surface ships unstyled-friendly hooks; target these classes in your own
|
|
219
|
+
CSS to brand the units:
|
|
220
|
+
|
|
221
|
+
| Class | Surface |
|
|
222
|
+
| ------------------------------ | ------------- |
|
|
223
|
+
| `.sovads-banner` | Banner |
|
|
224
|
+
| `.sovads-sidebar` | Sidebar |
|
|
225
|
+
| `.sovads-popup-overlay` | Popup |
|
|
226
|
+
| `.sovads-bottom-bar` | BottomBar |
|
|
227
|
+
| `.sovads-overlay` | Overlay / Interstitial |
|
|
228
|
+
| `.sovads-native-card` | NativeCard |
|
|
229
|
+
| `.sovads-cta-panel` | Attached CTA panel (all surfaces) |
|
|
230
|
+
| `.sovads-disclosure` | "Sponsored" badge |
|
|
231
|
+
| `.sovads-reward-badge` | "Earn N pts" badge |
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Frequency capping
|
|
236
|
+
|
|
237
|
+
Popup, Overlay, and Interstitial each persist a `last-shown` timestamp in
|
|
238
|
+
`localStorage` and a session counter in `sessionStorage`. The same
|
|
239
|
+
`popupMinIntervalMinutes` / `popupSessionMax` knobs apply to all three —
|
|
240
|
+
publishers don't have to think about three sets of dials. Banner / Sidebar /
|
|
241
|
+
BottomBar / NativeCard do **not** frequency-cap (they're publisher-placed).
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Tracking
|
|
246
|
+
|
|
247
|
+
The SDK sends two events:
|
|
248
|
+
|
|
249
|
+
- `IMPRESSION` — fired once the creative is verified visible
|
|
250
|
+
(IntersectionObserver, ≥ 50% area for ≥ 1s by default).
|
|
251
|
+
- `CLICK` — fired on banner / button click-through.
|
|
252
|
+
|
|
253
|
+
Attached-CTA submissions go through the regular `/api/tasks/*` endpoints and
|
|
254
|
+
emit `onCtaComplete` callbacks.
|
|
255
|
+
|
|
256
|
+
All outbound tracking carries the `X-SovAds-SDK-Version` header so the server
|
|
257
|
+
can correlate metrics with SDK releases.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
134
261
|
## Features
|
|
135
262
|
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
|
|
263
|
+
- Automatic site detection
|
|
264
|
+
- IntersectionObserver-based viewability tracking
|
|
265
|
+
- Network retry with exponential backoff
|
|
266
|
+
- Image / video load error handling
|
|
267
|
+
- `navigator.sendBeacon` fallback for tracking on page unload
|
|
268
|
+
- Reduced-motion respect (`prefers-reduced-motion`)
|
|
269
|
+
- TypeScript-first
|
|
270
|
+
- Zero runtime dependencies
|
|
271
|
+
|
|
272
|
+
## Browser support
|
|
273
|
+
|
|
274
|
+
Evergreen Chromium, Firefox, Safari (last 2 versions). Requires native
|
|
275
|
+
`IntersectionObserver` and ES2020.
|
|
145
276
|
|
|
146
277
|
## License
|
|
147
278
|
|
|
148
|
-
MIT
|
|
279
|
+
MIT — see [LICENSE](https://github.com/sovseas/sovads/blob/main/sdk/LICENSE).
|
|
280
|
+
|
|
281
|
+
## Links
|
|
149
282
|
|
|
283
|
+
- [Documentation](https://ads.sovseas.xyz/docs)
|
|
284
|
+
- [Repository](https://github.com/sovseas/sovads)
|
|
285
|
+
- [Issues](https://github.com/sovseas/sovads/issues)
|