ani-ads-sdk 1.0.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 +61 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +194 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +169 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Ani Ads SDK
|
|
2
|
+
|
|
3
|
+
SDK für Mini App Creators um Werbung in ihren Apps anzuzeigen.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ani-ads/sdk
|
|
9
|
+
# oder
|
|
10
|
+
pnpm add @ani-ads/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Verwendung
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { AniAds } from '@ani-ads/sdk'
|
|
17
|
+
|
|
18
|
+
function MyApp() {
|
|
19
|
+
return (
|
|
20
|
+
<AniAds
|
|
21
|
+
creator_code="XYZ"
|
|
22
|
+
user_wallet_address="0x..."
|
|
23
|
+
ad_format={["16:9", "9:16"]}
|
|
24
|
+
api_url="https://your-domain.com" // Optional
|
|
25
|
+
onAdClick={(adId, url) => console.log('Ad clicked:', adId, url)} // Optional
|
|
26
|
+
/>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Props
|
|
32
|
+
|
|
33
|
+
- `creator_code` (string, required): Eindeutiger Code für deine App
|
|
34
|
+
- `user_wallet_address` (string, required): Wallet-Adresse des aktuellen Users
|
|
35
|
+
- `ad_format` (string[] | string, required): Gewünschte Bildformate (z.B. `["16:9", "9:16", "1:1"]`)
|
|
36
|
+
- `api_url` (string, optional): API URL (Standard: Production URL)
|
|
37
|
+
- `onAdClick` (function, optional): Callback wenn Ad geklickt wird
|
|
38
|
+
|
|
39
|
+
## Bildformate
|
|
40
|
+
|
|
41
|
+
- `"1:1"` oder `"11"` - Quadratisch (Square)
|
|
42
|
+
- `"9:16"` oder `"916"` - Hochformat (Portrait)
|
|
43
|
+
- `"16:9"` oder `"169"` - Querformat (Landscape)
|
|
44
|
+
|
|
45
|
+
## Wie es funktioniert
|
|
46
|
+
|
|
47
|
+
Die SDK kommuniziert mit der Ani Ads API, die dann:
|
|
48
|
+
|
|
49
|
+
1. **Datenbank liest**: Prüft verfügbare Ads und ob User bereits geklickt hat (unique user check)
|
|
50
|
+
2. **Datenbank schreibt**: Speichert Clicks und Earnings
|
|
51
|
+
3. **Smart Contract schreibt**: Verarbeitet Zahlungen (0.005 USDC an Creator, 0.005 USDC an Platform)
|
|
52
|
+
|
|
53
|
+
**Wichtig**: Die SDK kann nicht direkt auf Datenbank oder Smart Contract zugreifen, da:
|
|
54
|
+
- Smart Contract Write-Operationen müssen vom Contract Creator signiert werden (Private Key im Backend)
|
|
55
|
+
- Datenbank-Zugriff läuft über die API für Sicherheit und Validierung
|
|
56
|
+
|
|
57
|
+
Bei jedem Click wird automatisch:
|
|
58
|
+
- Geprüft ob unique user (nur einmal pro User bezahlt)
|
|
59
|
+
- Zahlung im Smart Contract verarbeitet
|
|
60
|
+
- Earnings in der Datenbank aktualisiert
|
|
61
|
+
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface AniAdsProps {
|
|
4
|
+
creator_code: string;
|
|
5
|
+
user_wallet_address: string;
|
|
6
|
+
ad_format: string[] | string;
|
|
7
|
+
api_url?: string;
|
|
8
|
+
onAdClick?: (adId: string, destinationUrl: string) => void;
|
|
9
|
+
}
|
|
10
|
+
declare const AniAds: React.FC<AniAdsProps>;
|
|
11
|
+
|
|
12
|
+
export { AniAds, type AniAdsProps, AniAds as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface AniAdsProps {
|
|
4
|
+
creator_code: string;
|
|
5
|
+
user_wallet_address: string;
|
|
6
|
+
ad_format: string[] | string;
|
|
7
|
+
api_url?: string;
|
|
8
|
+
onAdClick?: (adId: string, destinationUrl: string) => void;
|
|
9
|
+
}
|
|
10
|
+
declare const AniAds: React.FC<AniAdsProps>;
|
|
11
|
+
|
|
12
|
+
export { AniAds, type AniAdsProps, AniAds as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.tsx
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
AniAds: () => AniAds,
|
|
24
|
+
default: () => index_default
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
var import_react = require("react");
|
|
28
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
29
|
+
var AniAds = ({
|
|
30
|
+
creator_code,
|
|
31
|
+
user_wallet_address,
|
|
32
|
+
ad_format,
|
|
33
|
+
api_url = "https://your-domain.com",
|
|
34
|
+
// Replace with your Ani Ads API domain
|
|
35
|
+
onAdClick
|
|
36
|
+
}) => {
|
|
37
|
+
const [ad, setAd] = (0, import_react.useState)(null);
|
|
38
|
+
const [loading, setLoading] = (0, import_react.useState)(true);
|
|
39
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
40
|
+
const formats = Array.isArray(ad_format) ? ad_format : typeof ad_format === "string" ? ad_format.split(",").map((f) => f.trim()) : [];
|
|
41
|
+
const getImageUrl = (ad2, format) => {
|
|
42
|
+
const normalizedFormat = format.toLowerCase().replace(/[:\s]/g, "");
|
|
43
|
+
if (normalizedFormat === "11" || normalizedFormat === "1:1") {
|
|
44
|
+
return ad2.image_square || null;
|
|
45
|
+
} else if (normalizedFormat === "916" || normalizedFormat === "9:16") {
|
|
46
|
+
return ad2.image_portrait || null;
|
|
47
|
+
} else if (normalizedFormat === "169" || normalizedFormat === "16:9") {
|
|
48
|
+
return ad2.image_landscape || null;
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
};
|
|
52
|
+
const fetchAd = (0, import_react.useCallback)(async () => {
|
|
53
|
+
try {
|
|
54
|
+
setLoading(true);
|
|
55
|
+
setError(null);
|
|
56
|
+
const response = await fetch(`${api_url}/api/ads/sdk`, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "application/json"
|
|
60
|
+
},
|
|
61
|
+
body: JSON.stringify({
|
|
62
|
+
creator_code,
|
|
63
|
+
formats
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
throw new Error("Failed to fetch ads");
|
|
68
|
+
}
|
|
69
|
+
const data = await response.json();
|
|
70
|
+
if (data.ad) {
|
|
71
|
+
setAd(data.ad);
|
|
72
|
+
} else {
|
|
73
|
+
setAd(null);
|
|
74
|
+
}
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.error("Error fetching ad:", err);
|
|
77
|
+
setError(err instanceof Error ? err.message : "Failed to load ad");
|
|
78
|
+
setAd(null);
|
|
79
|
+
} finally {
|
|
80
|
+
setLoading(false);
|
|
81
|
+
}
|
|
82
|
+
}, [creator_code, formats, api_url]);
|
|
83
|
+
const handleClick = (0, import_react.useCallback)(async () => {
|
|
84
|
+
if (!ad || !user_wallet_address) return;
|
|
85
|
+
try {
|
|
86
|
+
const response = await fetch(`${api_url}/api/ads/click`, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: {
|
|
89
|
+
"Content-Type": "application/json"
|
|
90
|
+
},
|
|
91
|
+
body: JSON.stringify({
|
|
92
|
+
ad_id: ad.id,
|
|
93
|
+
creator_code,
|
|
94
|
+
user_wallet_address: user_wallet_address.toLowerCase()
|
|
95
|
+
})
|
|
96
|
+
});
|
|
97
|
+
if (response.ok) {
|
|
98
|
+
if (onAdClick) {
|
|
99
|
+
onAdClick(ad.id, ad.destination_url);
|
|
100
|
+
}
|
|
101
|
+
window.open(ad.destination_url, "_blank", "noopener,noreferrer");
|
|
102
|
+
await fetchAd();
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error("Error tracking click:", err);
|
|
106
|
+
window.open(ad.destination_url, "_blank", "noopener,noreferrer");
|
|
107
|
+
}
|
|
108
|
+
}, [ad, creator_code, user_wallet_address, api_url, onAdClick, fetchAd]);
|
|
109
|
+
const getBestImage = (ad2) => {
|
|
110
|
+
for (const format of formats) {
|
|
111
|
+
const imageUrl2 = getImageUrl(ad2, format);
|
|
112
|
+
if (imageUrl2) return imageUrl2;
|
|
113
|
+
}
|
|
114
|
+
return ad2.image_square || ad2.image_portrait || ad2.image_landscape || null;
|
|
115
|
+
};
|
|
116
|
+
(0, import_react.useEffect)(() => {
|
|
117
|
+
if (creator_code && formats.length > 0) {
|
|
118
|
+
fetchAd();
|
|
119
|
+
} else {
|
|
120
|
+
setLoading(false);
|
|
121
|
+
}
|
|
122
|
+
}, [creator_code, formats, fetchAd]);
|
|
123
|
+
if (loading) {
|
|
124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
|
|
125
|
+
display: "flex",
|
|
126
|
+
width: "100%",
|
|
127
|
+
minHeight: "100px",
|
|
128
|
+
backgroundColor: "#f3f4f6",
|
|
129
|
+
borderRadius: "8px",
|
|
130
|
+
alignItems: "center",
|
|
131
|
+
justifyContent: "center"
|
|
132
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#6b7280" }, children: "Loading ad..." }) });
|
|
133
|
+
}
|
|
134
|
+
if (error) {
|
|
135
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
|
|
136
|
+
display: "flex",
|
|
137
|
+
width: "100%",
|
|
138
|
+
minHeight: "100px",
|
|
139
|
+
backgroundColor: "#fee2e2",
|
|
140
|
+
borderRadius: "8px",
|
|
141
|
+
alignItems: "center",
|
|
142
|
+
justifyContent: "center",
|
|
143
|
+
padding: "12px"
|
|
144
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#dc2626", fontSize: "14px" }, children: error }) });
|
|
145
|
+
}
|
|
146
|
+
if (!ad) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
const imageUrl = getBestImage(ad);
|
|
150
|
+
if (!imageUrl) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
154
|
+
"div",
|
|
155
|
+
{
|
|
156
|
+
style: {
|
|
157
|
+
display: "inline-block",
|
|
158
|
+
width: "100%",
|
|
159
|
+
cursor: "pointer",
|
|
160
|
+
borderRadius: "8px",
|
|
161
|
+
overflow: "hidden",
|
|
162
|
+
transition: "transform 0.2s, box-shadow 0.2s"
|
|
163
|
+
},
|
|
164
|
+
onClick: handleClick,
|
|
165
|
+
onMouseEnter: (e) => {
|
|
166
|
+
e.currentTarget.style.transform = "scale(1.02)";
|
|
167
|
+
e.currentTarget.style.boxShadow = "0 4px 12px rgba(0,0,0,0.15)";
|
|
168
|
+
},
|
|
169
|
+
onMouseLeave: (e) => {
|
|
170
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
171
|
+
e.currentTarget.style.boxShadow = "none";
|
|
172
|
+
},
|
|
173
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
174
|
+
"img",
|
|
175
|
+
{
|
|
176
|
+
src: imageUrl,
|
|
177
|
+
alt: ad.title,
|
|
178
|
+
style: {
|
|
179
|
+
width: "100%",
|
|
180
|
+
height: "auto",
|
|
181
|
+
display: "block"
|
|
182
|
+
},
|
|
183
|
+
loading: "lazy"
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
};
|
|
189
|
+
var index_default = AniAds;
|
|
190
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
191
|
+
0 && (module.exports = {
|
|
192
|
+
AniAds
|
|
193
|
+
});
|
|
194
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import React, { useEffect, useState, useCallback } from 'react'\r\n\r\nexport interface AniAdsProps {\r\n creator_code: string\r\n user_wallet_address: string\r\n ad_format: string[] | string // Can be array like [\"16:9\", \"9:16\"] or string like \"16:9,9:16\"\r\n api_url?: string // Optional API URL, defaults to production\r\n onAdClick?: (adId: string, destinationUrl: string) => void // Optional click handler\r\n}\r\n\r\ninterface Ad {\r\n id: string\r\n title: string\r\n destination_url: string\r\n image_square: string\r\n image_portrait: string\r\n image_landscape: string\r\n status: 'active' | 'paused' | 'deleting'\r\n remaining_budget: number\r\n}\r\n\r\nexport const AniAds: React.FC<AniAdsProps> = ({\r\n creator_code,\r\n user_wallet_address,\r\n ad_format,\r\n api_url = 'https://your-domain.com', // Replace with your Ani Ads API domain\r\n onAdClick,\r\n}) => {\r\n const [ad, setAd] = useState<Ad | null>(null)\r\n const [loading, setLoading] = useState(true)\r\n const [error, setError] = useState<string | null>(null)\r\n\r\n // Parse ad format\r\n const formats = Array.isArray(ad_format) \r\n ? ad_format \r\n : typeof ad_format === 'string' \r\n ? ad_format.split(',').map(f => f.trim())\r\n : []\r\n\r\n // Map format strings to image keys\r\n const getImageUrl = (ad: Ad, format: string): string | null => {\r\n const normalizedFormat = format.toLowerCase().replace(/[:\\s]/g, '')\r\n \r\n if (normalizedFormat === '11' || normalizedFormat === '1:1') {\r\n return ad.image_square || null\r\n } else if (normalizedFormat === '916' || normalizedFormat === '9:16') {\r\n return ad.image_portrait || null\r\n } else if (normalizedFormat === '169' || normalizedFormat === '16:9') {\r\n return ad.image_landscape || null\r\n }\r\n \r\n return null\r\n }\r\n\r\n // Fetch available ads\r\n const fetchAd = useCallback(async () => {\r\n try {\r\n setLoading(true)\r\n setError(null)\r\n\r\n const response = await fetch(`${api_url}/api/ads/sdk`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n creator_code,\r\n formats,\r\n }),\r\n })\r\n\r\n if (!response.ok) {\r\n throw new Error('Failed to fetch ads')\r\n }\r\n\r\n const data = await response.json()\r\n \r\n if (data.ad) {\r\n setAd(data.ad)\r\n } else {\r\n setAd(null)\r\n }\r\n } catch (err) {\r\n console.error('Error fetching ad:', err)\r\n setError(err instanceof Error ? err.message : 'Failed to load ad')\r\n setAd(null)\r\n } finally {\r\n setLoading(false)\r\n }\r\n }, [creator_code, formats, api_url])\r\n\r\n // Track ad click\r\n const handleClick = useCallback(async () => {\r\n if (!ad || !user_wallet_address) return\r\n\r\n try {\r\n // Track click on backend\r\n const response = await fetch(`${api_url}/api/ads/click`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n ad_id: ad.id,\r\n creator_code,\r\n user_wallet_address: user_wallet_address.toLowerCase(),\r\n }),\r\n })\r\n\r\n if (response.ok) {\r\n // Call optional click handler\r\n if (onAdClick) {\r\n onAdClick(ad.id, ad.destination_url)\r\n }\r\n\r\n // Open destination URL\r\n window.open(ad.destination_url, '_blank', 'noopener,noreferrer')\r\n\r\n // Fetch new ad after click\r\n await fetchAd()\r\n }\r\n } catch (err) {\r\n console.error('Error tracking click:', err)\r\n // Still open the URL even if tracking fails\r\n window.open(ad.destination_url, '_blank', 'noopener,noreferrer')\r\n }\r\n }, [ad, creator_code, user_wallet_address, api_url, onAdClick, fetchAd])\r\n\r\n // Find best matching image for formats\r\n const getBestImage = (ad: Ad): string | null => {\r\n for (const format of formats) {\r\n const imageUrl = getImageUrl(ad, format)\r\n if (imageUrl) return imageUrl\r\n }\r\n // Fallback to any available image\r\n return ad.image_square || ad.image_portrait || ad.image_landscape || null\r\n }\r\n\r\n useEffect(() => {\r\n if (creator_code && formats.length > 0) {\r\n fetchAd()\r\n } else {\r\n setLoading(false)\r\n }\r\n }, [creator_code, formats, fetchAd])\r\n\r\n if (loading) {\r\n return (\r\n <div style={{\r\n display: 'flex',\r\n width: '100%',\r\n minHeight: '100px',\r\n backgroundColor: '#f3f4f6',\r\n borderRadius: '8px',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n }}>\r\n <span style={{ color: '#6b7280' }}>Loading ad...</span>\r\n </div>\r\n )\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div style={{\r\n display: 'flex',\r\n width: '100%',\r\n minHeight: '100px',\r\n backgroundColor: '#fee2e2',\r\n borderRadius: '8px',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n padding: '12px',\r\n }}>\r\n <span style={{ color: '#dc2626', fontSize: '14px' }}>{error}</span>\r\n </div>\r\n )\r\n }\r\n\r\n if (!ad) {\r\n return null // Don't render anything if no ad available\r\n }\r\n\r\n const imageUrl = getBestImage(ad)\r\n\r\n if (!imageUrl) {\r\n return null\r\n }\r\n\r\n return (\r\n <div\r\n style={{\r\n display: 'inline-block',\r\n width: '100%',\r\n cursor: 'pointer',\r\n borderRadius: '8px',\r\n overflow: 'hidden',\r\n transition: 'transform 0.2s, box-shadow 0.2s',\r\n }}\r\n onClick={handleClick}\r\n onMouseEnter={(e) => {\r\n e.currentTarget.style.transform = 'scale(1.02)'\r\n e.currentTarget.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)'\r\n }}\r\n onMouseLeave={(e) => {\r\n e.currentTarget.style.transform = 'scale(1)'\r\n e.currentTarget.style.boxShadow = 'none'\r\n }}\r\n >\r\n <img\r\n src={imageUrl}\r\n alt={ad.title}\r\n style={{\r\n width: '100%',\r\n height: 'auto',\r\n display: 'block',\r\n }}\r\n loading=\"lazy\"\r\n />\r\n </div>\r\n )\r\n}\r\n\r\nexport default AniAds\r\n\r\n"],"mappings":"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","names":["ad","imageUrl"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// src/index.tsx
|
|
2
|
+
import { useEffect, useState, useCallback } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var AniAds = ({
|
|
5
|
+
creator_code,
|
|
6
|
+
user_wallet_address,
|
|
7
|
+
ad_format,
|
|
8
|
+
api_url = "https://your-domain.com",
|
|
9
|
+
// Replace with your Ani Ads API domain
|
|
10
|
+
onAdClick
|
|
11
|
+
}) => {
|
|
12
|
+
const [ad, setAd] = useState(null);
|
|
13
|
+
const [loading, setLoading] = useState(true);
|
|
14
|
+
const [error, setError] = useState(null);
|
|
15
|
+
const formats = Array.isArray(ad_format) ? ad_format : typeof ad_format === "string" ? ad_format.split(",").map((f) => f.trim()) : [];
|
|
16
|
+
const getImageUrl = (ad2, format) => {
|
|
17
|
+
const normalizedFormat = format.toLowerCase().replace(/[:\s]/g, "");
|
|
18
|
+
if (normalizedFormat === "11" || normalizedFormat === "1:1") {
|
|
19
|
+
return ad2.image_square || null;
|
|
20
|
+
} else if (normalizedFormat === "916" || normalizedFormat === "9:16") {
|
|
21
|
+
return ad2.image_portrait || null;
|
|
22
|
+
} else if (normalizedFormat === "169" || normalizedFormat === "16:9") {
|
|
23
|
+
return ad2.image_landscape || null;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
};
|
|
27
|
+
const fetchAd = useCallback(async () => {
|
|
28
|
+
try {
|
|
29
|
+
setLoading(true);
|
|
30
|
+
setError(null);
|
|
31
|
+
const response = await fetch(`${api_url}/api/ads/sdk`, {
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers: {
|
|
34
|
+
"Content-Type": "application/json"
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify({
|
|
37
|
+
creator_code,
|
|
38
|
+
formats
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new Error("Failed to fetch ads");
|
|
43
|
+
}
|
|
44
|
+
const data = await response.json();
|
|
45
|
+
if (data.ad) {
|
|
46
|
+
setAd(data.ad);
|
|
47
|
+
} else {
|
|
48
|
+
setAd(null);
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
console.error("Error fetching ad:", err);
|
|
52
|
+
setError(err instanceof Error ? err.message : "Failed to load ad");
|
|
53
|
+
setAd(null);
|
|
54
|
+
} finally {
|
|
55
|
+
setLoading(false);
|
|
56
|
+
}
|
|
57
|
+
}, [creator_code, formats, api_url]);
|
|
58
|
+
const handleClick = useCallback(async () => {
|
|
59
|
+
if (!ad || !user_wallet_address) return;
|
|
60
|
+
try {
|
|
61
|
+
const response = await fetch(`${api_url}/api/ads/click`, {
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: {
|
|
64
|
+
"Content-Type": "application/json"
|
|
65
|
+
},
|
|
66
|
+
body: JSON.stringify({
|
|
67
|
+
ad_id: ad.id,
|
|
68
|
+
creator_code,
|
|
69
|
+
user_wallet_address: user_wallet_address.toLowerCase()
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
if (response.ok) {
|
|
73
|
+
if (onAdClick) {
|
|
74
|
+
onAdClick(ad.id, ad.destination_url);
|
|
75
|
+
}
|
|
76
|
+
window.open(ad.destination_url, "_blank", "noopener,noreferrer");
|
|
77
|
+
await fetchAd();
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error("Error tracking click:", err);
|
|
81
|
+
window.open(ad.destination_url, "_blank", "noopener,noreferrer");
|
|
82
|
+
}
|
|
83
|
+
}, [ad, creator_code, user_wallet_address, api_url, onAdClick, fetchAd]);
|
|
84
|
+
const getBestImage = (ad2) => {
|
|
85
|
+
for (const format of formats) {
|
|
86
|
+
const imageUrl2 = getImageUrl(ad2, format);
|
|
87
|
+
if (imageUrl2) return imageUrl2;
|
|
88
|
+
}
|
|
89
|
+
return ad2.image_square || ad2.image_portrait || ad2.image_landscape || null;
|
|
90
|
+
};
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (creator_code && formats.length > 0) {
|
|
93
|
+
fetchAd();
|
|
94
|
+
} else {
|
|
95
|
+
setLoading(false);
|
|
96
|
+
}
|
|
97
|
+
}, [creator_code, formats, fetchAd]);
|
|
98
|
+
if (loading) {
|
|
99
|
+
return /* @__PURE__ */ jsx("div", { style: {
|
|
100
|
+
display: "flex",
|
|
101
|
+
width: "100%",
|
|
102
|
+
minHeight: "100px",
|
|
103
|
+
backgroundColor: "#f3f4f6",
|
|
104
|
+
borderRadius: "8px",
|
|
105
|
+
alignItems: "center",
|
|
106
|
+
justifyContent: "center"
|
|
107
|
+
}, children: /* @__PURE__ */ jsx("span", { style: { color: "#6b7280" }, children: "Loading ad..." }) });
|
|
108
|
+
}
|
|
109
|
+
if (error) {
|
|
110
|
+
return /* @__PURE__ */ jsx("div", { style: {
|
|
111
|
+
display: "flex",
|
|
112
|
+
width: "100%",
|
|
113
|
+
minHeight: "100px",
|
|
114
|
+
backgroundColor: "#fee2e2",
|
|
115
|
+
borderRadius: "8px",
|
|
116
|
+
alignItems: "center",
|
|
117
|
+
justifyContent: "center",
|
|
118
|
+
padding: "12px"
|
|
119
|
+
}, children: /* @__PURE__ */ jsx("span", { style: { color: "#dc2626", fontSize: "14px" }, children: error }) });
|
|
120
|
+
}
|
|
121
|
+
if (!ad) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const imageUrl = getBestImage(ad);
|
|
125
|
+
if (!imageUrl) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
return /* @__PURE__ */ jsx(
|
|
129
|
+
"div",
|
|
130
|
+
{
|
|
131
|
+
style: {
|
|
132
|
+
display: "inline-block",
|
|
133
|
+
width: "100%",
|
|
134
|
+
cursor: "pointer",
|
|
135
|
+
borderRadius: "8px",
|
|
136
|
+
overflow: "hidden",
|
|
137
|
+
transition: "transform 0.2s, box-shadow 0.2s"
|
|
138
|
+
},
|
|
139
|
+
onClick: handleClick,
|
|
140
|
+
onMouseEnter: (e) => {
|
|
141
|
+
e.currentTarget.style.transform = "scale(1.02)";
|
|
142
|
+
e.currentTarget.style.boxShadow = "0 4px 12px rgba(0,0,0,0.15)";
|
|
143
|
+
},
|
|
144
|
+
onMouseLeave: (e) => {
|
|
145
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
146
|
+
e.currentTarget.style.boxShadow = "none";
|
|
147
|
+
},
|
|
148
|
+
children: /* @__PURE__ */ jsx(
|
|
149
|
+
"img",
|
|
150
|
+
{
|
|
151
|
+
src: imageUrl,
|
|
152
|
+
alt: ad.title,
|
|
153
|
+
style: {
|
|
154
|
+
width: "100%",
|
|
155
|
+
height: "auto",
|
|
156
|
+
display: "block"
|
|
157
|
+
},
|
|
158
|
+
loading: "lazy"
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
);
|
|
163
|
+
};
|
|
164
|
+
var index_default = AniAds;
|
|
165
|
+
export {
|
|
166
|
+
AniAds,
|
|
167
|
+
index_default as default
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import React, { useEffect, useState, useCallback } from 'react'\r\n\r\nexport interface AniAdsProps {\r\n creator_code: string\r\n user_wallet_address: string\r\n ad_format: string[] | string // Can be array like [\"16:9\", \"9:16\"] or string like \"16:9,9:16\"\r\n api_url?: string // Optional API URL, defaults to production\r\n onAdClick?: (adId: string, destinationUrl: string) => void // Optional click handler\r\n}\r\n\r\ninterface Ad {\r\n id: string\r\n title: string\r\n destination_url: string\r\n image_square: string\r\n image_portrait: string\r\n image_landscape: string\r\n status: 'active' | 'paused' | 'deleting'\r\n remaining_budget: number\r\n}\r\n\r\nexport const AniAds: React.FC<AniAdsProps> = ({\r\n creator_code,\r\n user_wallet_address,\r\n ad_format,\r\n api_url = 'https://your-domain.com', // Replace with your Ani Ads API domain\r\n onAdClick,\r\n}) => {\r\n const [ad, setAd] = useState<Ad | null>(null)\r\n const [loading, setLoading] = useState(true)\r\n const [error, setError] = useState<string | null>(null)\r\n\r\n // Parse ad format\r\n const formats = Array.isArray(ad_format) \r\n ? ad_format \r\n : typeof ad_format === 'string' \r\n ? ad_format.split(',').map(f => f.trim())\r\n : []\r\n\r\n // Map format strings to image keys\r\n const getImageUrl = (ad: Ad, format: string): string | null => {\r\n const normalizedFormat = format.toLowerCase().replace(/[:\\s]/g, '')\r\n \r\n if (normalizedFormat === '11' || normalizedFormat === '1:1') {\r\n return ad.image_square || null\r\n } else if (normalizedFormat === '916' || normalizedFormat === '9:16') {\r\n return ad.image_portrait || null\r\n } else if (normalizedFormat === '169' || normalizedFormat === '16:9') {\r\n return ad.image_landscape || null\r\n }\r\n \r\n return null\r\n }\r\n\r\n // Fetch available ads\r\n const fetchAd = useCallback(async () => {\r\n try {\r\n setLoading(true)\r\n setError(null)\r\n\r\n const response = await fetch(`${api_url}/api/ads/sdk`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n creator_code,\r\n formats,\r\n }),\r\n })\r\n\r\n if (!response.ok) {\r\n throw new Error('Failed to fetch ads')\r\n }\r\n\r\n const data = await response.json()\r\n \r\n if (data.ad) {\r\n setAd(data.ad)\r\n } else {\r\n setAd(null)\r\n }\r\n } catch (err) {\r\n console.error('Error fetching ad:', err)\r\n setError(err instanceof Error ? err.message : 'Failed to load ad')\r\n setAd(null)\r\n } finally {\r\n setLoading(false)\r\n }\r\n }, [creator_code, formats, api_url])\r\n\r\n // Track ad click\r\n const handleClick = useCallback(async () => {\r\n if (!ad || !user_wallet_address) return\r\n\r\n try {\r\n // Track click on backend\r\n const response = await fetch(`${api_url}/api/ads/click`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n ad_id: ad.id,\r\n creator_code,\r\n user_wallet_address: user_wallet_address.toLowerCase(),\r\n }),\r\n })\r\n\r\n if (response.ok) {\r\n // Call optional click handler\r\n if (onAdClick) {\r\n onAdClick(ad.id, ad.destination_url)\r\n }\r\n\r\n // Open destination URL\r\n window.open(ad.destination_url, '_blank', 'noopener,noreferrer')\r\n\r\n // Fetch new ad after click\r\n await fetchAd()\r\n }\r\n } catch (err) {\r\n console.error('Error tracking click:', err)\r\n // Still open the URL even if tracking fails\r\n window.open(ad.destination_url, '_blank', 'noopener,noreferrer')\r\n }\r\n }, [ad, creator_code, user_wallet_address, api_url, onAdClick, fetchAd])\r\n\r\n // Find best matching image for formats\r\n const getBestImage = (ad: Ad): string | null => {\r\n for (const format of formats) {\r\n const imageUrl = getImageUrl(ad, format)\r\n if (imageUrl) return imageUrl\r\n }\r\n // Fallback to any available image\r\n return ad.image_square || ad.image_portrait || ad.image_landscape || null\r\n }\r\n\r\n useEffect(() => {\r\n if (creator_code && formats.length > 0) {\r\n fetchAd()\r\n } else {\r\n setLoading(false)\r\n }\r\n }, [creator_code, formats, fetchAd])\r\n\r\n if (loading) {\r\n return (\r\n <div style={{\r\n display: 'flex',\r\n width: '100%',\r\n minHeight: '100px',\r\n backgroundColor: '#f3f4f6',\r\n borderRadius: '8px',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n }}>\r\n <span style={{ color: '#6b7280' }}>Loading ad...</span>\r\n </div>\r\n )\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div style={{\r\n display: 'flex',\r\n width: '100%',\r\n minHeight: '100px',\r\n backgroundColor: '#fee2e2',\r\n borderRadius: '8px',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n padding: '12px',\r\n }}>\r\n <span style={{ color: '#dc2626', fontSize: '14px' }}>{error}</span>\r\n </div>\r\n )\r\n }\r\n\r\n if (!ad) {\r\n return null // Don't render anything if no ad available\r\n }\r\n\r\n const imageUrl = getBestImage(ad)\r\n\r\n if (!imageUrl) {\r\n return null\r\n }\r\n\r\n return (\r\n <div\r\n style={{\r\n display: 'inline-block',\r\n width: '100%',\r\n cursor: 'pointer',\r\n borderRadius: '8px',\r\n overflow: 'hidden',\r\n transition: 'transform 0.2s, box-shadow 0.2s',\r\n }}\r\n onClick={handleClick}\r\n onMouseEnter={(e) => {\r\n e.currentTarget.style.transform = 'scale(1.02)'\r\n e.currentTarget.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)'\r\n }}\r\n onMouseLeave={(e) => {\r\n e.currentTarget.style.transform = 'scale(1)'\r\n e.currentTarget.style.boxShadow = 'none'\r\n }}\r\n >\r\n <img\r\n src={imageUrl}\r\n alt={ad.title}\r\n style={{\r\n width: '100%',\r\n height: 'auto',\r\n display: 'block',\r\n }}\r\n loading=\"lazy\"\r\n />\r\n </div>\r\n )\r\n}\r\n\r\nexport default AniAds\r\n\r\n"],"mappings":"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","names":["ad","imageUrl"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ani-ads-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Ani Ads SDK for Mini App Creators to display ads in their apps",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsup",
|
|
13
|
+
"dev": "tsup --watch"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ads",
|
|
17
|
+
"worldchain",
|
|
18
|
+
"world-app",
|
|
19
|
+
"mini-app"
|
|
20
|
+
],
|
|
21
|
+
"author": "",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/react": "^19",
|
|
25
|
+
"@types/react-dom": "^19",
|
|
26
|
+
"tsup": "^8.0.0",
|
|
27
|
+
"typescript": "^5"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
31
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"react": "^19.2.0",
|
|
35
|
+
"react-dom": "^19.2.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|