@yubing744/rooch-sdk
Version:
225 lines (224 loc) • 6.83 kB
JavaScript
import { hexlify } from "@ethersproject/bytes";
import { fromHexString } from "./hex";
import { ROOCH_ADDRESS_LENGTH } from "../constants";
import * as rooch_types from "../types/bcs";
import {
U256,
BcsSerializer
} from "../types/bcs";
import { parseFunctionId, normalizeRoochAddress, structTagToObjectID } from "./encode";
function encodeFunctionCall(functionId, tyArgs, args) {
const funcId = parseFunctionId(functionId);
const functionCall = new rooch_types.FunctionCall(
new rooch_types.FunctionId(
new rooch_types.ModuleId(
addressToSCS(funcId.address),
new rooch_types.Identifier(funcId.module)
),
new rooch_types.Identifier(funcId.functionName)
),
tyArgs.map((t) => typeTagToSCS(t)),
bytesArrayToSeqSeq(args)
);
return new rooch_types.MoveActionVariantFunction(functionCall);
}
function typeTagToSCS(ty) {
if (ty === "Bool") {
return new rooch_types.TypeTagVariantbool();
}
if (ty === "U8") {
return new rooch_types.TypeTagVariantu8();
}
if (ty === "U16") {
return new rooch_types.TypeTagVariantu16();
}
if (ty === "U32") {
return new rooch_types.TypeTagVariantu32();
}
if (ty === "U64") {
return new rooch_types.TypeTagVariantu64();
}
if (ty === "U128") {
return new rooch_types.TypeTagVariantu128();
}
if (ty === "U256") {
return new rooch_types.TypeTagVariantu256();
}
if (ty === "Address") {
return new rooch_types.TypeTagVariantaddress();
}
if (ty === "Signer") {
return new rooch_types.TypeTagVariantsigner();
}
if (ty.Vector) {
return new rooch_types.TypeTagVariantvector(typeTagToSCS(ty.Vector));
}
if (ty.Struct) {
return new rooch_types.TypeTagVariantstruct(
structTagToSCS(ty.Struct)
);
}
throw new Error(`invalid type tag: ${ty}`);
}
function structTagToSCS(data) {
return new rooch_types.StructTag(
addressToSCS(data.address),
new rooch_types.Identifier(data.module),
new rooch_types.Identifier(data.name),
data.type_params ? data.type_params.map((t) => typeTagToSCS(t)) : []
);
}
function addressToSCS(addr) {
const bytes = fromHexString(addr, 16 * 2);
const data = [];
for (let i = 0; i < bytes.length; i++) {
data.push([bytes[i]]);
}
return new rooch_types.AccountAddress(data);
}
function encodeStructTypeTags(typeArgsString) {
return typeArgsString.map((str) => encodeStructTypeTag(str));
}
function encodeStructTypeTag(str) {
const arr = str.split("<");
const arr1 = arr[0].split("::");
const address = arr1[0];
const module = arr1[1];
const name = arr1[2];
const params = arr[1] ? arr[1].replace(">", "").split(",") : [];
const type_params = [];
if (params.length > 0) {
params.forEach((param) => {
type_params.push(encodeStructTypeTag(param.trim()));
});
}
const result = {
Struct: {
address,
module,
name,
type_params
}
};
return result;
}
function bytesToSeq(byteArray) {
return Array.from(byteArray);
}
function stringToSeq(str) {
const seq = new Array();
for (let i = 0; i < str.length; i++) {
seq.push(str.charCodeAt(i));
}
return seq;
}
function bytesArrayToSeqSeq(input) {
return input.map((byteArray) => bytesToSeq(byteArray));
}
function addressToListTuple(ethAddress) {
const cleanedEthAddress = ethAddress.startsWith("0x") ? ethAddress.slice(2) : ethAddress;
if (cleanedEthAddress.length !== ROOCH_ADDRESS_LENGTH) {
throw new Error("Invalid Rooch address");
}
const listTuple = [];
for (let i = 0; i < cleanedEthAddress.length; i += 2) {
const byte = parseInt(cleanedEthAddress.slice(i, i + 2), 16);
listTuple.push([byte]);
}
return listTuple;
}
function addressToSeqNumber(ethAddress) {
const cleanedEthAddress = ethAddress.startsWith("0x") ? ethAddress.slice(2) : ethAddress;
const seqNumber = [];
for (let i = 0; i < cleanedEthAddress.length; i += 2) {
const byte = parseInt(cleanedEthAddress.slice(i, i + 2), 16);
seqNumber.push(byte);
}
return seqNumber;
}
function serializeValue(value, type, se) {
if (type === "Bool") {
se.serializeBool(value);
} else if (type === "U8") {
se.serializeU8(value);
} else if (type === "U16") {
se.serializeU16(value);
} else if (type === "U32") {
se.serializeU32(value);
} else if (type === "U64") {
se.serializeU64(value);
} else if (type === "U128") {
se.serializeU128(value);
} else if (type === "U256") {
const u256 = new U256(value);
u256.serialize(se);
} else if (type === "Address") {
const list = addressToListTuple(normalizeRoochAddress(value));
const accountAddress = new rooch_types.AccountAddress(list);
accountAddress.serialize(se);
} else if (type === "Ascii") {
const bytes = stringToSeq(value);
const moveAsciiString = new rooch_types.MoveAsciiString(bytes);
moveAsciiString.serialize(se);
} else if (type === "String") {
const bytes = stringToSeq(value);
const moveString = new rooch_types.MoveString(bytes);
moveString.serialize(se);
} else if (type.Vector) {
const vectorValues = value;
se.serializeLen(vectorValues.length);
for (let item of vectorValues) {
serializeValue(item, type.Vector, se);
}
} else if (type.Struct) {
const serializable = value;
serializable.serialize(se);
} else if (type === "ObjectID") {
const list = addressToListTuple(normalizeRoochAddress(value));
const accountAddress = new rooch_types.AccountAddress(list);
accountAddress.serialize(se);
} else if (type === "Object") {
const objectId = structTagToObjectID(value);
const list = addressToListTuple(normalizeRoochAddress(objectId));
const accountAddress = new rooch_types.AccountAddress(list);
accountAddress.serialize(se);
} else if (type === "Raw") {
const vectorValues = value;
se.serializeLen(vectorValues.length);
for (let item of vectorValues) {
se.serializeU8(item);
}
}
}
function encodeArg(arg) {
const se = new BcsSerializer();
serializeValue(arg.value, arg.type, se);
return se.getBytes();
}
const encodeMoveCallData = (funcId, tyArgs, args) => {
const bcsArgs = args?.map((arg) => encodeArg(arg));
const scriptFunction = encodeFunctionCall(funcId, tyArgs, bcsArgs);
const payloadInHex = (() => {
const se = new BcsSerializer();
scriptFunction.serialize(se);
return se.getBytes();
})();
return payloadInHex;
};
const encodeMoveCallDataWithETH = (funcId, tyArgs, args) => {
return hexlify(encodeMoveCallData(funcId, tyArgs, args));
};
export {
addressToListTuple,
addressToSCS,
addressToSeqNumber,
encodeArg,
encodeFunctionCall,
encodeMoveCallData,
encodeMoveCallDataWithETH,
encodeStructTypeTag,
encodeStructTypeTags,
structTagToSCS,
typeTagToSCS
};
//# sourceMappingURL=tx.js.map