@momo-cloud/gami-sdk 0.0.95 → 0.0.98

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
@@ -87,9 +87,9 @@ await GamiSDK.startGame();
87
87
  Typical game loop calls (signatures match `IGameApi`):
88
88
 
89
89
  - `getConfig({ ext? })`
90
- - `getBalance({ balanceId? })`
90
+ - `getBalance({ balanceId? })` — `balanceId` accepts a single `string` or an array `string[]`
91
91
  - `getBalanceConfig()`
92
- - `spin({ checkCounter?, giftCate?, isBonus? })`
92
+ - `spin({ checkCounter?, giftCate?, isBonus? })` — `giftCate` is a free-form `string`
93
93
  - `shake()`
94
94
  - `getCoinBalance()`
95
95
  - `getCoinExchangeInfo({ actionId? })`
@@ -242,7 +242,27 @@ if (res?.response_info?.error_code !== 0) {
242
242
  }
243
243
  ```
244
244
 
245
- ## 8) Leaderboard APIs
245
+ ## 8) Balance API
246
+
247
+ ### Fetch a single balance
248
+
249
+ ```ts
250
+ const res = await GamiSDK.getBalance({ balanceId: 'turn' });
251
+ ```
252
+
253
+ ### Fetch multiple balances in one call
254
+
255
+ Pass a `string[]` to request several balance IDs at once. The server receives them as a comma-separated list.
256
+
257
+ ```ts
258
+ const res = await GamiSDK.getBalance({ balanceId: ['turn', 'coin', 'ticket'] });
259
+ ```
260
+
261
+ The result shape is always `TBalance` regardless of how many IDs were requested. Omitting `balanceId` defaults to `'turn'`.
262
+
263
+ ---
264
+
265
+ ## 9) Leaderboard APIs
246
266
 
247
267
  ### Read leaderboard
248
268
 
@@ -270,7 +290,7 @@ await GamiSDK.submitLeaderboard({
270
290
 
271
291
  `gameId` and `userId` are injected automatically from the SDK session — do not pass them manually.
272
292
 
273
- ## 9) Browser vs Host Runtime
293
+ ## 10) Browser vs Host Runtime
274
294
 
275
295
  - In MoMo host: full platform bridge behavior is available.
276
296
  - In browser/dev mode: host-only behavior may be mocked, no-op, or limited.
@@ -280,7 +300,7 @@ Integration recommendation:
280
300
  - Keep game domain flow independent from host-only APIs.
281
301
  - Wrap optional host actions with graceful fallback in browser.
282
302
 
283
- ## 10) Build and Publish Modes
303
+ ## 11) Build and Publish Modes
284
304
 
285
305
  This repository supports two build modes:
286
306
 
@@ -302,7 +322,7 @@ npm run publish:npm
302
322
  npm run publish:all
303
323
  ```
304
324
 
305
- ## 11) Integration Checklist
325
+ ## 12) Integration Checklist
306
326
 
307
327
  Before releasing a game integration:
308
328
 
@@ -314,7 +334,7 @@ Before releasing a game integration:
314
334
  - Local cache keys use SDK helpers to avoid collisions
315
335
  - Permissions flow validated for calendar/contacts/image capture
316
336
 
317
- ## 12) Minimal End-to-End Example
337
+ ## 13) Minimal End-to-End Example
318
338
 
319
339
  ```ts
320
340
  import GamiSDK from '@momo-cloud/gami-sdk';
@@ -340,7 +360,7 @@ export async function run() {
340
360
  }
341
361
  ```
342
362
 
343
- ## 13) Notes for Architects
363
+ ## 14) Notes for Architects
344
364
 
345
365
  - Keep `GamiSDK` behind your own `sdkService` adapter in app code.
346
366
  - Separate domain logic from host bridge calls for easier testability.
@@ -4,6 +4,29 @@ export declare const GameEvent: EventEmitter<string | symbol, any>;
4
4
  export declare const GamiSDK: Record<string, any>;
5
5
  export default GamiSDK;
6
6
 
7
+ export declare const AudioPlayer: {
8
+ init(options: { baseURL: string }): void;
9
+ play(name: string, options?: { loop?: boolean; volume?: number }): Promise<any>;
10
+ playMusic(name: string, options?: { loop?: boolean; volume?: number; onComplete?: () => void }): Promise<any>;
11
+ stop(name: string): void;
12
+ pause(name?: string): void;
13
+ resume(name?: string): void;
14
+ setVolume(name: string, value: number): void;
15
+ setMute(name: string, value: boolean): void;
16
+ musicVolume: number;
17
+ enableSfx: boolean;
18
+ enable: boolean;
19
+ };
20
+
21
+ export declare const Storage: {
22
+ cacheJson(key: string, value: object): void;
23
+ cacheValue(key: string, value: string): void;
24
+ getJson<T = any>(key: string, defaultVal?: T): Promise<T>;
25
+ getValue(key: string, defaultVal?: string): Promise<string | undefined>;
26
+ cacheFile(url: string): Promise<string>;
27
+ getInCache(url: string): string | undefined;
28
+ };
29
+
7
30
  export type IUserInfo = {
8
31
  id: string;
9
32
  name?: string;
@@ -20,15 +43,263 @@ export type TDeviceInfo = {
20
43
  devicePerformance?: string;
21
44
  };
22
45
 
23
- export type TGetExchangeResponse = any;
24
- export type TPostExchangeResponse = any;
25
- export type TSpin = any;
26
- export type TShake = any;
27
- export type TCoinBalanceResponse = any;
28
- export type TBalance = any;
29
- export type TBalanceConfig = any;
30
- export type TGameConfig = any;
31
- export type THistory = any;
32
- export type TEvent = any;
33
- export type TLeaderboard = any;
34
- export type TMissionResponse = any;
46
+ export type TResponseInfo = {
47
+ error_message: string;
48
+ error_code: number;
49
+ event_tracking: string;
50
+ };
51
+
52
+ export type TGetExchangeResponse = {
53
+ response_info: TResponseInfo;
54
+ result: {
55
+ balance: number;
56
+ exchangeRate: number;
57
+ counter: number;
58
+ counterLimit: number;
59
+ fromCurrency: string;
60
+ toCurrency: string;
61
+ };
62
+ };
63
+
64
+ export type TPostExchangeResponse = {
65
+ response_info: TResponseInfo;
66
+ result: {
67
+ from: { walletType: string; currency: string; before: number; after: number };
68
+ to: { walletType: string; currency: string; before: number; after: number };
69
+ counter: { value: number; limit: number };
70
+ };
71
+ };
72
+
73
+ export type TSpin = {
74
+ response_info: TResponseInfo;
75
+ result: {
76
+ time: number;
77
+ statusCode: number;
78
+ countTurnLeft: number;
79
+ requestId: string;
80
+ counter: number;
81
+ giftInfo: {
82
+ giftId: string;
83
+ giftCode: string;
84
+ imgUrl: string;
85
+ walletType: number;
86
+ ver: number;
87
+ amount: number;
88
+ agent: string;
89
+ duration: number;
90
+ giftDesc: string;
91
+ ctaStatus: string;
92
+ title: string;
93
+ description: string;
94
+ quantity: number;
95
+ iconUrl: string;
96
+ index: number;
97
+ notiId: string;
98
+ extra: string;
99
+ };
100
+ };
101
+ };
102
+
103
+ export type TShake = {
104
+ response_info: TResponseInfo;
105
+ result: {
106
+ time: number;
107
+ statusCode: number;
108
+ countTurnLeft: number;
109
+ requestId: string;
110
+ giftInfo: {
111
+ giftId: string;
112
+ giftCode: string;
113
+ imgUrl: string;
114
+ walletType: number;
115
+ ver: number;
116
+ amount: string;
117
+ agent: string;
118
+ duration: string;
119
+ giftDesc: string;
120
+ ctaStatus: string;
121
+ revision: string;
122
+ status: string;
123
+ createdDate: string;
124
+ createdUser: string;
125
+ updatedDate: string;
126
+ updatedUser: string;
127
+ giftPackage: string;
128
+ title: string;
129
+ description: string;
130
+ quantity: number;
131
+ index: number;
132
+ iconUrl: string;
133
+ };
134
+ };
135
+ };
136
+
137
+ export type TCoinBalanceResponse = {
138
+ response_info: TResponseInfo;
139
+ result: { userId: string; balance: number };
140
+ };
141
+
142
+ export type TBalance = {
143
+ response_info: TResponseInfo;
144
+ result: { balances: { turn: number; icon: string } };
145
+ };
146
+
147
+ export type TBalanceConfig = {
148
+ response_info: TResponseInfo;
149
+ result: {
150
+ config: { balanceId: string; name: string; icon: string }[];
151
+ balances: { [key: string]: number };
152
+ };
153
+ };
154
+
155
+ export type TGameConfigCampaign = {
156
+ gameId: string;
157
+ gameidTitle: string;
158
+ startTime: number;
159
+ endTime: number;
160
+ ruleDetail: string;
161
+ icon: string;
162
+ themes: any;
163
+ status: boolean;
164
+ };
165
+
166
+ export type TGameConfig = {
167
+ response_info: TResponseInfo;
168
+ result: { time: number; campaign: TGameConfigCampaign };
169
+ };
170
+
171
+ export type THistoryItem = {
172
+ tag: string[];
173
+ icon: string;
174
+ title: string;
175
+ desc: string;
176
+ refId: string;
177
+ refExtra: string;
178
+ timestamp: number;
179
+ };
180
+
181
+ export type THistory = {
182
+ response_info: TResponseInfo;
183
+ result: { history: THistoryItem[]; category: string[] };
184
+ };
185
+
186
+ export type TeventItem = {
187
+ id: string;
188
+ startMs: number;
189
+ endMs: number;
190
+ title: string;
191
+ banner1x2: string;
192
+ banner1x1: string;
193
+ refId: string;
194
+ };
195
+
196
+ export type TEvent = {
197
+ response_info: TResponseInfo;
198
+ result: TeventItem[];
199
+ };
200
+
201
+ export type TLeaderboardItem = {
202
+ name: string;
203
+ avatar: string;
204
+ rank: number;
205
+ score: number;
206
+ };
207
+
208
+ export type TLeaderboard = {
209
+ response_info: TResponseInfo;
210
+ result: {
211
+ serverTime: number;
212
+ resetTime: number;
213
+ metadata: TLeaderboardItem;
214
+ board: TLeaderboardItem[];
215
+ };
216
+ };
217
+
218
+ export interface TMissionBalanceItem {
219
+ balanceAmount: number;
220
+ balanceId: string;
221
+ }
222
+
223
+ export interface TMissionInstructionStep {
224
+ title: string;
225
+ image: string;
226
+ instruction: string;
227
+ }
228
+
229
+ export interface TMissionInstructionInfo {
230
+ steps: TMissionInstructionStep[];
231
+ }
232
+
233
+ export interface TMissionRewardCondition {
234
+ rewardId: string;
235
+ conditionType: string;
236
+ conditionValue: number;
237
+ numAvailableReward: number;
238
+ numReceivedReward: number;
239
+ canGetReward: boolean;
240
+ isAutoClaimReward: boolean;
241
+ }
242
+
243
+ export interface TMissionSucceededCounter {
244
+ counterId: string;
245
+ limitType: string;
246
+ limitUnit: number;
247
+ startTime: number;
248
+ endTime: number;
249
+ upperBound: number;
250
+ numSucceeded: number;
251
+ isMainCounter: boolean;
252
+ rewardConditions: TMissionRewardCondition[];
253
+ }
254
+
255
+ export interface TMissionInfo {
256
+ title?: string;
257
+ description?: string;
258
+ icon?: string;
259
+ ctaText?: string;
260
+ refId?: string;
261
+ refExtra?: string | Record<string, unknown> | null;
262
+ progressData?: string;
263
+ rewardText?: string;
264
+ missionType?: string;
265
+ frameType?: string;
266
+ videoLink?: string;
267
+ videoDesc?: string;
268
+ balanceList?: TMissionBalanceItem[];
269
+ shareTitle?: string;
270
+ shareDescription?: string;
271
+ shareImgUrl?: string;
272
+ linkShare?: string;
273
+ instructionInfo?: TMissionInstructionInfo;
274
+ instruction_info?: TMissionInstructionInfo;
275
+ bonusInfo: TMissionBonusInfo;
276
+ }
277
+
278
+ export interface TMissionBonusInfo {
279
+ missionId: string;
280
+ missionInfo: TMissionInfo;
281
+ endMission: number;
282
+ succeededCounter: TMissionSucceededCounter[];
283
+ globalSucceededCounter: TMissionSucceededCounter[];
284
+ isCompleted: boolean;
285
+ }
286
+
287
+ export interface TMissionItem {
288
+ missionId: string;
289
+ missionInfo: TMissionInfo;
290
+ startMission: number;
291
+ endMission: number;
292
+ group: string;
293
+ sort: number;
294
+ succeededCounter: TMissionSucceededCounter[];
295
+ globalSucceededCounter: TMissionSucceededCounter[];
296
+ isCompleted: boolean;
297
+ canGetReward: boolean;
298
+ isComingSoon: boolean;
299
+ isExpired: boolean;
300
+ }
301
+
302
+ export interface TMissionResponse {
303
+ response_info: TResponseInfo;
304
+ result: TMissionItem[];
305
+ }