@mysten/sui
Version:
Sui TypeScript API(Work in Progress)
281 lines (280 loc) • 9.01 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var TransactionData_exports = {};
__export(TransactionData_exports, {
TransactionDataBuilder: () => TransactionDataBuilder
});
module.exports = __toCommonJS(TransactionData_exports);
var import_bcs = require("@mysten/bcs");
var import_valibot = require("valibot");
var import_bcs2 = require("../bcs/index.js");
var import_sui_types = require("../utils/sui-types.js");
var import_internal = require("./data/internal.js");
var import_v1 = require("./data/v1.js");
var import_hash = require("./hash.js");
function prepareSuiAddress(address) {
return (0, import_sui_types.normalizeSuiAddress)(address).replace("0x", "");
}
class TransactionDataBuilder {
constructor(clone) {
this.version = 2;
this.sender = clone?.sender ?? null;
this.expiration = clone?.expiration ?? null;
this.inputs = clone?.inputs ?? [];
this.commands = clone?.commands ?? [];
this.gasData = clone?.gasData ?? {
budget: null,
price: null,
owner: null,
payment: null
};
}
static fromKindBytes(bytes) {
const kind = import_bcs2.bcs.TransactionKind.parse(bytes);
const programmableTx = kind.ProgrammableTransaction;
if (!programmableTx) {
throw new Error("Unable to deserialize from bytes.");
}
return TransactionDataBuilder.restore({
version: 2,
sender: null,
expiration: null,
gasData: {
budget: null,
owner: null,
payment: null,
price: null
},
inputs: programmableTx.inputs,
commands: programmableTx.commands
});
}
static fromBytes(bytes) {
const rawData = import_bcs2.bcs.TransactionData.parse(bytes);
const data = rawData?.V1;
const programmableTx = data.kind.ProgrammableTransaction;
if (!data || !programmableTx) {
throw new Error("Unable to deserialize from bytes.");
}
return TransactionDataBuilder.restore({
version: 2,
sender: data.sender,
expiration: data.expiration,
gasData: data.gasData,
inputs: programmableTx.inputs,
commands: programmableTx.commands
});
}
static restore(data) {
if (data.version === 2) {
return new TransactionDataBuilder((0, import_valibot.parse)(import_internal.TransactionData, data));
} else {
return new TransactionDataBuilder((0, import_valibot.parse)(import_internal.TransactionData, (0, import_v1.transactionDataFromV1)(data)));
}
}
/**
* Generate transaction digest.
*
* @param bytes BCS serialized transaction data
* @returns transaction digest.
*/
static getDigestFromBytes(bytes) {
const hash = (0, import_hash.hashTypedData)("TransactionData", bytes);
return (0, import_bcs.toBase58)(hash);
}
// @deprecated use gasData instead
get gasConfig() {
return this.gasData;
}
// @deprecated use gasData instead
set gasConfig(value) {
this.gasData = value;
}
build({
maxSizeBytes = Infinity,
overrides,
onlyTransactionKind
} = {}) {
const inputs = this.inputs;
const commands = this.commands;
const kind = {
ProgrammableTransaction: {
inputs,
commands
}
};
if (onlyTransactionKind) {
return import_bcs2.bcs.TransactionKind.serialize(kind, { maxSize: maxSizeBytes }).toBytes();
}
const expiration = overrides?.expiration ?? this.expiration;
const sender = overrides?.sender ?? this.sender;
const gasData = { ...this.gasData, ...overrides?.gasConfig, ...overrides?.gasData };
if (!sender) {
throw new Error("Missing transaction sender");
}
if (!gasData.budget) {
throw new Error("Missing gas budget");
}
if (!gasData.payment) {
throw new Error("Missing gas payment");
}
if (!gasData.price) {
throw new Error("Missing gas price");
}
const transactionData = {
sender: prepareSuiAddress(sender),
expiration: expiration ? expiration : { None: true },
gasData: {
payment: gasData.payment,
owner: prepareSuiAddress(this.gasData.owner ?? sender),
price: BigInt(gasData.price),
budget: BigInt(gasData.budget)
},
kind: {
ProgrammableTransaction: {
inputs,
commands
}
}
};
return import_bcs2.bcs.TransactionData.serialize(
{ V1: transactionData },
{ maxSize: maxSizeBytes }
).toBytes();
}
addInput(type, arg) {
const index = this.inputs.length;
this.inputs.push(arg);
return { Input: index, type, $kind: "Input" };
}
getInputUses(index, fn) {
this.mapArguments((arg, command) => {
if (arg.$kind === "Input" && arg.Input === index) {
fn(arg, command);
}
return arg;
});
}
mapCommandArguments(index, fn) {
const command = this.commands[index];
switch (command.$kind) {
case "MoveCall":
command.MoveCall.arguments = command.MoveCall.arguments.map(
(arg) => fn(arg, command, index)
);
break;
case "TransferObjects":
command.TransferObjects.objects = command.TransferObjects.objects.map(
(arg) => fn(arg, command, index)
);
command.TransferObjects.address = fn(command.TransferObjects.address, command, index);
break;
case "SplitCoins":
command.SplitCoins.coin = fn(command.SplitCoins.coin, command, index);
command.SplitCoins.amounts = command.SplitCoins.amounts.map(
(arg) => fn(arg, command, index)
);
break;
case "MergeCoins":
command.MergeCoins.destination = fn(command.MergeCoins.destination, command, index);
command.MergeCoins.sources = command.MergeCoins.sources.map(
(arg) => fn(arg, command, index)
);
break;
case "MakeMoveVec":
command.MakeMoveVec.elements = command.MakeMoveVec.elements.map(
(arg) => fn(arg, command, index)
);
break;
case "Upgrade":
command.Upgrade.ticket = fn(command.Upgrade.ticket, command, index);
break;
case "$Intent":
const inputs = command.$Intent.inputs;
command.$Intent.inputs = {};
for (const [key, value] of Object.entries(inputs)) {
command.$Intent.inputs[key] = Array.isArray(value) ? value.map((arg) => fn(arg, command, index)) : fn(value, command, index);
}
break;
case "Publish":
break;
default:
throw new Error(`Unexpected transaction kind: ${command.$kind}`);
}
}
mapArguments(fn) {
for (const commandIndex of this.commands.keys()) {
this.mapCommandArguments(commandIndex, fn);
}
}
replaceCommand(index, replacement, resultIndex = index) {
if (!Array.isArray(replacement)) {
this.commands[index] = replacement;
return;
}
const sizeDiff = replacement.length - 1;
this.commands.splice(index, 1, ...replacement);
if (sizeDiff !== 0) {
this.mapArguments((arg, _command, commandIndex) => {
if (commandIndex < index + replacement.length) {
return arg;
}
switch (arg.$kind) {
case "Result":
if (arg.Result === index) {
arg.Result = resultIndex;
}
if (arg.Result > index) {
arg.Result += sizeDiff;
}
break;
case "NestedResult":
if (arg.NestedResult[0] === index) {
arg.NestedResult[0] = resultIndex;
}
if (arg.NestedResult[0] > index) {
arg.NestedResult[0] += sizeDiff;
}
break;
}
return arg;
});
}
}
getDigest() {
const bytes = this.build({ onlyTransactionKind: false });
return TransactionDataBuilder.getDigestFromBytes(bytes);
}
snapshot() {
return (0, import_valibot.parse)(import_internal.TransactionData, this);
}
shallowClone() {
return new TransactionDataBuilder({
version: this.version,
sender: this.sender,
expiration: this.expiration,
gasData: {
...this.gasData
},
inputs: [...this.inputs],
commands: [...this.commands]
});
}
}
//# sourceMappingURL=TransactionData.js.map
;