@1selfworld/adchain-sdk-react-native 1.0.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/src/index.tsx ADDED
@@ -0,0 +1,274 @@
1
+ import { NativeModules, Platform, NativeEventEmitter } from 'react-native';
2
+ import Constants from 'expo-constants';
3
+
4
+ const LINKING_ERROR =
5
+ `The package 'adchain-sdk' doesn't seem to be linked. Make sure: \n\n` +
6
+ Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
7
+ '- You rebuilt the app after installing the package\n' +
8
+ '- You are not using Expo Go\n';
9
+
10
+ const AdchainSdk = NativeModules.AdchainSdk
11
+ ? NativeModules.AdchainSdk
12
+ : new Proxy(
13
+ {},
14
+ {
15
+ get() {
16
+ throw new Error(LINKING_ERROR);
17
+ },
18
+ }
19
+ );
20
+
21
+ // Event Emitter 생성
22
+ const adchainEventEmitter = new NativeEventEmitter(AdchainSdk);
23
+
24
+ // ===== Type Definitions =====
25
+
26
+ export interface AdchainConfig {
27
+ appKey: string;
28
+ appSecret: string;
29
+ environment?: 'PRODUCTION' | 'STAGING' | 'DEVELOPMENT';
30
+ timeout?: number;
31
+ }
32
+
33
+ export interface AdchainUser {
34
+ userId: string;
35
+ gender?: 'MALE' | 'FEMALE' | 'OTHER' | 'M' | 'F';
36
+ birthYear?: number;
37
+ customProperties?: Record<string, string>;
38
+ }
39
+
40
+ export interface Quiz {
41
+ id: string;
42
+ title: string;
43
+ description: string;
44
+ imageUrl: string;
45
+ reward: number;
46
+ isCompleted: boolean;
47
+ }
48
+
49
+ export interface QuizResponse {
50
+ success: boolean;
51
+ titleText?: string;
52
+ completedImageUrl?: string;
53
+ completedImageWidth?: number;
54
+ completedImageHeight?: number;
55
+ events: Quiz[];
56
+ message?: string;
57
+ }
58
+
59
+ export interface Mission {
60
+ id: string;
61
+ title: string;
62
+ description: string;
63
+ imageUrl: string;
64
+ reward: number;
65
+ isCompleted: boolean;
66
+ type: string;
67
+ actionUrl: string;
68
+ }
69
+
70
+ export interface MissionListResponse {
71
+ missions: Mission[];
72
+ completedCount: number;
73
+ totalCount: number;
74
+ canClaimReward: boolean;
75
+ }
76
+
77
+ export interface SuccessResponse {
78
+ success: boolean;
79
+ message: string;
80
+ }
81
+
82
+ // ===== SDK Class =====
83
+
84
+ class AdchainSDK {
85
+ // 1. SDK 초기화
86
+ async initialize(config: AdchainConfig): Promise<SuccessResponse> {
87
+ // options 객체로 environment와 timeout 전달
88
+ const options = {
89
+ environment: config.environment,
90
+ timeout: config.timeout
91
+ };
92
+
93
+ return AdchainSdk.initialize(
94
+ config.appKey,
95
+ config.appSecret,
96
+ options
97
+ );
98
+ }
99
+
100
+ // Expo용 자동 초기화 (app.json 설정 사용) - 플랫폼별 credentials 지원
101
+ async autoInitialize(): Promise<SuccessResponse> {
102
+ try {
103
+ const expoConfig = Constants.expoConfig;
104
+
105
+ if (!expoConfig) {
106
+ throw new Error(
107
+ 'AdChain: Expo config not found. ' +
108
+ 'Are you running in Expo Go? This SDK requires a development build. ' +
109
+ 'Please use: npx expo run:android or npx expo run:ios'
110
+ );
111
+ }
112
+
113
+ const {
114
+ adchainAndroidAppKey,
115
+ adchainAndroidAppSecret,
116
+ adchainIosAppKey,
117
+ adchainIosAppSecret,
118
+ adchainEnvironment,
119
+ adchainTimeout
120
+ } = expoConfig.extra || {};
121
+
122
+ // 플랫폼별 credentials 선택
123
+ const isIOS = Platform.OS === 'ios';
124
+ const appKey = isIOS ? adchainIosAppKey : adchainAndroidAppKey;
125
+ const appSecret = isIOS ? adchainIosAppSecret : adchainAndroidAppSecret;
126
+
127
+ if (!appKey || !appSecret) {
128
+ throw new Error(
129
+ `AdChain: Missing ${Platform.OS} configuration in app.json. ` +
130
+ 'Please add AdChain SDK to plugins section:\n\n' +
131
+ '{\n' +
132
+ ' "expo": {\n' +
133
+ ' "plugins": [\n' +
134
+ ' ["@adchain/expo-sdk", {\n' +
135
+ ' "android": {\n' +
136
+ ' "appKey": "YOUR_ANDROID_APP_KEY",\n' +
137
+ ' "appSecret": "YOUR_APP_SECRET"\n' +
138
+ ' },\n' +
139
+ ' "ios": {\n' +
140
+ ' "appKey": "YOUR_IOS_APP_KEY",\n' +
141
+ ' "appSecret": "YOUR_APP_SECRET"\n' +
142
+ ' }\n' +
143
+ ' }]\n' +
144
+ ' ]\n' +
145
+ ' }\n' +
146
+ '}'
147
+ );
148
+ }
149
+
150
+ console.log(`[AdChain] Auto-initializing with ${Platform.OS} credentials...`);
151
+
152
+ return await this.initialize({
153
+ appKey,
154
+ appSecret,
155
+ environment: adchainEnvironment || 'PRODUCTION',
156
+ timeout: adchainTimeout
157
+ });
158
+ } catch (error) {
159
+ console.error('[AdChain autoInitialize] Failed:', error);
160
+ throw error;
161
+ }
162
+ }
163
+
164
+ // 2. 인증 관련 (4개)
165
+ async login(user: AdchainUser): Promise<SuccessResponse> {
166
+ // userInfo 객체로 모든 정보 전달
167
+ const userInfo = {
168
+ gender: user.gender,
169
+ birthYear: user.birthYear,
170
+ customProperties: user.customProperties
171
+ };
172
+
173
+ return AdchainSdk.login(
174
+ user.userId,
175
+ userInfo
176
+ );
177
+ }
178
+
179
+ async logout(): Promise<SuccessResponse> {
180
+ return AdchainSdk.logout();
181
+ }
182
+
183
+ async isLoggedIn(): Promise<boolean> {
184
+ return AdchainSdk.isLoggedIn();
185
+ }
186
+
187
+ async getCurrentUser(): Promise<AdchainUser | null> {
188
+ return AdchainSdk.getCurrentUser();
189
+ }
190
+
191
+ // 3. Quiz 관련 (2개)
192
+ async loadQuizList(unitId: string): Promise<QuizResponse> {
193
+ return AdchainSdk.loadQuizList(unitId);
194
+ }
195
+
196
+ async clickQuiz(unitId: string, quizId: string): Promise<SuccessResponse> {
197
+ return AdchainSdk.clickQuiz(unitId, quizId);
198
+ }
199
+
200
+ // 4. Mission 관련 (3개)
201
+ async loadMissionList(unitId: string): Promise<MissionListResponse> {
202
+ return AdchainSdk.loadMissionList(unitId);
203
+ }
204
+
205
+ async clickMission(unitId: string, missionId: string): Promise<SuccessResponse> {
206
+ return AdchainSdk.clickMission(unitId, missionId);
207
+ }
208
+
209
+ async claimReward(unitId: string): Promise<SuccessResponse> {
210
+ return AdchainSdk.claimReward(unitId);
211
+ }
212
+
213
+ // 5. Offerwall (3개)
214
+ async openOfferwall(placementId?: string): Promise<SuccessResponse> {
215
+ // SDK requires placementId, use empty string if not provided
216
+ return AdchainSdk.openOfferwall(placementId || "");
217
+ }
218
+
219
+ async openOfferwallWithUrl(url: string, placementId?: string): Promise<SuccessResponse> {
220
+ // SDK requires placementId, use empty string if not provided
221
+ return AdchainSdk.openOfferwallWithUrl(url, placementId || "");
222
+ }
223
+
224
+ async openExternalBrowser(url: string, placementId?: string): Promise<SuccessResponse> {
225
+ // SDK requires placementId, use empty string if not provided
226
+ return AdchainSdk.openExternalBrowser(url, placementId || "");
227
+ }
228
+
229
+ async openAdjoeOfferwall(placementId?: string): Promise<SuccessResponse> {
230
+ // SDK requires placementId, use empty string if not provided
231
+ return AdchainSdk.openAdjoeOfferwall(placementId || "");
232
+ }
233
+
234
+ // 6. Debug/Utility Methods (3개)
235
+ async isInitialized(): Promise<boolean> {
236
+ return AdchainSdk.isInitialized();
237
+ }
238
+
239
+ async getUserId(): Promise<string> {
240
+ return AdchainSdk.getUserId();
241
+ }
242
+
243
+ async getIFA(): Promise<string> {
244
+ return AdchainSdk.getIFA();
245
+ }
246
+
247
+ // 7. Banner (1개)
248
+ async getBannerInfo(placementId: string): Promise<any> {
249
+ return AdchainSdk.getBannerInfo(placementId);
250
+ }
251
+ }
252
+
253
+ // ===== Event Helper Functions =====
254
+
255
+ export function addQuizCompletedListener(callback: (event: { quizId: string; unitId: string }) => void) {
256
+ return adchainEventEmitter.addListener('onQuizCompleted', callback as any);
257
+ }
258
+
259
+ export function addMissionCompletedListener(callback: (event: { missionId: string; unitId: string }) => void) {
260
+ return adchainEventEmitter.addListener('onMissionCompleted', callback as any);
261
+ }
262
+
263
+ export function addMissionProgressedListener(callback: (event: { missionId: string; unitId: string }) => void) {
264
+ return adchainEventEmitter.addListener('onMissionProgressed', callback as any);
265
+ }
266
+
267
+ export function addMissionRefreshedListener(callback: (event: { unitId: string }) => void) {
268
+ return adchainEventEmitter.addListener('onMissionRefreshed', callback as any);
269
+ }
270
+
271
+ // ===== Export =====
272
+
273
+ const sdk = new AdchainSDK();
274
+ export default sdk;