@pixels-online/pixels-client-js-sdk 1.4.0 → 1.6.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 CHANGED
@@ -68,7 +68,8 @@ client.on('offersUpdated', (offers) => {
68
68
 
69
69
  // Listen for player updates
70
70
  client.on('playerUpdated', (player) => {
71
- console.log('Player data updated:', player);
71
+ console.log('Player snapshot updated:', player.snapshot);
72
+ console.log('Player data updated:', player.data);
72
73
  updatePlayerStatsUI(player);
73
74
  });
74
75
  ```
@@ -85,6 +86,36 @@ try {
85
86
  }
86
87
  ```
87
88
 
89
+ ## 📊 Player Data Structure
90
+
91
+ The SDK provides player information through the `IClientPlayer` interface:
92
+
93
+ ```typescript
94
+ interface IClientPlayer {
95
+ snapshot: IPlayerSnapshot; // Core player data (levels, currencies, achievements, etc.)
96
+ data?: IPlayerData | null; // Additional game-specific data
97
+ }
98
+ ```
99
+
100
+ ### Accessing Player Information
101
+
102
+ ```typescript
103
+ // Get the current player
104
+ const player = client.getPlayer();
105
+
106
+ if (player) {
107
+ // Access core player data
108
+ console.log('Player ID:', player.snapshot.playerId);
109
+ console.log('Player level:', player.snapshot.levels?.combat?.level);
110
+ console.log('Currency balance:', player.snapshot.currencies?.gold?.balance);
111
+
112
+ // Access additional player data (if available)
113
+ if (player.data) {
114
+ console.log('Additional currencies:', player.data.currencies);
115
+ }
116
+ }
117
+ ```
118
+
88
119
  ## 🎯 Configuration Options
89
120
 
90
121
  ### OfferwallConfig
@@ -157,7 +188,8 @@ const client = new OfferwallClient({
157
188
  // Control which offers to show
158
189
  onOfferSurfaced: (offer) => {
159
190
  // Custom logic to determine if offer should be shown
160
- return player.level >= offer.minLevel;
191
+ const currentPlayer = client.getPlayer();
192
+ return currentPlayer?.snapshot.levels?.overall?.level >= offer.minLevel;
161
193
  },
162
194
 
163
195
  // Handle successful offer claims
@@ -234,22 +266,14 @@ Initialize the client and establish connection.
234
266
 
235
267
  Disconnect from the service.
236
268
 
237
- #### `getOffers(): IClientOffer[]`
238
-
239
- Get all current offers.
269
+ #### `refreshOffersAndPlayer(): { offers: IClientOffer[], player: IClientPlayer }`
240
270
 
241
- #### `getOffer(offerId: string): IClientOffer | null`
242
-
243
- Get a specific offer by ID.
271
+ Refresh and get all current offers.
244
272
 
245
273
  #### `claimOffer(offerId: string): Promise<ClaimResult>`
246
274
 
247
275
  Claim an offer and receive rewards.
248
276
 
249
- #### `getPlayer(): IClientPlayerSnapshot | null`
250
-
251
- Get current player data.
252
-
253
277
  #### `getConnectionState(): ConnectionState`
254
278
 
255
279
  Get current connection status.
@@ -260,7 +284,7 @@ Get current connection status.
260
284
  import { meetsConditions, AssetHelper } from '@pixels-online/pixels-client-js-sdk';
261
285
 
262
286
  // Check if player meets offer conditions
263
- const canClaim = meetsConditions(player, offer.surfacingConditions);
287
+ const canClaim = meetsConditions(player.snapshot, offer.surfacingConditions);
264
288
 
265
289
  // Asset helper utilities
266
290
  const assetHelper = new AssetHelper(assetResolver, fallbackImage);
@@ -302,7 +326,53 @@ The SDK supports multiple environments:
302
326
  - **`dev`** - Development environment
303
327
  - **Custom URL** - Provide your own endpoint
304
328
 
305
- ## 📋 Requirements
329
+ ## Migration Guide
330
+
331
+ ### v1.0.0+ Breaking Changes
332
+
333
+ **Player Data Structure Update**
334
+
335
+ The player data structure has been updated to provide better separation between core player data and additional game-specific data:
336
+
337
+ - **Old**: `IClientPlayerSnapshot` (flat structure)
338
+ - **New**: `IClientPlayer` (structured with `snapshot` and `data` properties)
339
+
340
+ **Migration Steps:**
341
+
342
+ ```typescript
343
+ // Before (v0.x)
344
+ const player = client.getPlayer(); // IClientPlayerSnapshot
345
+ const level = player.levels?.combat?.level;
346
+ const gold = player.currencies?.gold?.balance;
347
+
348
+ // After (v1.0+)
349
+ const player = client.getPlayer(); // IClientPlayer
350
+ const level = player.snapshot.levels?.combat?.level;
351
+ const gold = player.snapshot.currencies?.gold?.balance;
352
+
353
+ // Access additional data (new feature)
354
+ const additionalCurrencies = player.data?.currencies;
355
+ ```
356
+
357
+ **Event Handler Updates:**
358
+
359
+ ```typescript
360
+ // Before
361
+ client.on('playerUpdated', (playerSnapshot) => {
362
+ updateUI(playerSnapshot.currencies);
363
+ });
364
+
365
+ // After
366
+ client.on('playerUpdated', (player) => {
367
+ updateUI(player.snapshot.currencies);
368
+ // Also handle additional data if needed
369
+ if (player.data) {
370
+ handleAdditionalData(player.data);
371
+ }
372
+ });
373
+ ```
374
+
375
+ ## �📋 Requirements
306
376
 
307
377
  - Node.js 16+
308
378
  - TypeScript 4.5+ (if using TypeScript)
@@ -1,13 +1,13 @@
1
1
  import { OfferwallConfig } from '../types';
2
2
  import { IClientOffer, PlayerOfferStatus } from '../types/offer';
3
- import { IClientPlayerSnapshot } from '../types/player';
3
+ import { IClientPlayer } from '../types/player';
4
4
  export declare class OfferStore {
5
5
  private offers;
6
- private playerSnapshot;
6
+ private player;
7
7
  private logger;
8
8
  constructor(config: OfferwallConfig);
9
- getSnapshot(): IClientPlayerSnapshot | null;
10
- setSnapshot(snapshot: IClientPlayerSnapshot): void;
9
+ getPlayer(): IClientPlayer | null;
10
+ setPlayer(player: IClientPlayer): void;
11
11
  /**
12
12
  * Set all offers (replaces existing)
13
13
  */
@@ -1,9 +1,10 @@
1
1
  import { EventEmitter } from '../events/EventEmitter';
2
2
  import { OfferStore } from './OfferStore';
3
3
  import { AssetHelper } from '../utils/assets';
4
- import { OfferwallConfig } from '../types';
4
+ import { OfferwallConfig } from '../types/index';
5
+ import { IClientOffer } from '../types/offer';
5
6
  import { ConnectionState } from '../types/connection';
6
- export declare const mapEnvToBuildOnApiUrl: (env: "test" | "live" | (string & {})) => "https://api.pixels.xyz" | "https://api.sandbox.pixels.xyz" | "https://api.staging.pixels.xyz" | "https://api.preview.pixels.xyz" | "https://api.dev.pixels.xyz";
7
+ import { IClientPlayer } from '../types/player';
7
8
  export declare const mapEnvToOfferClientUrl: (env: "test" | "live" | (string & {})) => "https://offers.pixels.xyz" | "https://offers.sandbox.pixels.xyz" | "https://offers.staging.pixels.xyz" | "https://offers.preview.pixels.xyz" | "https://offers.dev.pixels.xyz";
8
9
  export declare class OfferwallClient {
9
10
  private config;
@@ -59,8 +60,10 @@ export declare class OfferwallClient {
59
60
  */
60
61
  private postWithAuth;
61
62
  private claimOfferAPI;
62
- refreshOffersAndSnapshot(): Promise<void>;
63
- private getOffersAndSnapshot;
63
+ getPlayer(): IClientPlayer | null;
64
+ getOffers(): IClientOffer[];
65
+ refreshOffersAndPlayer(): Promise<void>;
66
+ private getOffersAndPlayer;
64
67
  getAuthLinkToken(): Promise<string>;
65
68
  getGameId(): string | null;
66
69
  getDashboardRedirectUrl(): Promise<string | null>;
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from '../events/EventEmitter';
2
- import { OfferwallConfig } from '../types';
2
+ import { OfferwallConfig } from '../types/index';
3
3
  import { ConnectionState } from '../types/connection';
4
4
  import { TokenManager } from './TokenManager';
5
5
  export declare class SSEConnection {
package/dist/index.esm.js CHANGED
@@ -332,6 +332,24 @@ class CustomEventSource {
332
332
  }
333
333
  }
334
334
 
335
+ const mapEnvToBuildOnApiUrl = (env) => {
336
+ switch (env) {
337
+ case 'live':
338
+ return 'https://api.pixels.xyz';
339
+ case 'test':
340
+ return 'https://api.sandbox.pixels.xyz';
341
+ case 'staging':
342
+ return 'https://api.staging.pixels.xyz';
343
+ case 'preview':
344
+ return 'https://api.preview.pixels.xyz';
345
+ case 'dev':
346
+ case 'development':
347
+ return 'https://api.dev.pixels.xyz';
348
+ default:
349
+ return 'https://api.sandbox.pixels.xyz';
350
+ }
351
+ };
352
+
335
353
  class SSEConnection {
336
354
  constructor(config, eventEmitter, tokenManager) {
337
355
  this.config = config;
@@ -606,22 +624,22 @@ class SSEConnection {
606
624
  class OfferStore {
607
625
  constructor(config) {
608
626
  this.offers = new Map();
609
- this.playerSnapshot = null;
627
+ this.player = null;
610
628
  this.logger = createLogger(config, 'OfferStore');
611
629
  }
612
- getSnapshot() {
613
- return this.playerSnapshot;
630
+ getPlayer() {
631
+ return this.player || null;
614
632
  }
615
- setSnapshot(snapshot) {
616
- this.playerSnapshot = snapshot;
617
- this.logger.log('Updated player snapshot:', snapshot);
633
+ setPlayer(player) {
634
+ this.player = player;
635
+ this.logger.log('Updated player:', player);
618
636
  }
619
637
  /**
620
638
  * Set all offers (replaces existing)
621
639
  */
622
640
  setOffers(offers) {
623
641
  this.offers.clear();
624
- offers.forEach(offer => {
642
+ offers.forEach((offer) => {
625
643
  this.offers.set(offer.instanceId, offer);
626
644
  });
627
645
  this.logger.log(`Set ${offers.length} offers`);
@@ -661,16 +679,18 @@ class OfferStore {
661
679
  * Get offers filtered by status
662
680
  */
663
681
  getOffersByStatus(status) {
664
- return this.getAllOffers().filter(offer => offer.status === status);
682
+ return this.getAllOffers().filter((offer) => offer.status === status);
665
683
  }
666
684
  /**
667
685
  * Get active offers (not expired, not claimed)
668
686
  */
669
687
  getActiveOffers() {
670
- return this.getAllOffers().filter(offer => {
688
+ return this.getAllOffers().filter((offer) => {
671
689
  if (!offer.status)
672
690
  return false; // Must have a status
673
- return offer.status === 'surfaced' || offer.status === 'viewed' || offer.status === 'claimable';
691
+ return (offer.status === 'surfaced' ||
692
+ offer.status === 'viewed' ||
693
+ offer.status === 'claimable');
674
694
  });
675
695
  }
676
696
  /**
@@ -798,67 +818,31 @@ class AssetHelper {
798
818
  this.config = config;
799
819
  }
800
820
  resolveReward(reward) {
801
- // Determine the ID to translate based on reward kind
802
- let id;
803
- switch (reward.kind) {
804
- case 'item':
805
- id = reward.itemId;
806
- break;
807
- case 'coins':
808
- id = reward.currencyId;
809
- break;
810
- case 'exp':
811
- id = reward.skillId;
812
- break;
813
- case 'on_chain':
814
- id = reward.assetId;
815
- break;
816
- case 'trust_points':
817
- id = 'trust_points';
818
- break;
819
- }
820
821
  // Fallback to reward's built-in name, we should add 5x popberry etc
821
822
  const formattedName = reward.amount > 1 ? `${reward.amount}x ${reward.name}` : reward.name;
822
823
  // Try to resolve asset content if ID exists and resolver is set
823
- if (id && this.config.assetResolver) {
824
- const content = this.config.assetResolver(reward, id);
824
+ if (this.config.assetResolver) {
825
+ const content = this.config.assetResolver(reward);
825
826
  if (content) {
826
827
  return {
827
828
  name: content.name || formattedName,
828
- image: content.image || this.config.fallbackRewardImage
829
+ image: content.image || this.config.fallbackRewardImage,
829
830
  };
830
831
  }
831
832
  }
832
833
  return {
833
834
  name: formattedName,
834
- image: this.config.fallbackRewardImage
835
+ image: this.config.fallbackRewardImage,
835
836
  };
836
837
  }
837
838
  resolveOfferRewards(offer) {
838
- return offer.rewards.map(reward => ({
839
+ return offer.rewards.map((reward) => ({
839
840
  ...reward,
840
841
  ...this.resolveReward(reward),
841
842
  }));
842
843
  }
843
844
  }
844
845
 
845
- const mapEnvToBuildOnApiUrl = (env) => {
846
- switch (env) {
847
- case 'live':
848
- return 'https://api.pixels.xyz';
849
- case 'test':
850
- return 'https://api.sandbox.pixels.xyz';
851
- case 'staging':
852
- return 'https://api.staging.pixels.xyz';
853
- case 'preview':
854
- return 'https://api.preview.pixels.xyz';
855
- case 'dev':
856
- case 'development':
857
- return 'https://api.dev.pixels.xyz';
858
- default:
859
- return 'https://api.sandbox.pixels.xyz';
860
- }
861
- };
862
846
  const mapEnvToOfferClientUrl = (env) => {
863
847
  switch (env) {
864
848
  case 'live':
@@ -930,7 +914,7 @@ class OfferwallClient {
930
914
  return;
931
915
  }
932
916
  this.isInitializing = true;
933
- await this.refreshOffersAndSnapshot();
917
+ await this.refreshOffersAndPlayer();
934
918
  await this.connect();
935
919
  this.isInitializing = false;
936
920
  }
@@ -1089,28 +1073,34 @@ class OfferwallClient {
1089
1073
  kind: 'offer',
1090
1074
  });
1091
1075
  }
1092
- async refreshOffersAndSnapshot() {
1076
+ getPlayer() {
1077
+ return this.offerStore.getPlayer();
1078
+ }
1079
+ getOffers() {
1080
+ return this.offerStore.getAllOffers();
1081
+ }
1082
+ async refreshOffersAndPlayer() {
1093
1083
  try {
1094
- const { offers, snapshot } = await this.getOffersAndSnapshot();
1084
+ const { offers, player } = await this.getOffersAndPlayer();
1095
1085
  this.offerStore.setOffers(offers);
1096
- this.offerStore.setSnapshot(snapshot);
1097
- this.eventEmitter.emit(OfferEvent.REFRESH, { offers, playerSnapshot: snapshot });
1086
+ this.offerStore.setPlayer(player);
1087
+ this.eventEmitter.emit(OfferEvent.REFRESH, { offers, player: player });
1098
1088
  this.logger.log('Refreshed offers and player snapshot');
1099
1089
  }
1100
1090
  catch (error) {
1101
- this.handleError(error, 'refreshOffersAndSnapshot');
1091
+ this.handleError(error, 'refreshOffersAndPlayer');
1102
1092
  throw error;
1103
1093
  }
1104
1094
  }
1105
- async getOffersAndSnapshot() {
1095
+ async getOffersAndPlayer() {
1106
1096
  const data = await this.postWithAuth('/v1/client/player/campaigns', {
1107
1097
  viewingCampaigns: true,
1108
1098
  });
1109
1099
  if (!data.offers || !Array.isArray(data.offers)) {
1110
1100
  throw new Error('No offers returned from offers endpoint');
1111
1101
  }
1112
- if (!data.snapshot) {
1113
- throw new Error('No player snapshot returned from offers endpoint');
1102
+ if (!data.player) {
1103
+ throw new Error('No player returned from offers endpoint');
1114
1104
  }
1115
1105
  return data;
1116
1106
  }
@@ -1477,6 +1467,93 @@ const meetsBaseConditions = ({ conditions, playerSnap, addDetails, }) => {
1477
1467
  }
1478
1468
  return { isValid, conditionData: addDetails ? conditionData : undefined };
1479
1469
  };
1470
+ const meetsSurfacingConditions = ({ surfacingContexts, surfacingConditions, playerSnap, context, }) => {
1471
+ if (surfacingContexts?.length && !surfacingContexts.includes(context || '')) {
1472
+ // context is not in the list of surfacing contexts, so we don't want to surface this offer
1473
+ return { isValid: false };
1474
+ }
1475
+ const conditions = surfacingConditions;
1476
+ if (conditions?.andTags?.length) {
1477
+ // check if player has all of the tags
1478
+ const hasAllTags = conditions.andTags.every((tag) => playerSnap.tags?.includes(tag));
1479
+ if (!hasAllTags) {
1480
+ return { isValid: false };
1481
+ }
1482
+ }
1483
+ if (conditions?.orTags?.length) {
1484
+ // check if player has any of the tags
1485
+ const hasAnyTags = conditions.orTags.some((tag) => playerSnap.tags?.includes(tag));
1486
+ if (!hasAnyTags) {
1487
+ return { isValid: false };
1488
+ }
1489
+ }
1490
+ if (conditions?.notTags?.length) {
1491
+ // check if player has any of the tags
1492
+ const hasAnyTags = conditions.notTags.some((tag) => playerSnap.tags?.includes(tag));
1493
+ if (hasAnyTags) {
1494
+ return { isValid: false };
1495
+ }
1496
+ }
1497
+ if (conditions?.maxDaysInGame &&
1498
+ (playerSnap.daysInGame || Infinity) > conditions.maxDaysInGame) {
1499
+ return { isValid: false };
1500
+ }
1501
+ if (conditions.loginStreak && (playerSnap.loginStreak || 0) < conditions.loginStreak) {
1502
+ return { isValid: false };
1503
+ }
1504
+ // Check dynamic conditions if present
1505
+ if (conditions.dynamic?.conditions?.length) {
1506
+ if (!meetsDynamicConditions(playerSnap.dynamic || {}, conditions.dynamic)) {
1507
+ return { isValid: false };
1508
+ }
1509
+ }
1510
+ return meetsBaseConditions({ conditions, playerSnap });
1511
+ };
1512
+ const hasConditions = (conditions) => {
1513
+ if (!conditions)
1514
+ return false;
1515
+ if (Object.keys(conditions.currencies || {}).length > 0)
1516
+ return true;
1517
+ if (Object.keys(conditions.levels || {}).length > 0)
1518
+ return true;
1519
+ if (Object.keys(conditions.stakedTokens || {}).length > 0)
1520
+ return true;
1521
+ if (Object.keys(conditions.memberships || {}).length > 0)
1522
+ return true;
1523
+ if (Object.keys(conditions.quests || {}).length > 0)
1524
+ return true;
1525
+ if (conditions.minTrustScore)
1526
+ return true;
1527
+ if (conditions.maxTrustScore)
1528
+ return true;
1529
+ if (conditions.achievements)
1530
+ return true;
1531
+ if (conditions.minDaysInGame)
1532
+ return true;
1533
+ const surCond = conditions;
1534
+ if (surCond.andTags?.length)
1535
+ return true;
1536
+ if (surCond.orTags?.length)
1537
+ return true;
1538
+ if (surCond.notTags?.length)
1539
+ return true;
1540
+ if (surCond.maxDaysInGame)
1541
+ return true;
1542
+ if (surCond.loginStreak)
1543
+ return true;
1544
+ const compCond = conditions;
1545
+ if (compCond.buyItem)
1546
+ return true;
1547
+ if (compCond.spendCurrency)
1548
+ return true;
1549
+ if (compCond.depositCurrency)
1550
+ return true;
1551
+ if (compCond.login)
1552
+ return true;
1553
+ if (compCond.loginStreak)
1554
+ return true;
1555
+ return false;
1556
+ };
1480
1557
  const meetsCompletionConditions = ({ completionConditions, completionTrackers, playerSnap, addDetails = false, }) => {
1481
1558
  if (completionConditions) {
1482
1559
  const conditions = completionConditions;
@@ -1579,8 +1656,84 @@ const meetsCompletionConditions = ({ completionConditions, completionTrackers, p
1579
1656
  }
1580
1657
  return { isValid: true, conditionData: [] };
1581
1658
  };
1659
+ /**
1660
+ * Checks if a dynamic object meets a set of dynamic field conditions.
1661
+ * @param dynamicObj - The object with any key and string or number value.
1662
+ * @param conditions - Array of conditions to check.
1663
+ * @returns true if all conditions are met, false otherwise.
1664
+ */
1665
+ /**
1666
+ * Evaluates a single dynamic condition against the dynamic object.
1667
+ */
1668
+ function evaluateDynamicCondition(dynamicObj, cond) {
1669
+ const val = dynamicObj[cond.key];
1670
+ if (val === undefined)
1671
+ return false;
1672
+ switch (cond.operator) {
1673
+ case '==':
1674
+ return val === cond.compareTo;
1675
+ case '!=':
1676
+ return val !== cond.compareTo;
1677
+ case '>':
1678
+ return (typeof val === 'number' &&
1679
+ typeof cond.compareTo === 'number' &&
1680
+ val > cond.compareTo);
1681
+ case '>=':
1682
+ return (typeof val === 'number' &&
1683
+ typeof cond.compareTo === 'number' &&
1684
+ val >= cond.compareTo);
1685
+ case '<':
1686
+ return (typeof val === 'number' &&
1687
+ typeof cond.compareTo === 'number' &&
1688
+ val < cond.compareTo);
1689
+ case '<=':
1690
+ return (typeof val === 'number' &&
1691
+ typeof cond.compareTo === 'number' &&
1692
+ val <= cond.compareTo);
1693
+ case 'has':
1694
+ return (typeof val === 'string' &&
1695
+ typeof cond.compareTo === 'string' &&
1696
+ val.includes(cond.compareTo));
1697
+ case 'not_has':
1698
+ return (typeof val === 'string' &&
1699
+ typeof cond.compareTo === 'string' &&
1700
+ !val.includes(cond.compareTo));
1701
+ default:
1702
+ return false;
1703
+ }
1704
+ }
1705
+ /**
1706
+ * Evaluates a group of dynamic conditions with logical links (AND, OR, AND NOT).
1707
+ * @param dynamicObj - The player's dynamic object with any key and string or number value.
1708
+ * @param dynamicGroup - The group of conditions and links to check.
1709
+ * @returns true if the group evaluates to true, false otherwise.
1710
+ */
1711
+ function meetsDynamicConditions(dynamicObj, dynamicGroup) {
1712
+ const { conditions, links } = dynamicGroup;
1713
+ if (!conditions || conditions.length === 0)
1714
+ return true;
1715
+ // If no links, treat as AND between all conditions
1716
+ if (!links || links.length === 0) {
1717
+ return conditions.every((cond) => evaluateDynamicCondition(dynamicObj, cond));
1718
+ }
1719
+ // Evaluate the first condition
1720
+ let result = evaluateDynamicCondition(dynamicObj, conditions[0]);
1721
+ for (let i = 0; i < links.length; i++) {
1722
+ const nextCond = evaluateDynamicCondition(dynamicObj, conditions[i + 1]);
1723
+ const link = links[i];
1724
+ if (link === 'AND') {
1725
+ result = result && nextCond;
1726
+ }
1727
+ else if (link === 'OR') {
1728
+ result = result || nextCond;
1729
+ }
1730
+ else if (link === 'AND NOT') {
1731
+ result = result && !nextCond;
1732
+ }
1733
+ }
1734
+ return result;
1735
+ }
1582
1736
 
1583
- // Taken from buildon_server/src/commons/types/offer.ts and merged into a single interface
1584
1737
  const PlayerOfferStatuses = [
1585
1738
  'inQueue',
1586
1739
  'surfaced',
@@ -1590,16 +1743,26 @@ const PlayerOfferStatuses = [
1590
1743
  'expired',
1591
1744
  ];
1592
1745
 
1593
- // Taken from buildon_server/src/commons/types/reward.ts
1594
1746
  // Use a const assertion for the array and infer the union type directly
1595
1747
  const rewardKinds = [
1596
1748
  'item',
1597
1749
  'coins',
1598
1750
  'exp',
1599
1751
  'trust_points',
1752
+ 'loyalty_currency', // loyalty currency that the player can exchange for rewards like on-chain via withdraw, etc.
1600
1753
  /** on-chain rewards require the builder to send funds to a custodial wallet that we use to send to player wallets*/
1601
- 'on_chain',
1602
1754
  ];
1755
+ const rewardSchema = {
1756
+ _id: false,
1757
+ kind: { type: String, enum: rewardKinds },
1758
+ rewardId: String,
1759
+ skillId: String,
1760
+ currencyId: String, // could be a loyalty currency
1761
+ itemId: String,
1762
+ amount: Number,
1763
+ name: String,
1764
+ image: String,
1765
+ };
1603
1766
 
1604
- export { AssetHelper, ConnectionState, EventEmitter, OfferEvent, OfferStore, OfferwallClient, PlayerOfferStatuses, SSEConnection, meetsBaseConditions, meetsCompletionConditions, rewardKinds };
1767
+ export { AssetHelper, ConnectionState, EventEmitter, OfferEvent, OfferStore, OfferwallClient, PlayerOfferStatuses, SSEConnection, hasConditions, meetsBaseConditions, meetsCompletionConditions, meetsDynamicConditions, meetsSurfacingConditions, rewardKinds, rewardSchema };
1605
1768
  //# sourceMappingURL=index.esm.js.map