UNPKG

@moveflow/sui-sdk.js

Version:

Typescript SDK for MoveFlow on SUI blockchain

705 lines 32.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Stream = exports.StreamDirection = void 0; const tslib_1 = require("tslib"); const config_1 = require("./config"); const sui_js_1 = require("@mysten/sui.js"); /** * StreamDirection enum describes the relationship between the payment stream and the users. * * OUT - outgoing stream. If a user sends money to the stream, the stream is the outgoing stream to the user. * IN - incoming stream. If a user receives money from the stream, the stream is the incoming stream to the user. */ var StreamDirection; (function (StreamDirection) { StreamDirection[StreamDirection["OUT"] = 0] = "OUT"; StreamDirection[StreamDirection["IN"] = 1] = "IN"; })(StreamDirection = exports.StreamDirection || (exports.StreamDirection = {})); class Stream { constructor(network) { this.SUI = '0x2::sui::SUI'; this._network = network; this._config = (0, config_1.getConfig)(network); const conn = new sui_js_1.Connection({ fullnode: this._config.fullNodeUrl }); this._rpcProvider = new sui_js_1.JsonRpcProvider(conn); } get network() { return this._network; } get networkName() { return config_1.Network[this._network]; } /** * This function builds a TransactionBlock to create a new payment stream * * @param coinType the coin type that is used in the payment stream, e.g., 0x2::sui::SUI * * @param name the name of the stream, max 1024 characters * @param remark the remark of the stream, max 1024 characters * @param sender the payment sender's address, which must be the same as the TransactionBlock signer * @param recipient the payment receiver's address * @param depositAmount the initial deposit amount of the coin specified by the coinType parameter * @param startTime the unix epoch time in seconds, i.e., Date.now() / 1000 * @param stopTime the unix epoch time in seconds * @param interval the payment interval in seconds, and the deposit is divided evenly among the intervals. Default to 60 seconds * @param closeable if the stream can be closed by the sender. Default to true * @param modifiable if the stream can be modified by the recipient. Default to true. Not effective now * @returns the TransactionBlock which can be signed to create a new payment stream */ createTransaction(coinType, name, remark, sender, recipient, depositAmount, startTime, stopTime, interval = 60, closeable = true, modifiable = true) { return tslib_1.__awaiter(this, void 0, void 0, function* () { this.ensureValidCoinType(coinType); if (name.length > 1024) throw new Error('name exceeds the maximum length 1024 characters'); if (remark.length > 1024) throw new Error('remark exceeds the maximum length 1024 characters'); // if (!isValidstring(sender)) throw new Error(`${sender} is not a valid address`) // if (!isValidstring(recipient)) throw new Error(`${recipient} is not a valid address`) if (depositAmount < 0) throw new Error(`depositAmount ${depositAmount} is negative`); this.ensureValidTime(startTime); this.ensureValidTime(stopTime); if (stopTime <= startTime) throw new Error(`stopTime ${stopTime} is before startTime ${startTime}`); if (stopTime <= Date.now() / 1000) throw new Error(`stopTime ${stopTime} is in the past`); this.ensureValidTime(interval); const balance = yield this._rpcProvider.getBalance({ owner: sender, coinType }); const totalBalance = BigInt(balance.totalBalance); const lockedBalance = balance.lockedBalance.number ? BigInt(balance.lockedBalance.number) : BigInt(0); const availableBalance = totalBalance - lockedBalance; if (availableBalance <= depositAmount) { throw new Error(`the sender ${sender} has not enough balance of ${coinType} to pay the deposit ${depositAmount}`); } const txb = new sui_js_1.TransactionBlock(); const coin = yield this.getCoin(txb, sender, coinType, depositAmount); txb.moveCall({ target: `${this._config.packageObjectId}::stream::create`, typeArguments: [coinType], arguments: [ txb.object(this._config.globalConfigObjectId), coin, txb.pure(name), txb.pure(remark), txb.pure(recipient), txb.pure(depositAmount), txb.pure(startTime), txb.pure(stopTime), txb.pure(interval), txb.pure(closeable), txb.pure(modifiable), txb.object(sui_js_1.SUI_CLOCK_OBJECT_ID), ], }); return txb; }); } /** * This function builds a TransactionBlock to extend an existing payment stream * * @param coinType the coin type that is used in the payment stream, e.g., 0x2::sui::SUI * @param sender the payment sender's address, which must be the same as the TransactionBlock signer * @param senderCap the sender capability object id * @param streamId the payment stream object id * @param newStopTime the new stop time of the payment stream * @returns the TransactionBlock which can be signed to extend an existing payment stream */ extendTransaction(coinType, sender, senderCap, streamId, newStopTime) { return tslib_1.__awaiter(this, void 0, void 0, function* () { this.ensureValidCoinType(coinType); // if (!isValidstring(sender)) throw new Error(`${sender} is not a valid address`) // if (!isValidSuistring(senderCap)) throw new Error(`${senderCap} is not a valid string`) // if (!isValidSuistring(streamId)) throw new Error(`${streamId} is not a valid string`) this.ensureValidTime(newStopTime); const streamInfo = yield this.getStreamById(streamId); if (newStopTime <= streamInfo.stopTime) { throw new Error(`newStopTime ${newStopTime} is earlier than the stopTime ${streamInfo.stopTime}`); } const txb = new sui_js_1.TransactionBlock(); const numOfIntervals = (newStopTime - streamInfo.stopTime) / streamInfo.interval; const depositAmount = BigInt(Math.ceil(streamInfo.ratePerInterval * numOfIntervals / 1000)); const coin = yield this.getCoin(txb, sender, coinType, depositAmount); txb.moveCall({ target: `${this._config.packageObjectId}::stream::extend`, typeArguments: [coinType], arguments: [ txb.object(senderCap), txb.object(streamId), coin, txb.pure(newStopTime), ], }); return txb; }); } /** * This function builds a TransactionBlock to pause an existing payment stream * * @param coinType the coin type that is used in the payment stream, e.g., 0x2::sui::SUI * @param senderCap the sender capability object id * @param streamId the payment stream object id * @returns the TransactionBlock which can be signed to pause an existing payment stream */ pauseTransaction(coinType, senderCap, streamId) { this.ensureValidCoinType(coinType); // if (!isValidSuistring(senderCap)) throw new Error(`${senderCap} is not a valid string`) // if (!isValidSuistring(streamId)) throw new Error(`${streamId} is not a valid string`) const txb = new sui_js_1.TransactionBlock(); txb.moveCall({ target: `${this._config.packageObjectId}::stream::pause`, typeArguments: [coinType], arguments: [ txb.object(senderCap), txb.object(streamId), txb.object(sui_js_1.SUI_CLOCK_OBJECT_ID), ], }); return txb; } /** * This function builds a TransactionBlock to resume a paused payment stream * * @param coinType the coin type that is used in the payment stream, e.g., 0x2::sui::SUI * @param senderCap the sender capability object id * @param streamId the payment stream object id * @returns the TransactionBlock which can be signed to resume a paused payment stream */ resumeTransaction(coinType, senderCap, streamId) { this.ensureValidCoinType(coinType); // if (!isValidSuistring(senderCap)) throw new Error(`${senderCap} is not a valid string`) // if (!isValidSuistring(streamId)) throw new Error(`${streamId} is not a valid string`) const txb = new sui_js_1.TransactionBlock(); txb.moveCall({ target: `${this._config.packageObjectId}::stream::resume`, typeArguments: [coinType], arguments: [ txb.object(senderCap), txb.object(streamId), txb.object(sui_js_1.SUI_CLOCK_OBJECT_ID), ], }); return txb; } /** * This function builds a TransactionBlock to withdraw from a payment stream, whose signer must be the recipient. * * @param coinType the coin type that is used in the payment stream, e.g., 0x2::sui::SUI * @param streamId the payment stream object id * @returns the TransactionBlock which can be signed to withdraw from a payment stream. */ withdrawTransaction(coinType, streamId) { this.ensureValidCoinType(coinType); // if (!isValidSuistring(streamId)) throw new Error(`${streamId} is not a valid string`) const txb = new sui_js_1.TransactionBlock(); txb.moveCall({ target: `${this._config.packageObjectId}::stream::withdraw`, typeArguments: [coinType], arguments: [ txb.object(streamId), txb.object(sui_js_1.SUI_CLOCK_OBJECT_ID), ], }); return txb; } /** * This function builds a TransactionBlock to set a new recipient of a payment stream, whose signer must be the current recipient. * * @param coinType the coin type that is used in the payment stream, e.g., 0x2::sui::SUI * @param streamId the payment stream object id * @returns the TransactionBlock which can be signed to set a new recipient of the payment stream. */ setNewRecipientTransaction(coinType, streamId, newRecipient) { this.ensureValidCoinType(coinType); // if (!isValidSuistring(streamId)) throw new Error(`${streamId} is not a valid string`) // if (!isValidstring(newRecipient)) throw new Error(` ${newRecipient} is not a valid address`) const txb = new sui_js_1.TransactionBlock(); txb.moveCall({ target: `${this._config.packageObjectId}::stream::set_new_recipient`, typeArguments: [coinType], arguments: [ txb.object(streamId), txb.object(this._config.globalConfigObjectId), txb.pure(newRecipient), ], }); return txb; } /** * This function builds a TransactionBlock to close an existing payment stream * * @param coinType the coin type that is used in the payment stream, e.g., 0x2::sui::SUI * @param senderCap the sender capability object id * @param streamId the payment stream object id * @returns the TransactionBlock which can be signed to close an existing payment stream */ closeTransaction(coinType, senderCap, streamId) { this.ensureValidCoinType(coinType); // if (!isValidSuistring(senderCap)) throw new Error(`${senderCap} is not a valid string`) // if (!isValidSuistring(streamId)) throw new Error(`${streamId} is not a valid string`) const txb = new sui_js_1.TransactionBlock(); txb.moveCall({ target: `${this._config.packageObjectId}::stream::close`, typeArguments: [coinType], arguments: [ txb.object(senderCap), txb.object(streamId), txb.object(sui_js_1.SUI_CLOCK_OBJECT_ID), ], }); return txb; } /** * This function parses a createTransaction response * * @param response the transaction response of the createTransaction * @returns a StreamCreationResult struct */ getStreamCreationResult(response) { if (!response.objectChanges) throw new Error('the response is missing object changes'); let streamId = '', senderCap = '', recipientCap = ''; for (const objectChange of response.objectChanges) { if ('objectType' in objectChange) { if (objectChange.objectType.includes('StreamInfo')) streamId = objectChange.objectId; else if (objectChange.objectType.includes('SenderCap')) senderCap = objectChange.objectId; else if (objectChange.objectType.includes('RecipientCap')) recipientCap = objectChange.objectId; } } const streamCreationResult = { streamId, senderCap, recipientCap, }; return streamCreationResult; } /** * This function get the payment streams specified by the parameters * * @param address the sender or recipient's address of the payment streams, depending on the direction * @param direction the direction of the payment stream, IN or OUT. If IN, then the address is the recipient, otherwise, sender * @returns an array of StreamInfo objects satisfying the parameters */ getStreams(address, direction) { var _a, _b; return tslib_1.__awaiter(this, void 0, void 0, function* () { // if (!isValidstring(address)) throw new Error(`${address} is not a valid address`) const parentId = direction == StreamDirection.IN ? this._config.incomingStreamObjectId : this._config.outgoingStreamObjectId; const streamIds = yield this._rpcProvider.getDynamicFieldObject({ parentId, name: { type: 'address', value: address }, }); const streamIdsContent = (_a = streamIds.data) === null || _a === void 0 ? void 0 : _a.content; const streamRecords = yield this._rpcProvider.multiGetObjects({ ids: streamIdsContent.fields.value, options: { showContent: true, showOwner: true }, }); const streams = []; for (let i = 0; i < streamRecords.length; i++) { const streamRecord = (_b = streamRecords[i].data) === null || _b === void 0 ? void 0 : _b.content; if (direction == StreamDirection.IN && streamRecord.fields.recipient == address || direction == StreamDirection.OUT && streamRecord.fields.sender == address) { streams.push(this.convert(streamRecord)); } } return streams; }); } /** * This function get the stream info specified by the id * * @param id the stream id * @returns the StreamInfo object */ getStreamById(id) { var _a; return tslib_1.__awaiter(this, void 0, void 0, function* () { // if (!isValidSuistring(id)) throw new Error(`${id} is not a valid string`) const _record = yield this._rpcProvider.getObject({ id, options: { showContent: true, showOwner: true }, }); const streamInfo = this.convert((_a = _record.data) === null || _a === void 0 ? void 0 : _a.content); return streamInfo; }); } /** * This function returns the amount of the withdrawable fund in the payment stream * * @param stream the StreamInfo object * @returns the amount of the withdrawable fund */ withdrawable(stream) { if (stream.closed || stream.pauseInfo.paused || stream.remainingAmount == 0) { return BigInt(0); } const lastWithdrawTime = stream.lastWithdrawTime; const stopTime = stream.stopTime; const interval = stream.interval; const accPausedTime = stream.pauseInfo.accPausedTime; const currTime = Date.now() / 1000; // seconds const timeSpan = Math.min(currTime, stopTime) - lastWithdrawTime - accPausedTime; const numOfIntervals = Math.floor(timeSpan / interval); const gross = BigInt(numOfIntervals) * BigInt(stream.ratePerInterval) / BigInt(1000); const fee = gross * BigInt(stream.feeInfo.feePoint) / BigInt(10000); return gross - fee; } /** * This function returns true if the stream can be closed by the sender, and false otherwise * * @param stream the StreamInfo object * @param sender the sender address * @returns true if the stream can be closed by the sender, and false otherwise */ closeable(stream, sender) { return stream.sender == sender && stream.featureInfo.senderCloseable && !stream.closed; } /** * This function returns true if the stream can be paused by the sender, and false otherwise * * @param stream the StreamInfo object * @param sender the sender address * @returns true if the stream can be paused by the sender, and false otherwise */ pauseable(stream, sender) { return stream.sender == sender && stream.featureInfo.pauseable && !stream.closed && !stream.pauseInfo.paused; } /** * This function returns true if the stream can be modified by the recipient, and false otherwise * * @param stream the StreamInfo object * @param recipient the recipient address * @returns true if the stream can be modified by the recipient, and false otherwise */ recipientModifiable(stream, recipient) { return stream.recipient == recipient && stream.featureInfo.recipientModifiable && !stream.closed; } /** * This function returns all the SenderCap object ids of the owner. Use this function if there aren't many (over 100) SenderCaps * * @param owner the owner of the SenderCaps * @returns an array of SenderCap object ids */ getSenderCaps(owner) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return this.getOwnedObjects(owner, `${this._config.packageObjectId}::stream::SenderCap`); }); } // async getSenderCap(owner: string) { // const senderObjects = await this._rpcProvider.getOwnedObjects({ // owner: owner, // options: {showContent: true}, // filter: { // StructType: `${this._config.packageObjectId}::stream::SenderCap` // } // }) // return senderObjects // } /** * This function returns Paginatedstrings. Use this function if there are many (over 100) senderCaps * * @param owner the owner of the SenderCaps * @param paginationArguments pagination arguments, such as cursor, limit * @returns Paginatedstrings object */ getPaginatedSenderCaps(owner, paginationArguments) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return this.getPaginatedOwnedObjects(owner, `${this._config.packageObjectId}::stream::SenderCap`, paginationArguments); }); } /** * This function returns all the RecipientCap object ids of the owner. Use this function if there aren't many (over 100) RecipientCaps * * @param owner the owner of the RecipientCaps * @returns an array of RecipientCap object ids */ getRecipientCaps(owner) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return this.getOwnedObjects(owner, `${this._config.packageObjectId}::stream::RecipientCap`); }); } /** * This function returns Paginatedstrings. Use this function if there are many (over 100) recipientCaps * * @param owner the owner of the RecipientCaps * @param paginationArguments pagination arguments, such as cursor, limit * @returns Paginatedstrings object */ getPaginatedRecipientCaps(owner, paginationArguments) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return this.getPaginatedOwnedObjects(owner, `${this._config.packageObjectId}::stream::RecipientCap`, paginationArguments); }); } /** * This function returns an array of all the supported coins. Use this function if there aren't many (over 100) coins supported. * * @returns all the supported coins */ getSupportedCoins() { return tslib_1.__awaiter(this, void 0, void 0, function* () { const coinConfigs = []; let hasNextPage = true; let nextCursor = null; while (hasNextPage) { const paginatedCoinConfigs = yield this.getPaginatedSupportedCoins({ cursor: nextCursor, }); coinConfigs.push(...paginatedCoinConfigs.coinConfigs); hasNextPage = paginatedCoinConfigs.hasNextPage; nextCursor = paginatedCoinConfigs.nextCursor; } return coinConfigs; }); } /** * This function returns PaginatedCoinConfigs. Use this function if there are many (over 100) coins supported. * * @returns paginated supported coins */ getPaginatedSupportedCoins(paginationArguments) { var _a; return tslib_1.__awaiter(this, void 0, void 0, function* () { const coinConfigs = []; const coinConfigsObject = yield this._rpcProvider.getDynamicFields(Object.assign({ parentId: this._config.coinConfigsObjectId }, paginationArguments)); const objectIds = []; for (const data of coinConfigsObject.data) { objectIds.push(data.objectId); } const coinConfigObjects = yield this._rpcProvider.multiGetObjects({ ids: objectIds, options: { showContent: true }, }); for (const coinConfigObject of coinConfigObjects) { const content = (_a = coinConfigObject.data) === null || _a === void 0 ? void 0 : _a.content; coinConfigs.push({ coinType: content.fields.value.fields.coin_type, feePoint: content.fields.value.fields.fee_point, }); } return { coinConfigs, nextCursor: coinConfigsObject.nextCursor, hasNextPage: coinConfigsObject.hasNextPage, }; }); } // ---- private functions ---- getOwnedObjects(owner, structType) { return tslib_1.__awaiter(this, void 0, void 0, function* () { // if (!isValidstring(owner)) throw new Error(`${owner} is not a valid address`) const objectIds = []; let hasNextPage = true; let nextCursor = null; while (hasNextPage) { const paginatedOwnedObjects = yield this.getPaginatedOwnedObjects(owner, structType, { cursor: nextCursor }); objectIds.push(...paginatedOwnedObjects.objectIds); hasNextPage = paginatedOwnedObjects.hasNextPage; nextCursor = paginatedOwnedObjects.nextCursor; } return objectIds; }); } getPaginatedOwnedObjects(owner, structType, paginationArguments) { return tslib_1.__awaiter(this, void 0, void 0, function* () { // if (!isValidstring(owner)) throw new Error(`${owner} is not a valid address`) const objectIds = []; const ownedObjects = yield this._rpcProvider.getOwnedObjects(Object.assign({ owner, filter: { StructType: structType, } }, paginationArguments)); for (const ownedObject of ownedObjects.data) { if (ownedObject.data) { objectIds.push(ownedObject.data.objectId); } } return { objectIds, nextCursor: ownedObjects.nextCursor, hasNextPage: ownedObjects.hasNextPage, }; }); } convert(streamRecord) { const streamInfo = { id: streamRecord.fields.id.id, coinType: this.extractCoinType(streamRecord.type), name: streamRecord.fields.name, remark: streamRecord.fields.remark, sender: streamRecord.fields.sender, recipient: streamRecord.fields.recipient, interval: parseInt(streamRecord.fields.interval), ratePerInterval: parseInt(streamRecord.fields.rate_per_interval), lastWithdrawTime: parseInt(streamRecord.fields.last_withdraw_time), startTime: parseInt(streamRecord.fields.start_time), stopTime: parseInt(streamRecord.fields.stop_time), depositAmount: parseInt(streamRecord.fields.deposit_amount), withdrawnAmount: parseInt(streamRecord.fields.withdrawn_amount), remainingAmount: parseInt(streamRecord.fields.remaining_amount), closed: streamRecord.fields.closed, featureInfo: { pauseable: streamRecord.fields.feature_info.fields.pauseable, senderCloseable: streamRecord.fields.feature_info.fields.sender_closeable, recipientModifiable: streamRecord.fields.feature_info.fields.recipient_modifiable, }, feeInfo: { feeRecipient: streamRecord.fields.fee_info.fields.fee_recipient, feePoint: streamRecord.fields.fee_info.fields.fee_point, }, pauseInfo: { paused: streamRecord.fields.pause_info.fields.paused, pausedAt: parseInt(streamRecord.fields.pause_info.fields.pause_at), accPausedTime: parseInt(streamRecord.fields.pause_info.fields.acc_paused_time), }, balance: parseInt(streamRecord.fields.balance), }; return streamInfo; } extractCoinType(type) { const match = type.match(/.+<(.+)>/); if (!match) throw new Error(`${type} is missing coin type`); return match[1]; } ensurePositiveInteger(num) { if (num < 0 || !Number.isInteger(num)) { throw new Error(`The number ${num} is negative or not an integer`); } } ensureValidTime(time) { this.ensurePositiveInteger(time); if (time > 253402300799) { // 9999/12/31 23:59:59 throw new Error(`The time ${time} is later than 9999/12/31 23:59:59`); } } ensureValidFeePoint(feePoint) { this.ensurePositiveInteger(feePoint); if (feePoint > 255) { throw new Error(`The feePoint ${feePoint} exceeds 255`); } } // basic format validation ensureValidCoinType(coinType) { const parts = coinType.split('::'); if (parts.length != 3) throw new Error(`${coinType} is not in a valid format`); } isSUI(coinType) { return coinType === this.SUI; } getCoins(owner, coinType, amount) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const coinstrings = []; let total = BigInt(0); let hasNextPage = true; let nextCursor = null; while (hasNextPage && total < amount) { const paginatedCoins = yield this._rpcProvider.getCoins({ owner, coinType, cursor: nextCursor }); hasNextPage = paginatedCoins.hasNextPage; nextCursor = paginatedCoins.nextCursor; for (const coin of paginatedCoins.data) { // if (!coin.lockedUntilEpoch) { total += BigInt(coin.balance); coinstrings.push(coin.coinObjectId); if (total >= amount) break; // } } } return coinstrings; }); } getCoin(txb, owner, coinType, amount) { return tslib_1.__awaiter(this, void 0, void 0, function* () { let coin; if (this.isSUI(coinType)) { coin = txb.splitCoins(txb.gas, [txb.pure(amount)])[0]; } else { const coinstrings = yield this.getCoins(owner, coinType, amount); if (coinstrings.length == 1) { coin = txb.object(coinstrings[0]); } else { // number of coins cannot be 0, as we have checked the balance before const primaryCoinInput = txb.object(coinstrings[0]); txb.mergeCoins(primaryCoinInput, coinstrings.slice(1).map(id => txb.object(id))); coin = txb.splitCoins(primaryCoinInput, [txb.pure(amount)])[0]; } } return coin; }); } // ----- admin functions ----- /** * This function builds a TransactionBlock to register a coin type * * @param coinType the coin type that is used in the payment streams, e.g., 0x2::sui::SUI * @param feePoint the denominator of fee point is 10000, i.e, 25 means 0.25% * @returns the TransactionBlock which can be signed by the admin to register a new coin type */ registerCoinTransaction(coinType, feePoint) { this.ensureValidCoinType(coinType); this.ensureValidFeePoint(feePoint); const txb = new sui_js_1.TransactionBlock(); txb.moveCall({ target: `${this._config.packageObjectId}::stream::register_coin`, typeArguments: [coinType], arguments: [ txb.object(this._config.manageCap), txb.object(this._config.globalConfigObjectId), txb.pure(feePoint), ], }); return txb; } /** * This function builds a TransactionBlock to set a new fee point for the coin type * * @param coinType the coin type that is used in the payment streams, e.g., 0x2::sui::SUI * @param newFeePoint the denominator of fee point is 10000, i.e, 25 means 0.25% * @returns the TransactionBlock which can be signed by the admin to set the new fee point */ setFeePointTransaction(coinType, newFeePoint) { this.ensureValidCoinType(coinType); this.ensureValidFeePoint(newFeePoint); const txb = new sui_js_1.TransactionBlock(); txb.moveCall({ target: `${this._config.packageObjectId}::stream::set_fee_point`, typeArguments: [coinType], arguments: [ txb.object(this._config.manageCap), txb.object(this._config.globalConfigObjectId), txb.pure(newFeePoint), ], }); return txb; } /** * This function builds a TransactionBlock to set a new fee recipient * * @param newFeeRecipient the new fee recipient address * @returns the TransactionBlock which can be signed by the admin to set the new fee recipient */ setFeeRecipientTransaction(newFeeRecipient) { // if (!isValidstring(newFeeRecipient)) throw new Error(`${newFeeRecipient} is not a valid address`) const txb = new sui_js_1.TransactionBlock(); txb.moveCall({ target: `${this._config.packageObjectId}::stream::set_fee_recipient`, arguments: [ txb.object(this._config.manageCap), txb.object(this._config.globalConfigObjectId), txb.pure(newFeeRecipient), ], }); return txb; } } exports.Stream = Stream; //# sourceMappingURL=stream.js.map