@msafe/sui-app-store 0.0.25 → 0.0.26

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/dist/index.mjs CHANGED
@@ -1,2871 +1,2 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
- // src/apps/mpay/helper.ts
8
- import {
9
- TransactionType
10
- } from "@msafe/sui3-utils";
11
-
12
- // src/apps/msafe-core/intention.ts
13
- import sortKeys from "sort-keys-recursive";
14
- var CoreBaseIntention = class {
15
- constructor(data) {
16
- this.data = data;
17
- }
18
- get application() {
19
- return "msafe-core";
20
- }
21
- serialize() {
22
- return JSON.stringify(sortKeys(this.data));
23
- }
24
- };
25
-
26
- // src/apps/mpay/config/dev.json
27
- var dev_exports = {};
28
- __export(dev_exports, {
29
- contractId: () => contractId,
30
- default: () => dev_default,
31
- feeObjId: () => feeObjId,
32
- roleObjId: () => roleObjId,
33
- status: () => status,
34
- transaction: () => transaction,
35
- upgradeCapObjId: () => upgradeCapObjId,
36
- vaultObjId: () => vaultObjId
37
- });
38
- var transaction = "DiBZq4UmVVYiRL6ZJmFKYoHcxtxqrhsCXSkFyT7wUr3j";
39
- var status = "success";
40
- var contractId = "0x81c960dc653975fbd0072deca8afb92d322898c911622898ba1b2e3ad0c4bd8d";
41
- var roleObjId = "0xc6ec0bdee0bb59a72077e9acd2f42457043cf47080b3d3fad4d39abf28bba63a";
42
- var vaultObjId = "0xbc4021387fbac149119fd24e92be9e58f745774292f3a2a12e2ac6daf5363e1d";
43
- var feeObjId = "0x4178f63970fe2daeb256dc5730ad172e82b3e8eb45f31b33e0daae72cd35e1e1";
44
- var upgradeCapObjId = "0xe1e9aa7d222d151bfe6dd83358b0d7fdcb11260f710800cfaf7ccc1b1e245115";
45
- var dev_default = {
46
- transaction,
47
- status,
48
- contractId,
49
- roleObjId,
50
- vaultObjId,
51
- feeObjId,
52
- upgradeCapObjId
53
- };
54
-
55
- // src/apps/mpay/config/prod.json
56
- var prod_exports = {};
57
- __export(prod_exports, {
58
- contractId: () => contractId2,
59
- default: () => prod_default,
60
- feeObjId: () => feeObjId2,
61
- roleObjId: () => roleObjId2,
62
- status: () => status2,
63
- transaction: () => transaction2,
64
- upgradeCapObjId: () => upgradeCapObjId2,
65
- vaultObjId: () => vaultObjId2
66
- });
67
- var transaction2 = "855FNDV8o8Z3fWULPnQo9qdhLJpsg7wZrkCpNyfw9KfB";
68
- var status2 = "success";
69
- var contractId2 = "0xc357c3985e8fb875d6b37141497af660779aa1bab0ec489b2213efd74067d1fa";
70
- var roleObjId2 = "0x5ab49bdf9fd1413e328ef242b3f8d83dde791b38a0b627bfc87fb25c010d34f1";
71
- var vaultObjId2 = "0xb483558770d8eb26007f193b75db40f0a45f2e36863a687625885d4de6993378";
72
- var feeObjId2 = "0x48453fc4d7cde3fe35aad89e5dfb496608a6a55ea529a1c0274681a808627f94";
73
- var upgradeCapObjId2 = "0x34279779a0d0d36bd5044b04830d607fa1b0ecf316548c8ac3a44151e4f1a42a";
74
- var prod_default = {
75
- transaction: transaction2,
76
- status: status2,
77
- contractId: contractId2,
78
- roleObjId: roleObjId2,
79
- vaultObjId: vaultObjId2,
80
- feeObjId: feeObjId2,
81
- upgradeCapObjId: upgradeCapObjId2
82
- };
83
-
84
- // src/apps/mpay/common/env.ts
85
- var DEV_RPC_ENDPOINT = "https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD";
86
- var STG_RPC_ENDPOINT = "https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD";
87
- var PREV_RPC_ENDPOINT = "https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7";
88
- var PROD_RPC_ENDPOINT = "https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7";
89
- var DEV_BE_API = "https://bc3p6l5unl.execute-api.us-west-1.amazonaws.com/prod";
90
- var STG_BE_API = "https://rolsbkota7.execute-api.us-west-1.amazonaws.com/prod";
91
- var PREV_BE_API = "https://6p6mkx33ne.execute-api.us-west-1.amazonaws.com/prod";
92
- var PROD_BE_API = "https://xrae3mrjv5.execute-api.us-west-1.amazonaws.com/prod";
93
- var CONTRACT_DEV = dev_exports;
94
- var CONTRACT_PROD = prod_exports;
95
- var ENV_CONFIG = /* @__PURE__ */ new Map([
96
- [
97
- "dev" /* dev */,
98
- {
99
- env: "dev" /* dev */,
100
- rpc: {
101
- url: DEV_RPC_ENDPOINT
102
- },
103
- backend: {
104
- url: DEV_BE_API
105
- },
106
- contract: CONTRACT_DEV
107
- }
108
- ],
109
- [
110
- "stg" /* stg */,
111
- {
112
- env: "stg" /* stg */,
113
- rpc: {
114
- url: STG_RPC_ENDPOINT
115
- },
116
- backend: {
117
- url: STG_BE_API
118
- },
119
- contract: CONTRACT_DEV
120
- }
121
- ],
122
- [
123
- "prev" /* prev */,
124
- {
125
- env: "prev" /* prev */,
126
- rpc: {
127
- url: PREV_RPC_ENDPOINT
128
- },
129
- backend: {
130
- url: PREV_BE_API
131
- },
132
- contract: CONTRACT_PROD
133
- }
134
- ],
135
- [
136
- "prod" /* prod */,
137
- {
138
- env: "prod" /* prod */,
139
- rpc: {
140
- url: PROD_RPC_ENDPOINT
141
- },
142
- backend: {
143
- url: PROD_BE_API
144
- },
145
- contract: CONTRACT_PROD
146
- }
147
- ]
148
- ]);
149
- function getConfig(env, options) {
150
- const ec = ENV_CONFIG.get(env);
151
- if (!ec) {
152
- throw new Error(`Env not supported: ${env}`);
153
- }
154
- if (options && options.rpc) {
155
- ec.rpc = options.rpc;
156
- }
157
- if (options && options.backend) {
158
- ec.backend = options.backend;
159
- }
160
- if (options && options.contract) {
161
- ec.contract = options.contract;
162
- }
163
- return ec;
164
- }
165
-
166
- // src/apps/mpay/common/globals.ts
167
- import { SuiClient } from "@mysten/sui.js/client";
168
-
169
- // src/apps/mpay/error/base.ts
170
- var MPayError = class extends Error {
171
- mpayErrorCode;
172
- context;
173
- constructor(mpayErrorCode, msg, options = {}) {
174
- const { cause, context } = options;
175
- if (cause) {
176
- super(`[MPay] ${msg}: ${cause}`);
177
- } else {
178
- super(`[MPay] ${msg}`);
179
- }
180
- this.mpayErrorCode = mpayErrorCode;
181
- this.context = context;
182
- }
183
- };
184
-
185
- // src/apps/mpay/error/NoBackendError.ts
186
- var NoBackendError = class extends MPayError {
187
- constructor() {
188
- super(11 /* NoBackend */, "Backend is not specified");
189
- }
190
- };
191
-
192
- // src/apps/mpay/error/WalletNotConnectedError.ts
193
- var WalletNotConnectedError = class extends MPayError {
194
- constructor() {
195
- super(1 /* walletNotConnected */, "Wallet not connected");
196
- }
197
- };
198
-
199
- // src/apps/mpay/stream/backend.ts
200
- import axios, { AxiosError } from "axios";
201
-
202
- // src/apps/mpay/error/BackendError.ts
203
- var BackendError = class extends MPayError {
204
- constructor(msg, context) {
205
- super(10 /* BackendError */, msg, { context });
206
- }
207
- };
208
-
209
- // src/apps/mpay/stream/backend.ts
210
- var Backend = class _Backend {
211
- constructor(apiURL) {
212
- this.apiURL = apiURL;
213
- }
214
- static parseResponseData(response) {
215
- if (response instanceof AxiosError) {
216
- throw new BackendError(response.response?.statusText);
217
- }
218
- if (response.status === 200) {
219
- if (response.data.success) {
220
- return response.data.data;
221
- }
222
- throw new BackendError(response.data.code);
223
- }
224
- throw new BackendError(response.status.toString());
225
- }
226
- async getIncomingStreams(recipient, options) {
227
- const res = await axios.post(`${this.apiURL}/stream`, {
228
- recipient,
229
- ...options
230
- });
231
- return _Backend.parseResponseData(res);
232
- }
233
- async getOutgoingStreams(sender, options) {
234
- const res = await axios.post(`${this.apiURL}/stream`, {
235
- sender,
236
- ...options
237
- });
238
- return _Backend.parseResponseData(res);
239
- }
240
- async getStreamHistory(query) {
241
- const res = await axios.post(`${this.apiURL}/stream-events`, query);
242
- const paginatedData = _Backend.parseResponseData(res);
243
- paginatedData.data.forEach((event) => {
244
- const formalizedEvent = event;
245
- if (formalizedEvent.data.type === "create_stream") {
246
- formalizedEvent.data.balance = BigInt(formalizedEvent.data.balance);
247
- } else if (formalizedEvent.data.type === "cancel_stream") {
248
- formalizedEvent.data.withdrawAmount = BigInt(formalizedEvent.data.withdrawAmount);
249
- } else if (formalizedEvent.data.type === "claim" || formalizedEvent.data.type === "auto_claim") {
250
- formalizedEvent.data.claimAmount = BigInt(formalizedEvent.data.claimAmount);
251
- } else if (formalizedEvent.data.type === "set_auto_claim") {
252
- formalizedEvent.data.enabled = !!formalizedEvent.data.enabled;
253
- }
254
- formalizedEvent.createdAt = new Date(formalizedEvent.createdAt);
255
- return formalizedEvent;
256
- });
257
- return paginatedData;
258
- }
259
- async getAllCoinTypes(address) {
260
- const res = await axios.post(`${this.apiURL}/stream-info`, { address });
261
- return _Backend.parseResponseData(res);
262
- }
263
- async getAllRecipients(sender, options) {
264
- const res = await axios.post(`${this.apiURL}/stream-info`, { sender, status: options });
265
- return _Backend.parseResponseData(res);
266
- }
267
- async getAllSenders(recipient, options) {
268
- const res = await axios.post(`${this.apiURL}/stream-info`, { recipient, status: options });
269
- return _Backend.parseResponseData(res);
270
- }
271
- };
272
-
273
- // src/apps/mpay/common/globals.ts
274
- var Globals = class _Globals {
275
- signer;
276
- suiClient;
277
- envConfig;
278
- _backend;
279
- constructor(envConfig) {
280
- this.envConfig = envConfig;
281
- this.suiClient = new SuiClient({ url: envConfig.rpc.url });
282
- if (envConfig.backend) {
283
- this._backend = new Backend(envConfig.backend.url);
284
- }
285
- }
286
- static new(env, options) {
287
- const ec = getConfig(env, options);
288
- return new _Globals(ec);
289
- }
290
- get walletType() {
291
- if (!this.wallet) {
292
- return "disconnected";
293
- }
294
- return this.wallet.type;
295
- }
296
- get backend() {
297
- if (!this._backend) {
298
- throw new NoBackendError();
299
- }
300
- return this._backend;
301
- }
302
- // Used for test cases
303
- set backend(b) {
304
- this._backend = b;
305
- }
306
- connectWallet(wallet) {
307
- this.signer = wallet;
308
- }
309
- disconnect() {
310
- this.signer = void 0;
311
- }
312
- get wallet() {
313
- if (!this.signer) {
314
- throw new WalletNotConnectedError();
315
- }
316
- return this.signer;
317
- }
318
- async walletAddress() {
319
- return this.wallet.address();
320
- }
321
- };
322
-
323
- // src/apps/mpay/stream/client.ts
324
- import { SUI_TYPE_ARG as SUI_TYPE_ARG3, normalizeStructTag as normalizeStructTag6, normalizeSuiAddress as normalizeSuiAddress3 } from "@mysten/sui.js/utils";
325
-
326
- // src/apps/mpay/stream/helper.ts
327
- import { normalizeStructTag as normalizeStructTag3, SUI_TYPE_ARG as SUI_TYPE_ARG2 } from "@mysten/sui.js/utils";
328
- import { Duration } from "luxon";
329
-
330
- // src/apps/mpay/builder/MPayBuilder.ts
331
- import { TransactionBlock as TransactionBlock3 } from "@mysten/sui.js/transactions";
332
-
333
- // src/apps/mpay/builder/CreateStreamHelper.ts
334
- import { TransactionBlock } from "@mysten/sui.js/transactions";
335
- import { normalizeStructTag as normalizeStructTag2, SUI_TYPE_ARG } from "@mysten/sui.js/utils";
336
- import { nanoid } from "nanoid";
337
-
338
- // src/apps/mpay/builder/const.ts
339
- var FEE_NUMERATOR = 50n;
340
- var FEE_DENOMINATOR = 10000n;
341
- var CLAIM_FEE_NUMERATOR = 25n;
342
- var FLAT_FEE_SUI = 100000000n;
343
-
344
- // src/apps/mpay/common/transaction.ts
345
- var MoveObject = class {
346
- constructor(object) {
347
- this.object = object;
348
- }
349
- moveArg(txb) {
350
- return txb.object(this.object);
351
- }
352
- };
353
- var ObjectVector = class {
354
- constructor(objects) {
355
- this.objects = objects;
356
- }
357
- moveArgs(txb) {
358
- return txb.makeMoveVec({ objects: this.objects.map((o) => txb.object(o)) });
359
- }
360
- };
361
- var ResultRef = class _ResultRef {
362
- constructor(result) {
363
- this.result = result;
364
- return new Proxy(this, {
365
- set() {
366
- throw new Error("The transaction result is a proxy, and does not support setting properties directly");
367
- },
368
- get(target, property) {
369
- if (property in target) {
370
- return Reflect.get(target, property);
371
- }
372
- const nestedResultFor = (resultIndex2) => new _ResultRef(target.result[resultIndex2]);
373
- if (property === Symbol.iterator) {
374
- return function* () {
375
- let i = 0;
376
- while (true) {
377
- yield nestedResultFor(i);
378
- i++;
379
- }
380
- };
381
- }
382
- if (typeof property === "symbol") {
383
- return;
384
- }
385
- const resultIndex = parseInt(property, 10);
386
- if (Number.isNaN(resultIndex) || resultIndex < 0) {
387
- return;
388
- }
389
- return nestedResultFor(resultIndex);
390
- }
391
- });
392
- }
393
- moveArg() {
394
- return this.result;
395
- }
396
- };
397
-
398
- // src/apps/mpay/contract/InspectViewer.ts
399
- import { Buffer as Buffer2 } from "buffer";
400
- import { normalizeSuiAddress } from "@mysten/sui.js/utils";
401
-
402
- // src/apps/mpay/error/InvalidRpcResultError.ts
403
- var InvalidRpcResultError = class extends MPayError {
404
- constructor(msg, ctx) {
405
- super(3 /* InvalidRpcResult */, msg, { context: ctx });
406
- }
407
- };
408
-
409
- // src/apps/mpay/contract/InspectViewer.ts
410
- var InspectViewer = class {
411
- constructor(results) {
412
- this.results = results;
413
- }
414
- callResult(index) {
415
- return this.results.results[index];
416
- }
417
- returnValue(returned, index) {
418
- return returned.returnValues[index];
419
- }
420
- getValue(callIndex = 0, returnIndex = 0) {
421
- const callResult = this.callResult(callIndex);
422
- return this.returnValue(callResult, returnIndex);
423
- }
424
- getAddress(callIndex = 0, returnIndex = 0) {
425
- const [value, type] = this.getValue(callIndex, returnIndex);
426
- if (type !== "address") {
427
- throw new InvalidRpcResultError("Invalid contract return type.", {
428
- ctx: {
429
- expectType: "address",
430
- gotType: type
431
- }
432
- });
433
- }
434
- return normalizeSuiAddress(Buffer2.from(value).toString("hex"));
435
- }
436
- getU64(callIndex = 0, returnIndex = 0) {
437
- const [value, type] = this.getValue(callIndex, returnIndex);
438
- if (type !== "u64") {
439
- throw new InvalidRpcResultError("Invalid contract return type.", {
440
- ctx: {
441
- expectType: "u64",
442
- gotType: type
443
- }
444
- });
445
- }
446
- return Buffer2.from(value).readBigInt64LE();
447
- }
448
- };
449
-
450
- // src/apps/mpay/stream/metadata.ts
451
- import { bcs } from "@mysten/sui.js/bcs";
452
-
453
- // src/apps/mpay/error/InvalidInputError.ts
454
- var InvalidInputError = class extends MPayError {
455
- constructor(msg, fieldKey, fieldValue) {
456
- super(2 /* InvalidInput */, `Invalid input: ${msg}`, {
457
- context: {
458
- fieldKey,
459
- fieldValue
460
- }
461
- });
462
- }
463
- };
464
-
465
- // src/apps/mpay/stream/metadata.ts
466
- var metadataBcsType = {
467
- groupId: "string",
468
- name: "string"
469
- };
470
- var MAX_NAME_SIZE = 64;
471
- function encodeMetadata(metadata) {
472
- validateMetadata(metadata);
473
- return bcs.ser(metadataBcsType, metadata).toString("base64");
474
- }
475
- function decodeMetadata(metaStr) {
476
- const metadata = bcs.de(metadataBcsType, metaStr, "base64");
477
- validateMetadata(metadata);
478
- return metadata;
479
- }
480
- function validateMetadata(metadata) {
481
- if (!isAsciiString(metadata.name)) {
482
- throw new InvalidInputError("Invalid metadata: Name contains unknown character");
483
- }
484
- if (!isAsciiString(metadata.groupId)) {
485
- throw new InvalidInputError("Invalid metadata: Group ID contains unknown character");
486
- }
487
- if (metadata.name.length > MAX_NAME_SIZE) {
488
- throw new InvalidInputError("Invalid metadata: Name exceed max length 64");
489
- }
490
- }
491
- function isAsciiString(str) {
492
- const asciiPattern = /^[\x00-\x7F]+$/;
493
- return asciiPattern.test(str);
494
- }
495
-
496
- // src/apps/mpay/sui/utils.ts
497
- import { normalizeStructTag } from "@mysten/sui.js/utils";
498
- function isSameCoinType(type1, type2) {
499
- return normalizeStructTag(type1) === normalizeStructTag(type2);
500
- }
501
- function isSameTarget(target1, target2) {
502
- return normalizeStructTag(target1) === normalizeStructTag(target2);
503
- }
504
-
505
- // src/apps/mpay/types/wallet.ts
506
- var GAS_OBJECT_SPEC = "txn.gas";
507
-
508
- // src/apps/mpay/builder/CreateStreamHelper.ts
509
- var CreateStreamHelper = class _CreateStreamHelper {
510
- constructor(globals, feeContract, streamContract) {
511
- this.globals = globals;
512
- this.feeContract = feeContract;
513
- this.streamContract = streamContract;
514
- }
515
- static convertCreateStreamInfoToInternal(info) {
516
- return {
517
- metadata: encodeMetadata({
518
- name: info.name,
519
- groupId: nanoid()
520
- }),
521
- coinType: normalizeStructTag2(info.coinType),
522
- recipients: info.recipients.map((recipient) => ({
523
- address: recipient.address,
524
- cliffAmount: recipient.cliffAmount,
525
- amountPerEpoch: recipient.amountPerStep
526
- })),
527
- epochInterval: info.interval,
528
- numberEpoch: info.steps,
529
- startTime: info.startTimeMs,
530
- cancelable: info.cancelable
531
- };
532
- }
533
- async buildCreateStreamTransactionBlock(info) {
534
- const txb = new TransactionBlock();
535
- const paymentWithFee = this.calculateFeesInternal(info);
536
- const coinReqs = this.getCreateStreamCoinRequests(info, paymentWithFee);
537
- const coinResp = await this.wallet.requestCoins(coinReqs);
538
- const paymentMergedObject = await this.addMergeCoins(txb, coinResp[0]);
539
- let flatFeeMergedObject;
540
- if (coinReqs.length > 1) {
541
- flatFeeMergedObject = await this.addMergeCoins(txb, coinResp[1]);
542
- } else {
543
- flatFeeMergedObject = paymentMergedObject;
544
- }
545
- for (let i = 0; i < info.recipients.length; i++) {
546
- const recipient = info.recipients[i];
547
- const paymentAmount = this.amountForRecipient(recipient, info.numberEpoch);
548
- const feeAmount = this.getStreamFeeLocal(paymentAmount);
549
- const [paymentCoin] = txb.splitCoins(paymentMergedObject, [txb.pure(paymentAmount + feeAmount, "u64")]);
550
- const [flatFeeCoin] = txb.splitCoins(flatFeeMergedObject, [txb.pure(this.flatSuiFee, "u64")]);
551
- this.streamContract.createStream(txb, {
552
- paymentCoin: new ResultRef(paymentCoin),
553
- flatFeeCoin: new ResultRef(flatFeeCoin),
554
- metadata: info.metadata,
555
- recipient: recipient.address,
556
- timeStart: info.startTime,
557
- cliff: recipient.cliffAmount,
558
- epochInterval: info.epochInterval,
559
- numEpoch: info.numberEpoch,
560
- amountPerEpoch: recipient.amountPerEpoch,
561
- cancelable: info.cancelable,
562
- coinType: info.coinType
563
- });
564
- }
565
- return txb;
566
- }
567
- calculateCreateStreamFees(createInfo) {
568
- const infoInternal = _CreateStreamHelper.convertCreateStreamInfoToInternal(createInfo);
569
- return this.calculateFeesInternal(infoInternal);
570
- }
571
- feeParams() {
572
- return {
573
- createFeePercent: {
574
- numerator: FEE_NUMERATOR,
575
- denominator: FEE_DENOMINATOR
576
- },
577
- claimFeePercent: {
578
- numerator: CLAIM_FEE_NUMERATOR,
579
- denominator: FEE_DENOMINATOR
580
- },
581
- flatFeePerStream: FLAT_FEE_SUI
582
- };
583
- }
584
- async addMergeCoins(txb, coins) {
585
- let mergedCoin;
586
- if (coins.mergedCoins && coins.mergedCoins.length) {
587
- txb.mergeCoins(
588
- txb.object(coins.primaryCoin),
589
- coins.mergedCoins.map((coinId) => txb.object(coinId))
590
- );
591
- mergedCoin = txb.object(coins.primaryCoin);
592
- } else if (coins.primaryCoin === GAS_OBJECT_SPEC) {
593
- mergedCoin = txb.gas;
594
- } else {
595
- mergedCoin = txb.object(coins.primaryCoin);
596
- }
597
- return mergedCoin;
598
- }
599
- getCreateStreamCoinRequests(info, payment) {
600
- const streamCoinType = info.coinType;
601
- if (isSameCoinType(streamCoinType, SUI_TYPE_ARG)) {
602
- return [
603
- {
604
- coinType: streamCoinType,
605
- amount: payment.totalAmount + payment.streamFeeAmount + payment.flatFeeAmount
606
- }
607
- ];
608
- }
609
- return [
610
- {
611
- coinType: streamCoinType,
612
- amount: payment.totalAmount + payment.streamFeeAmount
613
- },
614
- {
615
- coinType: SUI_TYPE_ARG,
616
- amount: payment.flatFeeAmount
617
- }
618
- ];
619
- }
620
- calculateFeesInternal(info) {
621
- const streamPayment = info.recipients.reduce(
622
- (sum, recipient) => {
623
- const totalAmount = this.amountForRecipient(recipient, info.numberEpoch);
624
- const fee = this.getStreamFeeLocal(totalAmount);
625
- return {
626
- totalAmount: sum.totalAmount + totalAmount,
627
- streamFeeAmount: sum.streamFeeAmount + fee
628
- };
629
- },
630
- {
631
- totalAmount: 0n,
632
- streamFeeAmount: 0n
633
- }
634
- );
635
- const flatFeeAmount = BigInt(info.recipients.length) * this.flatSuiFee;
636
- return {
637
- flatFeeAmount,
638
- ...streamPayment
639
- };
640
- }
641
- amountForRecipient(recipient, numEpoch) {
642
- return BigInt(recipient.amountPerEpoch) * BigInt(numEpoch) + BigInt(recipient.cliffAmount);
643
- }
644
- get flatSuiFee() {
645
- return FLAT_FEE_SUI;
646
- }
647
- getStreamFeeLocal(streamAmount) {
648
- return streamAmount * FEE_NUMERATOR / FEE_DENOMINATOR;
649
- }
650
- async getStreamFeeRemote(streamAmount) {
651
- const txb = this.feeContract.streamingFee(new TransactionBlock(), streamAmount);
652
- const res = await this.globals.suiClient.devInspectTransactionBlock({
653
- sender: await this.globals.walletAddress(),
654
- transactionBlock: txb
655
- });
656
- const iv = new InspectViewer(res);
657
- return iv.getU64();
658
- }
659
- get wallet() {
660
- return this.globals.wallet;
661
- }
662
- };
663
-
664
- // src/apps/mpay/contract/BaseContract.ts
665
- import { Transactions } from "@mysten/sui.js/transactions";
666
-
667
- // src/apps/mpay/const.ts
668
- var CLOCK_ID = "0x0000000000000000000000000000000000000000000000000000000000000006";
669
-
670
- // src/apps/mpay/contract/BaseContract.ts
671
- var BaseContract = class {
672
- constructor(moduleName, config, globals) {
673
- this.moduleName = moduleName;
674
- this.config = config;
675
- this.globals = globals;
676
- }
677
- addContractCall(txb, input) {
678
- const target = `${this.config.contractId}::${this.moduleName}::${input.method}`;
679
- txb.add(
680
- Transactions.MoveCall({
681
- target,
682
- arguments: input.arguments.map((arg) => {
683
- if (arg instanceof ObjectVector) {
684
- return arg.moveArgs(txb);
685
- }
686
- if (arg instanceof MoveObject) {
687
- return arg.moveArg(txb);
688
- }
689
- if (arg instanceof ResultRef) {
690
- return arg.moveArg();
691
- }
692
- return txb.pure(arg);
693
- }),
694
- typeArguments: input.typeArgs
695
- })
696
- );
697
- return txb;
698
- }
699
- addTransactionBlock(txb, target, callArgs = [], typeArgs = []) {
700
- txb.add(
701
- Transactions.MoveCall({
702
- target,
703
- arguments: callArgs.map((arg) => {
704
- if (arg instanceof ObjectVector) {
705
- return arg.moveArgs(txb);
706
- }
707
- if (arg instanceof MoveObject) {
708
- return arg.moveArg(txb);
709
- }
710
- if (arg instanceof ResultRef) {
711
- return arg.moveArg();
712
- }
713
- return txb.pure(arg);
714
- }),
715
- typeArguments: typeArgs
716
- })
717
- );
718
- }
719
- makeObject(object) {
720
- return typeof object === "string" ? new MoveObject(object) : object;
721
- }
722
- vaultObject() {
723
- return new MoveObject(this.config.vaultObjId);
724
- }
725
- roleObject() {
726
- return new MoveObject(this.config.roleObjId);
727
- }
728
- feeObject() {
729
- return new MoveObject(this.config.feeObjId);
730
- }
731
- clockObject() {
732
- return new MoveObject(CLOCK_ID);
733
- }
734
- };
735
-
736
- // src/apps/mpay/contract/FeeContract.ts
737
- var FeeContract = class _FeeContract extends BaseContract {
738
- constructor(config, globals) {
739
- super(_FeeContract.ModuleName, config, globals);
740
- this.config = config;
741
- this.globals = globals;
742
- }
743
- static ModuleName = "fee_module";
744
- static MethodName = {
745
- set_streaming_fee: "set_streaming_fee",
746
- set_claim_fee: "set_claim_fee",
747
- set_streaming_flat_fee: "set_streaming_flat_fee",
748
- streaming_flat_fee: "streaming_flat_fee",
749
- streaming_fee: "streaming_fee",
750
- claim_fee: "claim_fee",
751
- fee_denominator: "fee_denominator"
752
- };
753
- setStreamingFee(txb, createFeeNumerator) {
754
- const roleObject = this.roleObject();
755
- const feeObject = this.feeObject();
756
- return this.addContractCall(txb, {
757
- method: _FeeContract.MethodName.set_streaming_fee,
758
- arguments: [roleObject, feeObject, createFeeNumerator],
759
- typeArgs: []
760
- });
761
- }
762
- setStreamingFlatFee(txb, flatFee) {
763
- const roleObject = this.roleObject();
764
- const feeObject = this.feeObject();
765
- return this.addContractCall(txb, {
766
- method: _FeeContract.MethodName.set_streaming_flat_fee,
767
- arguments: [roleObject, feeObject, flatFee],
768
- typeArgs: []
769
- });
770
- }
771
- setClaimFee(txb, claimFee) {
772
- const roleObject = this.roleObject();
773
- const feeObject = this.feeObject();
774
- return this.addContractCall(txb, {
775
- method: _FeeContract.MethodName.set_claim_fee,
776
- arguments: [roleObject, feeObject, claimFee],
777
- typeArgs: []
778
- });
779
- }
780
- streamingFee(txb, amount) {
781
- const feeObject = this.feeObject();
782
- return this.addContractCall(txb, {
783
- method: _FeeContract.MethodName.streaming_fee,
784
- arguments: [feeObject, amount],
785
- typeArgs: []
786
- });
787
- }
788
- claimFee(txb, amount) {
789
- return this.addContractCall(txb, {
790
- method: _FeeContract.MethodName.claim_fee,
791
- arguments: [this.feeObject(), amount],
792
- typeArgs: []
793
- });
794
- }
795
- feeDenominator(txb) {
796
- return this.addContractCall(txb, {
797
- method: _FeeContract.MethodName.fee_denominator,
798
- arguments: [this.feeObject()],
799
- typeArgs: []
800
- });
801
- }
802
- };
803
-
804
- // src/apps/mpay/contract/StreamContract.ts
805
- var StreamContract = class _StreamContract extends BaseContract {
806
- constructor(config, globals) {
807
- super(_StreamContract.ModuleName, config, globals);
808
- this.config = config;
809
- this.globals = globals;
810
- }
811
- static ModuleName = "stream";
812
- static MethodName = {
813
- create_stream: "create_stream",
814
- set_auto_claim: "set_auto_claim",
815
- cancel_stream: "cancel_stream",
816
- claim_stream: "claim_stream",
817
- claim_stream_by_proxy: "claim_stream_by_proxy",
818
- stream_current_epoch: "stream_current_epoch",
819
- now_milli_seconds: "now_milli_seconds"
820
- };
821
- createStream(txb, input) {
822
- const feeObject = this.feeObject();
823
- const vaultObject = this.vaultObject();
824
- const paymentCoinObject = this.makeObject(input.paymentCoin);
825
- const flatFeeObject = this.makeObject(input.flatFeeCoin);
826
- const clockObject = this.clockObject();
827
- return this.addContractCall(txb, {
828
- method: _StreamContract.MethodName.create_stream,
829
- arguments: [
830
- feeObject,
831
- vaultObject,
832
- paymentCoinObject,
833
- flatFeeObject,
834
- input.metadata,
835
- input.recipient,
836
- input.timeStart,
837
- input.cliff,
838
- input.epochInterval,
839
- input.numEpoch,
840
- input.amountPerEpoch,
841
- input.cancelable,
842
- clockObject
843
- ],
844
- typeArgs: [input.coinType]
845
- });
846
- }
847
- setAutoClaim(txb, input) {
848
- const streamObject = this.makeObject(input.streamId);
849
- return this.addContractCall(txb, {
850
- method: _StreamContract.MethodName.set_auto_claim,
851
- arguments: [streamObject, input.enabled],
852
- typeArgs: [input.coinType]
853
- });
854
- }
855
- cancelStream(txb, input) {
856
- const streamObject = this.makeObject(input.streamId);
857
- const clockObject = this.clockObject();
858
- return this.addContractCall(txb, {
859
- method: _StreamContract.MethodName.cancel_stream,
860
- arguments: [streamObject, clockObject],
861
- typeArgs: [input.coinType]
862
- });
863
- }
864
- claimStream(txb, input) {
865
- const streamObject = this.makeObject(input.streamId);
866
- const clockObject = this.clockObject();
867
- return this.addContractCall(txb, {
868
- method: _StreamContract.MethodName.claim_stream,
869
- arguments: [streamObject, clockObject],
870
- typeArgs: [input.coinType]
871
- });
872
- }
873
- claimStreamByProxy(txb, input) {
874
- const streamObject = this.makeObject(input.streamId);
875
- const vaultObject = this.vaultObject();
876
- const feeObject = this.feeObject();
877
- const clockObject = this.clockObject();
878
- return this.addContractCall(txb, {
879
- method: _StreamContract.MethodName.claim_stream_by_proxy,
880
- arguments: [streamObject, vaultObject, feeObject, clockObject],
881
- typeArgs: [input.coinType]
882
- });
883
- }
884
- get createStreamTarget() {
885
- return `${this.config.contractId}::${_StreamContract.ModuleName}::${_StreamContract.MethodName.create_stream}`;
886
- }
887
- get setAutoClaimTarget() {
888
- return `${this.config.contractId}::${_StreamContract.ModuleName}::${_StreamContract.MethodName.set_auto_claim}`;
889
- }
890
- get cancelStreamTarget() {
891
- return `${this.config.contractId}::${_StreamContract.ModuleName}::${_StreamContract.MethodName.cancel_stream}`;
892
- }
893
- get claimStreamTarget() {
894
- return `${this.config.contractId}::${_StreamContract.ModuleName}::${_StreamContract.MethodName.claim_stream}`;
895
- }
896
- get claimStreamByProxyTarget() {
897
- return `${this.config.contractId}::${_StreamContract.ModuleName}::${_StreamContract.MethodName.claim_stream_by_proxy}`;
898
- }
899
- };
900
-
901
- // src/apps/mpay/builder/MPayBuilder.ts
902
- var MPayBuilder = class {
903
- constructor(globals) {
904
- this.globals = globals;
905
- const config = globals.envConfig.contract;
906
- this.feeContract = new FeeContract(config, globals);
907
- this.streamContract = new StreamContract(config, globals);
908
- }
909
- feeContract;
910
- streamContract;
911
- async createStreams(info) {
912
- const infoInternal = CreateStreamHelper.convertCreateStreamInfoToInternal(info);
913
- return this.createStreamHelper().buildCreateStreamTransactionBlock(infoInternal);
914
- }
915
- createStreamHelper() {
916
- return new CreateStreamHelper(this.globals, this.feeContract, this.streamContract);
917
- }
918
- setAutoClaim(streamId, enabled, coinType) {
919
- const txb = new TransactionBlock3();
920
- return this.streamContract.setAutoClaim(txb, {
921
- streamId,
922
- enabled,
923
- coinType
924
- });
925
- }
926
- claimStream(streamId, coinType) {
927
- const txb = new TransactionBlock3();
928
- return this.streamContract.claimStream(txb, {
929
- streamId,
930
- coinType
931
- });
932
- }
933
- claimStreamByProxy(streamId, coinType) {
934
- const txb = new TransactionBlock3();
935
- return this.streamContract.claimStreamByProxy(txb, {
936
- streamId,
937
- coinType
938
- });
939
- }
940
- cancelStream(streamId, coinType) {
941
- const txb = new TransactionBlock3();
942
- this.streamContract.cancelStream(txb, {
943
- streamId,
944
- coinType
945
- });
946
- return txb;
947
- }
948
- };
949
-
950
- // src/apps/mpay/error/TransactionFailedError.ts
951
- var TransactionFailedError = class extends MPayError {
952
- constructor(status3, msg) {
953
- super(12 /* TransactionFailed */, `Transaction failed: ${msg}`, {
954
- context: {
955
- status: status3,
956
- msg
957
- }
958
- });
959
- }
960
- };
961
-
962
- // src/apps/mpay/stream/helper.ts
963
- var MIN_INTERVAL_MS = 1e3;
964
- var MPayHelper = class {
965
- constructor(globals) {
966
- this.globals = globals;
967
- this.coinMetaHelper = new CoinMetaHelper(globals.suiClient);
968
- this.createStreamHelper = new MPayBuilder(globals).createStreamHelper();
969
- }
970
- coinMetaHelper;
971
- createStreamHelper;
972
- getStreamIdsFromCreateStreamResponse(res) {
973
- if (res.effects?.status.status !== "success") {
974
- throw new TransactionFailedError(res.effects?.status.status, res.effects?.status.error);
975
- }
976
- return res.objectChanges.filter(
977
- (change) => change.type === "created" && change.objectType.startsWith(`${this.globals.envConfig.contract.contractId}::stream::Stream`)
978
- ).map((change) => change.objectId);
979
- }
980
- calculateCreateStreamFees(info) {
981
- return this.createStreamHelper.calculateCreateStreamFees(info);
982
- }
983
- feeParams() {
984
- return this.createStreamHelper.feeParams();
985
- }
986
- calculateStreamAmount(input) {
987
- if (input.steps === 0n) {
988
- throw new InvalidInputError("Invalid stream steps: 0");
989
- }
990
- const cliffFraction = input.cliff ? input.cliff : {
991
- numerator: 0n,
992
- denominator: 100n
993
- };
994
- const cliffAmount = input.totalAmount * cliffFraction.numerator / cliffFraction.denominator;
995
- const amountPerStep = (input.totalAmount - cliffAmount) / input.steps;
996
- const realTotalAmount = amountPerStep * input.steps + cliffAmount;
997
- const res = {
998
- realTotalAmount,
999
- cliffAmount,
1000
- amountPerStep
1001
- };
1002
- this.validateStreamAmount(res, input.totalAmount);
1003
- return res;
1004
- }
1005
- calculateTimelineByInterval(input) {
1006
- if (input.steps === 0n) {
1007
- throw new InvalidInputError("Invalid stream steps: 0");
1008
- }
1009
- const timeEnd = input.timeStart.plus(input.interval.toMillis() * Number(input.steps));
1010
- const res = {
1011
- timeStart: input.timeStart,
1012
- timeEnd,
1013
- interval: input.interval,
1014
- steps: input.steps
1015
- };
1016
- this.validateTimeline(res);
1017
- return res;
1018
- }
1019
- calculateTimelineByTotalDuration(input) {
1020
- if (input.steps === 0n) {
1021
- throw new InvalidInputError("Invalid stream steps: 0");
1022
- }
1023
- const intervalMilli = BigInt(input.total.toMillis()) / input.steps;
1024
- const timeEnd = input.timeStart.plus(Duration.fromMillis(Number(intervalMilli * input.steps)));
1025
- const res = {
1026
- timeStart: input.timeStart,
1027
- timeEnd,
1028
- interval: Duration.fromMillis(Number(intervalMilli)),
1029
- steps: input.steps
1030
- };
1031
- this.validateTimeline(res);
1032
- return res;
1033
- }
1034
- async getBalance(address, coinType) {
1035
- const balance = await this.globals.suiClient.getBalance({
1036
- owner: address,
1037
- coinType
1038
- });
1039
- const coinMeta = await this.getCoinMeta(coinType);
1040
- return {
1041
- ...balance,
1042
- coinType: normalizeStructTag3(balance.coinType),
1043
- coinMeta
1044
- };
1045
- }
1046
- async getAllBalance(address) {
1047
- const allBalance = await this.globals.suiClient.getAllBalances({
1048
- owner: address
1049
- });
1050
- const coinMetas = await Promise.all(allBalance.map((bal) => this.getCoinMeta(bal.coinType)));
1051
- return allBalance.map((bal, i) => ({
1052
- ...bal,
1053
- coinType: normalizeStructTag3(bal.coinType),
1054
- coinMeta: coinMetas[i]
1055
- }));
1056
- }
1057
- async getCoinMeta(coinType) {
1058
- return this.coinMetaHelper.getCoinMeta(coinType);
1059
- }
1060
- async simulateTransactionBlock(txb) {
1061
- return this.globals.suiClient.devInspectTransactionBlock({
1062
- transactionBlock: txb,
1063
- sender: await this.globals.wallet.address()
1064
- });
1065
- }
1066
- validateStreamAmount(val, originTotalAmount) {
1067
- if (val.amountPerStep === 0n) {
1068
- throw new InvalidInputError("Stream amount too small", "totalAmount", originTotalAmount);
1069
- }
1070
- if (val.cliffAmount > val.realTotalAmount) {
1071
- throw new InvalidInputError("Invalid cliff settings");
1072
- }
1073
- }
1074
- validateTimeline(val) {
1075
- if (val.interval.toMillis() < MIN_INTERVAL_MS) {
1076
- throw new InvalidInputError("Interval shall be at least 1 second", "interval", val.interval);
1077
- }
1078
- }
1079
- };
1080
- var CoinMetaHelper = class {
1081
- constructor(suiClient) {
1082
- this.suiClient = suiClient;
1083
- this.coinMetaReg = /* @__PURE__ */ new Map();
1084
- }
1085
- coinMetaReg;
1086
- async getCoinMeta(coinType) {
1087
- const normalized = normalizeStructTag3(coinType || SUI_TYPE_ARG2);
1088
- if (this.coinMetaReg.has(normalized)) {
1089
- return this.coinMetaReg.get(normalized);
1090
- }
1091
- const meta = await this.queryCoinMeta(normalized);
1092
- if (meta) {
1093
- this.coinMetaReg.set(normalized, meta);
1094
- }
1095
- return meta;
1096
- }
1097
- async queryCoinMeta(coinType) {
1098
- const res = await this.suiClient.getCoinMetadata({ coinType });
1099
- return res || void 0;
1100
- }
1101
- };
1102
-
1103
- // src/apps/mpay/stream/query.ts
1104
- import { normalizeStructTag as normalizeStructTag5, normalizeSuiAddress as normalizeSuiAddress2 } from "@mysten/sui.js/utils";
1105
- import { DateTime as DateTime4 } from "luxon";
1106
-
1107
- // src/apps/mpay/stream/Stream.ts
1108
- import { TransactionBlock as TransactionBlock4 } from "@mysten/sui.js/transactions";
1109
- import { normalizeStructTag as normalizeStructTag4, parseStructTag } from "@mysten/sui.js/utils";
1110
- import { DateTime as DateTime3 } from "luxon";
1111
-
1112
- // src/apps/mpay/error/NotCreatorError.ts
1113
- var NotCreatorError = class extends MPayError {
1114
- constructor() {
1115
- super(7 /* NotCreator */, "Connected wallet is not creator");
1116
- }
1117
- };
1118
-
1119
- // src/apps/mpay/error/NotRecipientError.ts
1120
- var NotRecipientError = class extends MPayError {
1121
- constructor() {
1122
- super(8 /* NotRecipient */, "Connected wallet is not recipient");
1123
- }
1124
- };
1125
-
1126
- // src/apps/mpay/error/RpcError.ts
1127
- var RpcError = class extends MPayError {
1128
- constructor(msg, context) {
1129
- super(6 /* RpcError */, msg, {
1130
- context
1131
- });
1132
- }
1133
- };
1134
-
1135
- // src/apps/mpay/error/SanityError.ts
1136
- var SanityError = class extends MPayError {
1137
- constructor(msg, options = {}) {
1138
- super(0 /* sanity */, msg, options);
1139
- }
1140
- };
1141
-
1142
- // src/apps/mpay/error/StreamNotFoundError.ts
1143
- var StreamNotFoundError = class extends MPayError {
1144
- constructor(streamId) {
1145
- super(5 /* StreamNotFound */, "Stream not found", {
1146
- context: {
1147
- streamId
1148
- }
1149
- });
1150
- }
1151
- };
1152
-
1153
- // src/apps/mpay/utils/utils.ts
1154
- import { DateTime as DateTime2, Duration as Duration2 } from "luxon";
1155
- var MAX_U64 = (1n << 64n) - 1n;
1156
- var TIME_ROUND_UNIT = 1e3;
1157
- function roundDateTime(date) {
1158
- let dateMs;
1159
- if (typeof date === "number") {
1160
- dateMs = date;
1161
- } else if (typeof date === "bigint") {
1162
- dateMs = Number(date);
1163
- } else {
1164
- dateMs = date.toMillis();
1165
- }
1166
- const roundMs = Math.round(dateMs / TIME_ROUND_UNIT);
1167
- return DateTime2.fromMillis(roundMs * TIME_ROUND_UNIT);
1168
- }
1169
- function roundDuration(duration) {
1170
- let durationMs;
1171
- if (typeof duration === "number") {
1172
- durationMs = duration;
1173
- } else if (typeof duration === "bigint") {
1174
- durationMs = Number(duration);
1175
- } else {
1176
- durationMs = duration.toMillis();
1177
- }
1178
- const roundMs = Math.round(durationMs / TIME_ROUND_UNIT);
1179
- return Duration2.fromMillis(roundMs * TIME_ROUND_UNIT);
1180
- }
1181
-
1182
- // src/apps/mpay/stream/Stream.ts
1183
- var Stream = class _Stream {
1184
- constructor(globals, streamId, rawData) {
1185
- this.globals = globals;
1186
- this.streamId = streamId;
1187
- this.rawData = rawData;
1188
- this.streamContract = new StreamContract(globals.envConfig.contract, globals);
1189
- }
1190
- streamContract;
1191
- type = "Stream";
1192
- static async new(globals, streamId) {
1193
- const rawData = await _Stream.fetchStreamData(globals, streamId);
1194
- return new _Stream(globals, streamId, rawData);
1195
- }
1196
- static fromObjectData(globals, streamId, data) {
1197
- const rawData = _Stream.parseRawStreamData(streamId, data);
1198
- return new _Stream(globals, streamId, rawData);
1199
- }
1200
- get info() {
1201
- return {
1202
- name: this.name,
1203
- creator: this.creator,
1204
- coinType: this.coinType,
1205
- totalAmount: this.totalAmount,
1206
- start: this.timeStart,
1207
- end: this.timeEnd,
1208
- cancelable: this.cancelable,
1209
- cliffAmount: this.cliff,
1210
- duration: this.duration,
1211
- interval: this.interval,
1212
- steps: this.totalSteps,
1213
- nextReleaseDate: this.nextReleaseDate,
1214
- nextReleaseAmount: this.nextReleaseAmount,
1215
- groupId: this.groupId,
1216
- streamId: this.streamId,
1217
- recipient: this.recipient,
1218
- progress: this.progress,
1219
- autoClaim: this.autoClaim
1220
- };
1221
- }
1222
- get groupCommonInfo() {
1223
- return {
1224
- name: this.name,
1225
- groupId: this.groupId,
1226
- creator: this.creator,
1227
- start: this.timeStart,
1228
- interval: this.interval,
1229
- steps: this.totalSteps,
1230
- cancelable: this.cancelable
1231
- };
1232
- }
1233
- async refresh() {
1234
- this.rawData = await _Stream.fetchStreamData(this.globals, this.streamId);
1235
- }
1236
- refreshWithData(data) {
1237
- if (data.data?.objectId !== this.streamId) {
1238
- throw new SanityError("Object Id does not align");
1239
- }
1240
- this.rawData = _Stream.parseRawStreamData(this.streamId, data);
1241
- }
1242
- async historyEvents(pagination) {
1243
- return this.globals.backend.getStreamHistory({
1244
- streamId: this.streamId,
1245
- pagination
1246
- });
1247
- }
1248
- async cancel() {
1249
- if (await this.globals.walletAddress() !== this.creator) {
1250
- throw new NotCreatorError();
1251
- }
1252
- const txb = new TransactionBlock4();
1253
- this.streamContract.cancelStream(txb, {
1254
- streamId: this.streamId,
1255
- coinType: this.coinType
1256
- });
1257
- return txb;
1258
- }
1259
- async claim() {
1260
- if (await this.globals.walletAddress() !== this.recipient) {
1261
- throw new NotRecipientError();
1262
- }
1263
- const txb = new TransactionBlock4();
1264
- this.streamContract.claimStream(txb, {
1265
- streamId: this.streamId,
1266
- coinType: this.coinType
1267
- });
1268
- return txb;
1269
- }
1270
- async setAutoClaim(enabled) {
1271
- if (await this.globals.walletAddress() !== this.recipient) {
1272
- throw new NotRecipientError();
1273
- }
1274
- const txb = new TransactionBlock4();
1275
- this.streamContract.setAutoClaim(txb, {
1276
- streamId: this.streamId,
1277
- coinType: this.coinType,
1278
- enabled
1279
- });
1280
- return txb;
1281
- }
1282
- async claimByProxy() {
1283
- const txb = new TransactionBlock4();
1284
- this.streamContract.claimStreamByProxy(txb, {
1285
- streamId: this.streamId,
1286
- coinType: this.coinType
1287
- });
1288
- return txb;
1289
- }
1290
- get wallet() {
1291
- return this.globals.wallet;
1292
- }
1293
- get client() {
1294
- return this.globals.suiClient;
1295
- }
1296
- get coinType() {
1297
- return normalizeStructTag4(this.rawData.coinType);
1298
- }
1299
- get progress() {
1300
- return {
1301
- status: this.streamStatus,
1302
- total: this.totalAmount,
1303
- streamed: this.streamedAmount,
1304
- claimed: this.claimedAmount,
1305
- claimable: this.claimable,
1306
- canceled: this.canceledAmount
1307
- };
1308
- }
1309
- get balance() {
1310
- return this.rawData.balance;
1311
- }
1312
- get autoClaim() {
1313
- return this.rawData.autoClaim;
1314
- }
1315
- get amountPerEpoch() {
1316
- return this.rawData.config.amountPerEpoch;
1317
- }
1318
- get cancelable() {
1319
- return this.rawData.config.cancelable;
1320
- }
1321
- get cliff() {
1322
- return this.rawData.config.cliff;
1323
- }
1324
- get creator() {
1325
- return this.rawData.config.creator;
1326
- }
1327
- get interval() {
1328
- return roundDuration(this.rawData.config.epochInterval);
1329
- }
1330
- get groupId() {
1331
- const { metadata } = this.rawData.config;
1332
- const md = decodeMetadata(metadata);
1333
- return md.groupId;
1334
- }
1335
- get name() {
1336
- const { metadata } = this.rawData.config;
1337
- const md = decodeMetadata(metadata);
1338
- return md.name;
1339
- }
1340
- get recipient() {
1341
- return this.rawData.config.recipient;
1342
- }
1343
- get timeStart() {
1344
- return roundDateTime(this.rawData.config.timeStart);
1345
- }
1346
- get duration() {
1347
- const rawConfig = this.rawData.config;
1348
- const duration = rawConfig.epochInterval * rawConfig.totalEpoch;
1349
- return roundDuration(duration);
1350
- }
1351
- get timeEnd() {
1352
- return this.timeStart.plus(this.duration);
1353
- }
1354
- get totalSteps() {
1355
- return this.rawData.config.totalEpoch;
1356
- }
1357
- get claimable() {
1358
- return this.streamedAmount - this.claimedAmount;
1359
- }
1360
- get nextReleaseDate() {
1361
- if (this.currentEpoch === -1n) {
1362
- return this.timeStart;
1363
- }
1364
- if (this.currentEpoch >= this.totalSteps || this.isCanceled) {
1365
- return null;
1366
- }
1367
- return roundDateTime((this.currentEpoch + 1n) * this.rawData.config.epochInterval + this.rawData.config.timeStart);
1368
- }
1369
- get nextReleaseAmount() {
1370
- if (this.currentEpoch === -1n) {
1371
- return this.cliff;
1372
- }
1373
- if (this.currentEpoch >= this.totalSteps || this.isCanceled) {
1374
- return null;
1375
- }
1376
- return this.amountPerEpoch;
1377
- }
1378
- get streamStatus() {
1379
- const rawStatus = this.rawData.status.status;
1380
- if (rawStatus === 16 /* CANCELED */) {
1381
- return "CANCELED" /* CANCELED */;
1382
- }
1383
- if (rawStatus === 17 /* CANCELED_COMPLETED */) {
1384
- return "SETTLED" /* SETTLED */;
1385
- }
1386
- if (rawStatus === 1 /* COMPLETED */) {
1387
- return "COMPLETED" /* COMPLETED */;
1388
- }
1389
- if (this.currentEpoch >= this.totalSteps) {
1390
- return "STREAMED" /* STREAMED */;
1391
- }
1392
- return "STREAMING" /* STREAMING */;
1393
- }
1394
- get streamedAmount() {
1395
- if (this.currentEpoch === -1n) {
1396
- return 0n;
1397
- }
1398
- if (this.isCanceled) {
1399
- return this.rawData.status.epochCanceled * this.amountPerEpoch + this.cliff;
1400
- }
1401
- return this.currentEpoch * this.amountPerEpoch + this.cliff;
1402
- }
1403
- get claimedAmount() {
1404
- if (this.rawData.status.epochClaimed === MAX_U64) {
1405
- return 0n;
1406
- }
1407
- return this.rawData.status.epochClaimed * this.amountPerEpoch + this.cliff;
1408
- }
1409
- get currentEpoch() {
1410
- const timeNowMs = DateTime3.now().toMillis();
1411
- const timeStartMs = this.timeStart.toMillis();
1412
- if (timeNowMs < timeStartMs) {
1413
- return -1n;
1414
- }
1415
- const epoch = Math.floor((timeNowMs - timeStartMs) / Number(this.rawData.config.epochInterval));
1416
- return BigInt(epoch) > Number(this.rawData.config.totalEpoch) ? this.rawData.config.totalEpoch : BigInt(epoch);
1417
- }
1418
- get totalAmount() {
1419
- const rawConfig = this.rawData.config;
1420
- return rawConfig.amountPerEpoch * rawConfig.totalEpoch + rawConfig.cliff;
1421
- }
1422
- get isCanceled() {
1423
- const rawStatus = this.rawData.status.status;
1424
- return rawStatus === 16 /* CANCELED */ || rawStatus === 17 /* CANCELED_COMPLETED */;
1425
- }
1426
- get canceledAmount() {
1427
- return this.isCanceled ? this.totalAmount - this.streamedAmount : 0n;
1428
- }
1429
- static async fetchStreamData(globals, streamId) {
1430
- const res = await globals.suiClient.getObject({
1431
- id: streamId,
1432
- options: {
1433
- showContent: true,
1434
- showType: true
1435
- }
1436
- });
1437
- return _Stream.parseRawStreamData(streamId, res);
1438
- }
1439
- static parseRawStreamData(streamId, res) {
1440
- if (res.error) {
1441
- if (res.error.code === "notExists") {
1442
- throw new StreamNotFoundError(streamId);
1443
- }
1444
- throw new RpcError(`get stream data: ${res.error.code}`, {
1445
- streamId,
1446
- ...res.error
1447
- });
1448
- }
1449
- const content = res.data.content;
1450
- if (content.dataType !== "moveObject") {
1451
- throw new RpcError("Unexpected object type", {
1452
- gotType: content.dataType
1453
- });
1454
- }
1455
- const { typeParams } = parseStructTag(content.type);
1456
- const coinType = normalizeStructTag4(typeParams[0]);
1457
- const dataFields = content.fields;
1458
- const config = dataFields.config.fields;
1459
- const status3 = dataFields.status.fields;
1460
- return {
1461
- coinType,
1462
- autoClaim: dataFields.auto_claim,
1463
- balance: BigInt(dataFields.balance.fields.balance),
1464
- config: {
1465
- amountPerEpoch: BigInt(config.amount_per_epoch),
1466
- cancelable: config.cancelable,
1467
- cliff: BigInt(config.cliff),
1468
- creator: config.creator,
1469
- epochInterval: BigInt(config.epoch_interval),
1470
- metadata: config.metadata,
1471
- recipient: config.recipient,
1472
- timeStart: BigInt(config.time_start),
1473
- totalEpoch: BigInt(config.total_epoch)
1474
- },
1475
- status: {
1476
- status: status3.status,
1477
- epochCanceled: BigInt(status3.epoch_canceled),
1478
- epochClaimed: BigInt(status3.epoch_claimed)
1479
- }
1480
- };
1481
- }
1482
- };
1483
-
1484
- // src/apps/mpay/error/InvalidStreamGroupError.ts
1485
- var InvalidStreamGroupError = class extends MPayError {
1486
- constructor(msg, context) {
1487
- super(9 /* InvalidStreamGroup */, `Invalid stream group: ${msg}`, { context });
1488
- }
1489
- };
1490
-
1491
- // src/apps/mpay/sui/iterator/iterator.ts
1492
- async function getAllFromIterator(it) {
1493
- const res = [];
1494
- while (await it.hasNext()) {
1495
- const val = await it.next();
1496
- res.push(val);
1497
- }
1498
- if (res && Array.isArray(res[0])) {
1499
- return res.flat(1);
1500
- }
1501
- return res;
1502
- }
1503
- var PagedIterator = class {
1504
- constructor(requester) {
1505
- this.requester = requester;
1506
- this.curPage = void 0;
1507
- this.init = true;
1508
- }
1509
- curPage;
1510
- init;
1511
- async hasNext() {
1512
- if (this.init) {
1513
- if (!this.curPage) {
1514
- this.curPage = await this.requester.doNextRequest();
1515
- }
1516
- return !!this.curPage.data?.length || this.curPage.hasNext;
1517
- }
1518
- if (!this.curPage) {
1519
- throw new Error("invalid implementation of iterator");
1520
- }
1521
- return this.curPage.hasNext;
1522
- }
1523
- async next() {
1524
- if (this.init) {
1525
- this.init = false;
1526
- if (!this.curPage) {
1527
- this.curPage = await this.requester.doNextRequest();
1528
- }
1529
- return this.curPage.data;
1530
- }
1531
- this.curPage = await this.requester.doNextRequest();
1532
- return this.curPage.data;
1533
- }
1534
- };
1535
- var EntryIterator = class {
1536
- constructor(requester) {
1537
- this.requester = requester;
1538
- this.pager = new PagedIterator(requester);
1539
- this.curData = [];
1540
- this.cursor = 0;
1541
- }
1542
- cursor;
1543
- pager;
1544
- curData;
1545
- async hasNext() {
1546
- if (this.cursor < this.curData.length - 1) {
1547
- return true;
1548
- }
1549
- return this.pager.hasNext();
1550
- }
1551
- async next() {
1552
- this.cursor += 1;
1553
- while (this.cursor >= this.curData.length) {
1554
- if (!await this.pager.hasNext()) {
1555
- throw new Error("not more data");
1556
- } else {
1557
- this.curData = await this.pager.next();
1558
- this.cursor = 0;
1559
- }
1560
- }
1561
- return this.curData[this.cursor];
1562
- }
1563
- };
1564
-
1565
- // src/apps/mpay/sui/iterator/object.ts
1566
- var REQUEST_PAGE_SIZE = 25;
1567
- async function getObjectsById(suiClient, ids, options) {
1568
- const oidIter = new ListOidIterator(ids);
1569
- const iter = new ObjectBatchIterator(suiClient, oidIter, options);
1570
- return await getAllFromIterator(iter);
1571
- }
1572
- var ListOidIterator = class {
1573
- constructor(ids) {
1574
- this.ids = ids;
1575
- this.cursor = -1;
1576
- }
1577
- cursor;
1578
- async hasNext() {
1579
- return this.cursor < this.ids.length - 1;
1580
- }
1581
- async next() {
1582
- this.cursor += 1;
1583
- if (this.cursor >= this.ids.length) {
1584
- throw new Error("invalid iterator implementation");
1585
- }
1586
- return this.ids[this.cursor];
1587
- }
1588
- };
1589
- var ObjectBatchIterator = class extends EntryIterator {
1590
- constructor(suiClient, idIter, options) {
1591
- super(new ObjectBatchRequester(suiClient, idIter, options));
1592
- this.suiClient = suiClient;
1593
- this.idIter = idIter;
1594
- this.options = options;
1595
- }
1596
- };
1597
- var ObjectBatchRequester = class {
1598
- constructor(suiClient, stringIter, options) {
1599
- this.suiClient = suiClient;
1600
- this.stringIter = stringIter;
1601
- this.options = options;
1602
- this.filter = options?.filter;
1603
- this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;
1604
- this.objectOptions = options?.objectOptions || {
1605
- showType: true,
1606
- showContent: true
1607
- };
1608
- }
1609
- filter;
1610
- pageSize;
1611
- objectOptions;
1612
- async doNextRequest() {
1613
- const requestPage = [];
1614
- while (requestPage.length < this.pageSize) {
1615
- const hasNext = await this.stringIter.hasNext();
1616
- if (!hasNext) {
1617
- break;
1618
- }
1619
- const objId = await this.stringIter.next();
1620
- if (objId) {
1621
- requestPage.push(objId);
1622
- }
1623
- }
1624
- const res = await this.suiClient.multiGetObjects({
1625
- ids: requestPage,
1626
- options: this.objectOptions
1627
- });
1628
- let filtered;
1629
- if (this.filter) {
1630
- const { filter } = this;
1631
- filtered = res.filter((r) => filter?.(r));
1632
- } else {
1633
- filtered = res;
1634
- }
1635
- return {
1636
- data: filtered,
1637
- hasNext: await this.stringIter.hasNext()
1638
- };
1639
- }
1640
- };
1641
-
1642
- // src/apps/mpay/stream/StreamGroup.ts
1643
- var StreamGroup = class _StreamGroup {
1644
- constructor(globals, streams) {
1645
- this.globals = globals;
1646
- this.streams = streams;
1647
- if (streams.length === 0) {
1648
- throw new InvalidStreamGroupError("stream size 0");
1649
- }
1650
- const gids = streams.map((st) => st.groupId);
1651
- const set = new Set(gids);
1652
- if (set.size !== 1) {
1653
- throw new InvalidInputError("Stream does not have same group ID");
1654
- }
1655
- }
1656
- type = "StreamGroup";
1657
- static async new(globals, ids) {
1658
- const streamObjs = await getObjectsById(globals.suiClient, ids);
1659
- streamObjs.forEach((obj) => {
1660
- if (!obj) {
1661
- throw new SanityError("stream group object data undefined");
1662
- }
1663
- });
1664
- return _StreamGroup.newFromObjectResponse(globals, ids, streamObjs);
1665
- }
1666
- static async newFromObjectResponse(globals, ids, responses) {
1667
- const streams = await _StreamGroup.parseGroupStreams(globals, ids, responses);
1668
- return new _StreamGroup(globals, streams);
1669
- }
1670
- static checkStreamGroup(streams) {
1671
- const commonInfos = streams.map((stream) => stream.groupCommonInfo);
1672
- const expInfo = commonInfos[0];
1673
- let isEqual = true;
1674
- commonInfos.forEach((info) => {
1675
- if (!isEqualStreamGroupCommonInfo(expInfo, info)) {
1676
- isEqual = false;
1677
- }
1678
- });
1679
- return isEqual;
1680
- }
1681
- async refresh() {
1682
- const streamObjs = await getObjectsById(
1683
- this.globals.suiClient,
1684
- this.streams.map((stream) => stream.streamId)
1685
- );
1686
- this.streams.forEach((stream, i) => {
1687
- stream.refreshWithData(streamObjs[i]);
1688
- });
1689
- }
1690
- get groupId() {
1691
- return this.streams[0].groupId;
1692
- }
1693
- get creator() {
1694
- return this.streams[0].creator;
1695
- }
1696
- get info() {
1697
- return {
1698
- groupId: this.groupId,
1699
- streamIds: this.streams.map((st) => st.streamId),
1700
- progress: this.progress,
1701
- name: this.streams[0].name,
1702
- creator: this.creator,
1703
- coinType: this.streams[0].coinType,
1704
- totalAmount: this.streams.reduce((sum, st) => sum + st.totalAmount, 0n),
1705
- start: this.streams[0].timeStart,
1706
- end: this.streams[0].timeEnd,
1707
- cancelable: this.streams[0].cancelable,
1708
- cliffAmount: this.streams.reduce((sum, st) => sum + st.cliff, 0n),
1709
- duration: this.streams[0].duration,
1710
- interval: this.streams[0].interval,
1711
- steps: this.streams[0].totalSteps,
1712
- nextReleaseAmount: this.streams.reduce((sum, st) => {
1713
- if (st.nextReleaseAmount === null) {
1714
- return sum;
1715
- }
1716
- return sum + st.nextReleaseAmount;
1717
- }, 0n),
1718
- nextReleaseDate: this.streams[0].nextReleaseDate
1719
- };
1720
- }
1721
- get progress() {
1722
- return {
1723
- total: this.streams.reduce((sum, st) => sum + st.totalAmount, 0n),
1724
- streamed: this.streams.reduce((sum, st) => sum + st.streamedAmount, 0n),
1725
- claimed: this.streams.reduce((sum, st) => sum + st.claimedAmount, 0n),
1726
- claimable: this.streams.reduce((sum, st) => sum + st.claimable, 0n),
1727
- canceled: this.streams.reduce((sum, st) => sum + st.canceledAmount, 0n)
1728
- };
1729
- }
1730
- async historyEvents(pagination) {
1731
- return this.globals.backend.getStreamHistory({
1732
- groupId: this.groupId,
1733
- pagination
1734
- });
1735
- }
1736
- static async parseGroupStreams(globals, ids, responses) {
1737
- const streams = responses.map((obj, i) => Stream.fromObjectData(globals, ids[i], obj)).filter((stream) => !!stream);
1738
- if (new Set(streams.map((st) => st.groupId)).size !== 1) {
1739
- throw new InvalidStreamGroupError("Not same group ID");
1740
- }
1741
- if (!this.checkStreamGroup(streams)) {
1742
- throw new InvalidStreamGroupError("Not same stream settings");
1743
- }
1744
- return streams;
1745
- }
1746
- };
1747
- function isEqualStreamGroupCommonInfo(info1, info2) {
1748
- return info1.name === info2.name && info1.groupId === info2.groupId && info1.creator === info2.creator && info1.start.toMillis() === info2.start.toMillis() && info1.interval.toMillis() === info2.interval.toMillis() && info1.steps === info2.steps && info1.cancelable === info2.cancelable;
1749
- }
1750
-
1751
- // src/apps/mpay/stream/query.ts
1752
- var PagedStreamListIterator = class _PagedStreamListIterator {
1753
- constructor(it, pageSize) {
1754
- this.it = it;
1755
- this.pageSize = pageSize;
1756
- }
1757
- static async newIncoming(input) {
1758
- const it = await StreamListIterator.newIncoming(input);
1759
- return new _PagedStreamListIterator(it, input.pageSize);
1760
- }
1761
- static async newOutgoing(input) {
1762
- const it = await StreamListIterator.newOutgoing(input);
1763
- return new _PagedStreamListIterator(it, input.pageSize);
1764
- }
1765
- async hasNext() {
1766
- return this.it.hasNext();
1767
- }
1768
- async next() {
1769
- const res = [];
1770
- while (res.length < this.pageSize && await this.it.hasNext()) {
1771
- res.push(await this.it.next());
1772
- }
1773
- return res;
1774
- }
1775
- };
1776
- var StreamListIterator = class _StreamListIterator {
1777
- constructor(requester) {
1778
- this.requester = requester;
1779
- }
1780
- cachedNext;
1781
- static async newIncoming(input) {
1782
- const requester = await StreamListRequester.newIncomingQuery(input);
1783
- return new _StreamListIterator(requester);
1784
- }
1785
- static async newOutgoing(input) {
1786
- const requester = await StreamListRequester.newOutgoingQuery(input);
1787
- return new _StreamListIterator(requester);
1788
- }
1789
- async hasNext() {
1790
- if (this.cachedNext === void 0) {
1791
- this.cachedNext = await this.requester.doNextRequest();
1792
- }
1793
- return this.cachedNext !== null;
1794
- }
1795
- async next() {
1796
- if (this.cachedNext === void 0) {
1797
- const res2 = await this.requester.doNextRequest();
1798
- if (res2 === null) {
1799
- throw new SanityError("No more results");
1800
- }
1801
- return res2;
1802
- }
1803
- const res = this.cachedNext;
1804
- this.cachedNext = void 0;
1805
- if (res === null) {
1806
- throw new SanityError("No more results");
1807
- }
1808
- return res;
1809
- }
1810
- };
1811
- var StreamListRequester = class _StreamListRequester {
1812
- constructor(globals, recipient, groupRefs, query) {
1813
- this.globals = globals;
1814
- this.recipient = recipient;
1815
- this.groupRefs = groupRefs;
1816
- this.query = query;
1817
- this.current = 0;
1818
- const oidIter = new ListOidIterator(groupRefs.flat().map((ref) => ref.streamId));
1819
- this.objectIter = new ObjectBatchIterator(globals.suiClient, oidIter);
1820
- }
1821
- current = 0;
1822
- objectIter;
1823
- static async newIncomingQuery(input) {
1824
- const backendQuery = convertToIncomingBackendQuery(input.query);
1825
- const recipient = await input.globals.walletAddress();
1826
- const refs = await input.globals.backend.getIncomingStreams(recipient, backendQuery);
1827
- const filtered = refs.filter((ref) => normalizeSuiAddress2(ref.recipient) === normalizeSuiAddress2(recipient));
1828
- const groupedRefs = groupAndSortRefs(filtered);
1829
- return new _StreamListRequester(input.globals, recipient, groupedRefs, input.query);
1830
- }
1831
- static async newOutgoingQuery(input) {
1832
- const backendQuery = convertToOutgoingBackendQuery(input.query);
1833
- const sender = await input.globals.walletAddress();
1834
- const refs = await input.globals.backend.getOutgoingStreams(sender, backendQuery);
1835
- const groupedRefs = groupAndSortRefs(refs);
1836
- return new _StreamListRequester(input.globals, sender, groupedRefs, input.query);
1837
- }
1838
- async doNextRequest() {
1839
- if (this.current >= this.groupRefs.length) {
1840
- return null;
1841
- }
1842
- const stRefs = this.groupRefs[this.current];
1843
- if (stRefs.length === 1) {
1844
- const stream = await getStreamFromIterator(this.globals, stRefs[0].streamId, this.objectIter);
1845
- this.current++;
1846
- return isStreamOfQuery(stream, this.query) ? stream : this.doNextRequest();
1847
- }
1848
- if (stRefs.length > 1) {
1849
- const sg = await getStreamGroupFromIterator(
1850
- this.globals,
1851
- stRefs.map((ref) => ref.streamId),
1852
- this.objectIter
1853
- );
1854
- this.current++;
1855
- return isStreamGroupOfQuery(sg, this.query) ? sg : this.doNextRequest();
1856
- }
1857
- throw new SanityError("Stream group with no stream");
1858
- }
1859
- };
1860
- function groupAndSortRefs(refs) {
1861
- const m = /* @__PURE__ */ new Map();
1862
- refs.forEach((ref) => {
1863
- const groupList = m.get(ref.groupId);
1864
- if (groupList) {
1865
- groupList.push(ref);
1866
- m.set(ref.groupId, groupList);
1867
- } else {
1868
- m.set(ref.groupId, [ref]);
1869
- }
1870
- });
1871
- return Array.from(m.values()).sort(
1872
- (gl1, gl2) => DateTime4.fromISO(gl2[0].createDate).toMillis() - DateTime4.fromISO(gl1[0].createDate).toMillis()
1873
- );
1874
- }
1875
- function isStreamOfQuery(stream, query) {
1876
- if (query === void 0) {
1877
- return true;
1878
- }
1879
- const isStatus = isStreamOfStatus(stream, query.status);
1880
- if (query && "claimable" in query && query.claimable !== void 0) {
1881
- const isClaimable = query.claimable ? stream.progress.claimable !== 0n : stream.progress.claimable === 0n;
1882
- return isStatus && isClaimable;
1883
- }
1884
- return isStatus;
1885
- }
1886
- function isStreamOfStatus(stream, filter) {
1887
- if (filter === void 0) {
1888
- return true;
1889
- }
1890
- if (!Array.isArray(filter)) {
1891
- return stream.progress.status === filter;
1892
- }
1893
- return filter.includes(stream.progress.status);
1894
- }
1895
- function isStreamGroupOfQuery(sg, query) {
1896
- if (!query) {
1897
- return true;
1898
- }
1899
- let isStatus = false;
1900
- sg.streams.forEach((stream) => {
1901
- if (isStreamOfQuery(stream, query)) {
1902
- isStatus = true;
1903
- }
1904
- });
1905
- return isStatus;
1906
- }
1907
- async function getStreamFromIterator(globals, streamId, it) {
1908
- const data = await getStreamObjectResponseFromIter(it, streamId);
1909
- return Stream.fromObjectData(globals, streamId, data);
1910
- }
1911
- async function getStreamGroupFromIterator(globals, streamIds, it) {
1912
- const objResponses = [];
1913
- while (objResponses.length < streamIds.length) {
1914
- const data = await getStreamObjectResponseFromIter(it, streamIds[objResponses.length]);
1915
- objResponses.push(data);
1916
- }
1917
- return StreamGroup.newFromObjectResponse(globals, streamIds, objResponses);
1918
- }
1919
- async function getStreamObjectResponseFromIter(it, streamId) {
1920
- if (!await it.hasNext()) {
1921
- throw new SanityError("object iterator has been consumed");
1922
- }
1923
- const data = await it.next();
1924
- if (!data || data.error || data.data === void 0 || data.data === null) {
1925
- throw new SanityError(`object iterator undefined response`, {
1926
- cause: data?.error
1927
- });
1928
- }
1929
- if (data?.data?.objectId !== streamId) {
1930
- throw new SanityError("stream id not aligned");
1931
- }
1932
- return data;
1933
- }
1934
- function convertToIncomingBackendQuery(query) {
1935
- return {
1936
- status: convertStreamStatus(query?.status),
1937
- coinType: normalizeCoinTypeFilter(query?.coinType),
1938
- sender: normalizeAddressFilter(query?.sender)
1939
- };
1940
- }
1941
- function convertToOutgoingBackendQuery(query) {
1942
- return {
1943
- status: convertStreamStatus(query?.status),
1944
- coinType: normalizeCoinTypeFilter(query?.coinType),
1945
- recipient: normalizeAddressFilter(query?.recipient)
1946
- };
1947
- }
1948
- function convertStreamStatus(status3) {
1949
- if (status3 === void 0 || status3.length === 0) {
1950
- return "all";
1951
- }
1952
- if (!Array.isArray(status3)) {
1953
- return convertStreamStatusSingle(status3);
1954
- }
1955
- return status3.reduce((res, st) => {
1956
- const sts = convertStreamStatus(st);
1957
- if (!res) {
1958
- return sts;
1959
- }
1960
- if (res === sts) {
1961
- return sts;
1962
- }
1963
- return "all";
1964
- }, void 0);
1965
- }
1966
- function convertStreamStatusSingle(status3) {
1967
- switch (status3) {
1968
- case "STREAMING":
1969
- case "STREAMED":
1970
- case "CANCELED":
1971
- return "active";
1972
- case "COMPLETED":
1973
- case "SETTLED":
1974
- return "inactive";
1975
- default:
1976
- throw new InvalidInputError("Unknown stream filtered status");
1977
- }
1978
- }
1979
- function normalizeCoinTypeFilter(coinType) {
1980
- if (!coinType) {
1981
- return void 0;
1982
- }
1983
- if (!Array.isArray(coinType)) {
1984
- return normalizeStructTag5(coinType);
1985
- }
1986
- return coinType.length !== 0 ? coinType.map((ct) => normalizeStructTag5(ct)) : void 0;
1987
- }
1988
- function normalizeAddressFilter(address) {
1989
- if (!address) {
1990
- return void 0;
1991
- }
1992
- if (!Array.isArray(address)) {
1993
- return normalizeSuiAddress2(address);
1994
- }
1995
- return address.length !== 0 ? address.map((addr) => normalizeSuiAddress2(addr)) : void 0;
1996
- }
1997
-
1998
- // src/apps/mpay/error/NotEnoughBalanceError.ts
1999
- var NotEnoughBalanceError = class extends MPayError {
2000
- constructor(coinType, requestAmount, gotAmount) {
2001
- super(4 /* NotEnoughBalance */, `Not enough balance: ${coinType}`, {
2002
- context: {
2003
- coinType,
2004
- requestAmount,
2005
- gotAmount
2006
- }
2007
- });
2008
- this.coinType = coinType;
2009
- this.requestAmount = requestAmount;
2010
- this.gotAmount = gotAmount;
2011
- }
2012
- };
2013
-
2014
- // src/apps/mpay/sui/iterator/coin.ts
2015
- var DEF_REQ_PAGE_SIZE = 25;
2016
- async function getCoinsWithAmount(suiClient, owner, requestAmount, coinType = "0x2::sui::SUI", pageSize = DEF_REQ_PAGE_SIZE) {
2017
- const it = new OwnedCoinIterator(suiClient, owner, coinType, pageSize);
2018
- let totalAmount = BigInt(0);
2019
- const res = [];
2020
- while (await it.hasNext() && totalAmount < requestAmount) {
2021
- const val = await it.next();
2022
- if (!val) {
2023
- continue;
2024
- }
2025
- res.push(val);
2026
- totalAmount += BigInt(val.balance);
2027
- }
2028
- if (totalAmount < requestAmount) {
2029
- throw new NotEnoughBalanceError(coinType, requestAmount, totalAmount);
2030
- }
2031
- return res;
2032
- }
2033
- var OwnedCoinIterator = class extends EntryIterator {
2034
- constructor(suiClient, owner, coinType, reqPageSize) {
2035
- super(new OwnedCoinRequester(suiClient, owner, coinType, reqPageSize));
2036
- this.suiClient = suiClient;
2037
- this.owner = owner;
2038
- this.coinType = coinType;
2039
- this.reqPageSize = reqPageSize;
2040
- }
2041
- };
2042
- var OwnedCoinRequester = class {
2043
- constructor(suiClient, owner, coinType, reqPageSize) {
2044
- this.suiClient = suiClient;
2045
- this.owner = owner;
2046
- this.coinType = coinType;
2047
- this.reqPageSize = reqPageSize;
2048
- if (reqPageSize <= 0) {
2049
- throw new SanityError("Invalid reqPageSize");
2050
- }
2051
- }
2052
- nextCursor;
2053
- async doNextRequest() {
2054
- const res = await this.suiClient.getCoins({
2055
- owner: this.owner,
2056
- coinType: this.coinType,
2057
- cursor: this.nextCursor,
2058
- limit: this.reqPageSize
2059
- });
2060
- this.nextCursor = res.nextCursor;
2061
- return {
2062
- data: res.data,
2063
- hasNext: res.hasNextPage
2064
- };
2065
- }
2066
- };
2067
-
2068
- // src/apps/mpay/stream/client.ts
2069
- var MSafeAccountAdapter = class {
2070
- constructor(msafe) {
2071
- this.msafe = msafe;
2072
- }
2073
- get type() {
2074
- return "msafe" /* msafe */;
2075
- }
2076
- async address() {
2077
- return this.msafe.address();
2078
- }
2079
- async requestCoins(reqs) {
2080
- return this.msafe.requestCoins(reqs);
2081
- }
2082
- };
2083
- var MSafeSingleWallet = class {
2084
- constructor(account) {
2085
- this.account = account;
2086
- }
2087
- async address() {
2088
- return this.account.address;
2089
- }
2090
- };
2091
- var SingleWalletAdapter = class {
2092
- constructor(singleWallet, suiClient) {
2093
- this.singleWallet = singleWallet;
2094
- this.suiClient = suiClient;
2095
- }
2096
- get type() {
2097
- return "single" /* single */;
2098
- }
2099
- async address() {
2100
- return this.singleWallet.address();
2101
- }
2102
- async requestCoins(reqs) {
2103
- return Promise.all(reqs.map((req) => this.requestCoin(req)));
2104
- }
2105
- async requestCoin(req) {
2106
- if (isSameCoinType(req.coinType, SUI_TYPE_ARG3)) {
2107
- return {
2108
- primaryCoin: GAS_OBJECT_SPEC
2109
- };
2110
- }
2111
- if (req.amount <= 0) {
2112
- throw new InvalidInputError("Invalid coin request", "coinAmount", req.amount);
2113
- }
2114
- const coins = await getCoinsWithAmount(this.suiClient, await this.address(), req.amount, req.coinType);
2115
- if (coins.length === 0) {
2116
- throw new SanityError("no coins available");
2117
- }
2118
- return {
2119
- primaryCoin: coins[0].coinObjectId,
2120
- mergedCoins: coins.slice(1).map((coin) => coin.coinObjectId)
2121
- };
2122
- }
2123
- };
2124
- var MPayClient = class {
2125
- globals;
2126
- helper;
2127
- constructor(env, options) {
2128
- this.globals = Globals.new(env, options);
2129
- this.helper = new MPayHelper(this.globals);
2130
- }
2131
- connectSingleWallet(wallet) {
2132
- const adapter = new SingleWalletAdapter(wallet, this.globals.suiClient);
2133
- this.globals.connectWallet(adapter);
2134
- }
2135
- connectMSafeAccount(msafe) {
2136
- const adapter = new MSafeAccountAdapter(msafe);
2137
- this.globals.connectWallet(adapter);
2138
- }
2139
- async createStream(info) {
2140
- return this.builder().createStreams(info);
2141
- }
2142
- async getStream(streamId) {
2143
- return Stream.new(this.globals, streamId);
2144
- }
2145
- async getIncomingStreams(query, pageSize = 10) {
2146
- return PagedStreamListIterator.newIncoming({
2147
- globals: this.globals,
2148
- query,
2149
- pageSize
2150
- });
2151
- }
2152
- async getOutgoingStreams(query, pageSize = 10) {
2153
- return PagedStreamListIterator.newOutgoing({
2154
- globals: this.globals,
2155
- query,
2156
- pageSize
2157
- });
2158
- }
2159
- async getCoinTypesForStreamFilter() {
2160
- const address = await this.wallet.address();
2161
- const coinTypes = await this.globals.backend.getAllCoinTypes(address);
2162
- return coinTypes.map((coinType) => normalizeStructTag6(coinType));
2163
- }
2164
- async getRecipientsForStreamFilter(options) {
2165
- const address = await this.wallet.address();
2166
- const recipients = await this.globals.backend.getAllRecipients(address, options);
2167
- return recipients.map((recipient) => normalizeSuiAddress3(recipient));
2168
- }
2169
- async getCreatorsForStreamFilter(options) {
2170
- const address = await this.wallet.address();
2171
- const creators = await this.globals.backend.getAllSenders(address, options);
2172
- return creators.map((creator) => normalizeSuiAddress3(creator));
2173
- }
2174
- get wallet() {
2175
- return this.globals.wallet;
2176
- }
2177
- builder() {
2178
- return new MPayBuilder(this.globals);
2179
- }
2180
- };
2181
-
2182
- // src/apps/mpay/cancel-stream.ts
2183
- var CancelStreamIntention = class _CancelStreamIntention extends CoreBaseIntention {
2184
- constructor(data) {
2185
- super(data);
2186
- this.data = data;
2187
- }
2188
- txType;
2189
- txSubType;
2190
- async build(input) {
2191
- const { network, account } = input;
2192
- const mpayClient = new MPayClient(network === "sui:mainnet" ? "prod" /* prod */ : "dev" /* dev */);
2193
- mpayClient.connectSingleWallet(new MSafeSingleWallet(account));
2194
- const stream = await mpayClient.getStream(this.data.streamId);
2195
- const txb = await stream.cancel();
2196
- return txb;
2197
- }
2198
- static fromData(data) {
2199
- return new _CancelStreamIntention(data);
2200
- }
2201
- };
2202
-
2203
- // src/apps/mpay/claim-by-proxy-stream.ts
2204
- var ClaimByProxyStreamIntention = class _ClaimByProxyStreamIntention extends CoreBaseIntention {
2205
- constructor(data) {
2206
- super(data);
2207
- this.data = data;
2208
- }
2209
- txType;
2210
- txSubType;
2211
- async build(input) {
2212
- const { network, account } = input;
2213
- const mpayClient = new MPayClient(network === "sui:mainnet" ? "prod" /* prod */ : "dev" /* dev */);
2214
- mpayClient.connectSingleWallet(new MSafeSingleWallet(account));
2215
- const stream = await mpayClient.getStream(this.data.streamId);
2216
- const txb = await stream.claimByProxy();
2217
- return txb;
2218
- }
2219
- static fromData(data) {
2220
- return new _ClaimByProxyStreamIntention(data);
2221
- }
2222
- };
2223
-
2224
- // src/apps/mpay/claim-stream.ts
2225
- var ClaimStreamIntention = class _ClaimStreamIntention extends CoreBaseIntention {
2226
- constructor(data) {
2227
- super(data);
2228
- this.data = data;
2229
- }
2230
- txType;
2231
- txSubType;
2232
- async build(input) {
2233
- const { network, account } = input;
2234
- const mpayClient = new MPayClient(network === "sui:mainnet" ? "prod" /* prod */ : "dev" /* dev */);
2235
- mpayClient.connectSingleWallet(new MSafeSingleWallet(account));
2236
- const stream = await mpayClient.getStream(this.data.streamId);
2237
- const txb = await stream.claim();
2238
- return txb;
2239
- }
2240
- static fromData(data) {
2241
- return new _ClaimStreamIntention(data);
2242
- }
2243
- };
2244
-
2245
- // src/apps/mpay/create-stream.ts
2246
- var CreateStreamIntention = class _CreateStreamIntention extends CoreBaseIntention {
2247
- constructor(data) {
2248
- super(data);
2249
- this.data = data;
2250
- }
2251
- txType;
2252
- txSubType;
2253
- async build(input) {
2254
- const { network, account } = input;
2255
- const mpayClient = new MPayClient(network === "sui:mainnet" ? "prod" /* prod */ : "dev" /* dev */);
2256
- mpayClient.connectSingleWallet(new MSafeSingleWallet(account));
2257
- const txb = await mpayClient.createStream(this.data);
2258
- return txb;
2259
- }
2260
- static fromData(data) {
2261
- return new _CreateStreamIntention(data);
2262
- }
2263
- };
2264
-
2265
- // src/apps/mpay/decoder/create.ts
2266
- import { normalizeStructTag as normalizeStructTag8, SUI_TYPE_ARG as SUI_TYPE_ARG4 } from "@mysten/sui.js/utils";
2267
-
2268
- // src/apps/mpay/decoder/moveCall.ts
2269
- import { bcs as bcs2 } from "@mysten/sui.js/bcs";
2270
- import { normalizeStructTag as normalizeStructTag7, normalizeSuiAddress as normalizeSuiAddress4 } from "@mysten/sui.js/utils";
2271
- var MoveCallHelper = class _MoveCallHelper {
2272
- constructor(moveCall, txb) {
2273
- this.moveCall = moveCall;
2274
- this.txb = txb;
2275
- }
2276
- decodeSharedObjectId(argIndex) {
2277
- const input = this.getInputParam(argIndex);
2278
- return _MoveCallHelper.getSharedObjectId(input);
2279
- }
2280
- decodeOwnedObjectId(argIndex) {
2281
- const input = this.getInputParam(argIndex);
2282
- return _MoveCallHelper.getOwnedObjectId(input);
2283
- }
2284
- decodeInputU64(argIndex) {
2285
- const strVal = this.decodePureArg(argIndex, "u64");
2286
- return BigInt(strVal);
2287
- }
2288
- decodeInputAddress(argIndex) {
2289
- const input = this.decodePureArg(argIndex, "address");
2290
- return normalizeSuiAddress4(input);
2291
- }
2292
- decodeInputString(argIndex) {
2293
- return this.decodePureArg(argIndex, "string");
2294
- }
2295
- decodeInputBool(argIndex) {
2296
- return this.decodePureArg(argIndex, "bool");
2297
- }
2298
- decodePureArg(argIndex, bcsType) {
2299
- const input = this.getInputParam(argIndex);
2300
- return _MoveCallHelper.getPureInputValue(input, bcsType);
2301
- }
2302
- getInputParam(argIndex) {
2303
- const arg = this.moveCall.arguments[argIndex];
2304
- if (arg.kind !== "Input") {
2305
- throw new Error("not input type");
2306
- }
2307
- return this.txb.blockData.inputs[arg.index];
2308
- }
2309
- static getPureInputValue(input, bcsType) {
2310
- if (input.type !== "pure") {
2311
- throw new Error("not pure argument");
2312
- }
2313
- if (typeof input.value === "object" && "Pure" in input.value) {
2314
- const bcsNums = input.value.Pure;
2315
- return bcs2.de(bcsType, new Uint8Array(bcsNums));
2316
- }
2317
- return input.value;
2318
- }
2319
- static getOwnedObjectId(input) {
2320
- if (input.type !== "object") {
2321
- throw new Error(`not object argument: ${JSON.stringify(input)}`);
2322
- }
2323
- if (typeof input.value === "object") {
2324
- if (!("Object" in input.value) || !("ImmOrOwned" in input.value.Object)) {
2325
- throw new Error("not ImmOrOwned");
2326
- }
2327
- return normalizeSuiAddress4(input.value.Object.ImmOrOwned.objectId);
2328
- }
2329
- return normalizeSuiAddress4(input.value);
2330
- }
2331
- static getSharedObjectId(input) {
2332
- if (input.type !== "object") {
2333
- throw new Error(`not object argument: ${JSON.stringify(input)}`);
2334
- }
2335
- if (typeof input.value !== "object") {
2336
- return normalizeSuiAddress4(input.value);
2337
- }
2338
- if (!("Object" in input.value) || !("Shared" in input.value.Object)) {
2339
- throw new Error("not Shared");
2340
- }
2341
- return normalizeSuiAddress4(input.value.Object.Shared.objectId);
2342
- }
2343
- static getPureInput(input, bcsType) {
2344
- if (input.type !== "pure") {
2345
- throw new Error("not pure argument");
2346
- }
2347
- if (typeof input.value !== "object") {
2348
- return input.value;
2349
- }
2350
- if (!("Pure" in input.value)) {
2351
- throw new Error("Pure not in value");
2352
- }
2353
- const bcsVal = input.value.Pure;
2354
- return bcs2.de(bcsType, new Uint8Array(bcsVal));
2355
- }
2356
- typeArg(index) {
2357
- return normalizeStructTag7(this.moveCall.typeArguments[index]);
2358
- }
2359
- txArg(index) {
2360
- return this.moveCall.arguments[index];
2361
- }
2362
- };
2363
-
2364
- // src/apps/mpay/decoder/create.ts
2365
- var CreateStreamDecodeHelper = class {
2366
- constructor(globals, txb) {
2367
- this.globals = globals;
2368
- this.txb = txb;
2369
- }
2370
- decode() {
2371
- const streamInfo = this.decodeCreateStreamInfo();
2372
- const fees = this.createStreamHelper().calculateCreateStreamFees(streamInfo);
2373
- const coinMerges = this.getCoinMerges();
2374
- return {
2375
- type: "CreateStream" /* CREATE_STREAM */,
2376
- info: streamInfo,
2377
- fees,
2378
- coinMerges
2379
- };
2380
- }
2381
- decodeCreateStreamInfo() {
2382
- const moveCalls = this.createStreamTransactions();
2383
- const infos = moveCalls.map((moveCall) => this.getCreationInfoFromMoveCall(moveCall));
2384
- return this.aggregateGroupStreamInfo(infos);
2385
- }
2386
- createStreamTransactions() {
2387
- const txs = this.transactions.filter(
2388
- (tx) => tx.kind === "MoveCall" && isSameTarget(tx.target, this.contract.createStreamTarget)
2389
- );
2390
- if (txs.length === 0) {
2391
- throw new SanityError("No create stream transactions");
2392
- }
2393
- return txs.map((tx) => new MoveCallHelper(tx, this.txb));
2394
- }
2395
- getCreationInfoFromMoveCall(moveCall) {
2396
- const metadata = moveCall.decodeInputString(4);
2397
- const { name, groupId } = decodeMetadata(metadata);
2398
- const recipient = moveCall.decodeInputAddress(5);
2399
- const timeStart = moveCall.decodeInputU64(6);
2400
- const cliff = moveCall.decodeInputU64(7);
2401
- const epochInterval = moveCall.decodeInputU64(8);
2402
- const totalEpoch = moveCall.decodeInputU64(9);
2403
- const amountPerEpoch = moveCall.decodeInputU64(10);
2404
- const cancelable = moveCall.decodeInputBool(11);
2405
- const coinType = moveCall.typeArg(0);
2406
- return {
2407
- name,
2408
- groupId,
2409
- recipient,
2410
- timeStart,
2411
- cliff,
2412
- epochInterval,
2413
- totalEpoch,
2414
- amountPerEpoch,
2415
- cancelable,
2416
- coinType
2417
- };
2418
- }
2419
- aggregateGroupStreamInfo(infos) {
2420
- const commonInfoSet = new Set(
2421
- infos.map(
2422
- (info) => JSON.stringify({
2423
- name: info.name,
2424
- groupId: info.groupId,
2425
- timeStart: String(info.timeStart),
2426
- epochInterval: String(info.epochInterval),
2427
- totalEpoch: String(info.totalEpoch),
2428
- cancelable: info.cancelable,
2429
- coinType: info.coinType
2430
- })
2431
- )
2432
- );
2433
- if (commonInfoSet.size !== 1) {
2434
- throw new InvalidInputError("Stream group not have common info");
2435
- }
2436
- const recipients = infos.map((info) => ({
2437
- address: info.recipient,
2438
- amountPerStep: info.amountPerEpoch,
2439
- cliffAmount: info.cliff
2440
- }));
2441
- return {
2442
- name: infos[0].name,
2443
- coinType: infos[0].coinType,
2444
- recipients,
2445
- interval: infos[0].epochInterval,
2446
- steps: infos[0].totalEpoch,
2447
- startTimeMs: infos[0].timeStart,
2448
- cancelable: infos[0].cancelable
2449
- };
2450
- }
2451
- getCoinMerges() {
2452
- const createStreamTx = this.createStreamTransactions()[0];
2453
- return this.getCoinMergeForCreateStream(createStreamTx);
2454
- }
2455
- getCoinMergeForCreateStream(moveCall) {
2456
- const coinType = moveCall.typeArg(0);
2457
- const paymentCoin = moveCall.txArg(2);
2458
- const paymentCoinMerge = this.getCoinMergeFromNestedResult(paymentCoin, coinType, moveCall);
2459
- if (coinType === normalizeStructTag8(SUI_TYPE_ARG4)) {
2460
- return [paymentCoinMerge];
2461
- }
2462
- const flatFeeCoin = moveCall.txArg(3);
2463
- const flatCoinMerge = this.getCoinMergeFromNestedResult(flatFeeCoin, normalizeStructTag8(SUI_TYPE_ARG4), moveCall);
2464
- return [paymentCoinMerge, flatCoinMerge];
2465
- }
2466
- getCoinMergeFromNestedResult(coinArg, coinType, moveCall) {
2467
- if (coinArg.kind === "GasCoin") {
2468
- return {
2469
- primary: "GAS",
2470
- coinType
2471
- };
2472
- }
2473
- if (coinArg.kind === "Input") {
2474
- const arg = this.getInputArg(coinArg);
2475
- const objectId = MoveCallHelper.getOwnedObjectId(arg);
2476
- const mergeTx = this.transactions.find((tx) => {
2477
- if (tx.kind !== "MergeCoins") {
2478
- return false;
2479
- }
2480
- if (tx.destination.kind !== "Input") {
2481
- throw new Error("merge coin destination not Input type");
2482
- }
2483
- const primaryCoinInput = this.getInputArg(tx.destination);
2484
- return MoveCallHelper.getOwnedObjectId(primaryCoinInput) === objectId;
2485
- });
2486
- if (!mergeTx) {
2487
- return {
2488
- primary: objectId,
2489
- coinType
2490
- };
2491
- }
2492
- return {
2493
- primary: objectId,
2494
- merged: mergeTx.sources.map((sourceArg) => {
2495
- const sourceInputArg = this.getInputArg(sourceArg);
2496
- return MoveCallHelper.getOwnedObjectId(sourceInputArg);
2497
- }),
2498
- coinType
2499
- };
2500
- }
2501
- if (coinArg.kind === "NestedResult") {
2502
- const parentTx = this.transactions[coinArg.index];
2503
- if (parentTx.kind !== "SplitCoins") {
2504
- throw new InvalidInputError(`Transaction type not expected. Expect SplitCoins, got ${parentTx.kind}`);
2505
- }
2506
- return this.getCoinMergeFromNestedResult(parentTx.coin, coinType, moveCall);
2507
- }
2508
- if (coinArg.kind === "Result") {
2509
- throw new Error("Result type not expected for coin inputs");
2510
- }
2511
- throw new Error(`Unknown argument kind`);
2512
- }
2513
- mergeCoinTransactions() {
2514
- return this.transactions.filter((tx) => tx.kind === "MergeCoins");
2515
- }
2516
- get transactions() {
2517
- return this.txb.blockData.transactions;
2518
- }
2519
- get contract() {
2520
- return new StreamContract(this.globals.envConfig.contract, this.globals);
2521
- }
2522
- get feeContract() {
2523
- return new FeeContract(this.globals.envConfig.contract, this.globals);
2524
- }
2525
- createStreamHelper() {
2526
- return new CreateStreamHelper(this.globals, this.feeContract, this.contract);
2527
- }
2528
- getInputArg(arg) {
2529
- if (arg.kind !== "Input") {
2530
- throw new Error("not input type");
2531
- }
2532
- return "value" in arg ? arg : this.txb.blockData.inputs[arg.index];
2533
- }
2534
- };
2535
-
2536
- // src/apps/mpay/decoder/decoder.ts
2537
- var DecodeHelper = class {
2538
- constructor(globals, txb) {
2539
- this.globals = globals;
2540
- this.txb = txb;
2541
- this.contract = new StreamContract(globals.envConfig.contract, globals);
2542
- }
2543
- contract;
2544
- decode() {
2545
- if (this.isCreateStreamTransaction()) {
2546
- return this.decodeCreateStreamTransaction();
2547
- }
2548
- if (this.isClaimByProxyTransaction()) {
2549
- return this.decodeClaimByProxyTransaction();
2550
- }
2551
- if (this.isSetAutoClaimTransaction()) {
2552
- return this.decodeSetAutoClaimTransaction();
2553
- }
2554
- if (this.isCancelStreamTransaction()) {
2555
- return this.decodeCancelStreamTransaction();
2556
- }
2557
- if (this.isClaimStreamTransaction()) {
2558
- return this.decodeClaimTransaction();
2559
- }
2560
- return void 0;
2561
- }
2562
- get transactions() {
2563
- return this.txb.blockData.transactions;
2564
- }
2565
- isCreateStreamTransaction() {
2566
- const createStreamIndex = this.transactions.findIndex(
2567
- (tx) => tx.kind === "MoveCall" && isSameTarget(tx.target, this.contract.createStreamTarget)
2568
- );
2569
- return createStreamIndex !== -1;
2570
- }
2571
- isSetAutoClaimTransaction() {
2572
- return this.transactions.length === 1 && this.transactions[0].kind === "MoveCall" && isSameTarget(this.transactions[0].target, this.contract.setAutoClaimTarget);
2573
- }
2574
- isCancelStreamTransaction() {
2575
- return this.transactions.length === 1 && this.transactions[0].kind === "MoveCall" && isSameTarget(this.transactions[0].target, this.contract.cancelStreamTarget);
2576
- }
2577
- isClaimStreamTransaction() {
2578
- return this.transactions.length === 1 && this.transactions[0].kind === "MoveCall" && isSameTarget(this.transactions[0].target, this.contract.claimStreamTarget);
2579
- }
2580
- isClaimByProxyTransaction() {
2581
- return this.transactions.length === 1 && this.transactions[0].kind === "MoveCall" && isSameTarget(this.transactions[0].target, this.contract.claimStreamByProxyTarget);
2582
- }
2583
- decodeCreateStreamTransaction() {
2584
- const helper = new CreateStreamDecodeHelper(this.globals, this.txb);
2585
- return helper.decode();
2586
- }
2587
- decodeSetAutoClaimTransaction() {
2588
- const streamId = this.helper.decodeSharedObjectId(0);
2589
- const enabled = this.helper.decodeInputBool(1);
2590
- return {
2591
- type: "SetAutoClaim" /* SET_AUTO_CLAIM */,
2592
- streamId,
2593
- enabled
2594
- };
2595
- }
2596
- decodeClaimTransaction() {
2597
- const streamId = this.helper.decodeSharedObjectId(0);
2598
- return {
2599
- type: "Claim" /* CLAIM */,
2600
- streamId
2601
- };
2602
- }
2603
- decodeClaimByProxyTransaction() {
2604
- const streamId = this.helper.decodeSharedObjectId(0);
2605
- return {
2606
- type: "ClaimByProxy" /* CLAIM_BY_PROXY */,
2607
- streamId
2608
- };
2609
- }
2610
- decodeCancelStreamTransaction() {
2611
- const streamId = this.helper.decodeSharedObjectId(0);
2612
- return {
2613
- type: "Cancel" /* CANCEL */,
2614
- streamId
2615
- };
2616
- }
2617
- get helper() {
2618
- const moveCall = this.transactions[0];
2619
- return new MoveCallHelper(moveCall, this.txb);
2620
- }
2621
- };
2622
-
2623
- // src/apps/mpay/set-auto-claim-stream.ts
2624
- var SetAutoClaimStreamIntention = class _SetAutoClaimStreamIntention extends CoreBaseIntention {
2625
- constructor(data) {
2626
- super(data);
2627
- this.data = data;
2628
- }
2629
- txType;
2630
- txSubType;
2631
- async build(input) {
2632
- const { network, account } = input;
2633
- const mpayClient = new MPayClient(network === "sui:mainnet" ? "prod" /* prod */ : "dev" /* dev */);
2634
- mpayClient.connectSingleWallet(new MSafeSingleWallet(account));
2635
- const stream = await mpayClient.getStream(this.data.streamId);
2636
- const txb = await stream.setAutoClaim(true);
2637
- return txb;
2638
- }
2639
- static fromData(data) {
2640
- return new _SetAutoClaimStreamIntention(data);
2641
- }
2642
- };
2643
-
2644
- // src/apps/mpay/helper.ts
2645
- var MPayAppHelper = class {
2646
- application = "mpay";
2647
- async deserialize(input) {
2648
- const { chain, transactionBlock } = input;
2649
- const globals = Globals.new(chain === "sui:mainnet" ? "prod" /* prod */ : "dev" /* dev */);
2650
- const decoder = new DecodeHelper(globals, transactionBlock);
2651
- const result = decoder.decode();
2652
- if (result.type === "CreateStream" /* CREATE_STREAM */) {
2653
- return {
2654
- txType: TransactionType.Stream,
2655
- txSubType: result.type,
2656
- intentionData: result.info
2657
- };
2658
- }
2659
- if (result.type === "Claim" /* CLAIM */) {
2660
- return {
2661
- txType: TransactionType.Stream,
2662
- txSubType: result.type,
2663
- intentionData: {
2664
- streamId: result.streamId
2665
- }
2666
- };
2667
- }
2668
- if (result.type === "ClaimByProxy" /* CLAIM_BY_PROXY */) {
2669
- return {
2670
- txType: TransactionType.Stream,
2671
- txSubType: result.type,
2672
- intentionData: {
2673
- streamId: result.streamId
2674
- }
2675
- };
2676
- }
2677
- if (result.type === "SetAutoClaim" /* SET_AUTO_CLAIM */) {
2678
- return {
2679
- txType: TransactionType.Stream,
2680
- txSubType: result.type,
2681
- intentionData: {
2682
- streamId: result.streamId,
2683
- enabled: result.enabled
2684
- }
2685
- };
2686
- }
2687
- if (result.type === "Cancel" /* CANCEL */) {
2688
- return {
2689
- txType: TransactionType.Stream,
2690
- txSubType: result.type,
2691
- intentionData: {
2692
- streamId: result.streamId
2693
- }
2694
- };
2695
- }
2696
- throw new Error(`Unknown transaction type: ${result}`);
2697
- }
2698
- async build(input) {
2699
- const { network, intentionData, suiClient, account } = input;
2700
- let intention;
2701
- switch (input.txSubType) {
2702
- case "CreateStream" /* CREATE_STREAM */:
2703
- intention = CreateStreamIntention.fromData(intentionData);
2704
- break;
2705
- case "Claim" /* CLAIM */:
2706
- intention = ClaimStreamIntention.fromData(intentionData);
2707
- break;
2708
- case "ClaimByProxy" /* CLAIM_BY_PROXY */:
2709
- intention = ClaimByProxyStreamIntention.fromData(intentionData);
2710
- break;
2711
- case "SetAutoClaim" /* SET_AUTO_CLAIM */:
2712
- intention = SetAutoClaimStreamIntention.fromData(intentionData);
2713
- break;
2714
- case "Cancel" /* CANCEL */:
2715
- intention = CancelStreamIntention.fromData(intentionData);
2716
- break;
2717
- default:
2718
- throw new Error("not implemented");
2719
- }
2720
- return intention.build({ network, suiClient, account });
2721
- }
2722
- };
2723
-
2724
- // src/apps/msafe-core/helper.ts
2725
- import { TransactionDefaultApplication, TransactionSubTypes } from "@msafe/sui3-utils";
2726
-
2727
- // src/apps/msafe-core/coin-transfer.ts
2728
- import { buildCoinTransferTxb } from "@msafe/sui3-utils";
2729
- var CoinTransferIntention = class _CoinTransferIntention extends CoreBaseIntention {
2730
- constructor(data) {
2731
- super(data);
2732
- this.data = data;
2733
- }
2734
- txType;
2735
- txSubType;
2736
- async build(input) {
2737
- const { suiClient, account } = input;
2738
- return buildCoinTransferTxb(suiClient, this.data, account.address);
2739
- }
2740
- static fromData(data) {
2741
- return new _CoinTransferIntention(data);
2742
- }
2743
- };
2744
-
2745
- // src/apps/msafe-core/object-transfer.ts
2746
- import { buildObjectTransferTxb } from "@msafe/sui3-utils";
2747
- var ObjectTransferIntention = class _ObjectTransferIntention extends CoreBaseIntention {
2748
- constructor(data) {
2749
- super(data);
2750
- this.data = data;
2751
- }
2752
- txType;
2753
- txSubType;
2754
- async build(input) {
2755
- const { suiClient, account } = input;
2756
- return buildObjectTransferTxb(suiClient, this.data, account.address);
2757
- }
2758
- static fromData(data) {
2759
- return new _ObjectTransferIntention(data);
2760
- }
2761
- };
2762
-
2763
- // src/apps/msafe-core/plain-payload.ts
2764
- import { isSameAddress } from "@msafe/sui3-utils";
2765
- import { TransactionBlock as TransactionBlock5 } from "@mysten/sui.js/transactions";
2766
- var PlainPayloadIntention = class _PlainPayloadIntention extends CoreBaseIntention {
2767
- constructor(data) {
2768
- super(data);
2769
- this.data = data;
2770
- }
2771
- txType;
2772
- txSubType;
2773
- async build(input) {
2774
- const { account } = input;
2775
- const tb = TransactionBlock5.from(this.data.content);
2776
- if (!isSameAddress(tb.blockData.sender, account.address)) {
2777
- throw new Error("Invalid sender address");
2778
- }
2779
- return tb;
2780
- }
2781
- static fromData(data) {
2782
- return new _PlainPayloadIntention(data);
2783
- }
2784
- };
2785
-
2786
- // src/apps/msafe-core/helper.ts
2787
- var CoreHelper = class {
2788
- application;
2789
- constructor() {
2790
- this.application = TransactionDefaultApplication;
2791
- }
2792
- deserialize() {
2793
- throw new Error("MSafe core transaction intention should be build from API");
2794
- }
2795
- async build(input) {
2796
- const { suiClient, account } = input;
2797
- let intention;
2798
- switch (input.txSubType) {
2799
- case TransactionSubTypes.assets.coin.send:
2800
- intention = CoinTransferIntention.fromData(input.intentionData);
2801
- break;
2802
- case TransactionSubTypes.assets.object.send:
2803
- intention = ObjectTransferIntention.fromData(input.intentionData);
2804
- break;
2805
- case TransactionSubTypes.others.plain:
2806
- intention = PlainPayloadIntention.fromData(input.intentionData);
2807
- break;
2808
- default:
2809
- throw new Error("not implemented");
2810
- }
2811
- return intention.build({ suiClient, account });
2812
- }
2813
- };
2814
-
2815
- // src/apps/registry.ts
2816
- var MSafeApps = class {
2817
- apps;
2818
- constructor(apps) {
2819
- this.apps = new Map(apps.map((app) => [app.application, app]));
2820
- }
2821
- getAppHelper(appName) {
2822
- const app = this.apps.get(appName);
2823
- if (!app) {
2824
- throw new Error(`${appName} not registered`);
2825
- }
2826
- return app;
2827
- }
2828
- };
2829
-
2830
- // src/apps/plain-transaction/helper.ts
2831
- import { TransactionSubTypes as TransactionSubTypes2, TransactionType as TransactionType6 } from "@msafe/sui3-utils";
2832
- import { TransactionBlock as TransactionBlock6 } from "@mysten/sui.js/transactions";
2833
- import { fromHEX, toHEX } from "@mysten/sui.js/utils";
2834
- import sortKeys2 from "sort-keys-recursive";
2835
- var PlainTransactionApplication = "msafe-plain-tx";
2836
- var PlainTransactionType = TransactionSubTypes2.others.plain;
2837
- var PlainTransactionHelper = class {
2838
- application;
2839
- constructor() {
2840
- this.application = PlainTransactionApplication;
2841
- }
2842
- async deserialize(input) {
2843
- const { transactionBlock, suiClient } = input;
2844
- const content = await transactionBlock.build({ client: suiClient });
2845
- return {
2846
- txType: TransactionType6.Other,
2847
- txSubType: PlainTransactionType,
2848
- intentionData: { content: toHEX(content) }
2849
- };
2850
- }
2851
- async build(input) {
2852
- const { suiClient, account } = input;
2853
- const txb = TransactionBlock6.from(fromHEX(input.intentionData.content));
2854
- const inspectResult = await suiClient.devInspectTransactionBlock({
2855
- transactionBlock: txb,
2856
- sender: account.address
2857
- });
2858
- const success = inspectResult.effects.status.status === "success";
2859
- if (!success) {
2860
- throw new Error(inspectResult.effects.status.error);
2861
- }
2862
- return txb;
2863
- }
2864
- };
2865
-
2866
- // src/index.ts
2867
- var appHelpers = new MSafeApps([new CoreHelper(), new MPayAppHelper(), new PlainTransactionHelper()]);
2868
- export {
2869
- appHelpers
2870
- };
1
+ var Ae=Object.defineProperty;var Ht=(n,t)=>{for(var e in t)Ae(n,e,{get:t[e],enumerable:!0})};import{TransactionType as $}from"@msafe/sui3-utils";import ve from"sort-keys-recursive";var p=class{constructor(t){this.data=t}get application(){return"msafe-core"}serialize(){return JSON.stringify(ve(this.data))}};var Dt={};Ht(Dt,{contractId:()=>Pe,default:()=>je,feeObjId:()=>ke,roleObjId:()=>Ee,status:()=>De,transaction:()=>Oe,upgradeCapObjId:()=>Re,vaultObjId:()=>Me});var Oe="DiBZq4UmVVYiRL6ZJmFKYoHcxtxqrhsCXSkFyT7wUr3j",De="success",Pe="0x81c960dc653975fbd0072deca8afb92d322898c911622898ba1b2e3ad0c4bd8d",Ee="0xc6ec0bdee0bb59a72077e9acd2f42457043cf47080b3d3fad4d39abf28bba63a",Me="0xbc4021387fbac149119fd24e92be9e58f745774292f3a2a12e2ac6daf5363e1d",ke="0x4178f63970fe2daeb256dc5730ad172e82b3e8eb45f31b33e0daae72cd35e1e1",Re="0xe1e9aa7d222d151bfe6dd83358b0d7fdcb11260f710800cfaf7ccc1b1e245115",je={transaction:Oe,status:De,contractId:Pe,roleObjId:Ee,vaultObjId:Me,feeObjId:ke,upgradeCapObjId:Re};var Pt={};Ht(Pt,{contractId:()=>Fe,default:()=>qe,feeObjId:()=>Le,roleObjId:()=>_e,status:()=>Ne,transaction:()=>Be,upgradeCapObjId:()=>We,vaultObjId:()=>Ge});var Be="855FNDV8o8Z3fWULPnQo9qdhLJpsg7wZrkCpNyfw9KfB",Ne="success",Fe="0xc357c3985e8fb875d6b37141497af660779aa1bab0ec489b2213efd74067d1fa",_e="0x5ab49bdf9fd1413e328ef242b3f8d83dde791b38a0b627bfc87fb25c010d34f1",Ge="0xb483558770d8eb26007f193b75db40f0a45f2e36863a687625885d4de6993378",Le="0x48453fc4d7cde3fe35aad89e5dfb496608a6a55ea529a1c0274681a808627f94",We="0x34279779a0d0d36bd5044b04830d607fa1b0ecf316548c8ac3a44151e4f1a42a",qe={transaction:Be,status:Ne,contractId:Fe,roleObjId:_e,vaultObjId:Ge,feeObjId:Le,upgradeCapObjId:We};var Ue="https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD",$e="https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD",ze="https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7",He="https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7",Qe="https://bc3p6l5unl.execute-api.us-west-1.amazonaws.com/prod",Je="https://rolsbkota7.execute-api.us-west-1.amazonaws.com/prod",Ve="https://6p6mkx33ne.execute-api.us-west-1.amazonaws.com/prod",Ye="https://xrae3mrjv5.execute-api.us-west-1.amazonaws.com/prod",Qt=Dt,Jt=Pt,Xe=new Map([["dev",{env:"dev",rpc:{url:Ue},backend:{url:Qe},contract:Qt}],["stg",{env:"stg",rpc:{url:$e},backend:{url:Je},contract:Qt}],["prev",{env:"prev",rpc:{url:ze},backend:{url:Ve},contract:Jt}],["prod",{env:"prod",rpc:{url:He},backend:{url:Ye},contract:Jt}]]);function Vt(n,t){let e=Xe.get(n);if(!e)throw new Error(`Env not supported: ${n}`);return t&&t.rpc&&(e.rpc=t.rpc),t&&t.backend&&(e.backend=t.backend),t&&t.contract&&(e.contract=t.contract),e}import{SuiClient as Ze}from"@mysten/sui.js/client";var c=class extends Error{mpayErrorCode;context;constructor(t,e,r={}){let{cause:a,context:o}=r;a?super(`[MPay] ${e}: ${a}`):super(`[MPay] ${e}`),this.mpayErrorCode=t,this.context=o}};var H=class extends c{constructor(){super(11,"Backend is not specified")}};var Q=class extends c{constructor(){super(1,"Wallet not connected")}};import O,{AxiosError as Ke}from"axios";var v=class extends c{constructor(t,e){super(10,t,{context:e})}};var J=class n{constructor(t){this.apiURL=t}static parseResponseData(t){if(t instanceof Ke)throw new v(t.response?.statusText);if(t.status===200){if(t.data.success)return t.data.data;throw new v(t.data.code)}throw new v(t.status.toString())}async getIncomingStreams(t,e){let r=await O.post(`${this.apiURL}/stream`,{recipient:t,...e});return n.parseResponseData(r)}async getOutgoingStreams(t,e){let r=await O.post(`${this.apiURL}/stream`,{sender:t,...e});return n.parseResponseData(r)}async getStreamHistory(t){let e=await O.post(`${this.apiURL}/stream-events`,t),r=n.parseResponseData(e);return r.data.forEach(a=>{let o=a;return o.data.type==="create_stream"?o.data.balance=BigInt(o.data.balance):o.data.type==="cancel_stream"?o.data.withdrawAmount=BigInt(o.data.withdrawAmount):o.data.type==="claim"||o.data.type==="auto_claim"?o.data.claimAmount=BigInt(o.data.claimAmount):o.data.type==="set_auto_claim"&&(o.data.enabled=!!o.data.enabled),o.createdAt=new Date(o.createdAt),o}),r}async getAllCoinTypes(t){let e=await O.post(`${this.apiURL}/stream-info`,{address:t});return n.parseResponseData(e)}async getAllRecipients(t,e){let r=await O.post(`${this.apiURL}/stream-info`,{sender:t,status:e});return n.parseResponseData(r)}async getAllSenders(t,e){let r=await O.post(`${this.apiURL}/stream-info`,{recipient:t,status:e});return n.parseResponseData(r)}};var D=class n{signer;suiClient;envConfig;_backend;constructor(t){this.envConfig=t,this.suiClient=new Ze({url:t.rpc.url}),t.backend&&(this._backend=new J(t.backend.url))}static new(t,e){let r=Vt(t,e);return new n(r)}get walletType(){return this.wallet?this.wallet.type:"disconnected"}get backend(){if(!this._backend)throw new H;return this._backend}set backend(t){this._backend=t}connectWallet(t){this.signer=t}disconnect(){this.signer=void 0}get wallet(){if(!this.signer)throw new Q;return this.signer}async walletAddress(){return this.wallet.address()}};import{SUI_TYPE_ARG as Cr,normalizeStructTag as Ir,normalizeSuiAddress as ye}from"@mysten/sui.js/utils";import{normalizeStructTag as kt,SUI_TYPE_ARG as ar}from"@mysten/sui.js/utils";import{Duration as ce}from"luxon";import{TransactionBlock as tt}from"@mysten/sui.js/transactions";import{TransactionBlock as ae}from"@mysten/sui.js/transactions";import{SUI_TYPE_ARG as oe,normalizeStructTag as nr}from"@mysten/sui.js/utils";var Et=50n,V=10000n,Yt=25n,Mt=100000000n;var h=class{constructor(t){this.object=t}moveArg(t){return t.object(this.object)}},j=class{constructor(t){this.objects=t}moveArgs(t){return t.makeMoveVec({objects:this.objects.map(e=>t.object(e))})}},I=class n{constructor(t){this.result=t;return new Proxy(this,{set(){throw new Error("The transaction result is a proxy, and does not support setting properties directly")},get(e,r){if(r in e)return Reflect.get(e,r);let a=i=>new n(e.result[i]);if(r===Symbol.iterator)return function*(){let i=0;for(;;)yield a(i),i++};if(typeof r=="symbol")return;let o=parseInt(r,10);if(!(Number.isNaN(o)||o<0))return a(o)}})}moveArg(){return this.result}};import{Buffer as Xt}from"buffer";import{normalizeSuiAddress as tr}from"@mysten/sui.js/utils";var B=class extends c{constructor(t,e){super(3,t,{context:e})}};var Y=class{constructor(t){this.results=t}callResult(t){return this.results.results[t]}returnValue(t,e){return t.returnValues[e]}getValue(t=0,e=0){let r=this.callResult(t);return this.returnValue(r,e)}getAddress(t=0,e=0){let[r,a]=this.getValue(t,e);if(a!=="address")throw new B("Invalid contract return type.",{ctx:{expectType:"address",gotType:a}});return tr(Xt.from(r).toString("hex"))}getU64(t=0,e=0){let[r,a]=this.getValue(t,e);if(a!=="u64")throw new B("Invalid contract return type.",{ctx:{expectType:"u64",gotType:a}});return Xt.from(r).readBigInt64LE()}};import{bcs as Zt}from"@mysten/sui.js/bcs";var m=class extends c{constructor(t,e,r){super(2,`Invalid input: ${t}`,{context:{fieldKey:e,fieldValue:r}})}};var te={groupId:"string",name:"string"},er=64;function ee(n){return re(n),Zt.ser(te,n).toString("base64")}function N(n){let t=Zt.de(te,n,"base64");return re(t),t}function re(n){if(!Kt(n.name))throw new m("Invalid metadata: Name contains unknown character");if(!Kt(n.groupId))throw new m("Invalid metadata: Group ID contains unknown character");if(n.name.length>er)throw new m("Invalid metadata: Name exceed max length 64")}function Kt(n){return/^[\x00-\x7F]+$/.test(n)}import{normalizeStructTag as X}from"@mysten/sui.js/utils";function K(n,t){return X(n)===X(t)}function T(n,t){return X(n)===X(t)}var Z="txn.gas";import{nanoid as rr}from"nanoid";function ne(){return rr()}var x=class n{constructor(t,e,r){this.globals=t;this.feeContract=e;this.streamContract=r}static convertCreateStreamInfoToInternal(t){return{metadata:ee({name:t.name,groupId:ne()}),coinType:nr(t.coinType),recipients:t.recipients.map(e=>({address:e.address,cliffAmount:e.cliffAmount,amountPerEpoch:e.amountPerStep})),epochInterval:t.interval,numberEpoch:t.steps,startTime:t.startTimeMs,cancelable:t.cancelable}}async buildCreateStreamTransactionBlock(t){let e=new ae,r=this.calculateFeesInternal(t),a=this.getCreateStreamCoinRequests(t,r),o=await this.wallet.requestCoins(a),i=await this.addMergeCoins(e,o[0]),s;a.length>1?s=await this.addMergeCoins(e,o[1]):s=i;for(let l=0;l<t.recipients.length;l++){let A=t.recipients[l],z=this.amountForRecipient(A,t.numberEpoch),vt=this.getStreamFeeLocal(z),[Ot]=e.splitCoins(i,[e.pure(z+vt,"u64")]),[xe]=e.splitCoins(s,[e.pure(this.flatSuiFee,"u64")]);this.streamContract.createStream(e,{paymentCoin:new I(Ot),flatFeeCoin:new I(xe),metadata:t.metadata,recipient:A.address,timeStart:t.startTime,cliff:A.cliffAmount,epochInterval:t.epochInterval,numEpoch:t.numberEpoch,amountPerEpoch:A.amountPerEpoch,cancelable:t.cancelable,coinType:t.coinType})}return e}calculateCreateStreamFees(t){let e=n.convertCreateStreamInfoToInternal(t);return this.calculateFeesInternal(e)}feeParams(){return{createFeePercent:{numerator:Et,denominator:V},claimFeePercent:{numerator:Yt,denominator:V},flatFeePerStream:Mt}}async addMergeCoins(t,e){let r;return e.mergedCoins&&e.mergedCoins.length?(t.mergeCoins(t.object(e.primaryCoin),e.mergedCoins.map(a=>t.object(a))),r=t.object(e.primaryCoin)):e.primaryCoin===Z?r=t.gas:r=t.object(e.primaryCoin),r}getCreateStreamCoinRequests(t,e){let r=t.coinType;return K(r,oe)?[{coinType:r,amount:e.totalAmount+e.streamFeeAmount+e.flatFeeAmount}]:[{coinType:r,amount:e.totalAmount+e.streamFeeAmount},{coinType:oe,amount:e.flatFeeAmount}]}calculateFeesInternal(t){let e=t.recipients.reduce((a,o)=>{let i=this.amountForRecipient(o,t.numberEpoch),s=this.getStreamFeeLocal(i);return{totalAmount:a.totalAmount+i,streamFeeAmount:a.streamFeeAmount+s}},{totalAmount:0n,streamFeeAmount:0n});return{flatFeeAmount:BigInt(t.recipients.length)*this.flatSuiFee,...e}}amountForRecipient(t,e){return BigInt(t.amountPerEpoch)*BigInt(e)+BigInt(t.cliffAmount)}get flatSuiFee(){return Mt}getStreamFeeLocal(t){return t*Et/V}async getStreamFeeRemote(t){let e=this.feeContract.streamingFee(new ae,t),r=await this.globals.suiClient.devInspectTransactionBlock({sender:await this.globals.walletAddress(),transactionBlock:e});return new Y(r).getU64()}get wallet(){return this.globals.wallet}};import{Transactions as se}from"@mysten/sui.js/transactions";var ie="0x0000000000000000000000000000000000000000000000000000000000000006";var P=class{constructor(t,e,r){this.moduleName=t;this.config=e;this.globals=r}addContractCall(t,e){let r=`${this.config.contractId}::${this.moduleName}::${e.method}`;return t.add(se.MoveCall({target:r,arguments:e.arguments.map(a=>a instanceof j?a.moveArgs(t):a instanceof h?a.moveArg(t):a instanceof I?a.moveArg():t.pure(a)),typeArguments:e.typeArgs})),t}addTransactionBlock(t,e,r=[],a=[]){t.add(se.MoveCall({target:e,arguments:r.map(o=>o instanceof j?o.moveArgs(t):o instanceof h?o.moveArg(t):o instanceof I?o.moveArg():t.pure(o)),typeArguments:a}))}makeObject(t){return typeof t=="string"?new h(t):t}vaultObject(){return new h(this.config.vaultObjId)}roleObject(){return new h(this.config.roleObjId)}feeObject(){return new h(this.config.feeObjId)}clockObject(){return new h(ie)}};var E=class n extends P{constructor(e,r){super(n.ModuleName,e,r);this.config=e;this.globals=r}static ModuleName="fee_module";static MethodName={set_streaming_fee:"set_streaming_fee",set_claim_fee:"set_claim_fee",set_streaming_flat_fee:"set_streaming_flat_fee",streaming_flat_fee:"streaming_flat_fee",streaming_fee:"streaming_fee",claim_fee:"claim_fee",fee_denominator:"fee_denominator"};setStreamingFee(e,r){let a=this.roleObject(),o=this.feeObject();return this.addContractCall(e,{method:n.MethodName.set_streaming_fee,arguments:[a,o,r],typeArgs:[]})}setStreamingFlatFee(e,r){let a=this.roleObject(),o=this.feeObject();return this.addContractCall(e,{method:n.MethodName.set_streaming_flat_fee,arguments:[a,o,r],typeArgs:[]})}setClaimFee(e,r){let a=this.roleObject(),o=this.feeObject();return this.addContractCall(e,{method:n.MethodName.set_claim_fee,arguments:[a,o,r],typeArgs:[]})}streamingFee(e,r){let a=this.feeObject();return this.addContractCall(e,{method:n.MethodName.streaming_fee,arguments:[a,r],typeArgs:[]})}claimFee(e,r){return this.addContractCall(e,{method:n.MethodName.claim_fee,arguments:[this.feeObject(),r],typeArgs:[]})}feeDenominator(e){return this.addContractCall(e,{method:n.MethodName.fee_denominator,arguments:[this.feeObject()],typeArgs:[]})}};var S=class n extends P{constructor(e,r){super(n.ModuleName,e,r);this.config=e;this.globals=r}static ModuleName="stream";static MethodName={create_stream:"create_stream",set_auto_claim:"set_auto_claim",cancel_stream:"cancel_stream",claim_stream:"claim_stream",claim_stream_by_proxy:"claim_stream_by_proxy",stream_current_epoch:"stream_current_epoch",now_milli_seconds:"now_milli_seconds"};createStream(e,r){let a=this.feeObject(),o=this.vaultObject(),i=this.makeObject(r.paymentCoin),s=this.makeObject(r.flatFeeCoin),l=this.clockObject();return this.addContractCall(e,{method:n.MethodName.create_stream,arguments:[a,o,i,s,r.metadata,r.recipient,r.timeStart,r.cliff,r.epochInterval,r.numEpoch,r.amountPerEpoch,r.cancelable,l],typeArgs:[r.coinType]})}setAutoClaim(e,r){let a=this.makeObject(r.streamId);return this.addContractCall(e,{method:n.MethodName.set_auto_claim,arguments:[a,r.enabled],typeArgs:[r.coinType]})}cancelStream(e,r){let a=this.makeObject(r.streamId),o=this.clockObject();return this.addContractCall(e,{method:n.MethodName.cancel_stream,arguments:[a,o],typeArgs:[r.coinType]})}claimStream(e,r){let a=this.makeObject(r.streamId),o=this.clockObject();return this.addContractCall(e,{method:n.MethodName.claim_stream,arguments:[a,o],typeArgs:[r.coinType]})}claimStreamByProxy(e,r){let a=this.makeObject(r.streamId),o=this.vaultObject(),i=this.feeObject(),s=this.clockObject();return this.addContractCall(e,{method:n.MethodName.claim_stream_by_proxy,arguments:[a,o,i,s],typeArgs:[r.coinType]})}get createStreamTarget(){return`${this.config.contractId}::${n.ModuleName}::${n.MethodName.create_stream}`}get setAutoClaimTarget(){return`${this.config.contractId}::${n.ModuleName}::${n.MethodName.set_auto_claim}`}get cancelStreamTarget(){return`${this.config.contractId}::${n.ModuleName}::${n.MethodName.cancel_stream}`}get claimStreamTarget(){return`${this.config.contractId}::${n.ModuleName}::${n.MethodName.claim_stream}`}get claimStreamByProxyTarget(){return`${this.config.contractId}::${n.ModuleName}::${n.MethodName.claim_stream_by_proxy}`}};var M=class{constructor(t){this.globals=t;let e=t.envConfig.contract;this.feeContract=new E(e,t),this.streamContract=new S(e,t)}feeContract;streamContract;async createStreams(t){let e=x.convertCreateStreamInfoToInternal(t);return this.createStreamHelper().buildCreateStreamTransactionBlock(e)}createStreamHelper(){return new x(this.globals,this.feeContract,this.streamContract)}setAutoClaim(t,e,r){let a=new tt;return this.streamContract.setAutoClaim(a,{streamId:t,enabled:e,coinType:r})}claimStream(t,e){let r=new tt;return this.streamContract.claimStream(r,{streamId:t,coinType:e})}claimStreamByProxy(t,e){let r=new tt;return this.streamContract.claimStreamByProxy(r,{streamId:t,coinType:e})}cancelStream(t,e){let r=new tt;return this.streamContract.cancelStream(r,{streamId:t,coinType:e}),r}};var et=class extends c{constructor(t,e){super(12,`Transaction failed: ${e}`,{context:{status:t,msg:e}})}};var or=1e3,rt=class{constructor(t){this.globals=t;this.coinMetaHelper=new Rt(t.suiClient),this.createStreamHelper=new M(t).createStreamHelper()}coinMetaHelper;createStreamHelper;getStreamIdsFromCreateStreamResponse(t){if(t.effects?.status.status!=="success")throw new et(t.effects?.status.status,t.effects?.status.error);return t.objectChanges.filter(e=>e.type==="created"&&e.objectType.startsWith(`${this.globals.envConfig.contract.contractId}::stream::Stream`)).map(e=>e.objectId)}calculateCreateStreamFees(t){return this.createStreamHelper.calculateCreateStreamFees(t)}feeParams(){return this.createStreamHelper.feeParams()}calculateStreamAmount(t){if(t.steps===0n)throw new m("Invalid stream steps: 0");let e=t.cliff?t.cliff:{numerator:0n,denominator:100n},r=t.totalAmount*e.numerator/e.denominator,a=(t.totalAmount-r)/t.steps,i={realTotalAmount:a*t.steps+r,cliffAmount:r,amountPerStep:a};return this.validateStreamAmount(i,t.totalAmount),i}calculateTimelineByInterval(t){if(t.steps===0n)throw new m("Invalid stream steps: 0");let e=t.timeStart.plus(t.interval.toMillis()*Number(t.steps)),r={timeStart:t.timeStart,timeEnd:e,interval:t.interval,steps:t.steps};return this.validateTimeline(r),r}calculateTimelineByTotalDuration(t){if(t.steps===0n)throw new m("Invalid stream steps: 0");let e=BigInt(t.total.toMillis())/t.steps,r=t.timeStart.plus(ce.fromMillis(Number(e*t.steps))),a={timeStart:t.timeStart,timeEnd:r,interval:ce.fromMillis(Number(e)),steps:t.steps};return this.validateTimeline(a),a}async getBalance(t,e){let r=await this.globals.suiClient.getBalance({owner:t,coinType:e}),a=await this.getCoinMeta(e);return{...r,coinType:kt(r.coinType),coinMeta:a}}async getAllBalance(t){let e=await this.globals.suiClient.getAllBalances({owner:t}),r=await Promise.all(e.map(a=>this.getCoinMeta(a.coinType)));return e.map((a,o)=>({...a,coinType:kt(a.coinType),coinMeta:r[o]}))}async getCoinMeta(t){return this.coinMetaHelper.getCoinMeta(t)}async simulateTransactionBlock(t){return this.globals.suiClient.devInspectTransactionBlock({transactionBlock:t,sender:await this.globals.wallet.address()})}validateStreamAmount(t,e){if(t.amountPerStep===0n)throw new m("Stream amount too small","totalAmount",e);if(t.cliffAmount>t.realTotalAmount)throw new m("Invalid cliff settings")}validateTimeline(t){if(t.interval.toMillis()<or)throw new m("Interval shall be at least 1 second","interval",t.interval)}},Rt=class{constructor(t){this.suiClient=t;this.coinMetaReg=new Map}coinMetaReg;async getCoinMeta(t){let e=kt(t||ar);if(this.coinMetaReg.has(e))return this.coinMetaReg.get(e);let r=await this.queryCoinMeta(e);return r&&this.coinMetaReg.set(e,r),r}async queryCoinMeta(t){return await this.suiClient.getCoinMetadata({coinType:t})||void 0}};import{normalizeStructTag as ue,normalizeSuiAddress as ct}from"@mysten/sui.js/utils";import{DateTime as pe}from"luxon";import{TransactionBlock as it}from"@mysten/sui.js/transactions";import{normalizeStructTag as le,parseStructTag as cr}from"@mysten/sui.js/utils";import{DateTime as mr}from"luxon";var nt=class extends c{constructor(){super(7,"Connected wallet is not creator")}};var F=class extends c{constructor(){super(8,"Connected wallet is not recipient")}};var _=class extends c{constructor(t,e){super(6,t,{context:e})}};var u=class extends c{constructor(t,e={}){super(0,t,e)}};var at=class extends c{constructor(t){super(5,"Stream not found",{context:{streamId:t}})}};import{DateTime as ir,Duration as sr}from"luxon";var me=(1n<<64n)-1n,ot=1e3;function jt(n){let t;typeof n=="number"?t=n:typeof n=="bigint"?t=Number(n):t=n.toMillis();let e=Math.round(t/ot);return ir.fromMillis(e*ot)}function Bt(n){let t;typeof n=="number"?t=n:typeof n=="bigint"?t=Number(n):t=n.toMillis();let e=Math.round(t/ot);return sr.fromMillis(e*ot)}var w=class n{constructor(t,e,r){this.globals=t;this.streamId=e;this.rawData=r;this.streamContract=new S(t.envConfig.contract,t)}streamContract;type="Stream";static async new(t,e){let r=await n.fetchStreamData(t,e);return new n(t,e,r)}static fromObjectData(t,e,r){let a=n.parseRawStreamData(e,r);return new n(t,e,a)}get info(){return{name:this.name,creator:this.creator,coinType:this.coinType,totalAmount:this.totalAmount,start:this.timeStart,end:this.timeEnd,cancelable:this.cancelable,cliffAmount:this.cliff,duration:this.duration,interval:this.interval,steps:this.totalSteps,nextReleaseDate:this.nextReleaseDate,nextReleaseAmount:this.nextReleaseAmount,groupId:this.groupId,streamId:this.streamId,recipient:this.recipient,progress:this.progress,autoClaim:this.autoClaim}}get groupCommonInfo(){return{name:this.name,groupId:this.groupId,creator:this.creator,start:this.timeStart,interval:this.interval,steps:this.totalSteps,cancelable:this.cancelable}}async refresh(){this.rawData=await n.fetchStreamData(this.globals,this.streamId)}refreshWithData(t){if(t.data?.objectId!==this.streamId)throw new u("Object Id does not align");this.rawData=n.parseRawStreamData(this.streamId,t)}async historyEvents(t){return this.globals.backend.getStreamHistory({streamId:this.streamId,pagination:t})}async cancel(){if(await this.globals.walletAddress()!==this.creator)throw new nt;let t=new it;return this.streamContract.cancelStream(t,{streamId:this.streamId,coinType:this.coinType}),t}async claim(){if(await this.globals.walletAddress()!==this.recipient)throw new F;let t=new it;return this.streamContract.claimStream(t,{streamId:this.streamId,coinType:this.coinType}),t}async setAutoClaim(t){if(await this.globals.walletAddress()!==this.recipient)throw new F;let e=new it;return this.streamContract.setAutoClaim(e,{streamId:this.streamId,coinType:this.coinType,enabled:t}),e}async claimByProxy(){let t=new it;return this.streamContract.claimStreamByProxy(t,{streamId:this.streamId,coinType:this.coinType}),t}get wallet(){return this.globals.wallet}get client(){return this.globals.suiClient}get coinType(){return le(this.rawData.coinType)}get progress(){return{status:this.streamStatus,total:this.totalAmount,streamed:this.streamedAmount,claimed:this.claimedAmount,claimable:this.claimable,canceled:this.canceledAmount}}get balance(){return this.rawData.balance}get autoClaim(){return this.rawData.autoClaim}get amountPerEpoch(){return this.rawData.config.amountPerEpoch}get cancelable(){return this.rawData.config.cancelable}get cliff(){return this.rawData.config.cliff}get creator(){return this.rawData.config.creator}get interval(){return Bt(this.rawData.config.epochInterval)}get groupId(){let{metadata:t}=this.rawData.config;return N(t).groupId}get name(){let{metadata:t}=this.rawData.config;return N(t).name}get recipient(){return this.rawData.config.recipient}get timeStart(){return jt(this.rawData.config.timeStart)}get duration(){let t=this.rawData.config,e=t.epochInterval*t.totalEpoch;return Bt(e)}get timeEnd(){return this.timeStart.plus(this.duration)}get totalSteps(){return this.rawData.config.totalEpoch}get claimable(){return this.streamedAmount-this.claimedAmount}get nextReleaseDate(){return this.currentEpoch===-1n?this.timeStart:this.currentEpoch>=this.totalSteps||this.isCanceled?null:jt((this.currentEpoch+1n)*this.rawData.config.epochInterval+this.rawData.config.timeStart)}get nextReleaseAmount(){return this.currentEpoch===-1n?this.cliff:this.currentEpoch>=this.totalSteps||this.isCanceled?null:this.amountPerEpoch}get streamStatus(){let t=this.rawData.status.status;return t===16?"CANCELED":t===17?"SETTLED":t===1?"COMPLETED":this.currentEpoch>=this.totalSteps?"STREAMED":"STREAMING"}get streamedAmount(){return this.currentEpoch===-1n?0n:this.isCanceled?this.rawData.status.epochCanceled*this.amountPerEpoch+this.cliff:this.currentEpoch*this.amountPerEpoch+this.cliff}get claimedAmount(){return this.rawData.status.epochClaimed===me?0n:this.rawData.status.epochClaimed*this.amountPerEpoch+this.cliff}get currentEpoch(){let t=mr.now().toMillis(),e=this.timeStart.toMillis();if(t<e)return-1n;let r=Math.floor((t-e)/Number(this.rawData.config.epochInterval));return BigInt(r)>Number(this.rawData.config.totalEpoch)?this.rawData.config.totalEpoch:BigInt(r)}get totalAmount(){let t=this.rawData.config;return t.amountPerEpoch*t.totalEpoch+t.cliff}get isCanceled(){let t=this.rawData.status.status;return t===16||t===17}get canceledAmount(){return this.isCanceled?this.totalAmount-this.streamedAmount:0n}static async fetchStreamData(t,e){let r=await t.suiClient.getObject({id:e,options:{showContent:!0,showType:!0}});return n.parseRawStreamData(e,r)}static parseRawStreamData(t,e){if(e.error)throw e.error.code==="notExists"?new at(t):new _(`get stream data: ${e.error.code}`,{streamId:t,...e.error});let r=e.data.content;if(r.dataType!=="moveObject")throw new _("Unexpected object type",{gotType:r.dataType});let{typeParams:a}=cr(r.type),o=le(a[0]),i=r.fields,s=i.config.fields,l=i.status.fields;return{coinType:o,autoClaim:i.auto_claim,balance:BigInt(i.balance.fields.balance),config:{amountPerEpoch:BigInt(s.amount_per_epoch),cancelable:s.cancelable,cliff:BigInt(s.cliff),creator:s.creator,epochInterval:BigInt(s.epoch_interval),metadata:s.metadata,recipient:s.recipient,timeStart:BigInt(s.time_start),totalEpoch:BigInt(s.total_epoch)},status:{status:l.status,epochCanceled:BigInt(l.epoch_canceled),epochClaimed:BigInt(l.epoch_claimed)}}}};var k=class extends c{constructor(t,e){super(9,`Invalid stream group: ${t}`,{context:e})}};async function Ft(n){let t=[];for(;await n.hasNext();){let e=await n.next();t.push(e)}return t&&Array.isArray(t[0])?t.flat(1):t}var Nt=class{constructor(t){this.requester=t;this.curPage=void 0,this.init=!0}curPage;init;async hasNext(){if(this.init)return this.curPage||(this.curPage=await this.requester.doNextRequest()),!!this.curPage.data?.length||this.curPage.hasNext;if(!this.curPage)throw new Error("invalid implementation of iterator");return this.curPage.hasNext}async next(){return this.init?(this.init=!1,this.curPage||(this.curPage=await this.requester.doNextRequest()),this.curPage.data):(this.curPage=await this.requester.doNextRequest(),this.curPage.data)}},R=class{constructor(t){this.requester=t;this.pager=new Nt(t),this.curData=[],this.cursor=0}cursor;pager;curData;async hasNext(){return this.cursor<this.curData.length-1?!0:this.pager.hasNext()}async next(){for(this.cursor+=1;this.cursor>=this.curData.length;)if(await this.pager.hasNext())this.curData=await this.pager.next(),this.cursor=0;else throw new Error("not more data");return this.curData[this.cursor]}};var lr=25;async function Gt(n,t,e){let r=new G(t),a=new L(n,r,e);return await Ft(a)}var G=class{constructor(t){this.ids=t;this.cursor=-1}cursor;async hasNext(){return this.cursor<this.ids.length-1}async next(){if(this.cursor+=1,this.cursor>=this.ids.length)throw new Error("invalid iterator implementation");return this.ids[this.cursor]}},L=class extends R{constructor(e,r,a){super(new _t(e,r,a));this.suiClient=e;this.idIter=r;this.options=a}},_t=class{constructor(t,e,r){this.suiClient=t;this.stringIter=e;this.options=r;this.filter=r?.filter,this.pageSize=r?.pageSize||lr,this.objectOptions=r?.objectOptions||{showType:!0,showContent:!0}}filter;pageSize;objectOptions;async doNextRequest(){let t=[];for(;t.length<this.pageSize&&await this.stringIter.hasNext();){let o=await this.stringIter.next();o&&t.push(o)}let e=await this.suiClient.multiGetObjects({ids:t,options:this.objectOptions}),r;if(this.filter){let{filter:a}=this;r=e.filter(o=>a?.(o))}else r=e;return{data:r,hasNext:await this.stringIter.hasNext()}}};var st=class n{constructor(t,e){this.globals=t;this.streams=e;if(e.length===0)throw new k("stream size 0");let r=e.map(o=>o.groupId);if(new Set(r).size!==1)throw new m("Stream does not have same group ID")}type="StreamGroup";static async new(t,e){let r=await Gt(t.suiClient,e);return r.forEach(a=>{if(!a)throw new u("stream group object data undefined")}),n.newFromObjectResponse(t,e,r)}static async newFromObjectResponse(t,e,r){let a=await n.parseGroupStreams(t,e,r);return new n(t,a)}static checkStreamGroup(t){let e=t.map(o=>o.groupCommonInfo),r=e[0],a=!0;return e.forEach(o=>{ur(r,o)||(a=!1)}),a}async refresh(){let t=await Gt(this.globals.suiClient,this.streams.map(e=>e.streamId));this.streams.forEach((e,r)=>{e.refreshWithData(t[r])})}get groupId(){return this.streams[0].groupId}get creator(){return this.streams[0].creator}get info(){return{groupId:this.groupId,streamIds:this.streams.map(t=>t.streamId),progress:this.progress,name:this.streams[0].name,creator:this.creator,coinType:this.streams[0].coinType,totalAmount:this.streams.reduce((t,e)=>t+e.totalAmount,0n),start:this.streams[0].timeStart,end:this.streams[0].timeEnd,cancelable:this.streams[0].cancelable,cliffAmount:this.streams.reduce((t,e)=>t+e.cliff,0n),duration:this.streams[0].duration,interval:this.streams[0].interval,steps:this.streams[0].totalSteps,nextReleaseAmount:this.streams.reduce((t,e)=>e.nextReleaseAmount===null?t:t+e.nextReleaseAmount,0n),nextReleaseDate:this.streams[0].nextReleaseDate}}get progress(){return{total:this.streams.reduce((t,e)=>t+e.totalAmount,0n),streamed:this.streams.reduce((t,e)=>t+e.streamedAmount,0n),claimed:this.streams.reduce((t,e)=>t+e.claimedAmount,0n),claimable:this.streams.reduce((t,e)=>t+e.claimable,0n),canceled:this.streams.reduce((t,e)=>t+e.canceledAmount,0n)}}async historyEvents(t){return this.globals.backend.getStreamHistory({groupId:this.groupId,pagination:t})}static async parseGroupStreams(t,e,r){let a=r.map((o,i)=>w.fromObjectData(t,e[i],o)).filter(o=>!!o);if(new Set(a.map(o=>o.groupId)).size!==1)throw new k("Not same group ID");if(!this.checkStreamGroup(a))throw new k("Not same stream settings");return a}};function ur(n,t){return n.name===t.name&&n.groupId===t.groupId&&n.creator===t.creator&&n.start.toMillis()===t.start.toMillis()&&n.interval.toMillis()===t.interval.toMillis()&&n.steps===t.steps&&n.cancelable===t.cancelable}var W=class n{constructor(t,e){this.it=t;this.pageSize=e}static async newIncoming(t){let e=await mt.newIncoming(t);return new n(e,t.pageSize)}static async newOutgoing(t){let e=await mt.newOutgoing(t);return new n(e,t.pageSize)}async hasNext(){return this.it.hasNext()}async next(){let t=[];for(;t.length<this.pageSize&&await this.it.hasNext();)t.push(await this.it.next());return t}},mt=class n{constructor(t){this.requester=t}cachedNext;static async newIncoming(t){let e=await lt.newIncomingQuery(t);return new n(e)}static async newOutgoing(t){let e=await lt.newOutgoingQuery(t);return new n(e)}async hasNext(){return this.cachedNext===void 0&&(this.cachedNext=await this.requester.doNextRequest()),this.cachedNext!==null}async next(){if(this.cachedNext===void 0){let e=await this.requester.doNextRequest();if(e===null)throw new u("No more results");return e}let t=this.cachedNext;if(this.cachedNext=void 0,t===null)throw new u("No more results");return t}},lt=class n{constructor(t,e,r,a){this.globals=t;this.recipient=e;this.groupRefs=r;this.query=a;this.current=0;let o=new G(r.flat().map(i=>i.streamId));this.objectIter=new L(t.suiClient,o)}current=0;objectIter;static async newIncomingQuery(t){let e=hr(t.query),r=await t.globals.walletAddress(),o=(await t.globals.backend.getIncomingStreams(r,e)).filter(s=>ct(s.recipient)===ct(r)),i=de(o);return new n(t.globals,r,i,t.query)}static async newOutgoingQuery(t){let e=Sr(t.query),r=await t.globals.walletAddress(),a=await t.globals.backend.getOutgoingStreams(r,e),o=de(a);return new n(t.globals,r,o,t.query)}async doNextRequest(){if(this.current>=this.groupRefs.length)return null;let t=this.groupRefs[this.current];if(t.length===1){let e=await fr(this.globals,t[0].streamId,this.objectIter);return this.current++,fe(e,this.query)?e:this.doNextRequest()}if(t.length>1){let e=await gr(this.globals,t.map(r=>r.streamId),this.objectIter);return this.current++,dr(e,this.query)?e:this.doNextRequest()}throw new u("Stream group with no stream")}};function de(n){let t=new Map;return n.forEach(e=>{let r=t.get(e.groupId);r?(r.push(e),t.set(e.groupId,r)):t.set(e.groupId,[e])}),Array.from(t.values()).sort((e,r)=>pe.fromISO(r[0].createDate).toMillis()-pe.fromISO(e[0].createDate).toMillis())}function fe(n,t){if(t===void 0)return!0;let e=pr(n,t.status);if(t&&"claimable"in t&&t.claimable!==void 0){let r=t.claimable?n.progress.claimable!==0n:n.progress.claimable===0n;return e&&r}return e}function pr(n,t){return t===void 0?!0:Array.isArray(t)?t.includes(n.progress.status):n.progress.status===t}function dr(n,t){if(!t)return!0;let e=!1;return n.streams.forEach(r=>{fe(r,t)&&(e=!0)}),e}async function fr(n,t,e){let r=await ge(e,t);return w.fromObjectData(n,t,r)}async function gr(n,t,e){let r=[];for(;r.length<t.length;){let a=await ge(e,t[r.length]);r.push(a)}return st.newFromObjectResponse(n,t,r)}async function ge(n,t){if(!await n.hasNext())throw new u("object iterator has been consumed");let e=await n.next();if(!e||e.error||e.data===void 0||e.data===null)throw new u("object iterator undefined response",{cause:e?.error});if(e?.data?.objectId!==t)throw new u("stream id not aligned");return e}function hr(n){return{status:Lt(n?.status),coinType:he(n?.coinType),sender:Se(n?.sender)}}function Sr(n){return{status:Lt(n?.status),coinType:he(n?.coinType),recipient:Se(n?.recipient)}}function Lt(n){return n===void 0||n.length===0?"all":Array.isArray(n)?n.reduce((t,e)=>{let r=Lt(e);return!t||t===r?r:"all"},void 0):br(n)}function br(n){switch(n){case"STREAMING":case"STREAMED":case"CANCELED":return"active";case"COMPLETED":case"SETTLED":return"inactive";default:throw new m("Unknown stream filtered status")}}function he(n){if(n)return Array.isArray(n)?n.length!==0?n.map(t=>ue(t)):void 0:ue(n)}function Se(n){if(n)return Array.isArray(n)?n.length!==0?n.map(t=>ct(t)):void 0:ct(n)}var ut=class extends c{constructor(e,r,a){super(4,`Not enough balance: ${e}`,{context:{coinType:e,requestAmount:r,gotAmount:a}});this.coinType=e;this.requestAmount=r;this.gotAmount=a}};var yr=25;async function be(n,t,e,r="0x2::sui::SUI",a=yr){let o=new Wt(n,t,r,a),i=BigInt(0),s=[];for(;await o.hasNext()&&i<e;){let l=await o.next();l&&(s.push(l),i+=BigInt(l.balance))}if(i<e)throw new ut(r,e,i);return s}var Wt=class extends R{constructor(e,r,a,o){super(new qt(e,r,a,o));this.suiClient=e;this.owner=r;this.coinType=a;this.reqPageSize=o}},qt=class{constructor(t,e,r,a){this.suiClient=t;this.owner=e;this.coinType=r;this.reqPageSize=a;if(a<=0)throw new u("Invalid reqPageSize")}nextCursor;async doNextRequest(){let t=await this.suiClient.getCoins({owner:this.owner,coinType:this.coinType,cursor:this.nextCursor,limit:this.reqPageSize});return this.nextCursor=t.nextCursor,{data:t.data,hasNext:t.hasNextPage}}};var Ut=class{constructor(t){this.msafe=t}get type(){return"msafe"}async address(){return this.msafe.address()}async requestCoins(t){return this.msafe.requestCoins(t)}},f=class{constructor(t){this.account=t}async address(){return this.account.address}},$t=class{constructor(t,e){this.singleWallet=t;this.suiClient=e}get type(){return"single"}async address(){return this.singleWallet.address()}async requestCoins(t){return Promise.all(t.map(e=>this.requestCoin(e)))}async requestCoin(t){if(K(t.coinType,Cr))return{primaryCoin:Z};if(t.amount<=0)throw new m("Invalid coin request","coinAmount",t.amount);let e=await be(this.suiClient,await this.address(),t.amount,t.coinType);if(e.length===0)throw new u("no coins available");return{primaryCoin:e[0].coinObjectId,mergedCoins:e.slice(1).map(r=>r.coinObjectId)}}},g=class{globals;helper;constructor(t,e){this.globals=D.new(t,e),this.helper=new rt(this.globals)}connectSingleWallet(t){let e=new $t(t,this.globals.suiClient);this.globals.connectWallet(e)}connectMSafeAccount(t){let e=new Ut(t);this.globals.connectWallet(e)}async createStream(t){return this.builder().createStreams(t)}async getStream(t){return w.new(this.globals,t)}async getIncomingStreams(t,e=10){return W.newIncoming({globals:this.globals,query:t,pageSize:e})}async getOutgoingStreams(t,e=10){return W.newOutgoing({globals:this.globals,query:t,pageSize:e})}async getCoinTypesForStreamFilter(){let t=await this.wallet.address();return(await this.globals.backend.getAllCoinTypes(t)).map(r=>Ir(r))}async getRecipientsForStreamFilter(t){let e=await this.wallet.address();return(await this.globals.backend.getAllRecipients(e,t)).map(a=>ye(a))}async getCreatorsForStreamFilter(t){let e=await this.wallet.address();return(await this.globals.backend.getAllSenders(e,t)).map(a=>ye(a))}get wallet(){return this.globals.wallet}builder(){return new M(this.globals)}};var pt=class n extends p{constructor(e){super(e);this.data=e}txType;txSubType;async build(e){let{network:r,account:a}=e,o=new g(r==="sui:mainnet"?"prod":"dev");return o.connectSingleWallet(new f(a)),await(await o.getStream(this.data.streamId)).cancel()}static fromData(e){return new n(e)}};var dt=class n extends p{constructor(e){super(e);this.data=e}txType;txSubType;async build(e){let{network:r,account:a}=e,o=new g(r==="sui:mainnet"?"prod":"dev");return o.connectSingleWallet(new f(a)),await(await o.getStream(this.data.streamId)).claimByProxy()}static fromData(e){return new n(e)}};var ft=class n extends p{constructor(e){super(e);this.data=e}txType;txSubType;async build(e){let{network:r,account:a}=e,o=new g(r==="sui:mainnet"?"prod":"dev");return o.connectSingleWallet(new f(a)),await(await o.getStream(this.data.streamId)).claim()}static fromData(e){return new n(e)}};var gt=class n extends p{constructor(e){super(e);this.data=e}txType;txSubType;async build(e){let{network:r,account:a}=e,o=new g(r==="sui:mainnet"?"prod":"dev");return o.connectSingleWallet(new f(a)),await o.createStream(this.data)}static fromData(e){return new n(e)}};import{normalizeStructTag as Ie,SUI_TYPE_ARG as Te}from"@mysten/sui.js/utils";import{bcs as Ce}from"@mysten/sui.js/bcs";import{normalizeStructTag as Tr,normalizeSuiAddress as U}from"@mysten/sui.js/utils";var b=class n{constructor(t,e){this.moveCall=t;this.txb=e}decodeSharedObjectId(t){let e=this.getInputParam(t);return n.getSharedObjectId(e)}decodeOwnedObjectId(t){let e=this.getInputParam(t);return n.getOwnedObjectId(e)}decodeInputU64(t){let e=this.decodePureArg(t,"u64");return BigInt(e)}decodeInputAddress(t){let e=this.decodePureArg(t,"address");return U(e)}decodeInputString(t){return this.decodePureArg(t,"string")}decodeInputBool(t){return this.decodePureArg(t,"bool")}decodePureArg(t,e){let r=this.getInputParam(t);return n.getPureInputValue(r,e)}getInputParam(t){let e=this.moveCall.arguments[t];if(e.kind!=="Input")throw new Error("not input type");return this.txb.blockData.inputs[e.index]}static getPureInputValue(t,e){if(t.type!=="pure")throw new Error("not pure argument");if(typeof t.value=="object"&&"Pure"in t.value){let r=t.value.Pure;return Ce.de(e,new Uint8Array(r))}return t.value}static getOwnedObjectId(t){if(t.type!=="object")throw new Error(`not object argument: ${JSON.stringify(t)}`);if(typeof t.value=="object"){if(!("Object"in t.value)||!("ImmOrOwned"in t.value.Object))throw new Error("not ImmOrOwned");return U(t.value.Object.ImmOrOwned.objectId)}return U(t.value)}static getSharedObjectId(t){if(t.type!=="object")throw new Error(`not object argument: ${JSON.stringify(t)}`);if(typeof t.value!="object")return U(t.value);if(!("Object"in t.value)||!("Shared"in t.value.Object))throw new Error("not Shared");return U(t.value.Object.Shared.objectId)}static getPureInput(t,e){if(t.type!=="pure")throw new Error("not pure argument");if(typeof t.value!="object")return t.value;if(!("Pure"in t.value))throw new Error("Pure not in value");let r=t.value.Pure;return Ce.de(e,new Uint8Array(r))}typeArg(t){return Tr(this.moveCall.typeArguments[t])}txArg(t){return this.moveCall.arguments[t]}};var ht=class{constructor(t,e){this.globals=t;this.txb=e}decode(){let t=this.decodeCreateStreamInfo(),e=this.createStreamHelper().calculateCreateStreamFees(t),r=this.getCoinMerges();return{type:"CreateStream",info:t,fees:e,coinMerges:r}}decodeCreateStreamInfo(){let e=this.createStreamTransactions().map(r=>this.getCreationInfoFromMoveCall(r));return this.aggregateGroupStreamInfo(e)}createStreamTransactions(){let t=this.transactions.filter(e=>e.kind==="MoveCall"&&T(e.target,this.contract.createStreamTarget));if(t.length===0)throw new u("No create stream transactions");return t.map(e=>new b(e,this.txb))}getCreationInfoFromMoveCall(t){let e=t.decodeInputString(4),{name:r,groupId:a}=N(e),o=t.decodeInputAddress(5),i=t.decodeInputU64(6),s=t.decodeInputU64(7),l=t.decodeInputU64(8),A=t.decodeInputU64(9),z=t.decodeInputU64(10),vt=t.decodeInputBool(11),Ot=t.typeArg(0);return{name:r,groupId:a,recipient:o,timeStart:i,cliff:s,epochInterval:l,totalEpoch:A,amountPerEpoch:z,cancelable:vt,coinType:Ot}}aggregateGroupStreamInfo(t){if(new Set(t.map(a=>JSON.stringify({name:a.name,groupId:a.groupId,timeStart:String(a.timeStart),epochInterval:String(a.epochInterval),totalEpoch:String(a.totalEpoch),cancelable:a.cancelable,coinType:a.coinType}))).size!==1)throw new m("Stream group not have common info");let r=t.map(a=>({address:a.recipient,amountPerStep:a.amountPerEpoch,cliffAmount:a.cliff}));return{name:t[0].name,coinType:t[0].coinType,recipients:r,interval:t[0].epochInterval,steps:t[0].totalEpoch,startTimeMs:t[0].timeStart,cancelable:t[0].cancelable}}getCoinMerges(){let t=this.createStreamTransactions()[0];return this.getCoinMergeForCreateStream(t)}getCoinMergeForCreateStream(t){let e=t.typeArg(0),r=t.txArg(2),a=this.getCoinMergeFromNestedResult(r,e,t);if(e===Ie(Te))return[a];let o=t.txArg(3),i=this.getCoinMergeFromNestedResult(o,Ie(Te),t);return[a,i]}getCoinMergeFromNestedResult(t,e,r){if(t.kind==="GasCoin")return{primary:"GAS",coinType:e};if(t.kind==="Input"){let a=this.getInputArg(t),o=b.getOwnedObjectId(a),i=this.transactions.find(s=>{if(s.kind!=="MergeCoins")return!1;if(s.destination.kind!=="Input")throw new Error("merge coin destination not Input type");let l=this.getInputArg(s.destination);return b.getOwnedObjectId(l)===o});return i?{primary:o,merged:i.sources.map(s=>{let l=this.getInputArg(s);return b.getOwnedObjectId(l)}),coinType:e}:{primary:o,coinType:e}}if(t.kind==="NestedResult"){let a=this.transactions[t.index];if(a.kind!=="SplitCoins")throw new m(`Transaction type not expected. Expect SplitCoins, got ${a.kind}`);return this.getCoinMergeFromNestedResult(a.coin,e,r)}throw t.kind==="Result"?new Error("Result type not expected for coin inputs"):new Error("Unknown argument kind")}mergeCoinTransactions(){return this.transactions.filter(t=>t.kind==="MergeCoins")}get transactions(){return this.txb.blockData.transactions}get contract(){return new S(this.globals.envConfig.contract,this.globals)}get feeContract(){return new E(this.globals.envConfig.contract,this.globals)}createStreamHelper(){return new x(this.globals,this.feeContract,this.contract)}getInputArg(t){if(t.kind!=="Input")throw new Error("not input type");return"value"in t?t:this.txb.blockData.inputs[t.index]}};var St=class{constructor(t,e){this.globals=t;this.txb=e;this.contract=new S(t.envConfig.contract,t)}contract;decode(){if(this.isCreateStreamTransaction())return this.decodeCreateStreamTransaction();if(this.isClaimByProxyTransaction())return this.decodeClaimByProxyTransaction();if(this.isSetAutoClaimTransaction())return this.decodeSetAutoClaimTransaction();if(this.isCancelStreamTransaction())return this.decodeCancelStreamTransaction();if(this.isClaimStreamTransaction())return this.decodeClaimTransaction()}get transactions(){return this.txb.blockData.transactions}isCreateStreamTransaction(){return this.transactions.findIndex(e=>e.kind==="MoveCall"&&T(e.target,this.contract.createStreamTarget))!==-1}isSetAutoClaimTransaction(){return this.transactions.length===1&&this.transactions[0].kind==="MoveCall"&&T(this.transactions[0].target,this.contract.setAutoClaimTarget)}isCancelStreamTransaction(){return this.transactions.length===1&&this.transactions[0].kind==="MoveCall"&&T(this.transactions[0].target,this.contract.cancelStreamTarget)}isClaimStreamTransaction(){return this.transactions.length===1&&this.transactions[0].kind==="MoveCall"&&T(this.transactions[0].target,this.contract.claimStreamTarget)}isClaimByProxyTransaction(){return this.transactions.length===1&&this.transactions[0].kind==="MoveCall"&&T(this.transactions[0].target,this.contract.claimStreamByProxyTarget)}decodeCreateStreamTransaction(){return new ht(this.globals,this.txb).decode()}decodeSetAutoClaimTransaction(){let t=this.helper.decodeSharedObjectId(0),e=this.helper.decodeInputBool(1);return{type:"SetAutoClaim",streamId:t,enabled:e}}decodeClaimTransaction(){let t=this.helper.decodeSharedObjectId(0);return{type:"Claim",streamId:t}}decodeClaimByProxyTransaction(){let t=this.helper.decodeSharedObjectId(0);return{type:"ClaimByProxy",streamId:t}}decodeCancelStreamTransaction(){let t=this.helper.decodeSharedObjectId(0);return{type:"Cancel",streamId:t}}get helper(){let t=this.transactions[0];return new b(t,this.txb)}};var bt=class n extends p{constructor(e){super(e);this.data=e}txType;txSubType;async build(e){let{network:r,account:a}=e,o=new g(r==="sui:mainnet"?"prod":"dev");return o.connectSingleWallet(new f(a)),await(await o.getStream(this.data.streamId)).setAutoClaim(!0)}static fromData(e){return new n(e)}};var yt=class{application="mpay";async deserialize(t){let{chain:e,transactionBlock:r}=t,a=D.new(e==="sui:mainnet"?"prod":"dev"),i=new St(a,r).decode();if(i.type==="CreateStream")return{txType:$.Stream,txSubType:i.type,intentionData:i.info};if(i.type==="Claim")return{txType:$.Stream,txSubType:i.type,intentionData:{streamId:i.streamId}};if(i.type==="ClaimByProxy")return{txType:$.Stream,txSubType:i.type,intentionData:{streamId:i.streamId}};if(i.type==="SetAutoClaim")return{txType:$.Stream,txSubType:i.type,intentionData:{streamId:i.streamId,enabled:i.enabled}};if(i.type==="Cancel")return{txType:$.Stream,txSubType:i.type,intentionData:{streamId:i.streamId}};throw new Error(`Unknown transaction type: ${i}`)}async build(t){let{network:e,intentionData:r,suiClient:a,account:o}=t,i;switch(t.txSubType){case"CreateStream":i=gt.fromData(r);break;case"Claim":i=ft.fromData(r);break;case"ClaimByProxy":i=dt.fromData(r);break;case"SetAutoClaim":i=bt.fromData(r);break;case"Cancel":i=pt.fromData(r);break;default:throw new Error("not implemented")}return i.build({network:e,suiClient:a,account:o})}};import{TransactionDefaultApplication as Or,TransactionSubTypes as zt}from"@msafe/sui3-utils";import{buildCoinTransferTxb as wr}from"@msafe/sui3-utils";var Ct=class n extends p{constructor(e){super(e);this.data=e}txType;txSubType;async build(e){let{suiClient:r,account:a}=e;return wr(r,this.data,a.address)}static fromData(e){return new n(e)}};import{buildObjectTransferTxb as xr}from"@msafe/sui3-utils";var It=class n extends p{constructor(e){super(e);this.data=e}txType;txSubType;async build(e){let{suiClient:r,account:a}=e;return xr(r,this.data,a.address)}static fromData(e){return new n(e)}};import{isSameAddress as Ar}from"@msafe/sui3-utils";import{TransactionBlock as vr}from"@mysten/sui.js/transactions";var Tt=class n extends p{constructor(e){super(e);this.data=e}txType;txSubType;async build(e){let{account:r}=e,a=vr.from(this.data.content);if(!Ar(a.blockData.sender,r.address))throw new Error("Invalid sender address");return a}static fromData(e){return new n(e)}};var wt=class{application;constructor(){this.application=Or}deserialize(){throw new Error("MSafe core transaction intention should be build from API")}async build(t){let{suiClient:e,account:r}=t,a;switch(t.txSubType){case zt.assets.coin.send:a=Ct.fromData(t.intentionData);break;case zt.assets.object.send:a=It.fromData(t.intentionData);break;case zt.others.plain:a=Tt.fromData(t.intentionData);break;default:throw new Error("not implemented")}return a.build({suiClient:e,account:r})}};var xt=class{apps;constructor(t){this.apps=new Map(t.map(e=>[e.application,e]))}getAppHelper(t){let e=this.apps.get(t);if(!e)throw new Error(`${t} not registered`);return e}};import{TransactionSubTypes as Dr,TransactionType as Pr}from"@msafe/sui3-utils";import{TransactionBlock as Er}from"@mysten/sui.js/transactions";import{fromHEX as Mr,toHEX as kr}from"@mysten/sui.js/utils";import Es from"sort-keys-recursive";var Rr="msafe-plain-tx",jr=Dr.others.plain;var At=class{application;constructor(){this.application=Rr}async deserialize(t){let{transactionBlock:e,suiClient:r}=t,a=await e.build({client:r});return{txType:Pr.Other,txSubType:jr,intentionData:{content:kr(a)}}}async build(t){let{suiClient:e,account:r}=t,a=Er.from(Mr(t.intentionData.content)),o=await e.devInspectTransactionBlock({transactionBlock:a,sender:r.address});if(!(o.effects.status.status==="success"))throw new Error(o.effects.status.error);return a}};var Ns=new xt([new wt,new yt,new At]);export{Ns as appHelpers};
2871
2
  //# sourceMappingURL=index.mjs.map