Skip to content

Commit

Permalink
authenticators
Browse files Browse the repository at this point in the history
  • Loading branch information
0xmaayan committed Oct 3, 2023
1 parent 2128918 commit 94077c9
Show file tree
Hide file tree
Showing 5 changed files with 326 additions and 1 deletion.
2 changes: 1 addition & 1 deletion ecosystem/typescript/sdk_v2/src/crypto/ed25519.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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<AccountAddress>;

public readonly secondary_signers: Array<AccountAuthenticator>;

/**
* 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<AccountAddress>,
secondary_signers: Array<AccountAuthenticator>,
) {
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<AccountAddress>(this.secondary_signer_addresses);
serializer.serializeVector<AccountAuthenticator>(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<AccountAddress>;

public readonly secondary_signers: Array<AccountAuthenticator>;

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<AccountAddress>,
secondary_signers: Array<AccountAuthenticator>,
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<AccountAddress>(this.secondary_signer_addresses);
serializer.serializeVector<AccountAuthenticator>(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);
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
20 changes: 20 additions & 0 deletions ecosystem/typescript/sdk_v2/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down

0 comments on commit 94077c9

Please sign in to comment.