import * as $ from "@manahippo/move-to-ts"; import {AptosDataCache, AptosParserRepo, DummyCache, AptosLocalCache} from "@manahippo/move-to-ts"; import {U8, U64, U128} from "@manahippo/move-to-ts"; import {u8, u64, u128} from "@manahippo/move-to-ts"; import {TypeParamDeclType, FieldDeclType} from "@manahippo/move-to-ts"; import {AtomicTypeTag, StructTag, TypeTag, VectorTag, SimpleStructTag} from "@manahippo/move-to-ts"; import {OptionTransaction} from "@manahippo/move-to-ts"; import {HexString, AptosClient, AptosAccount, TxnBuilderTypes, Types} from "aptos"; import * as Account from "./account"; import * as Chain_id from "./chain_id"; import * as Coin from "./coin"; import * as Error from "./error"; import * as Signer from "./signer"; import * as System_addresses from "./system_addresses"; import * as Timestamp from "./timestamp"; import * as Transaction_fee from "./transaction_fee"; import * as Vector from "./vector"; export const packageName = "AptosFramework"; export const moduleAddress = new HexString("0x1"); export const moduleName = "transaction_validation"; export const EOUT_OF_GAS : U64 = u64("6"); export const MAX_U64 : U128 = u128("18446744073709551615"); export const PROLOGUE_EACCOUNT_DOES_NOT_EXIST : U64 = u64("1004"); export const PROLOGUE_EBAD_CHAIN_ID : U64 = u64("1007"); export const PROLOGUE_ECANT_PAY_GAS_DEPOSIT : U64 = u64("1005"); export const PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY : U64 = u64("1001"); export const PROLOGUE_ESECONDARY_KEYS_ADDRESSES_COUNT_MISMATCH : U64 = u64("1009"); export const PROLOGUE_ESEQUENCE_NUMBER_TOO_BIG : U64 = u64("1008"); export const PROLOGUE_ESEQUENCE_NUMBER_TOO_NEW : U64 = u64("1003"); export const PROLOGUE_ESEQUENCE_NUMBER_TOO_OLD : U64 = u64("1002"); export const PROLOGUE_ETRANSACTION_EXPIRED : U64 = u64("1006"); export class TransactionValidation { static moduleAddress = moduleAddress; static moduleName = moduleName; __app: $.AppType | null = null; static structName: string = "TransactionValidation"; static typeParameters: TypeParamDeclType[] = [ ]; static fields: FieldDeclType[] = [ { name: "module_addr", typeTag: AtomicTypeTag.Address }, { name: "module_name", typeTag: new VectorTag(AtomicTypeTag.U8) }, { name: "script_prologue_name", typeTag: new VectorTag(AtomicTypeTag.U8) }, { name: "module_prologue_name", typeTag: new VectorTag(AtomicTypeTag.U8) }, { name: "multi_agent_prologue_name", typeTag: new VectorTag(AtomicTypeTag.U8) }, { name: "user_epilogue_name", typeTag: new VectorTag(AtomicTypeTag.U8) }]; module_addr: HexString; module_name: U8[]; script_prologue_name: U8[]; module_prologue_name: U8[]; multi_agent_prologue_name: U8[]; user_epilogue_name: U8[]; constructor(proto: any, public typeTag: TypeTag) { this.module_addr = proto['module_addr'] as HexString; this.module_name = proto['module_name'] as U8[]; this.script_prologue_name = proto['script_prologue_name'] as U8[]; this.module_prologue_name = proto['module_prologue_name'] as U8[]; this.multi_agent_prologue_name = proto['multi_agent_prologue_name'] as U8[]; this.user_epilogue_name = proto['user_epilogue_name'] as U8[]; } static TransactionValidationParser(data:any, typeTag: TypeTag, repo: AptosParserRepo) : TransactionValidation { const proto = $.parseStructProto(data, typeTag, repo, TransactionValidation); return new TransactionValidation(proto, typeTag); } static async load(repo: AptosParserRepo, client: AptosClient, address: HexString, typeParams: TypeTag[]) { const result = await repo.loadResource(client, address, TransactionValidation, typeParams); return result as unknown as TransactionValidation; } static async loadByApp(app: $.AppType, address: HexString, typeParams: TypeTag[]) { const result = await app.repo.loadResource(app.client, address, TransactionValidation, typeParams); await result.loadFullState(app) return result as unknown as TransactionValidation; } static getTag(): StructTag { return new StructTag(moduleAddress, moduleName, "TransactionValidation", []); } async loadFullState(app: $.AppType) { this.__app = app; } } export function epilogue_ ( account: HexString, _txn_sequence_number: U64, txn_gas_price: U64, txn_max_gas_units: U64, gas_units_remaining: U64, $c: AptosDataCache, ): void { let addr, gas_used, transaction_fee_amount; if (!($.copy(txn_max_gas_units)).ge($.copy(gas_units_remaining))) { throw $.abortCode(Error.invalid_argument_($.copy(EOUT_OF_GAS), $c)); } gas_used = ($.copy(txn_max_gas_units)).sub($.copy(gas_units_remaining)); if (!((u128($.copy(txn_gas_price))).mul(u128($.copy(gas_used)))).le($.copy(MAX_U64))) { throw $.abortCode(Error.out_of_range_($.copy(EOUT_OF_GAS), $c)); } transaction_fee_amount = ($.copy(txn_gas_price)).mul($.copy(gas_used)); addr = Signer.address_of_(account, $c); if (!(Coin.balance_($.copy(addr), $c, [new StructTag(new HexString("0x1"), "aptos_coin", "AptosCoin", [])])).ge($.copy(transaction_fee_amount))) { throw $.abortCode(Error.out_of_range_($.copy(PROLOGUE_ECANT_PAY_GAS_DEPOSIT), $c)); } Transaction_fee.burn_fee_($.copy(addr), $.copy(transaction_fee_amount), $c); Account.increment_sequence_number_($.copy(addr), $c); return; } export function initialize_ ( aptos_framework: HexString, script_prologue_name: U8[], module_prologue_name: U8[], multi_agent_prologue_name: U8[], user_epilogue_name: U8[], $c: AptosDataCache, ): void { System_addresses.assert_aptos_framework_(aptos_framework, $c); $c.move_to(new SimpleStructTag(TransactionValidation), aptos_framework, new TransactionValidation({ module_addr: new HexString("0x1"), module_name: [u8("116"), u8("114"), u8("97"), u8("110"), u8("115"), u8("97"), u8("99"), u8("116"), u8("105"), u8("111"), u8("110"), u8("95"), u8("118"), u8("97"), u8("108"), u8("105"), u8("100"), u8("97"), u8("116"), u8("105"), u8("111"), u8("110")], script_prologue_name: $.copy(script_prologue_name), module_prologue_name: $.copy(module_prologue_name), multi_agent_prologue_name: $.copy(multi_agent_prologue_name), user_epilogue_name: $.copy(user_epilogue_name) }, new SimpleStructTag(TransactionValidation))); return; } export function module_prologue_ ( sender: HexString, txn_sequence_number: U64, txn_public_key: U8[], txn_gas_price: U64, txn_max_gas_units: U64, txn_expiration_time: U64, chain_id: U8, $c: AptosDataCache, ): void { return prologue_common_(sender, $.copy(txn_sequence_number), $.copy(txn_public_key), $.copy(txn_gas_price), $.copy(txn_max_gas_units), $.copy(txn_expiration_time), $.copy(chain_id), $c); } export function multi_agent_script_prologue_ ( sender: HexString, txn_sequence_number: U64, txn_sender_public_key: U8[], secondary_signer_addresses: HexString[], secondary_signer_public_key_hashes: U8[][], txn_gas_price: U64, txn_max_gas_units: U64, txn_expiration_time: U64, chain_id: U8, $c: AptosDataCache, ): void { let i, num_secondary_signers, secondary_address, signer_public_key_hash; prologue_common_(sender, $.copy(txn_sequence_number), $.copy(txn_sender_public_key), $.copy(txn_gas_price), $.copy(txn_max_gas_units), $.copy(txn_expiration_time), $.copy(chain_id), $c); num_secondary_signers = Vector.length_(secondary_signer_addresses, $c, [AtomicTypeTag.Address]); if (!(Vector.length_(secondary_signer_public_key_hashes, $c, [new VectorTag(AtomicTypeTag.U8)])).eq(($.copy(num_secondary_signers)))) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_ESECONDARY_KEYS_ADDRESSES_COUNT_MISMATCH), $c)); } i = u64("0"); while (($.copy(i)).lt($.copy(num_secondary_signers))) { { secondary_address = $.copy(Vector.borrow_(secondary_signer_addresses, $.copy(i), $c, [AtomicTypeTag.Address])); if (!Account.exists_at_($.copy(secondary_address), $c)) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_EACCOUNT_DOES_NOT_EXIST), $c)); } signer_public_key_hash = $.copy(Vector.borrow_(secondary_signer_public_key_hashes, $.copy(i), $c, [new VectorTag(AtomicTypeTag.U8)])); if (!$.veq($.copy(signer_public_key_hash), Account.get_authentication_key_($.copy(secondary_address), $c))) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), $c)); } i = ($.copy(i)).add(u64("1")); } }return; } export function prologue_common_ ( sender: HexString, txn_sequence_number: U64, txn_authentication_key: U8[], txn_gas_price: U64, txn_max_gas_units: U64, txn_expiration_time: U64, chain_id: U8, $c: AptosDataCache, ): void { let account_sequence_number, balance, max_transaction_fee, transaction_sender; if (!(Timestamp.now_seconds_($c)).lt($.copy(txn_expiration_time))) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_ETRANSACTION_EXPIRED), $c)); } if (!(Chain_id.get_($c)).eq(($.copy(chain_id)))) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_EBAD_CHAIN_ID), $c)); } transaction_sender = Signer.address_of_(sender, $c); if (!Account.exists_at_($.copy(transaction_sender), $c)) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_EACCOUNT_DOES_NOT_EXIST), $c)); } if (!$.veq($.copy(txn_authentication_key), Account.get_authentication_key_($.copy(transaction_sender), $c))) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), $c)); } if (!(u128($.copy(txn_sequence_number))).lt($.copy(MAX_U64))) { throw $.abortCode(Error.out_of_range_($.copy(PROLOGUE_ESEQUENCE_NUMBER_TOO_BIG), $c)); } account_sequence_number = Account.get_sequence_number_($.copy(transaction_sender), $c); if (!($.copy(txn_sequence_number)).ge($.copy(account_sequence_number))) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_ESEQUENCE_NUMBER_TOO_OLD), $c)); } if (!($.copy(txn_sequence_number)).eq(($.copy(account_sequence_number)))) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_ESEQUENCE_NUMBER_TOO_NEW), $c)); } max_transaction_fee = ($.copy(txn_gas_price)).mul($.copy(txn_max_gas_units)); if (!Coin.is_account_registered_($.copy(transaction_sender), $c, [new StructTag(new HexString("0x1"), "aptos_coin", "AptosCoin", [])])) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_ECANT_PAY_GAS_DEPOSIT), $c)); } balance = Coin.balance_($.copy(transaction_sender), $c, [new StructTag(new HexString("0x1"), "aptos_coin", "AptosCoin", [])]); if (!($.copy(balance)).ge($.copy(max_transaction_fee))) { throw $.abortCode(Error.invalid_argument_($.copy(PROLOGUE_ECANT_PAY_GAS_DEPOSIT), $c)); } return; } export function script_prologue_ ( sender: HexString, txn_sequence_number: U64, txn_public_key: U8[], txn_gas_price: U64, txn_max_gas_units: U64, txn_expiration_time: U64, chain_id: U8, _script_hash: U8[], $c: AptosDataCache, ): void { return prologue_common_(sender, $.copy(txn_sequence_number), $.copy(txn_public_key), $.copy(txn_gas_price), $.copy(txn_max_gas_units), $.copy(txn_expiration_time), $.copy(chain_id), $c); } export function loadParsers(repo: AptosParserRepo) { repo.addParser("0x1::transaction_validation::TransactionValidation", TransactionValidation.TransactionValidationParser); } export class App { constructor( public client: AptosClient, public repo: AptosParserRepo, public cache: AptosLocalCache, ) { } get moduleAddress() {{ return moduleAddress; }} get moduleName() {{ return moduleName; }} get TransactionValidation() { return TransactionValidation; } async loadTransactionValidation( owner: HexString, loadFull=true, fillCache=true, ) { const val = await TransactionValidation.load(this.repo, this.client, owner, [] as TypeTag[]); if (loadFull) { await val.loadFullState(this); } if (fillCache) { this.cache.set(val.typeTag, owner, val); } return val; } }