Untitled
unknown
plain_text
a year ago
6.7 kB
7
Indexable
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}`);
}
}
}Editor is loading...
Leave a Comment