@gabagool-sdk/react-native 0.1.1 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.2.1
2
+
3
+ * `GabagoolAds.setRewardedSsv({ userId?, customData? })`: SSV do rewarded, mesma semântica do Dart e do core (antes ou depois do `init`; `userId` > `identify`; `customData` ≤ 1024). O adapter aplica `serverSideVerificationOptions` (`react-native-google-mobile-ads` 17.x) no `RewardedAd.createForAdRequest`. Não testado em aparelho. Requer `@gabagool-sdk/core` ^0.2.1.
4
+
5
+ ## 0.2.0
6
+
7
+ * `GabagoolAds.onPaidEvent` (e opção `onPaidEvent` no `init`): receita de toda impressão, repassada do core. O lado nativo do RN continua parcial (API presente; emissão coberta pelos testes do core). Requer `@gabagool-sdk/core` ^0.2.0.
8
+
1
9
  ## 0.1.1
2
10
 
3
11
  * First release published through GitHub Actions trusted publishing (no functional changes).
package/README.md CHANGED
@@ -5,7 +5,7 @@ O servidor Gabagool decide segmento, ad units e pisos a cada `init`; o piso vai
5
5
  **key-value de targeting** (a key de piso é configurada no painel Gabagool, com a grafia exata do
6
6
  valor do piso). Sem configuração do servidor, o SDK não exibe anúncios.
7
7
 
8
- **Limitação da versão 0.1.0:** o formato **native** ainda não é suportado neste pacote
8
+ **Limitação da versão 0.2.0:** o formato **native** ainda não é suportado neste pacote
9
9
  (interstitial, rewarded, banner e app open já funcionam). Android é o alvo testado;
10
10
  no iOS, passe `installInfoProvider` no `init` (o plugin de Play Install Referrer é Android-only).
11
11
 
@@ -62,6 +62,14 @@ const result = await GabagoolAds.showInterstitial('home');
62
62
  const reward = await GabagoolAds.showRewarded('bonus');
63
63
  ```
64
64
 
65
+ **SSV (Server-Side Verification)**: para validar a recompensa no seu backend, defina `userId`/`customData` (antes ou depois do `init`; sem `userId`, vale o do `identify`):
66
+
67
+ ```tsx
68
+ GabagoolAds.setRewardedSsv({ userId: 'user-123', customData: '{"pack":"coins_50"}' });
69
+ ```
70
+
71
+ Vira `serverSideVerificationOptions` do `react-native-google-mobile-ads` no load do rewarded (`customData` até 1024 chars). Callback, assinatura e limites: `docs/SSV-REWARDED.md`. Não testado em aparelho nem contra o callback real do Google.
72
+
65
73
  ### Banner
66
74
 
67
75
  ```tsx
package/dist/adapter.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type AdHandle, type AdNetworkAdapter, type FloorKV, type LoadResult, type ShowResult } from '@gabagool-sdk/core';
1
+ import { type AdHandle, type AdNetworkAdapter, type FloorKV, type LoadResult, type RewardedLoadOptions, type ShowResult } from '@gabagool-sdk/core';
2
2
  /** Adapter do core para a API estável do Invertase 17.x. */
3
3
  export declare class ReactNativeGmaAdapter implements AdNetworkAdapter {
4
4
  private sequence;
@@ -9,7 +9,7 @@ export declare class ReactNativeGmaAdapter implements AdNetworkAdapter {
9
9
  /** Falha do initialize() não trava o app (como a Dart): segue e os loads reportam seus próprios erros. */
10
10
  initialize(): Promise<void>;
11
11
  loadInterstitial(adUnit: string, floorKV?: FloorKV): Promise<LoadResult>;
12
- loadRewarded(adUnit: string, floorKV?: FloorKV): Promise<LoadResult>;
12
+ loadRewarded(adUnit: string, floorKV?: FloorKV, opts?: RewardedLoadOptions): Promise<LoadResult>;
13
13
  loadAppOpen(adUnit: string, floorKV?: FloorKV): Promise<LoadResult>;
14
14
  loadBanner(adUnit: string, _floorKV?: FloorKV): Promise<LoadResult>;
15
15
  /** Native ainda não portado para RN (Invertase NativeAd): reporta erro explícito, nunca fill falso. */
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AA4B5B,4DAA4D;AAC5D,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAE5D,0GAA0G;IAC1G,QAAQ,CAAC,6BAA6B,QAAQ;IAE9C,0GAA0G;IACpG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAGxE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAGpE,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAWzE,uGAAuG;IACjG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAI1E,gBAAgB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;IAI9B,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,OAAO,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;IAM3B,IAAI,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAuCvC,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,MAAM;CAGf"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,mBAAmB,EAExB,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AA+B5B,4DAA4D;AAC5D,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAE5D,0GAA0G;IAC1G,QAAQ,CAAC,6BAA6B,QAAQ;IAE9C,0GAA0G;IACpG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAGxE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAGhG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAWzE,uGAAuG;IACjG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAI1E,gBAAgB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;IAI9B,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,OAAO,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;IAM3B,IAAI,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAuCvC,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,MAAM;CAGf"}
package/dist/adapter.js CHANGED
@@ -24,8 +24,8 @@ export class ReactNativeGmaAdapter {
24
24
  loadInterstitial(adUnit, floorKV) {
25
25
  return this.loadFullscreen('interstitial', adUnit, floorKV);
26
26
  }
27
- loadRewarded(adUnit, floorKV) {
28
- return this.loadFullscreen('rewarded', adUnit, floorKV);
27
+ loadRewarded(adUnit, floorKV, opts) {
28
+ return this.loadFullscreen('rewarded', adUnit, floorKV, opts?.ssv);
29
29
  }
30
30
  loadAppOpen(adUnit, floorKV) {
31
31
  return this.loadFullscreen('app_open', adUnit, floorKV);
@@ -99,11 +99,11 @@ export class ReactNativeGmaAdapter {
99
99
  }
100
100
  });
101
101
  }
102
- loadFullscreen(format, adUnit, floorKV) {
102
+ loadFullscreen(format, adUnit, floorKV, ssv) {
103
103
  return new Promise((resolve) => {
104
104
  let native;
105
105
  try {
106
- const request = this.requestOptions(adUnit, floorKV);
106
+ const request = this.requestOptions(adUnit, floorKV, format === 'rewarded' ? ssv : undefined);
107
107
  const created = format === 'app_open'
108
108
  ? AppOpenAd.createForAdRequest(adUnit, request)
109
109
  : format === 'rewarded'
@@ -149,9 +149,13 @@ export class ReactNativeGmaAdapter {
149
149
  }
150
150
  });
151
151
  }
152
- requestOptions(adUnit, floorKV) {
152
+ requestOptions(adUnit, floorKV, ssv) {
153
153
  const kv = this.requestFloor(adUnit, floorKV);
154
- return kv ? { customTargeting: kv } : undefined;
154
+ // Invertase: RequestOptions.serverSideVerificationOptions { userId, customData } (só no RewardedAd; vazio => omitido)
155
+ const ssvOptions = ssv && (ssv.userId !== undefined || ssv.customData !== undefined)
156
+ ? { serverSideVerificationOptions: { ...(ssv.userId !== undefined ? { userId: ssv.userId } : {}), ...(ssv.customData !== undefined ? { customData: ssv.customData } : {}) } }
157
+ : {};
158
+ return kv || ssvOptions.serverSideVerificationOptions ? { ...(kv ? { customTargeting: kv } : {}), ...ssvOptions } : undefined;
155
159
  }
156
160
  requestFloor(adUnit, floorKV) {
157
161
  return networkOf(adUnit) === 'gam' && floorKV && Object.keys(floorKV).length > 0 ? { ...floorKV } : undefined;
package/dist/facade.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type AdHandle, type AdNetworkAdapter, type BootAdResult, type FetchLike, type Gabagool, type GateResult, type InterstitialShowResult, type KVStorage, type RewardedResult, type TelemetryTransport, type WrapperConfig } from '@gabagool-sdk/core';
1
+ import { type AdHandle, type AdNetworkAdapter, type BootAdResult, type FetchLike, type Gabagool, type GateResult, type InterstitialShowResult, type KVStorage, type OnPaidEvent, type RewardedResult, type RewardedSsv, type TelemetryTransport, type WrapperConfig } from '@gabagool-sdk/core';
2
2
  import { ReactNativeGmaAdapter } from './adapter.js';
3
3
  import { type InstallInfoProvider } from './installInfo.js';
4
4
  export interface GabagoolInitOptions {
@@ -20,6 +20,8 @@ export interface GabagoolInitOptions {
20
20
  advertisingId?: string;
21
21
  debug?: boolean;
22
22
  context?: Record<string, unknown>;
23
+ /** atalho para `GabagoolAds.onPaidEvent` */
24
+ onPaidEvent?: OnPaidEvent;
23
25
  }
24
26
  /** Fachada singleton equivalente à fachada Dart. */
25
27
  export declare class GabagoolAds {
@@ -31,6 +33,19 @@ export declare class GabagoolAds {
31
33
  /** Resolve quando o `init` terminou (Banner pode montar antes; ver BannerFlow). Nunca rejeita. */
32
34
  static whenReady(): Promise<void>;
33
35
  private static resetReady;
36
+ /**
37
+ * Receita de TODA impressão (fullscreen, banner e native), para o app repassar a Firebase/Meta/MMP. Disparado além da
38
+ * telemetria; exceção do callback é engolida. Pode ser atribuído antes ou depois do `init`.
39
+ */
40
+ static onPaidEvent: OnPaidEvent | null;
41
+ /** SSV guardado aqui: setRewardedSsv antes do init sobrevive à recriação do core. */
42
+ private static ssv;
43
+ /**
44
+ * SSV do rewarded (Server-Side Verification): `userId`/`customData` chegam no callback do Google ao seu backend.
45
+ * Vale antes ou depois do `init` (próximos loads; um rewarded já carregado mantém o que tinha). Sem `userId`, usa o do
46
+ * `identify`. Sem argumentos limpa. `customData` acima de 1024 chars é cortado (com aviso). Ver docs/SSV-REWARDED.md.
47
+ */
48
+ static setRewardedSsv(ssv?: RewardedSsv): void;
34
49
  static get core(): Gabagool;
35
50
  static init(apiKey: string, baseUrl: string, appId: string, options?: GabagoolInitOptions): Promise<void>;
36
51
  static showInterstitial(screen?: string): Promise<InterstitialShowResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"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"}
package/dist/facade.js CHANGED
@@ -23,12 +23,31 @@ export class GabagoolAds {
23
23
  if (this.readyState.done)
24
24
  this.readyState = this.newReady();
25
25
  }
26
+ /**
27
+ * Receita de TODA impressão (fullscreen, banner e native), para o app repassar a Firebase/Meta/MMP. Disparado além da
28
+ * telemetria; exceção do callback é engolida. Pode ser atribuído antes ou depois do `init`.
29
+ */
30
+ static onPaidEvent = null;
31
+ /** SSV guardado aqui: setRewardedSsv antes do init sobrevive à recriação do core. */
32
+ static ssv;
33
+ /**
34
+ * SSV do rewarded (Server-Side Verification): `userId`/`customData` chegam no callback do Google ao seu backend.
35
+ * Vale antes ou depois do `init` (próximos loads; um rewarded já carregado mantém o que tinha). Sem `userId`, usa o do
36
+ * `identify`. Sem argumentos limpa. `customData` acima de 1024 chars é cortado (com aviso). Ver docs/SSV-REWARDED.md.
37
+ */
38
+ static setRewardedSsv(ssv) {
39
+ this.ssv = ssv;
40
+ this.instance.setRewardedSsv(ssv);
41
+ }
26
42
  static get core() { return this.instance; }
27
43
  static async init(apiKey, baseUrl, appId, options = {}) {
44
+ if (options.onPaidEvent)
45
+ this.onPaidEvent = options.onPaidEvent;
28
46
  this.lifecycle?.stop();
29
47
  this.instance.dispose();
30
48
  this.resetReady();
31
49
  this.instance = createGabagool();
50
+ this.instance.setRewardedSsv(this.ssv);
32
51
  const adapter = options.adapter ?? new ReactNativeGmaAdapter();
33
52
  this.gmaAdapter = adapter instanceof ReactNativeGmaAdapter ? adapter : null;
34
53
  if (this.gmaAdapter)
@@ -71,6 +90,7 @@ export class GabagoolAds {
71
90
  ...(options.context ?? {}),
72
91
  },
73
92
  debug: options.debug === true,
93
+ onPaidEvent: (e) => GabagoolAds.onPaidEvent?.(e),
74
94
  });
75
95
  this.lifecycle = new AppStateLifecycle(this.instance);
76
96
  this.lifecycle.start();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gabagool-sdk/react-native",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "React Native SDK for Gabagool Apps monetization: interstitial, rewarded and banner ads with server-side config, price floors and gating, on top of Google Mobile Ads (Ad Manager / AdMob).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "prepack": "npm run build"
24
24
  },
25
25
  "dependencies": {
26
- "@gabagool-sdk/core": "^0.1.0"
26
+ "@gabagool-sdk/core": "^0.2.1"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "@react-native-async-storage/async-storage": "^3.1.1",
package/src/adapter.ts CHANGED
@@ -15,9 +15,14 @@ import {
15
15
  type AdNetworkAdapter,
16
16
  type FloorKV,
17
17
  type LoadResult,
18
+ type RewardedLoadOptions,
19
+ type RewardedSsv,
18
20
  type ShowResult,
19
21
  } from '@gabagool-sdk/core';
20
- type RequestOptions = { customTargeting?: Record<string, string | number | (string | number)[]> };
22
+ type RequestOptions = {
23
+ customTargeting?: Record<string, string | number | (string | number)[]>;
24
+ serverSideVerificationOptions?: { userId?: string; customData?: string };
25
+ };
21
26
 
22
27
  type Remove = () => void;
23
28
  type EventPayload = Error & { code?: string; reason?: string; phase?: 'load' | 'show' };
@@ -61,8 +66,8 @@ export class ReactNativeGmaAdapter implements AdNetworkAdapter {
61
66
  loadInterstitial(adUnit: string, floorKV?: FloorKV): Promise<LoadResult> {
62
67
  return this.loadFullscreen('interstitial', adUnit, floorKV);
63
68
  }
64
- loadRewarded(adUnit: string, floorKV?: FloorKV): Promise<LoadResult> {
65
- return this.loadFullscreen('rewarded', adUnit, floorKV);
69
+ loadRewarded(adUnit: string, floorKV?: FloorKV, opts?: RewardedLoadOptions): Promise<LoadResult> {
70
+ return this.loadFullscreen('rewarded', adUnit, floorKV, opts?.ssv);
66
71
  }
67
72
  loadAppOpen(adUnit: string, floorKV?: FloorKV): Promise<LoadResult> {
68
73
  return this.loadFullscreen('app_open', adUnit, floorKV);
@@ -137,11 +142,11 @@ export class ReactNativeGmaAdapter implements AdNetworkAdapter {
137
142
  });
138
143
  }
139
144
 
140
- private loadFullscreen(format: Exclude<AdFormat, 'banner'>, adUnit: string, floorKV?: FloorKV): Promise<LoadResult> {
145
+ private loadFullscreen(format: Exclude<AdFormat, 'banner'>, adUnit: string, floorKV?: FloorKV, ssv?: RewardedSsv): Promise<LoadResult> {
141
146
  return new Promise((resolve) => {
142
147
  let native: NativeFullscreen;
143
148
  try {
144
- const request = this.requestOptions(adUnit, floorKV);
149
+ const request = this.requestOptions(adUnit, floorKV, format === 'rewarded' ? ssv : undefined);
145
150
  const created = format === 'app_open'
146
151
  ? AppOpenAd.createForAdRequest(adUnit, request)
147
152
  : format === 'rewarded'
@@ -178,9 +183,13 @@ export class ReactNativeGmaAdapter implements AdNetworkAdapter {
178
183
  });
179
184
  }
180
185
 
181
- private requestOptions(adUnit: string, floorKV?: FloorKV): RequestOptions | undefined {
186
+ private requestOptions(adUnit: string, floorKV?: FloorKV, ssv?: RewardedSsv): RequestOptions | undefined {
182
187
  const kv = this.requestFloor(adUnit, floorKV);
183
- return kv ? { customTargeting: kv } : undefined;
188
+ // Invertase: RequestOptions.serverSideVerificationOptions { userId, customData } (só no RewardedAd; vazio => omitido)
189
+ const ssvOptions = ssv && (ssv.userId !== undefined || ssv.customData !== undefined)
190
+ ? { serverSideVerificationOptions: { ...(ssv.userId !== undefined ? { userId: ssv.userId } : {}), ...(ssv.customData !== undefined ? { customData: ssv.customData } : {}) } }
191
+ : {};
192
+ return kv || ssvOptions.serverSideVerificationOptions ? { ...(kv ? { customTargeting: kv } : {}), ...ssvOptions } : undefined;
184
193
  }
185
194
 
186
195
  private requestFloor(adUnit: string, floorKV?: FloorKV): FloorKV | undefined {
package/src/facade.ts CHANGED
@@ -11,7 +11,9 @@ import {
11
11
  type GateResult,
12
12
  type InterstitialShowResult,
13
13
  type KVStorage,
14
+ type OnPaidEvent,
14
15
  type RewardedResult,
16
+ type RewardedSsv,
15
17
  type TelemetryTransport,
16
18
  type WrapperConfig,
17
19
  } from '@gabagool-sdk/core';
@@ -40,6 +42,8 @@ export interface GabagoolInitOptions {
40
42
  advertisingId?: string;
41
43
  debug?: boolean;
42
44
  context?: Record<string, unknown>;
45
+ /** atalho para `GabagoolAds.onPaidEvent` */
46
+ onPaidEvent?: OnPaidEvent;
43
47
  }
44
48
 
45
49
  /** Fachada singleton equivalente à fachada Dart. */
@@ -62,13 +66,34 @@ export class GabagoolAds {
62
66
  if (this.readyState.done) this.readyState = this.newReady();
63
67
  }
64
68
 
69
+ /**
70
+ * Receita de TODA impressão (fullscreen, banner e native), para o app repassar a Firebase/Meta/MMP. Disparado além da
71
+ * telemetria; exceção do callback é engolida. Pode ser atribuído antes ou depois do `init`.
72
+ */
73
+ static onPaidEvent: OnPaidEvent | null = null;
74
+
75
+ /** SSV guardado aqui: setRewardedSsv antes do init sobrevive à recriação do core. */
76
+ private static ssv: RewardedSsv | undefined;
77
+
78
+ /**
79
+ * SSV do rewarded (Server-Side Verification): `userId`/`customData` chegam no callback do Google ao seu backend.
80
+ * Vale antes ou depois do `init` (próximos loads; um rewarded já carregado mantém o que tinha). Sem `userId`, usa o do
81
+ * `identify`. Sem argumentos limpa. `customData` acima de 1024 chars é cortado (com aviso). Ver docs/SSV-REWARDED.md.
82
+ */
83
+ static setRewardedSsv(ssv?: RewardedSsv): void {
84
+ this.ssv = ssv;
85
+ this.instance.setRewardedSsv(ssv);
86
+ }
87
+
65
88
  static get core(): Gabagool { return this.instance; }
66
89
 
67
90
  static async init(apiKey: string, baseUrl: string, appId: string, options: GabagoolInitOptions = {}): Promise<void> {
91
+ if (options.onPaidEvent) this.onPaidEvent = options.onPaidEvent;
68
92
  this.lifecycle?.stop();
69
93
  this.instance.dispose();
70
94
  this.resetReady();
71
95
  this.instance = createGabagool();
96
+ this.instance.setRewardedSsv(this.ssv);
72
97
 
73
98
  const adapter = options.adapter ?? new ReactNativeGmaAdapter();
74
99
  this.gmaAdapter = adapter instanceof ReactNativeGmaAdapter ? adapter : null;
@@ -114,6 +139,7 @@ export class GabagoolAds {
114
139
  ...(options.context ?? {}),
115
140
  },
116
141
  debug: options.debug === true,
142
+ onPaidEvent: (e) => GabagoolAds.onPaidEvent?.(e),
117
143
  });
118
144
 
119
145
  this.lifecycle = new AppStateLifecycle(this.instance);