@quantabit/redpacket-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/LICENSE +21 -0
- package/README.md +114 -0
- package/dist/index.cjs +991 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.esm.js +967 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/styles.css +1 -0
- package/package.json +96 -0
- package/types/index.d.ts +73 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,991 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var sdkConfig = require('@quantabit/sdk-config');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* RedPacket SDK - API 客户端
|
|
8
|
+
* 红包系统后端接口封装
|
|
9
|
+
*
|
|
10
|
+
* 使用 BaseApiClient 基类简化代码
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 红包 API 客户端
|
|
16
|
+
*/
|
|
17
|
+
class RedPacketApiClient extends sdkConfig.BaseApiClient {
|
|
18
|
+
constructor(config = {}) {
|
|
19
|
+
super('/redpacket', config);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ============ 红包发送 ============
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 发送红包
|
|
26
|
+
* @param {Object} data - 红包数据
|
|
27
|
+
*/
|
|
28
|
+
async send(data) {
|
|
29
|
+
return this.post('/send', data);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 兼容旧 Hook 命名
|
|
34
|
+
*/
|
|
35
|
+
async createRedpacket(data) {
|
|
36
|
+
return this.send(data);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 发送群红包
|
|
41
|
+
* @param {string} groupId - 群组 ID
|
|
42
|
+
* @param {Object} data - 红包数据
|
|
43
|
+
*/
|
|
44
|
+
async sendToGroup(groupId, data) {
|
|
45
|
+
return this.post('/send/group', {
|
|
46
|
+
group_id: groupId,
|
|
47
|
+
...data
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 发送定向红包
|
|
53
|
+
* @param {string[]} userIds - 用户 ID 列表
|
|
54
|
+
* @param {Object} data - 红包数据
|
|
55
|
+
*/
|
|
56
|
+
async sendToUsers(userIds, data) {
|
|
57
|
+
return this.post('/send/users', {
|
|
58
|
+
user_ids: userIds,
|
|
59
|
+
...data
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ============ 红包领取 ============
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 领取红包
|
|
67
|
+
* @param {string} redpacketId - 红包 ID
|
|
68
|
+
*/
|
|
69
|
+
async claim(redpacketId) {
|
|
70
|
+
return this.post(`/${redpacketId}/claim`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 兼容旧 Hook 命名
|
|
75
|
+
*/
|
|
76
|
+
async grabRedpacket(redpacketId) {
|
|
77
|
+
return this.claim(redpacketId);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 获取红包详情
|
|
82
|
+
* @param {string} redpacketId - 红包 ID
|
|
83
|
+
*/
|
|
84
|
+
async getRedpacket(redpacketId) {
|
|
85
|
+
return this.get(`/${redpacketId}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 获取红包领取列表
|
|
90
|
+
* @param {string} redpacketId - 红包 ID
|
|
91
|
+
*/
|
|
92
|
+
async getClaimList(redpacketId) {
|
|
93
|
+
return this.get(`/${redpacketId}/claims`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ============ 我的红包 ============
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 获取收到的红包
|
|
100
|
+
* @param {Object} params - 查询参数
|
|
101
|
+
*/
|
|
102
|
+
async getReceivedRedpackets(params = {}) {
|
|
103
|
+
return this.get('/my/received', params);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 获取发出的红包
|
|
108
|
+
* @param {Object} params - 查询参数
|
|
109
|
+
*/
|
|
110
|
+
async getSentRedpackets(params = {}) {
|
|
111
|
+
return this.get('/my/sent', params);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 兼容旧 Hook 命名
|
|
116
|
+
*/
|
|
117
|
+
async getMyRedpackets(params = {}) {
|
|
118
|
+
return this.getSentRedpackets(params);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ============ 链上证明 ============
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 提交红包链上交易哈希
|
|
125
|
+
* @param {string} redpacketId - 红包 ID
|
|
126
|
+
* @param {string} txHash - QBit 交易哈希
|
|
127
|
+
* @param {Object} data - 额外链上证明数据
|
|
128
|
+
*/
|
|
129
|
+
async submitChainTx(redpacketId, txHash, data = {}) {
|
|
130
|
+
return this.post(`/${redpacketId}/chain/submit`, {
|
|
131
|
+
tx_hash: txHash,
|
|
132
|
+
chain: 'qbit',
|
|
133
|
+
network: 'mainnet',
|
|
134
|
+
...data
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* 查询红包链上确认状态
|
|
140
|
+
* @param {string} redpacketId - 红包 ID
|
|
141
|
+
*/
|
|
142
|
+
async getChainStatus(redpacketId) {
|
|
143
|
+
return this.get(`/${redpacketId}/chain/status`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* 获取红包统计
|
|
148
|
+
*/
|
|
149
|
+
async getMyStats() {
|
|
150
|
+
return this.get('/my/stats');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ============ 红包封面 ============
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* 获取可用红包封面
|
|
157
|
+
*/
|
|
158
|
+
async getCovers() {
|
|
159
|
+
return this.get('/covers');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* 获取我的红包封面
|
|
164
|
+
*/
|
|
165
|
+
async getMyCovers() {
|
|
166
|
+
return this.get('/my/covers');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* 领取红包封面
|
|
171
|
+
* @param {string} coverId - 封面 ID
|
|
172
|
+
*/
|
|
173
|
+
async claimCover(coverId) {
|
|
174
|
+
return this.post(`/covers/${coverId}/claim`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ============ 口令红包 ============
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* 发送口令红包
|
|
181
|
+
* @param {Object} data - 红包数据
|
|
182
|
+
*/
|
|
183
|
+
async sendPasswordRedpacket(data) {
|
|
184
|
+
return this.post('/send/password', data);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* 输入口令领取
|
|
189
|
+
* @param {string} password - 口令
|
|
190
|
+
*/
|
|
191
|
+
async claimByPassword(password) {
|
|
192
|
+
return this.post('/claim/password', {
|
|
193
|
+
password
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ============ 红包雨 ============
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 获取进行中的红包雨
|
|
201
|
+
*/
|
|
202
|
+
async getActiveRain() {
|
|
203
|
+
return this.get('/rain/active');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* 加入红包雨
|
|
208
|
+
* @param {string} rainId - 红包雨 ID
|
|
209
|
+
*/
|
|
210
|
+
async joinRain(rainId) {
|
|
211
|
+
return this.post(`/rain/${rainId}/join`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* 抢红包雨红包
|
|
216
|
+
* @param {string} rainId - 红包雨 ID
|
|
217
|
+
* @param {string} packetId - 红包 ID
|
|
218
|
+
*/
|
|
219
|
+
async grabRainPacket(rainId, packetId) {
|
|
220
|
+
return this.post(`/rain/${rainId}/grab`, {
|
|
221
|
+
packet_id: packetId
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ============ 管理员操作 ============
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* 创建红包活动(管理员)
|
|
229
|
+
* @param {Object} data - 活动数据
|
|
230
|
+
*/
|
|
231
|
+
async createActivity(data) {
|
|
232
|
+
return this.post('/admin/activities', data);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* 获取红包统计(管理员)
|
|
237
|
+
* @param {Object} params - 统计参数
|
|
238
|
+
*/
|
|
239
|
+
async getStats(params = {}) {
|
|
240
|
+
return this.get('/admin/stats', params);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 创建默认实例
|
|
245
|
+
const redPacketApi = new RedPacketApiClient();
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* RedPacket SDK - 国际化 i18n
|
|
249
|
+
*/
|
|
250
|
+
|
|
251
|
+
const SUPPORTED_LANGUAGES = ['en', 'zh', 'ja', 'ko'];
|
|
252
|
+
const messages = {
|
|
253
|
+
zh: {
|
|
254
|
+
loading: '加载中...',
|
|
255
|
+
redPacket: '红包',
|
|
256
|
+
redPackets: '红包记录',
|
|
257
|
+
sendRedPacket: '发红包',
|
|
258
|
+
receiveRedPacket: '收红包',
|
|
259
|
+
// 红包类型
|
|
260
|
+
typeNormal: '普通红包',
|
|
261
|
+
typeLucky: '拼手气红包',
|
|
262
|
+
typeExclusive: '专属红包',
|
|
263
|
+
typeGroup: '群红包',
|
|
264
|
+
// 状态
|
|
265
|
+
statusPending: '未领取',
|
|
266
|
+
statusReceived: '已领取',
|
|
267
|
+
statusExpired: '已过期',
|
|
268
|
+
statusEmpty: '已抢光',
|
|
269
|
+
// 发送
|
|
270
|
+
totalAmount: '总金额',
|
|
271
|
+
quantity: '红包个数',
|
|
272
|
+
blessing: '祝福语',
|
|
273
|
+
defaultBlessing: '恭喜发财,大吉大利!',
|
|
274
|
+
send: '塞钱进红包',
|
|
275
|
+
// 领取
|
|
276
|
+
open: '開',
|
|
277
|
+
claim: '拆红包',
|
|
278
|
+
luckyAmount: '手气最佳',
|
|
279
|
+
claimSuccess: '领取成功',
|
|
280
|
+
// 记录
|
|
281
|
+
sent: '发出的',
|
|
282
|
+
received: '收到的',
|
|
283
|
+
noRecords: '暂无红包记录',
|
|
284
|
+
// 详情
|
|
285
|
+
from: '来自',
|
|
286
|
+
claimedBy: '已领取',
|
|
287
|
+
remainingCount: '剩余 {count} 个',
|
|
288
|
+
expireIn: '{time} 后过期',
|
|
289
|
+
// 提示
|
|
290
|
+
insufficientBalance: '余额不足',
|
|
291
|
+
minAmount: '单个红包最低 {min}',
|
|
292
|
+
maxAmount: '单个红包最高 {max}',
|
|
293
|
+
alreadyClaimed: '您已领取过',
|
|
294
|
+
redPacketExpired: '红包已过期',
|
|
295
|
+
redPacketEmpty: '红包已被领完'
|
|
296
|
+
},
|
|
297
|
+
en: {
|
|
298
|
+
loading: 'Loading...',
|
|
299
|
+
redPacket: 'Red Packet',
|
|
300
|
+
redPackets: 'Red Packets',
|
|
301
|
+
sendRedPacket: 'Send',
|
|
302
|
+
receiveRedPacket: 'Receive',
|
|
303
|
+
typeNormal: 'Fixed Amount',
|
|
304
|
+
typeLucky: 'Lucky Draw',
|
|
305
|
+
typeExclusive: 'Exclusive',
|
|
306
|
+
typeGroup: 'Group',
|
|
307
|
+
statusPending: 'Pending',
|
|
308
|
+
statusReceived: 'Received',
|
|
309
|
+
statusExpired: 'Expired',
|
|
310
|
+
statusEmpty: 'Empty',
|
|
311
|
+
totalAmount: 'Total Amount',
|
|
312
|
+
quantity: 'Quantity',
|
|
313
|
+
blessing: 'Blessing',
|
|
314
|
+
defaultBlessing: 'Best wishes!',
|
|
315
|
+
send: 'Send Red Packet',
|
|
316
|
+
open: 'Open',
|
|
317
|
+
claim: 'Claim',
|
|
318
|
+
luckyAmount: 'Luckiest',
|
|
319
|
+
claimSuccess: 'Claimed successfully',
|
|
320
|
+
sent: 'Sent',
|
|
321
|
+
received: 'Received',
|
|
322
|
+
noRecords: 'No records',
|
|
323
|
+
from: 'From',
|
|
324
|
+
claimedBy: 'Claimed',
|
|
325
|
+
remainingCount: '{count} left',
|
|
326
|
+
expireIn: 'Expires in {time}',
|
|
327
|
+
insufficientBalance: 'Insufficient balance',
|
|
328
|
+
minAmount: 'Min {min} per packet',
|
|
329
|
+
maxAmount: 'Max {max} per packet',
|
|
330
|
+
alreadyClaimed: 'Already claimed',
|
|
331
|
+
redPacketExpired: 'Expired',
|
|
332
|
+
redPacketEmpty: 'No more left'
|
|
333
|
+
},
|
|
334
|
+
ja: {
|
|
335
|
+
loading: '読み込み中...',
|
|
336
|
+
redPacket: '紅包(お年玉)',
|
|
337
|
+
redPackets: '紅包履歴',
|
|
338
|
+
sendRedPacket: '紅包を送る',
|
|
339
|
+
receiveRedPacket: '紅包を受け取る',
|
|
340
|
+
typeNormal: '通常紅包',
|
|
341
|
+
typeLucky: 'ランダム紅包',
|
|
342
|
+
typeExclusive: '限定紅包',
|
|
343
|
+
typeGroup: 'グループ紅包',
|
|
344
|
+
statusPending: '未受け取り',
|
|
345
|
+
statusReceived: '受け取り済み',
|
|
346
|
+
statusExpired: '期限切れ',
|
|
347
|
+
statusEmpty: '品切れ',
|
|
348
|
+
totalAmount: '合計金額',
|
|
349
|
+
quantity: '個数',
|
|
350
|
+
blessing: 'メッセージ',
|
|
351
|
+
defaultBlessing: 'おめでとうございます!',
|
|
352
|
+
send: '紅包にお金を入れる',
|
|
353
|
+
open: '開く',
|
|
354
|
+
claim: '紅包を開ける',
|
|
355
|
+
luckyAmount: '最高額',
|
|
356
|
+
claimSuccess: '受け取り成功',
|
|
357
|
+
sent: '送った紅包',
|
|
358
|
+
received: '受け取った紅包',
|
|
359
|
+
noRecords: '紅包の履歴はありません',
|
|
360
|
+
from: '差出人',
|
|
361
|
+
claimedBy: '受け取り済み',
|
|
362
|
+
remainingCount: '残り {count} 個',
|
|
363
|
+
expireIn: '{time} 後に期限切れ',
|
|
364
|
+
insufficientBalance: '残高不足',
|
|
365
|
+
minAmount: '1つあたり最低 {min}',
|
|
366
|
+
maxAmount: '1つあたり最高 {max}',
|
|
367
|
+
alreadyClaimed: 'すでに受け取っています',
|
|
368
|
+
redPacketExpired: '紅包は期限切れです',
|
|
369
|
+
redPacketEmpty: '紅包は全て受け取られました'
|
|
370
|
+
},
|
|
371
|
+
ko: {
|
|
372
|
+
loading: '로딩 중...',
|
|
373
|
+
redPacket: '홍바오',
|
|
374
|
+
redPackets: '홍바오 내역',
|
|
375
|
+
sendRedPacket: '홍바오 보내기',
|
|
376
|
+
receiveRedPacket: '홍바오 받기',
|
|
377
|
+
typeNormal: '일반 홍바오',
|
|
378
|
+
typeLucky: '랜덤 홍바오',
|
|
379
|
+
typeExclusive: '전용 홍바오',
|
|
380
|
+
typeGroup: '그룹 홍바오',
|
|
381
|
+
statusPending: '미수령',
|
|
382
|
+
statusReceived: '수령 완료',
|
|
383
|
+
statusExpired: '만료됨',
|
|
384
|
+
statusEmpty: '소진됨',
|
|
385
|
+
totalAmount: '총 금액',
|
|
386
|
+
quantity: '개수',
|
|
387
|
+
blessing: '메시지',
|
|
388
|
+
defaultBlessing: '부자 되세요!',
|
|
389
|
+
send: '홍바오에 금액 넣기',
|
|
390
|
+
open: '열기',
|
|
391
|
+
claim: '홍바오 열기',
|
|
392
|
+
luckyAmount: '최고 당첨',
|
|
393
|
+
claimSuccess: '수령 성공',
|
|
394
|
+
sent: '보낸 내역',
|
|
395
|
+
received: '받은 내역',
|
|
396
|
+
noRecords: '홍바오 내역이 없습니다',
|
|
397
|
+
from: '보낸 사람',
|
|
398
|
+
claimedBy: '수령 완료',
|
|
399
|
+
remainingCount: '{count}개 남음',
|
|
400
|
+
expireIn: '{time} 후 만료',
|
|
401
|
+
insufficientBalance: '잔액 부족',
|
|
402
|
+
minAmount: '1개당 최소 {min}',
|
|
403
|
+
maxAmount: '1개당 최대 {max}',
|
|
404
|
+
alreadyClaimed: '이미 수령했습니다',
|
|
405
|
+
redPacketExpired: '홍바오가 만료되었습니다',
|
|
406
|
+
redPacketEmpty: '홍바오가 모두 소진되었습니다'
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
let currentLanguage = 'zh';
|
|
410
|
+
function setLanguage(lang) {
|
|
411
|
+
if (SUPPORTED_LANGUAGES.includes(lang)) {
|
|
412
|
+
currentLanguage = lang;
|
|
413
|
+
if (typeof window !== 'undefined') {
|
|
414
|
+
localStorage.setItem('qbit_did_redpacket_language', lang);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function getLanguage() {
|
|
419
|
+
if (typeof window !== 'undefined') {
|
|
420
|
+
const saved = localStorage.getItem('qbit_did_redpacket_language');
|
|
421
|
+
if (saved && SUPPORTED_LANGUAGES.includes(saved)) {
|
|
422
|
+
currentLanguage = saved;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return currentLanguage;
|
|
426
|
+
}
|
|
427
|
+
function t(key, params) {
|
|
428
|
+
const msgs = messages[getLanguage()] || messages.zh;
|
|
429
|
+
let text = msgs[key] || key;
|
|
430
|
+
if (params) {
|
|
431
|
+
Object.keys(params).forEach(k => {
|
|
432
|
+
text = text.replace(new RegExp(`\\{${k}\\}`, 'g'), params[k]);
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
return text;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* RedPacket SDK - Context Provider
|
|
440
|
+
*/
|
|
441
|
+
|
|
442
|
+
const RedPacketContext = /*#__PURE__*/React.createContext(null);
|
|
443
|
+
function RedPacketProvider({
|
|
444
|
+
children,
|
|
445
|
+
apiUrl,
|
|
446
|
+
token,
|
|
447
|
+
language = 'zh',
|
|
448
|
+
onSend,
|
|
449
|
+
onClaim,
|
|
450
|
+
onError
|
|
451
|
+
}) {
|
|
452
|
+
const [sentList, setSentList] = React.useState([]);
|
|
453
|
+
const [receivedList, setReceivedList] = React.useState([]);
|
|
454
|
+
const [stats, setStats] = React.useState(null);
|
|
455
|
+
const [loading, setLoading] = React.useState(false);
|
|
456
|
+
const [error, setError] = React.useState(null);
|
|
457
|
+
React.useEffect(() => {
|
|
458
|
+
setLanguage(language);
|
|
459
|
+
}, [language]);
|
|
460
|
+
const handleError = React.useCallback(err => {
|
|
461
|
+
setError(err);
|
|
462
|
+
onError?.(err);
|
|
463
|
+
}, [onError]);
|
|
464
|
+
const send = React.useCallback(async data => {
|
|
465
|
+
setLoading(true);
|
|
466
|
+
try {
|
|
467
|
+
const result = await redPacketApi.send(data);
|
|
468
|
+
onSend?.(result);
|
|
469
|
+
return result;
|
|
470
|
+
} catch (err) {
|
|
471
|
+
handleError(err);
|
|
472
|
+
throw err;
|
|
473
|
+
} finally {
|
|
474
|
+
setLoading(false);
|
|
475
|
+
}
|
|
476
|
+
}, [handleError, onSend]);
|
|
477
|
+
// ============ 领取红包 ============
|
|
478
|
+
|
|
479
|
+
const claim = React.useCallback(async redPacketId => {
|
|
480
|
+
setLoading(true);
|
|
481
|
+
try {
|
|
482
|
+
const result = await redPacketApi.claim(redPacketId);
|
|
483
|
+
onClaim?.(result);
|
|
484
|
+
return result;
|
|
485
|
+
} catch (err) {
|
|
486
|
+
handleError(err);
|
|
487
|
+
throw err;
|
|
488
|
+
} finally {
|
|
489
|
+
setLoading(false);
|
|
490
|
+
}
|
|
491
|
+
}, [handleError, onClaim]);
|
|
492
|
+
|
|
493
|
+
// ============ 加载记录 ============
|
|
494
|
+
|
|
495
|
+
const loadSentList = React.useCallback(async (params = {}) => {
|
|
496
|
+
try {
|
|
497
|
+
const result = await redPacketApi.getSentList(params);
|
|
498
|
+
const items = result.items || result.data || result || [];
|
|
499
|
+
setSentList(items);
|
|
500
|
+
return items;
|
|
501
|
+
} catch (err) {
|
|
502
|
+
handleError(err);
|
|
503
|
+
throw err;
|
|
504
|
+
}
|
|
505
|
+
}, [handleError]);
|
|
506
|
+
const loadReceivedList = React.useCallback(async (params = {}) => {
|
|
507
|
+
try {
|
|
508
|
+
const result = await redPacketApi.getReceivedList(params);
|
|
509
|
+
const items = result.items || result.data || result || [];
|
|
510
|
+
setReceivedList(items);
|
|
511
|
+
return items;
|
|
512
|
+
} catch (err) {
|
|
513
|
+
handleError(err);
|
|
514
|
+
throw err;
|
|
515
|
+
}
|
|
516
|
+
}, [handleError]);
|
|
517
|
+
const loadStats = React.useCallback(async () => {
|
|
518
|
+
try {
|
|
519
|
+
const result = await redPacketApi.getStats();
|
|
520
|
+
setStats(result);
|
|
521
|
+
return result;
|
|
522
|
+
} catch (err) {
|
|
523
|
+
handleError(err);
|
|
524
|
+
}
|
|
525
|
+
}, [handleError]);
|
|
526
|
+
const value = {
|
|
527
|
+
sentList,
|
|
528
|
+
receivedList,
|
|
529
|
+
stats,
|
|
530
|
+
loading,
|
|
531
|
+
error,
|
|
532
|
+
send,
|
|
533
|
+
claim,
|
|
534
|
+
loadSentList,
|
|
535
|
+
loadReceivedList,
|
|
536
|
+
loadStats,
|
|
537
|
+
api: redPacketApi
|
|
538
|
+
};
|
|
539
|
+
return /*#__PURE__*/React.createElement(RedPacketContext.Provider, {
|
|
540
|
+
value: value
|
|
541
|
+
}, children);
|
|
542
|
+
}
|
|
543
|
+
function useRedPacket() {
|
|
544
|
+
const context = React.useContext(RedPacketContext);
|
|
545
|
+
if (!context) {
|
|
546
|
+
throw new Error('useRedPacket must be used within a RedPacketProvider');
|
|
547
|
+
}
|
|
548
|
+
return context;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* RedPacket SDK - 类型定义
|
|
553
|
+
*/
|
|
554
|
+
|
|
555
|
+
// 红包类型
|
|
556
|
+
const RedPacketType = {
|
|
557
|
+
NORMAL: 'normal',
|
|
558
|
+
// 普通红包(均分)
|
|
559
|
+
LUCKY: 'lucky',
|
|
560
|
+
// 拼手气红包
|
|
561
|
+
EXCLUSIVE: 'exclusive',
|
|
562
|
+
// 专属红包(指定人)
|
|
563
|
+
GROUP: 'group' // 群红包
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
// 红包状态
|
|
567
|
+
const RedPacketStatus = {
|
|
568
|
+
PENDING: 'pending',
|
|
569
|
+
// 待领取
|
|
570
|
+
PARTIAL: 'partial',
|
|
571
|
+
// 部分领取
|
|
572
|
+
FINISHED: 'finished',
|
|
573
|
+
// 已领完
|
|
574
|
+
EXPIRED: 'expired',
|
|
575
|
+
// 已过期
|
|
576
|
+
REFUNDED: 'refunded' // 已退还
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
// 领取状态
|
|
580
|
+
const ClaimStatus = {
|
|
581
|
+
AVAILABLE: 'available',
|
|
582
|
+
// 可领取
|
|
583
|
+
CLAIMED: 'claimed',
|
|
584
|
+
// 已领取
|
|
585
|
+
EXPIRED: 'expired' // 已过期
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* 创建默认红包
|
|
590
|
+
*/
|
|
591
|
+
function createDefaultRedPacket(overrides = {}) {
|
|
592
|
+
return {
|
|
593
|
+
id: null,
|
|
594
|
+
sender_did: null,
|
|
595
|
+
sender_name: '',
|
|
596
|
+
sender_avatar: null,
|
|
597
|
+
type: RedPacketType.LUCKY,
|
|
598
|
+
total_amount: 0,
|
|
599
|
+
// 总金额
|
|
600
|
+
quantity: 1,
|
|
601
|
+
// 总个数
|
|
602
|
+
claimed_count: 0,
|
|
603
|
+
// 已领取个数
|
|
604
|
+
claimed_amount: 0,
|
|
605
|
+
// 已领取金额
|
|
606
|
+
blessing: '',
|
|
607
|
+
// 祝福语
|
|
608
|
+
currency: 'POINTS',
|
|
609
|
+
// 货币类型
|
|
610
|
+
status: RedPacketStatus.PENDING,
|
|
611
|
+
expire_at: null,
|
|
612
|
+
created_at: null,
|
|
613
|
+
...overrides
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* 创建默认领取记录
|
|
619
|
+
*/
|
|
620
|
+
function createDefaultClaim(overrides = {}) {
|
|
621
|
+
return {
|
|
622
|
+
id: null,
|
|
623
|
+
red_packet_id: null,
|
|
624
|
+
user_did: null,
|
|
625
|
+
user_name: '',
|
|
626
|
+
user_avatar: null,
|
|
627
|
+
amount: 0,
|
|
628
|
+
is_luckiest: false,
|
|
629
|
+
// 是否手气最佳
|
|
630
|
+
claimed_at: null,
|
|
631
|
+
...overrides
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* 计算红包剩余数量
|
|
637
|
+
*/
|
|
638
|
+
function getRemainingCount(redPacket) {
|
|
639
|
+
return redPacket.quantity - redPacket.claimed_count;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* 计算红包剩余金额
|
|
644
|
+
*/
|
|
645
|
+
function getRemainingAmount(redPacket) {
|
|
646
|
+
return redPacket.total_amount - redPacket.claimed_amount;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* 检查红包是否可领取
|
|
651
|
+
*/
|
|
652
|
+
function isClaimable(redPacket) {
|
|
653
|
+
if (redPacket.status === RedPacketStatus.FINISHED) return false;
|
|
654
|
+
if (redPacket.status === RedPacketStatus.EXPIRED) return false;
|
|
655
|
+
if (redPacket.expire_at && new Date(redPacket.expire_at) < new Date()) return false;
|
|
656
|
+
return getRemainingCount(redPacket) > 0;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* 格式化金额
|
|
661
|
+
*/
|
|
662
|
+
function formatAmount(amount, currency = 'POINTS') {
|
|
663
|
+
if (currency === 'POINTS') return `${amount} 积分`;
|
|
664
|
+
if (currency === 'CNY') return `¥${amount.toFixed(2)}`;
|
|
665
|
+
if (currency === 'USD') return `$${amount.toFixed(2)}`;
|
|
666
|
+
return `${amount} ${currency}`;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* RedPacket SDK - RedPacketCard 组件
|
|
671
|
+
* 红包卡片展示(可打开领取)
|
|
672
|
+
*/
|
|
673
|
+
|
|
674
|
+
function RedPacketCard({
|
|
675
|
+
redPacket,
|
|
676
|
+
onOpen,
|
|
677
|
+
onClaimSuccess,
|
|
678
|
+
showDetail = false,
|
|
679
|
+
className = ''
|
|
680
|
+
}) {
|
|
681
|
+
const {
|
|
682
|
+
claim,
|
|
683
|
+
loading
|
|
684
|
+
} = useRedPacket();
|
|
685
|
+
const [isOpening, setIsOpening] = React.useState(false);
|
|
686
|
+
const [claimResult, setClaimResult] = React.useState(null);
|
|
687
|
+
const [error, setError] = React.useState(null);
|
|
688
|
+
if (!redPacket) return null;
|
|
689
|
+
const {
|
|
690
|
+
id,
|
|
691
|
+
type,
|
|
692
|
+
status,
|
|
693
|
+
sender_name,
|
|
694
|
+
sender_avatar,
|
|
695
|
+
blessing,
|
|
696
|
+
total_amount,
|
|
697
|
+
currency = 'USD'
|
|
698
|
+
} = redPacket;
|
|
699
|
+
const remaining = getRemainingCount(redPacket);
|
|
700
|
+
const canClaim = isClaimable(redPacket) && !claimResult;
|
|
701
|
+
const handleOpen = async e => {
|
|
702
|
+
e.stopPropagation();
|
|
703
|
+
if (!canClaim || isOpening || loading) return;
|
|
704
|
+
setIsOpening(true);
|
|
705
|
+
setError(null);
|
|
706
|
+
try {
|
|
707
|
+
const result = await claim(id);
|
|
708
|
+
setClaimResult(result);
|
|
709
|
+
onClaimSuccess?.(result);
|
|
710
|
+
} catch (err) {
|
|
711
|
+
console.error(err);
|
|
712
|
+
setError(err?.message || String(err));
|
|
713
|
+
} finally {
|
|
714
|
+
setIsOpening(false);
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
const getTypeLabel = () => {
|
|
718
|
+
const labels = {
|
|
719
|
+
[RedPacketType.NORMAL]: t('typeNormal'),
|
|
720
|
+
[RedPacketType.LUCKY]: t('typeLucky'),
|
|
721
|
+
[RedPacketType.EXCLUSIVE]: t('typeExclusive'),
|
|
722
|
+
[RedPacketType.GROUP]: t('typeGroup')
|
|
723
|
+
};
|
|
724
|
+
return labels[type] || type;
|
|
725
|
+
};
|
|
726
|
+
const getStatusClass = () => {
|
|
727
|
+
if (claimResult) return 'opened';
|
|
728
|
+
if (status === RedPacketStatus.EXPIRED) return 'expired';
|
|
729
|
+
if (status === RedPacketStatus.FINISHED) return 'empty';
|
|
730
|
+
return '';
|
|
731
|
+
};
|
|
732
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
733
|
+
className: `redpacket-card ${getStatusClass()} ${className}`
|
|
734
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
735
|
+
className: "redpacket-body"
|
|
736
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
737
|
+
className: "redpacket-coins"
|
|
738
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
739
|
+
className: "coin"
|
|
740
|
+
}, "\uD83D\uDCB0"), /*#__PURE__*/React.createElement("span", {
|
|
741
|
+
className: "coin"
|
|
742
|
+
}, "\uD83D\uDCB0"), /*#__PURE__*/React.createElement("span", {
|
|
743
|
+
className: "coin"
|
|
744
|
+
}, "\uD83D\uDCB0")), /*#__PURE__*/React.createElement("div", {
|
|
745
|
+
className: "redpacket-sender"
|
|
746
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
747
|
+
className: "sender-avatar"
|
|
748
|
+
}, sender_avatar ? /*#__PURE__*/React.createElement("img", {
|
|
749
|
+
src: sender_avatar,
|
|
750
|
+
alt: ""
|
|
751
|
+
}) : /*#__PURE__*/React.createElement("span", null, "\uD83E\uDDE7")), /*#__PURE__*/React.createElement("span", {
|
|
752
|
+
className: "sender-name"
|
|
753
|
+
}, sender_name || t('redPacket'))), /*#__PURE__*/React.createElement("div", {
|
|
754
|
+
className: "redpacket-blessing"
|
|
755
|
+
}, blessing || t('defaultBlessing')), /*#__PURE__*/React.createElement("div", {
|
|
756
|
+
className: "redpacket-type"
|
|
757
|
+
}, getTypeLabel()), claimResult ? /*#__PURE__*/React.createElement("div", {
|
|
758
|
+
className: "redpacket-result"
|
|
759
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
760
|
+
className: "result-amount"
|
|
761
|
+
}, formatAmount(claimResult.amount, currency)), claimResult.is_luckiest && /*#__PURE__*/React.createElement("span", {
|
|
762
|
+
className: "result-lucky"
|
|
763
|
+
}, "\uD83C\uDF89 ", t('luckyAmount'))) : /*#__PURE__*/React.createElement("div", {
|
|
764
|
+
style: {
|
|
765
|
+
display: 'flex',
|
|
766
|
+
flexDirection: 'column',
|
|
767
|
+
alignItems: 'center',
|
|
768
|
+
gap: '8px'
|
|
769
|
+
}
|
|
770
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
771
|
+
className: "redpacket-open-btn",
|
|
772
|
+
onClick: handleOpen,
|
|
773
|
+
disabled: !canClaim || isOpening || loading
|
|
774
|
+
}, isOpening ? '...' : status === RedPacketStatus.EXPIRED ? t('statusExpired') : status === RedPacketStatus.FINISHED ? t('statusEmpty') : t('open')), error && /*#__PURE__*/React.createElement("div", {
|
|
775
|
+
style: {
|
|
776
|
+
color: '#FEE2E2',
|
|
777
|
+
fontSize: '12px',
|
|
778
|
+
background: 'rgba(239, 68, 68, 0.8)',
|
|
779
|
+
padding: '4px 8px',
|
|
780
|
+
borderRadius: '4px',
|
|
781
|
+
maxWidth: '100%',
|
|
782
|
+
wordBreak: 'break-word',
|
|
783
|
+
textAlign: 'center'
|
|
784
|
+
}
|
|
785
|
+
}, error)), showDetail && /*#__PURE__*/React.createElement("div", {
|
|
786
|
+
className: "redpacket-footer"
|
|
787
|
+
}, /*#__PURE__*/React.createElement("span", null, "\u5171 ", formatAmount(total_amount, currency)), remaining > 0 && /*#__PURE__*/React.createElement("span", null, t('remainingCount', {
|
|
788
|
+
count: remaining
|
|
789
|
+
})))));
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* RedPacket SDK - SendRedPacket 组件
|
|
794
|
+
* 发红包表单
|
|
795
|
+
*/
|
|
796
|
+
|
|
797
|
+
function SendRedPacket({
|
|
798
|
+
defaultType = RedPacketType.LUCKY,
|
|
799
|
+
currency = 'POINTS',
|
|
800
|
+
minAmount = 0.01,
|
|
801
|
+
maxAmount = 200,
|
|
802
|
+
onSuccess,
|
|
803
|
+
onCancel,
|
|
804
|
+
className = ''
|
|
805
|
+
}) {
|
|
806
|
+
const {
|
|
807
|
+
send,
|
|
808
|
+
loading
|
|
809
|
+
} = useRedPacket();
|
|
810
|
+
const [type, setType] = React.useState(defaultType);
|
|
811
|
+
const [totalAmount, setTotalAmount] = React.useState('');
|
|
812
|
+
const [quantity, setQuantity] = React.useState('');
|
|
813
|
+
const [blessing, setBlessing] = React.useState('');
|
|
814
|
+
const [error, setError] = React.useState('');
|
|
815
|
+
const handleSubmit = async e => {
|
|
816
|
+
e.preventDefault();
|
|
817
|
+
setError('');
|
|
818
|
+
if (loading) return;
|
|
819
|
+
const amount = parseFloat(totalAmount);
|
|
820
|
+
const count = parseInt(quantity);
|
|
821
|
+
if (!amount || amount <= 0) {
|
|
822
|
+
setError('请输入正确的金额');
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
if (!count || count < 1) {
|
|
826
|
+
setError('请输入红包个数');
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
if (amount / count < minAmount) {
|
|
830
|
+
setError(t('minAmount', {
|
|
831
|
+
min: minAmount
|
|
832
|
+
}));
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
if (amount / count > maxAmount) {
|
|
836
|
+
setError(t('maxAmount', {
|
|
837
|
+
max: maxAmount
|
|
838
|
+
}));
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
try {
|
|
842
|
+
const result = await send({
|
|
843
|
+
type,
|
|
844
|
+
total_amount: amount,
|
|
845
|
+
quantity: count,
|
|
846
|
+
blessing: blessing || t('defaultBlessing'),
|
|
847
|
+
currency
|
|
848
|
+
});
|
|
849
|
+
setTotalAmount('');
|
|
850
|
+
setQuantity('');
|
|
851
|
+
setBlessing('');
|
|
852
|
+
onSuccess?.(result);
|
|
853
|
+
} catch (err) {
|
|
854
|
+
setError(err.message);
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
const perAmount = totalAmount && quantity ? (parseFloat(totalAmount) / parseInt(quantity)).toFixed(2) : '0';
|
|
858
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
859
|
+
className: `send-redpacket ${className}`
|
|
860
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
861
|
+
className: "send-redpacket-header"
|
|
862
|
+
}, /*#__PURE__*/React.createElement("h3", null, t('sendRedPacket'))), /*#__PURE__*/React.createElement("form", {
|
|
863
|
+
onSubmit: handleSubmit
|
|
864
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
865
|
+
className: "form-group"
|
|
866
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
867
|
+
className: "type-selector"
|
|
868
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
869
|
+
type: "button",
|
|
870
|
+
className: type === RedPacketType.NORMAL ? 'active' : '',
|
|
871
|
+
onClick: () => setType(RedPacketType.NORMAL)
|
|
872
|
+
}, t('typeNormal')), /*#__PURE__*/React.createElement("button", {
|
|
873
|
+
type: "button",
|
|
874
|
+
className: type === RedPacketType.LUCKY ? 'active' : '',
|
|
875
|
+
onClick: () => setType(RedPacketType.LUCKY)
|
|
876
|
+
}, t('typeLucky')))), /*#__PURE__*/React.createElement("div", {
|
|
877
|
+
className: "form-group"
|
|
878
|
+
}, /*#__PURE__*/React.createElement("label", null, t('totalAmount')), /*#__PURE__*/React.createElement("div", {
|
|
879
|
+
className: "amount-input"
|
|
880
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
881
|
+
type: "number",
|
|
882
|
+
value: totalAmount,
|
|
883
|
+
onChange: e => setTotalAmount(e.target.value),
|
|
884
|
+
placeholder: "0.00",
|
|
885
|
+
min: "0",
|
|
886
|
+
step: "0.01"
|
|
887
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
888
|
+
className: "currency"
|
|
889
|
+
}, currency))), /*#__PURE__*/React.createElement("div", {
|
|
890
|
+
className: "form-group"
|
|
891
|
+
}, /*#__PURE__*/React.createElement("label", null, t('quantity')), /*#__PURE__*/React.createElement("input", {
|
|
892
|
+
type: "number",
|
|
893
|
+
value: quantity,
|
|
894
|
+
onChange: e => setQuantity(e.target.value),
|
|
895
|
+
placeholder: "1",
|
|
896
|
+
min: "1",
|
|
897
|
+
max: "100"
|
|
898
|
+
}), type === RedPacketType.NORMAL && /*#__PURE__*/React.createElement("span", {
|
|
899
|
+
className: "hint"
|
|
900
|
+
}, "\u6BCF\u4E2A\u7EA2\u5305 ", perAmount, " ", currency)), /*#__PURE__*/React.createElement("div", {
|
|
901
|
+
className: "form-group"
|
|
902
|
+
}, /*#__PURE__*/React.createElement("label", null, t('blessing')), /*#__PURE__*/React.createElement("input", {
|
|
903
|
+
type: "text",
|
|
904
|
+
value: blessing,
|
|
905
|
+
onChange: e => setBlessing(e.target.value),
|
|
906
|
+
placeholder: t('defaultBlessing'),
|
|
907
|
+
maxLength: 50
|
|
908
|
+
})), error && /*#__PURE__*/React.createElement("div", {
|
|
909
|
+
className: "form-error"
|
|
910
|
+
}, error), /*#__PURE__*/React.createElement("div", {
|
|
911
|
+
className: "form-actions"
|
|
912
|
+
}, onCancel && /*#__PURE__*/React.createElement("button", {
|
|
913
|
+
type: "button",
|
|
914
|
+
className: "btn-cancel",
|
|
915
|
+
onClick: onCancel
|
|
916
|
+
}, "\u53D6\u6D88"), /*#__PURE__*/React.createElement("button", {
|
|
917
|
+
type: "submit",
|
|
918
|
+
className: "btn-submit",
|
|
919
|
+
disabled: loading
|
|
920
|
+
}, loading ? t('loading') : t('send')))));
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
const REDPACKET_ANCHOR_NAMESPACE = 'qbit_redpacket';
|
|
924
|
+
function pickRedPacketId(redpacket) {
|
|
925
|
+
return redpacket?.id || redpacket?.redpacket_id || redpacket?.redpacketId || redpacket?.packet_id || redpacket?.packetId;
|
|
926
|
+
}
|
|
927
|
+
function pickContentHash(redpacket, options) {
|
|
928
|
+
return options.contentHash || redpacket?.content_hash || redpacket?.redpacket_hash || redpacket?.packet_hash || redpacket?.hash || null;
|
|
929
|
+
}
|
|
930
|
+
async function buildRedPacketAnchorMemo(redpacket, options = {}) {
|
|
931
|
+
const {
|
|
932
|
+
buildQBitAnchorMemo
|
|
933
|
+
} = await import('@quantabit/qbit-chain-sdk');
|
|
934
|
+
const redpacketId = options.redpacketId || pickRedPacketId(redpacket);
|
|
935
|
+
const contentHash = pickContentHash(redpacket, options);
|
|
936
|
+
return buildQBitAnchorMemo({
|
|
937
|
+
action: options.action || 'redpacket_anchor',
|
|
938
|
+
subject: redpacketId ? `redpacket:${redpacketId}` : 'redpacket',
|
|
939
|
+
resource_id: redpacketId,
|
|
940
|
+
content_hash: contentHash,
|
|
941
|
+
version: options.version,
|
|
942
|
+
timestamp: options.timestamp,
|
|
943
|
+
extra: {
|
|
944
|
+
amount: redpacket?.amount,
|
|
945
|
+
total_amount: redpacket?.total_amount,
|
|
946
|
+
token: redpacket?.token || redpacket?.currency || redpacket?.symbol,
|
|
947
|
+
sender_did: redpacket?.sender_did,
|
|
948
|
+
...options.extra
|
|
949
|
+
}
|
|
950
|
+
}, {
|
|
951
|
+
namespace: options.namespace || REDPACKET_ANCHOR_NAMESPACE,
|
|
952
|
+
maxBytes: options.maxBytes
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
function buildRedPacketChainSubmit(redpacketId, txHash, options = {}) {
|
|
956
|
+
return {
|
|
957
|
+
redpacket_id: redpacketId,
|
|
958
|
+
tx_hash: txHash,
|
|
959
|
+
chain: options.chain || 'qbit',
|
|
960
|
+
network: options.network || 'mainnet',
|
|
961
|
+
action: options.action || 'redpacket_anchor',
|
|
962
|
+
memo: options.memo,
|
|
963
|
+
content_hash: options.contentHash,
|
|
964
|
+
...options.extra
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
exports.ClaimStatus = ClaimStatus;
|
|
969
|
+
exports.REDPACKET_ANCHOR_NAMESPACE = REDPACKET_ANCHOR_NAMESPACE;
|
|
970
|
+
exports.RedPacketApiClient = RedPacketApiClient;
|
|
971
|
+
exports.RedPacketCard = RedPacketCard;
|
|
972
|
+
exports.RedPacketProvider = RedPacketProvider;
|
|
973
|
+
exports.RedPacketStatus = RedPacketStatus;
|
|
974
|
+
exports.RedPacketType = RedPacketType;
|
|
975
|
+
exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
|
|
976
|
+
exports.SendRedPacket = SendRedPacket;
|
|
977
|
+
exports.buildRedPacketAnchorMemo = buildRedPacketAnchorMemo;
|
|
978
|
+
exports.buildRedPacketChainSubmit = buildRedPacketChainSubmit;
|
|
979
|
+
exports.createDefaultClaim = createDefaultClaim;
|
|
980
|
+
exports.createDefaultRedPacket = createDefaultRedPacket;
|
|
981
|
+
exports.formatAmount = formatAmount;
|
|
982
|
+
exports.getLanguage = getLanguage;
|
|
983
|
+
exports.getRemainingAmount = getRemainingAmount;
|
|
984
|
+
exports.getRemainingCount = getRemainingCount;
|
|
985
|
+
exports.isClaimable = isClaimable;
|
|
986
|
+
exports.messages = messages;
|
|
987
|
+
exports.redPacketApi = redPacketApi;
|
|
988
|
+
exports.setLanguage = setLanguage;
|
|
989
|
+
exports.t = t;
|
|
990
|
+
exports.useRedPacket = useRedPacket;
|
|
991
|
+
//# sourceMappingURL=index.cjs.map
|