Untitled
unknown
plain_text
a month ago
6.7 kB
1
Indexable
Never
async txBuild(ticker: string, params: SuiTransactionParams): Promise<SuiTransactionParams> { SuiServiceUtils.validateBuildParams(params); const { from, to, } = params; const { address: fromAddress } = Array.isArray(from) ? from[0] : from; const { address: toAddress, value, } = Array.isArray(to) ? to[0] : to; const valueMiniMIST = mistToSui(value); const gasPrice = params.gasPrice ?? params.fee?.properties?.gasPrice ?? DEFAULT_GAS_AMOUNT; const gasBudget = params.gasLimit ?? params.gasAmount ?? params.fee?.properties?.gasLimit ?? params.fee?.properties?.gasAmount ?? DEFAULT_GAS_LIMIT; if (!Array.isArray(to)) { const params: ToParams = { address: to.address, value: to.value, }; const bytesTx = await this.build(fromAddress, gasPrice, gasBudget, params); if (!bytesTx) { throw new Error('BytesTx not serialized'); } return { ...params, from: [ { address: fromAddress, value: valueMiniMIST, }, ], to: [ { address: toAddress, value: valueMiniMIST, }, ], gasPrice, gasLimit: gasBudget, data: Buffer.from(bytesTx).toString('hex'), }; } else { throw new Error('toParams must be array'); } } async build(fromAddress: string, gasPrice: string, gasBudget: string, toParams: ToParams): Promise<Uint8Array> { const tx = new Transaction(); tx.setSender(fromAddress); tx.setGasOwner(fromAddress); tx.setGasBudget(BigInt(gasBudget)); tx.setGasPrice(BigInt(gasPrice)); const coins = await this.getBuildParams(NETWORK, { fromAddress, method: RPC_METHODS.GET_COINS, }); const gasCoin: CoinData | CoinData[] = SuiServiceUtils.selectGasCoin(+gasBudget, coins); const gasCoinBalance = SuiServiceUtils.gasCoinTotalBalance(gasCoin); const gasPaymentObjects = Array.isArray(gasCoin) ? gasCoin.map((coin) => ({ objectId: coin.coinObjectId, digest: coin.digest, version: coin.version, })) : [ { objectId: gasCoin.coinObjectId, digest: gasCoin.digest, version: gasCoin.version, }, ]; tx.setGasPayment(gasPaymentObjects); if (coins.data.length > 1) { let mergeStartIndex = 0; if (!Array.isArray(gasCoin)) { if (coins.data.length > 1 && coins.data[0].coinObjectId === gasCoin.coinObjectId) { mergeStartIndex = 1; } } else { for (let i = 0; i < gasCoin.length; i++) { if (coins.data[i].coinObjectId === gasCoin[i].coinObjectId) { mergeStartIndex++; } else { break; } } } const mainCoin = coins.data[mergeStartIndex]; for (let i = mergeStartIndex + 1; i < coins.data.length; i++) { const coinToMerge = coins.data[i]; let shouldMerge = true; if (Array.isArray(gasCoin)) { for (const coin of gasCoin) { if (coinToMerge.coinObjectId === coin.coinObjectId) { shouldMerge = false; break; } } } else if (coinToMerge.coinObjectId === gasCoin.coinObjectId) { shouldMerge = false; } if (shouldMerge) { tx.mergeCoins( tx.object(Inputs.ObjectRef({ objectId: mainCoin.coinObjectId, digest: mainCoin.digest, version: mainCoin.version, })), [ tx.object(Inputs.ObjectRef({ objectId: coinToMerge.coinObjectId, digest: coinToMerge.digest, version: coinToMerge.version, })), ], ); } } if (!Array.isArray(toParams)) { if (SuiServiceUtils.validateBalance(mainCoin.balance, toParams.value, gasBudget)) { if (Big(gasCoinBalance).gt(gasBudget)) { // const sum = Big(gasCoinBalance).minus(gasBudget); // Под вопросом, нужна ли такая жесткая валидация // const sumNumber = sum.toNumber(); // if (Big(toParams.value).gt(sum)) { // Под вопросом, нужна ли такая жесткая валидация // throw new Error(`sum: ${sumNumber} less than the value to send: ${mistToSui(toParams.value)}`); // } if (Big(mainCoin.balance).lt(Big(toParams.value))) { throw new Error(`coinBalance: ${mainCoin.balance} less than the value to send: ${Number(Big(toParams.value))}`); } if (Big(mainCoin.balance).gte(Big(toParams.value))) { const coinToSend = tx.splitCoins( tx.object(Inputs.ObjectRef({ objectId: mainCoin.coinObjectId, digest: mainCoin.digest, version: mainCoin.version, })), [toParams.value], ); tx.transferObjects( [coinToSend], tx.pure.address(toParams.address), ); return await tx.build(); } else { throw new Error('mainCoin balance must be greater than the value to send'); } } } else if (SuiServiceUtils.validateGasBalance(gasCoinBalance.toString(), toParams.value, gasBudget)) { tx.splitCoins({ GasCoin: true }, [toParams.value]); tx.transferObjects([{ Result: 0 }], tx.pure.address(toParams.address)); return await tx.build(); } else { const sum = SuiServiceUtils.getTxSumError(toParams.value, gasBudget); throw new Error(`gasCoin balance less than the ${mistToSui(gasCoinBalance.toString())} of gasBudget: ${(gasBudget)} + value: ${ toParams.value} = ${sum}`); } } } else { if (!Array.isArray(toParams) && !Array.isArray(gasCoin)) { if (SuiServiceUtils.validateGasBalance(gasCoinBalance.toString(), toParams.value, gasBudget)) { tx.splitCoins({ GasCoin: true }, [toParams.value]); tx.transferObjects([{ Result: 0 }], tx.pure.address(toParams.address)); return await tx.build(); } } else { const sum = mistToSui(SuiServiceUtils.getTxSumError(toParams.value, gasBudget)); throw new Error(`gasCoin balance less than the ${mistToSui(gasCoinBalance.toString())} of gasBudget: ${mistToSui( gasBudget)} + value: ${mistToSui( toParams.value)} = ${sum}`); } } }
Leave a Comment