PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-sui/src/lib/mystenlab/builder
Просмотр файла: bcs.ts
import { BCS, TypeName } from '@mysten/bcs';
import { bcs, TypeTag } from '../types/sui-bcs';
import { normalizeSuiAddress } from '../types/common';
import { TypeTagSerializer } from '../txn-data-serializers/type-tag-serializer';
import { TransactionArgument, MoveCallTransaction } from './Transactions';
export const ARGUMENT_INNER = 'Argument';
export const VECTOR = 'vector';
export const OPTION = 'Option';
export const CALL_ARG = 'CallArg';
export const TYPE_TAG = 'TypeTag';
export const OBJECT_ARG = 'ObjectArg';
export const PROGRAMMABLE_TX_BLOCK = 'ProgrammableTransaction';
export const PROGRAMMABLE_CALL_INNER = 'ProgrammableMoveCall';
export const TRANSACTION_INNER = 'Transaction';
export const ENUM_KIND = 'EnumKind';
/** Wrapper around transaction Enum to support `kind` matching in TS */
export const TRANSACTION: TypeName = [ENUM_KIND, TRANSACTION_INNER];
/** Wrapper around Argument Enum to support `kind` matching in TS */
export const ARGUMENT: TypeName = [ENUM_KIND, ARGUMENT_INNER];
/** Custom serializer for decoding package, module, function easier */
export const PROGRAMMABLE_CALL = 'SimpleProgrammableMoveCall';
/** Transaction types */
export type Option<T> = { some: T } | { none: true };
export const builder = new BCS(bcs)
.registerStructType(PROGRAMMABLE_TX_BLOCK, {
inputs: [VECTOR, CALL_ARG],
transactions: [VECTOR, TRANSACTION],
})
.registerEnumType(ARGUMENT_INNER, {
GasCoin: null,
Input: { index: BCS.U16 },
Result: { index: BCS.U16 },
NestedResult: { index: BCS.U16, resultIndex: BCS.U16 },
})
.registerStructType(PROGRAMMABLE_CALL_INNER, {
package: BCS.ADDRESS,
module: BCS.STRING,
function: BCS.STRING,
type_arguments: [VECTOR, TYPE_TAG],
arguments: [VECTOR, ARGUMENT],
})
.registerEnumType(TRANSACTION_INNER, {
/**
* A Move Call - any public Move function can be called via
* this transaction. The results can be used that instant to pass
* into the next transaction.
*/
MoveCall: PROGRAMMABLE_CALL,
/**
* Transfer vector of objects to a receiver.
*/
TransferObjects: {
objects: [VECTOR, ARGUMENT],
address: ARGUMENT,
},
/**
* Split `amount` from a `coin`.
*/
SplitCoins: { coin: ARGUMENT, amounts: [VECTOR, ARGUMENT] },
/**
* Merge Vector of Coins (`sources`) into a `destination`.
*/
MergeCoins: { destination: ARGUMENT, sources: [VECTOR, ARGUMENT] },
/**
* Publish a Move module.
*/
Publish: {
modules: [VECTOR, [VECTOR, BCS.U8]],
dependencies: [VECTOR, BCS.ADDRESS],
},
/**
* Build a vector of objects using the input arguments.
* It is impossible to construct a `vector<T: key>` otherwise,
* so this call serves a utility function.
*/
MakeMoveVec: {
type: [OPTION, TYPE_TAG],
objects: [VECTOR, ARGUMENT],
},
});
/**
* Utilities for better decoding.
*/
type ProgrammableCallInner = {
package: string;
module: string;
function: string;
type_arguments: TypeTag[];
arguments: TransactionArgument[];
};
/**
* Wrapper around Enum, which transforms any `T` into an object with `kind` property:
* @example
* ```
* let bcsEnum = { TransferObjects: { objects: [], address: ... } }
* // becomes
* let translatedEnum = { kind: 'TransferObjects', objects: [], address: ... };
* ```
*/
builder.registerType(
[ENUM_KIND, 'T'],
function encode(this: BCS, writer, data: { kind: string }, typeParams, typeMap) {
const kind = data.kind;
const invariant = { [kind]: data };
const [enumType] = typeParams;
return this.getTypeInterface(enumType as string)._encodeRaw.call(this, writer, invariant, typeParams, typeMap);
},
function decode(this: BCS, reader, typeParams, typeMap) {
const [enumType] = typeParams;
const data = this.getTypeInterface(enumType as string)._decodeRaw.call(this, reader, typeParams, typeMap);
// enum invariant can only have one `key` field
const kind = Object.keys(data)[0];
return { kind, ...data[kind] };
},
(data: { kind: string }) => {
if (typeof data !== 'object' && !('kind' in data)) {
throw new Error(`EnumKind: Missing property "kind" in the input ${JSON.stringify(data)}`);
}
return true;
}
);
/**
* Custom deserializer for the ProgrammableCall.
*
* Hides the inner structure and gives a simpler, more convenient
* interface to encode and decode this struct as a part of `TransactionData`.
*
* - `(package)::(module)::(function)` are now `target` property.
* - `TypeTag[]` array is now passed as strings, not as a struct.
*/
builder.registerType(
PROGRAMMABLE_CALL,
function encodeProgrammableTx(this: BCS, writer, data: MoveCallTransaction, typeParams, typeMap) {
const [pkg, module, fun] = data.target.split('::');
const type_arguments = data.typeArguments.map((tag) => TypeTagSerializer.parseFromStr(tag, true));
return this.getTypeInterface(PROGRAMMABLE_CALL_INNER)._encodeRaw.call(
this,
writer,
{
package: normalizeSuiAddress(pkg),
module,
function: fun,
type_arguments,
arguments: data.arguments,
} as ProgrammableCallInner,
typeParams,
typeMap
);
},
function decodeProgrammableTx(this: BCS, reader, typeParams, typeMap) {
let data: ProgrammableCallInner = builder
.getTypeInterface(PROGRAMMABLE_CALL_INNER)
._decodeRaw.call(this, reader, typeParams, typeMap);
return {
target: [data.package, data.module, data.function].join('::'),
arguments: data.arguments,
typeArguments: data.type_arguments.map(TypeTagSerializer.tagToString),
};
},
// Validation callback to error out if the data format is invalid.
// TODO: make sure TypeTag can be parsed.
(data: MoveCallTransaction) => {
return data.target.split('::').length === 3;
}
);
Выполнить команду
Для локальной разработки. Не используйте в интернете!