SUi calldata 其中一个分支

 avatar
user_0057973
java
8 months ago
12 kB
8
Indexable
private String buildSuiSwap(BigInteger amountIn, BigInteger minReturnAmount, DexQuoteInfoVO dexQuote, boolean isNativeFrom,
                                List<ExWalletInnerSignInfoInputCoins> inputCoins, List<ExWalletInnerSignInfoInputCoins> nativeCoins,
                                String gasPrice, String budget, String orderId, Integer toAmountDecimal, String fromTokenAddress,
                                String toTokenAddress, String userWalletAddress, PlatFormForMutilSwap platFormForMutilSwap) throws SerializationError {

        // True 正向   False 反向
        boolean tag = dexQuote.getExchangeDirection().equals(MultiSwapExchangeDirectionEnum.POSITIVE_DIRECTION.getDirection().toString());

        String[] toTokenSplit = toTokenAddress.split("::");
        String[] fromTokenSplit = fromTokenAddress.split("::");
        if (fromTokenSplit.length < NUMBER_THREE || toTokenSplit.length < NUMBER_THREE) {
            return null;
        }
        /**
         * inputs
         */
        List<CallArg> inputs = new ArrayList<>();

        //native 是 splitCoins amount
        if (isNativeFrom) {
            CallArg.Pure.Builder pureBuilderFromAmount = new CallArg.Pure.Builder();
            pureBuilderFromAmount.value = Arrays.asList(ArrayUtils.toObject(new MoveValue.U64(amountIn.longValue()).bcsSerialize()));
            inputs.add(pureBuilderFromAmount.build());
        } else {
            for (ExWalletInnerSignInfoInputCoins inputCoin : inputCoins) {
                SuiObjectRef suiObjectRef = new SuiObjectRef();
                suiObjectRef.setObjectId(inputCoin.getObjectId());
                suiObjectRef.setDigest(inputCoin.getDigest());
                suiObjectRef.setVersion(new BigInteger(inputCoin.getVersion()));
                Tuple3<ObjectID, SequenceNumber, ObjectDigest> objectRef = SuiProgrammableTransaction.getObjectRef(suiObjectRef);
                ObjectArg.ImmOrOwnedObject immOrOwnedObject = new ObjectArg.ImmOrOwnedObject(objectRef);
                CallArg.Object input = new CallArg.Object(immOrOwnedObject);
                inputs.add(input);
            }
        }

        //input 池子
        AccountAddress.Builder poolObjectBuilder = new AccountAddress.Builder();
        //池子地址
        poolObjectBuilder.value = SuiProgrammableTransaction.geAddressBytes(dexQuote.getPairAddress());
        ObjectArg.SharedObject object = new ObjectArg.SharedObject(new ObjectID(poolObjectBuilder.build()), new SequenceNumber(Long.valueOf(dexQuote.getPoolId())), true);
        CallArg.Object pool = new CallArg.Object(object);

        //input 参数3
        CallArg.Pure.Builder pureBuilder3 = new CallArg.Pure.Builder();
        pureBuilder3.value = Arrays.asList(ArrayUtils.toObject(new MoveValue.U64(amountIn.longValue()).bcsSerialize()));

        //input 参数4
        CallArg.Pure.Builder pureBuilder4 = new CallArg.Pure.Builder();
        pureBuilder4.value = Arrays.asList(ArrayUtils.toObject(new MoveValue.U64(minReturnAmount.longValue()).bcsSerialize()));

        //input 新版本新增一个clock参数
        AccountAddress.Builder clockObjectBuilder = new AccountAddress.Builder();
        //池子地址
        clockObjectBuilder.value = SuiProgrammableTransaction.geAddressBytes(CLOCK_OBJECT);
        ObjectArg.SharedObject clockObject = new ObjectArg.SharedObject(new ObjectID(clockObjectBuilder.build()), new SequenceNumber(1L), false);
        CallArg.Object clock = new CallArg.Object(clockObject);

        //input 参数5
        CallArg.Pure.Builder pureBuilder5 = new CallArg.Pure.Builder();
        pureBuilder5.value = Arrays.asList(ArrayUtils.toObject(new MoveValue.U64(Long.valueOf(orderId)).bcsSerialize()));

        //input 参数6
        CallArg.Pure.Builder pureBuilder6 = new CallArg.Pure.Builder();
        pureBuilder6.value = Arrays.asList(ArrayUtils.toObject(new MoveValue.U8(toAmountDecimal.byteValue()).bcsSerialize()));

        inputs.add(pool);
        inputs.add(pureBuilder3.build());
        inputs.add(pureBuilder4.build());
        inputs.add(clock);
        inputs.add(pureBuilder5.build());
        inputs.add(pureBuilder6.build());

        /**
         * gas
         */
        final GasData.Builder gasDataBuilder = new GasData.Builder();
        //主网币的coin放在gaspaymen里了
        gasDataBuilder.budget = Long.valueOf(budget);
        gasDataBuilder.price = Long.valueOf(gasPrice);
        List<Tuple3<ObjectID, SequenceNumber, ObjectDigest>> gasPayment = new ArrayList<>();
        // inputCoins就为主网币
        for (ExWalletInnerSignInfoInputCoins nativeCoin : nativeCoins) {
            SuiObjectRef suiObjectRef = new SuiObjectRef();
            suiObjectRef.setObjectId(nativeCoin.getObjectId());
            suiObjectRef.setDigest(nativeCoin.getDigest());
            suiObjectRef.setVersion(new BigInteger(nativeCoin.getVersion()));
            gasPayment.add(SuiProgrammableTransaction.getObjectRef(suiObjectRef));
        }
        gasDataBuilder.payment = gasPayment;
        SuiAddress.Builder senderAddress = new SuiAddress.Builder();
        senderAddress.value = geAddressBytes(userWalletAddress);
        gasDataBuilder.owner = senderAddress.build();

        /**
         * transactions
         */
        //from是native token需要SplitCoins
        List<Command> commands = new ArrayList<>();

        if (isNativeFrom) {
            Command.SplitCoins.Builder splitCoinCommandBuilder = new Command.SplitCoins.Builder();
            //transaction1 SplitCoins
            Argument amountArg = SuiProgrammableTransaction.pure(Long.valueOf(amountIn.toString()), 0);
            splitCoinCommandBuilder.field0 = new Argument.GasCoin.Builder().build();
            splitCoinCommandBuilder.field1 = Lists.newArrayList(amountArg);
            commands.add(splitCoinCommandBuilder.build());
            //transaction2 MakeMoveVec
            List<Argument> arguments = new ArrayList<>();
            Argument.Result.Builder resultBuilder = new Argument.Result.Builder();
            resultBuilder.value = 0;
            arguments.add(resultBuilder.build());
            Command.MakeMoveVec.Builder makeMoveVecBuilder = new Command.MakeMoveVec.Builder();
            makeMoveVecBuilder.field0 = Optional.empty();
            makeMoveVecBuilder.field1 = arguments;
            commands.add(makeMoveVecBuilder.build());
        } else {
            //transaction1 MakeMoveVec
            List<Argument> arguments = new ArrayList<>();
            for (short i = 0; i < inputCoins.size(); i++) {
                Argument.Input.Builder input = new Argument.Input.Builder();
                input.value = i;
                arguments.add(input.build());
            }
            Command.MakeMoveVec.Builder makeMoveVecBuilder = new Command.MakeMoveVec.Builder();
            makeMoveVecBuilder.field0 = Optional.empty();
            makeMoveVecBuilder.field1 = arguments;
            commands.add(makeMoveVecBuilder.build());
        }

        //transaction3 MoveCall
        Command.MoveCall.Builder moveCallBuilder = new Command.MoveCall.Builder();

        ProgrammableMoveCall.Builder progCallBuilder = new ProgrammableMoveCall.Builder();

        AccountAddress.Builder objectPackageBuilder = new AccountAddress.Builder();
        //todo 需要替换成合约的正式package和router
        objectPackageBuilder.value = geAddressBytes(platFormForMutilSwap.getDexRouterAddress());
        progCallBuilder.Package = new ObjectID(objectPackageBuilder.build());
        progCallBuilder.module = new Identifier(SWAP_ROUTER);
        List<TypeTag> typeTags = new ArrayList<>();
        //token0
        TypeTag.struct.Builder struct0 = new TypeTag.struct.Builder();
        StructTag.Builder structTag0 = new StructTag.Builder();
        AccountAddress.Builder structAddress0 = new AccountAddress.Builder();
        structAddress0.value = geAddressBytes(fromTokenSplit[ZERO]);
        structTag0.address = structAddress0.build();
        structTag0.module = new Identifier(fromTokenSplit[ONE]);
        structTag0.name = new Identifier(fromTokenSplit[TWO]);
        structTag0.type_args = new ArrayList<>();
        struct0.value = structTag0.build();
        //token1
        TypeTag.struct.Builder struct1 = new TypeTag.struct.Builder();
        StructTag.Builder structTag1 = new StructTag.Builder();
        AccountAddress.Builder structAddress1 = new AccountAddress.Builder();
        structAddress1.value = geAddressBytes(toTokenSplit[ZERO]);
        structTag1.address = structAddress1.build();
        structTag1.module = new Identifier(toTokenSplit[ONE]);
        structTag1.name = new Identifier(toTokenSplit[TWO]);
        structTag1.type_args = new ArrayList<>();
        struct1.value = structTag1.build();
        if (tag) {
            progCallBuilder.function = new Identifier("suiswap_x_2_y");
            typeTags.add(struct0.build());
            typeTags.add(struct1.build());
        } else {
            progCallBuilder.function = new Identifier("suiswap_y_2_x");
            typeTags.add(struct1.build());
            typeTags.add(struct0.build());
        }

        progCallBuilder.type_arguments = typeTags;

        int startIndex = isNativeFrom ? 1 : inputCoins.size();

        List<Argument> txArg = new ArrayList<>();
        Argument.Input.Builder inputBuilder0 = new Argument.Input.Builder();
        inputBuilder0.value = (short) startIndex;

        Argument.Result.Builder resultBuilder = new Argument.Result.Builder();
        resultBuilder.value = (short) (isNativeFrom ? 1 : 0);

        Argument.Input.Builder inputBuilder2 = new Argument.Input.Builder();
        inputBuilder2.value = (short) (startIndex + 1);

        Argument.Input.Builder inputBuilder3 = new Argument.Input.Builder();
        inputBuilder3.value = (short) (startIndex + 2);

        Argument.Input.Builder inputBuilder4 = new Argument.Input.Builder();
        inputBuilder4.value = (short) (startIndex + 3);

        Argument.Input.Builder inputBuilder5 = new Argument.Input.Builder();
        inputBuilder5.value = (short) (startIndex + 4);

        Argument.Input.Builder inputBuilder6 = new Argument.Input.Builder();
        inputBuilder6.value = (short) (startIndex + 5);

        txArg.add(inputBuilder0.build());
        txArg.add(resultBuilder.build());
        txArg.add(inputBuilder2.build());
        txArg.add(inputBuilder3.build());
        txArg.add(inputBuilder4.build());
        txArg.add(inputBuilder5.build());
        txArg.add(inputBuilder6.build());
        progCallBuilder.arguments = txArg;
        moveCallBuilder.value = progCallBuilder.build();
        commands.add(moveCallBuilder.build());

        ProgrammableTransaction programmableTransaction = new ProgrammableTransaction(inputs, commands);

        final TransactionDataV1.Builder transactionDataV1Builder = new TransactionDataV1.Builder();

        TransactionKind.ProgrammableTransaction.Builder builder = new TransactionKind.ProgrammableTransaction.Builder();
        builder.value = programmableTransaction;
        transactionDataV1Builder.kind = builder.build();
        transactionDataV1Builder.sender = senderAddress.build();
        transactionDataV1Builder.gas_data = gasDataBuilder.build();
        TransactionExpiration.None.Builder expirationBuilder = new TransactionExpiration.None.Builder();
        transactionDataV1Builder.expiration = expirationBuilder.build();

        final TransactionData.V1.Builder v1Builder = new TransactionData.V1.Builder();
        v1Builder.value = transactionDataV1Builder.build();

        byte[] tx = v1Builder.build().bcsSerialize();

        return Base64.toBase64String(tx);
    }
Editor is loading...
Leave a Comment