From 251fbef486feb82435d2c6c75c421008f6fce8e4 Mon Sep 17 00:00:00 2001 From: maayan Date: Mon, 2 Oct 2023 19:03:47 -0700 Subject: [PATCH 1/3] transaction types --- .../sdk_v2/src/transactions/types/moduleId.ts | 1 - .../src/transactions/types/rawTransaction.ts | 23 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ecosystem/typescript/sdk_v2/src/transactions/types/moduleId.ts b/ecosystem/typescript/sdk_v2/src/transactions/types/moduleId.ts index 2e049cf9464ee..62a4257d9966c 100644 --- a/ecosystem/typescript/sdk_v2/src/transactions/types/moduleId.ts +++ b/ecosystem/typescript/sdk_v2/src/transactions/types/moduleId.ts @@ -8,7 +8,6 @@ import { Identifier } from "./identifier"; */ export class ModuleId { public readonly address: AccountAddress; - public readonly name: Identifier; /** diff --git a/ecosystem/typescript/sdk_v2/src/transactions/types/rawTransaction.ts b/ecosystem/typescript/sdk_v2/src/transactions/types/rawTransaction.ts index 2a15f9a675a7c..bd0199363ecb8 100644 --- a/ecosystem/typescript/sdk_v2/src/transactions/types/rawTransaction.ts +++ b/ecosystem/typescript/sdk_v2/src/transactions/types/rawTransaction.ts @@ -101,12 +101,25 @@ export abstract class RawTransactionWithData { * Deserialize a Raw Transaction With Data */ static deserialize(deserializer: Deserializer): RawTransactionWithData { +<<<<<<< HEAD // undex enum variant const index = deserializer.deserializeUleb128AsU32(); switch (index) { case RustEnumTransactionVariants.MultiAgentTransaction: return MultiAgentRawTransaction.load(deserializer); case RustEnumTransactionVariants.FeePayerTransaction: +======= + const index = deserializer.deserializeUleb128AsU32(); + /** + * index is represented in rust as an enum + * {@link https://github.com/aptos-labs/aptos-core/blob/main/types/src/transaction/mod.rs#L440} + */ + + switch (index) { + case 0: + return MultiAgentRawTransaction.load(deserializer); + case 1: +>>>>>>> d3cd71d259 (transaction types) return FeePayerRawTransaction.load(deserializer); default: throw new Error(`Unknown variant index for RawTransactionWithData: ${index}`); @@ -135,7 +148,12 @@ export class MultiAgentRawTransaction extends RawTransactionWithData { } serialize(serializer: Serializer): void { +<<<<<<< HEAD serializer.serializeU32AsUleb128(RustEnumTransactionVariants.MultiAgentTransaction); +======= + // enum variant index + serializer.serializeU32AsUleb128(0); +>>>>>>> d3cd71d259 (transaction types) this.raw_txn.serialize(serializer); serializer.serializeVector(this.secondary_signer_addresses); } @@ -179,7 +197,12 @@ export class FeePayerRawTransaction extends RawTransactionWithData { } serialize(serializer: Serializer): void { +<<<<<<< HEAD serializer.serializeU32AsUleb128(RustEnumTransactionVariants.FeePayerTransaction); +======= + // enum variant index + serializer.serializeU32AsUleb128(1); +>>>>>>> d3cd71d259 (transaction types) this.raw_txn.serialize(serializer); serializer.serializeVector(this.secondary_signer_addresses); this.fee_payer_address.serialize(serializer); From 212891878458b6852e3e0aa2deb3f181544d3c6c Mon Sep 17 00:00:00 2001 From: maayan Date: Mon, 2 Oct 2023 21:55:40 -0700 Subject: [PATCH 2/3] address comments --- .../sdk_v2/src/transactions/types/moduleId.ts | 1 + .../src/transactions/types/rawTransaction.ts | 23 ------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/ecosystem/typescript/sdk_v2/src/transactions/types/moduleId.ts b/ecosystem/typescript/sdk_v2/src/transactions/types/moduleId.ts index 62a4257d9966c..2e049cf9464ee 100644 --- a/ecosystem/typescript/sdk_v2/src/transactions/types/moduleId.ts +++ b/ecosystem/typescript/sdk_v2/src/transactions/types/moduleId.ts @@ -8,6 +8,7 @@ import { Identifier } from "./identifier"; */ export class ModuleId { public readonly address: AccountAddress; + public readonly name: Identifier; /** diff --git a/ecosystem/typescript/sdk_v2/src/transactions/types/rawTransaction.ts b/ecosystem/typescript/sdk_v2/src/transactions/types/rawTransaction.ts index bd0199363ecb8..2a15f9a675a7c 100644 --- a/ecosystem/typescript/sdk_v2/src/transactions/types/rawTransaction.ts +++ b/ecosystem/typescript/sdk_v2/src/transactions/types/rawTransaction.ts @@ -101,25 +101,12 @@ export abstract class RawTransactionWithData { * Deserialize a Raw Transaction With Data */ static deserialize(deserializer: Deserializer): RawTransactionWithData { -<<<<<<< HEAD // undex enum variant const index = deserializer.deserializeUleb128AsU32(); switch (index) { case RustEnumTransactionVariants.MultiAgentTransaction: return MultiAgentRawTransaction.load(deserializer); case RustEnumTransactionVariants.FeePayerTransaction: -======= - const index = deserializer.deserializeUleb128AsU32(); - /** - * index is represented in rust as an enum - * {@link https://github.com/aptos-labs/aptos-core/blob/main/types/src/transaction/mod.rs#L440} - */ - - switch (index) { - case 0: - return MultiAgentRawTransaction.load(deserializer); - case 1: ->>>>>>> d3cd71d259 (transaction types) return FeePayerRawTransaction.load(deserializer); default: throw new Error(`Unknown variant index for RawTransactionWithData: ${index}`); @@ -148,12 +135,7 @@ export class MultiAgentRawTransaction extends RawTransactionWithData { } serialize(serializer: Serializer): void { -<<<<<<< HEAD serializer.serializeU32AsUleb128(RustEnumTransactionVariants.MultiAgentTransaction); -======= - // enum variant index - serializer.serializeU32AsUleb128(0); ->>>>>>> d3cd71d259 (transaction types) this.raw_txn.serialize(serializer); serializer.serializeVector(this.secondary_signer_addresses); } @@ -197,12 +179,7 @@ export class FeePayerRawTransaction extends RawTransactionWithData { } serialize(serializer: Serializer): void { -<<<<<<< HEAD serializer.serializeU32AsUleb128(RustEnumTransactionVariants.FeePayerTransaction); -======= - // enum variant index - serializer.serializeU32AsUleb128(1); ->>>>>>> d3cd71d259 (transaction types) this.raw_txn.serialize(serializer); serializer.serializeVector(this.secondary_signer_addresses); this.fee_payer_address.serialize(serializer); From 94077c91dbb19a42fe40a6143dcb020098cd9b14 Mon Sep 17 00:00:00 2001 From: maayan Date: Mon, 2 Oct 2023 23:09:17 -0700 Subject: [PATCH 3/3] authenticators --- .../typescript/sdk_v2/src/crypto/ed25519.ts | 2 +- .../src/transactions/authenticator/account.ts | 84 ++++++++ .../transactions/authenticator/transaction.ts | 183 ++++++++++++++++++ .../transactions/types/signedTransaction.ts | 38 ++++ .../typescript/sdk_v2/src/types/index.ts | 20 ++ 5 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 ecosystem/typescript/sdk_v2/src/transactions/authenticator/account.ts create mode 100644 ecosystem/typescript/sdk_v2/src/transactions/authenticator/transaction.ts create mode 100644 ecosystem/typescript/sdk_v2/src/transactions/types/signedTransaction.ts diff --git a/ecosystem/typescript/sdk_v2/src/crypto/ed25519.ts b/ecosystem/typescript/sdk_v2/src/crypto/ed25519.ts index 087aad930d194..4bc37eea5bdca 100644 --- a/ecosystem/typescript/sdk_v2/src/crypto/ed25519.ts +++ b/ecosystem/typescript/sdk_v2/src/crypto/ed25519.ts @@ -72,7 +72,7 @@ export class Ed25519PublicKey extends PublicKey { serializer.serializeBytes(this.key.toUint8Array()); } - static deserialize(deserializer: Deserializer): PublicKey { + static deserialize(deserializer: Deserializer): Ed25519PublicKey { const bytes = deserializer.deserializeBytes(); return new Ed25519PublicKey({ hexInput: bytes }); } diff --git a/ecosystem/typescript/sdk_v2/src/transactions/authenticator/account.ts b/ecosystem/typescript/sdk_v2/src/transactions/authenticator/account.ts new file mode 100644 index 0000000000000..c6ac8c6d27065 --- /dev/null +++ b/ecosystem/typescript/sdk_v2/src/transactions/authenticator/account.ts @@ -0,0 +1,84 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +import { Serializer, Deserializer, Serializable } from "../../bcs"; +import { Ed25519PublicKey, Ed25519Signature } from "../../crypto/ed25519"; +import { MultiEd25519PublicKey, MultiEd25519Signature } from "../../crypto/multi_ed25519"; +import { RustEnumAccountAuthenticatorVariant } from "../../types"; + +export abstract class AccountAuthenticator extends Serializable { + abstract serialize(serializer: Serializer): void; + + static deserialize(deserializer: Deserializer): AccountAuthenticator { + const index = deserializer.deserializeUleb128AsU32(); + switch (index) { + case RustEnumAccountAuthenticatorVariant.AccountAuthenticatorEd25519: + return AccountAuthenticatorEd25519.load(deserializer); + case RustEnumAccountAuthenticatorVariant.AccountAuthenticatorMultiEd25519: + return AccountAuthenticatorMultiEd25519.load(deserializer); + default: + throw new Error(`Unknown variant index for AccountAuthenticator: ${index}`); + } + } +} + +export class AccountAuthenticatorEd25519 extends AccountAuthenticator { + public readonly public_key: Ed25519PublicKey; + + public readonly signature: Ed25519Signature; + + constructor(public_key: Ed25519PublicKey, signature: Ed25519Signature) { + super(); + this.public_key = public_key; + this.signature = signature; + } + + /** + * Transaction authenticator Ed25519 for a multi signers transaction + * + * @param public_key Account's Ed25519 public key. + * @param signature Account's Ed25519 signature + * + */ + serialize(serializer: Serializer): void { + serializer.serializeU32AsUleb128(RustEnumAccountAuthenticatorVariant.AccountAuthenticatorEd25519); + this.public_key.serialize(serializer); + this.signature.serialize(serializer); + } + + static load(deserializer: Deserializer): AccountAuthenticatorEd25519 { + const public_key = Ed25519PublicKey.deserialize(deserializer); + const signature = Ed25519Signature.deserialize(deserializer); + return new AccountAuthenticatorEd25519(public_key, signature); + } +} + +export class AccountAuthenticatorMultiEd25519 extends AccountAuthenticator { + public readonly public_key: MultiEd25519PublicKey; + + public readonly signature: MultiEd25519Signature; + + /** + * Transaction authenticator Multi Ed25519 for a multi signers transaction + * + * @param public_key Account's MultiEd25519 public key. + * @param signature Account's MultiEd25519 signature + * + */ + constructor(public_key: MultiEd25519PublicKey, signature: MultiEd25519Signature) { + super(); + this.public_key = public_key; + this.signature = signature; + } + + serialize(serializer: Serializer): void { + serializer.serializeU32AsUleb128(RustEnumAccountAuthenticatorVariant.AccountAuthenticatorMultiEd25519); + this.public_key.serialize(serializer); + this.signature.serialize(serializer); + } + + static load(deserializer: Deserializer): AccountAuthenticatorMultiEd25519 { + const public_key = MultiEd25519PublicKey.deserialize(deserializer); + const signature = MultiEd25519Signature.deserialize(deserializer); + return new AccountAuthenticatorMultiEd25519(public_key, signature); + } +} diff --git a/ecosystem/typescript/sdk_v2/src/transactions/authenticator/transaction.ts b/ecosystem/typescript/sdk_v2/src/transactions/authenticator/transaction.ts new file mode 100644 index 0000000000000..d15eda877ffd5 --- /dev/null +++ b/ecosystem/typescript/sdk_v2/src/transactions/authenticator/transaction.ts @@ -0,0 +1,183 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +import { Deserializer, Serializer } from "../../bcs"; +import { AccountAddress } from "../../core"; +import { Ed25519PublicKey, Ed25519Signature } from "../../crypto/ed25519"; +import { MultiEd25519PublicKey, MultiEd25519Signature } from "../../crypto/multi_ed25519"; +import { RustEnumTransactionAuthenticatorVariant } from "../../types"; +import { AccountAuthenticator } from "./account"; + +export abstract class TransactionAuthenticator { + abstract serialize(serializer: Serializer): void; + + static deserialize(deserializer: Deserializer): TransactionAuthenticator { + const index = deserializer.deserializeUleb128AsU32(); + switch (index) { + case RustEnumTransactionAuthenticatorVariant.TransactionAuthenticatorEd25519: + return TransactionAuthenticatorEd25519.load(deserializer); + case RustEnumTransactionAuthenticatorVariant.TransactionAuthenticatorMultiEd25519: + return TransactionAuthenticatorMultiEd25519.load(deserializer); + case RustEnumTransactionAuthenticatorVariant.TransactionAuthenticatorMultiAgent: + return TransactionAuthenticatorMultiAgent.load(deserializer); + case RustEnumTransactionAuthenticatorVariant.TransactionAuthenticatorFeePayer: + return TransactionAuthenticatorFeePayer.load(deserializer); + default: + throw new Error(`Unknown variant index for TransactionAuthenticator: ${index}`); + } + } +} + +export class TransactionAuthenticatorEd25519 extends TransactionAuthenticator { + public readonly public_key: Ed25519PublicKey; + + public readonly signature: Ed25519Signature; + + /** + * Transaction authenticator Ed25519 for a single signer transaction + * + * @param public_key Client's public key. + * @param signature Ed25519 signature of a raw transaction. + * @see {@link https://aptos.dev/integration/creating-a-signed-transaction | Creating a Signed Transaction} + * for details about generating a signature. + */ + constructor(public_key: Ed25519PublicKey, signature: Ed25519Signature) { + super(); + this.public_key = public_key; + this.signature = signature; + } + + serialize(serializer: Serializer): void { + serializer.serializeU32AsUleb128(RustEnumTransactionAuthenticatorVariant.TransactionAuthenticatorEd25519); + this.public_key.serialize(serializer); + this.signature.serialize(serializer); + } + + static load(deserializer: Deserializer): TransactionAuthenticatorEd25519 { + const public_key = Ed25519PublicKey.deserialize(deserializer); + const signature = Ed25519Signature.deserialize(deserializer); + return new TransactionAuthenticatorEd25519(public_key, signature); + } +} + +export class TransactionAuthenticatorMultiEd25519 extends TransactionAuthenticator { + public readonly public_key: MultiEd25519PublicKey; + + public readonly signature: MultiEd25519Signature; + + /** + * Transaction authenticator Ed25519 for a multi signers transaction + * + * @param public_key Client's public key. + * @param signature Multi Ed25519 signature of a raw transaction. + * + */ + constructor(public_key: MultiEd25519PublicKey, signature: MultiEd25519Signature) { + super(); + this.public_key = public_key; + this.signature = signature; + } + + serialize(serializer: Serializer): void { + serializer.serializeU32AsUleb128(RustEnumTransactionAuthenticatorVariant.TransactionAuthenticatorMultiEd25519); + this.public_key.serialize(serializer); + this.signature.serialize(serializer); + } + + static load(deserializer: Deserializer): TransactionAuthenticatorMultiEd25519 { + const public_key = MultiEd25519PublicKey.deserialize(deserializer); + const signature = MultiEd25519Signature.deserialize(deserializer); + return new TransactionAuthenticatorMultiEd25519(public_key, signature); + } +} + +export class TransactionAuthenticatorMultiAgent extends TransactionAuthenticator { + public readonly sender: AccountAuthenticator; + + public readonly secondary_signer_addresses: Array; + + public readonly secondary_signers: Array; + + /** + * Transaction authenticator for a multi agent transaction + * + * @param sender Sender account authenticator + * @param secondary_signer_addresses Secondary signers address + * @param secondary_signers Secondary signers account authenticators + * + */ + constructor( + sender: AccountAuthenticator, + secondary_signer_addresses: Array, + secondary_signers: Array, + ) { + super(); + this.sender = sender; + this.secondary_signer_addresses = secondary_signer_addresses; + this.secondary_signers = secondary_signers; + } + + serialize(serializer: Serializer): void { + serializer.serializeU32AsUleb128(RustEnumTransactionAuthenticatorVariant.TransactionAuthenticatorMultiAgent); + this.sender.serialize(serializer); + serializer.serializeVector(this.secondary_signer_addresses); + serializer.serializeVector(this.secondary_signers); + } + + static load(deserializer: Deserializer): TransactionAuthenticatorMultiAgent { + const sender = AccountAuthenticator.deserialize(deserializer); + const secondary_signer_addresses = deserializer.deserializeVector(AccountAddress); + const secondary_signers = deserializer.deserializeVector(AccountAuthenticator); + return new TransactionAuthenticatorMultiAgent(sender, secondary_signer_addresses, secondary_signers); + } +} + +export class TransactionAuthenticatorFeePayer extends TransactionAuthenticator { + public readonly sender: AccountAuthenticator; + + public readonly secondary_signer_addresses: Array; + + public readonly secondary_signers: Array; + + public readonly fee_payer: { address: AccountAddress; authenticator: AccountAuthenticator }; + + /** + * Transaction authenticator for a fee payer transaction + * + * @param sender Sender account authenticator + * @param secondary_signer_addresses Secondary signers address + * @param secondary_signers Secondary signers account authenticators + * @param fee_payer Object of the fee payer account address and the fee payer authentication + * + */ + constructor( + sender: AccountAuthenticator, + secondary_signer_addresses: Array, + secondary_signers: Array, + fee_payer: { address: AccountAddress; authenticator: AccountAuthenticator }, + ) { + super(); + this.sender = sender; + this.secondary_signer_addresses = secondary_signer_addresses; + this.secondary_signers = secondary_signers; + this.fee_payer = fee_payer; + } + + serialize(serializer: Serializer): void { + serializer.serializeU32AsUleb128(RustEnumTransactionAuthenticatorVariant.TransactionAuthenticatorFeePayer); + this.sender.serialize(serializer); + serializer.serializeVector(this.secondary_signer_addresses); + serializer.serializeVector(this.secondary_signers); + this.fee_payer.address.serialize(serializer); + this.fee_payer.authenticator.serialize(serializer); + } + + static load(deserializer: Deserializer): TransactionAuthenticatorMultiAgent { + const sender = AccountAuthenticator.deserialize(deserializer); + const secondary_signer_addresses = deserializer.deserializeVector(AccountAddress); + const secondary_signers = deserializer.deserializeVector(AccountAuthenticator); + const address = AccountAddress.deserialize(deserializer); + const authenticator = AccountAuthenticator.deserialize(deserializer); + const fee_payer = { address, authenticator }; + return new TransactionAuthenticatorFeePayer(sender, secondary_signer_addresses, secondary_signers, fee_payer); + } +} diff --git a/ecosystem/typescript/sdk_v2/src/transactions/types/signedTransaction.ts b/ecosystem/typescript/sdk_v2/src/transactions/types/signedTransaction.ts new file mode 100644 index 0000000000000..99a71fe921613 --- /dev/null +++ b/ecosystem/typescript/sdk_v2/src/transactions/types/signedTransaction.ts @@ -0,0 +1,38 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +import { Serializer, Deserializer } from "../../bcs"; +import { TransactionAuthenticator } from "../authenticator/transaction"; +import { RawTransaction } from "./rawTransaction"; + +export class SignedTransaction { + public readonly raw_txn: RawTransaction; + + public readonly authenticator: TransactionAuthenticator; + + /** + * A SignedTransaction consists of a raw transaction and an authenticator. The authenticator + * contains a client's public key and the signature of the raw transaction. + * + * @see {@link https://aptos.dev/integration/creating-a-signed-transaction | Creating a Signed Transaction} + * + * @param raw_txn + * @param authenticator Contains a client's public key and the signature of the raw transaction. + * Authenticator has 3 flavors: single signature, multi-signature and multi-agent. + * @see {@link https://github.com/aptos-labs/aptos-core/blob/main/types/src/transaction/authenticator.rs} for details. + */ + constructor(raw_txn: RawTransaction, authenticator: TransactionAuthenticator) { + this.raw_txn = raw_txn; + this.authenticator = authenticator; + } + + serialize(serializer: Serializer): void { + this.raw_txn.serialize(serializer); + this.authenticator.serialize(serializer); + } + + static deserialize(deserializer: Deserializer): SignedTransaction { + const raw_txn = RawTransaction.deserialize(deserializer); + const authenticator = TransactionAuthenticator.deserialize(deserializer); + return new SignedTransaction(raw_txn, authenticator); + } +} diff --git a/ecosystem/typescript/sdk_v2/src/types/index.ts b/ecosystem/typescript/sdk_v2/src/types/index.ts index 04072781717be..f5e71249724f3 100644 --- a/ecosystem/typescript/sdk_v2/src/types/index.ts +++ b/ecosystem/typescript/sdk_v2/src/types/index.ts @@ -42,6 +42,26 @@ export enum RustEnumTransactionVariants { FeePayerTransaction = 1, } +/** + * Transaction Authenticator enum as they are represented in Rust + * {@link https://github.com/aptos-labs/aptos-core/blob/main/types/src/transaction/authenticator.rs#L44} + */ +export enum RustEnumTransactionAuthenticatorVariant { + TransactionAuthenticatorEd25519 = 0, + TransactionAuthenticatorMultiEd25519 = 1, + TransactionAuthenticatorMultiAgent = 2, + TransactionAuthenticatorFeePayer = 4, +} + +/** + * Transaction Authenticator enum as they are represented in Rust + * {@link https://github.com/aptos-labs/aptos-core/blob/main/types/src/transaction/authenticator.rs#L414} + */ +export enum RustEnumAccountAuthenticatorVariant { + AccountAuthenticatorEd25519 = 0, + AccountAuthenticatorMultiEd25519 = 1, +} + /** * BCS types */