Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permissioned account demo #511

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@
"update-version": "scripts/updateVersion.sh && pnpm doc"
},
"dependencies": {
"@aptos-labs/aptos-client": "^0.1.0",
"@aptos-labs/aptos-cli": "^0.1.9",
"@aptos-labs/aptos-client": "^0.1.0",
"@aptos-labs/ts-sdk": "^1.27.1",
"@noble/curves": "^1.4.0",
"@noble/hashes": "^1.4.0",
"@scure/bip32": "^1.4.0",
"@scure/bip39": "^1.3.0",
"@wgb5445/aptos-intent-npm": "^0.0.12",
"eventemitter3": "^5.0.1",
"form-data": "^4.0.0",
"js-base64": "^3.7.7",
Expand Down
54 changes: 54 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

127 changes: 127 additions & 0 deletions src/account/AbstractedAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { AccountAuthenticatorEd25519, AccountAuthenticatorAbstraction } from "../transactions/authenticator/account";
import { HexInput, SigningScheme } from "../types";
import { AccountAddress, AccountAddressInput } from "../core/accountAddress";
import { Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature } from "../core/crypto";
import type { Account } from "./Account";
import { AnyRawTransaction } from "../transactions/types";
import { generateSigningMessageForTransaction } from "../transactions/transactionBuilder/signingMessage";
import { FunctionInfo } from "../internal/function_info";

export interface Ed25519SignerConstructorArgs {
privateKey: Ed25519PrivateKey;
address?: AccountAddressInput;
}

export interface Ed25519SignerFromDerivationPathArgs {
path: string;
mnemonic: string;
}

export interface VerifyEd25519SignatureArgs {
message: HexInput;
signature: Ed25519Signature;
}

/**
* Signer implementation for the Ed25519 authentication scheme.
* This extends an {@link Ed25519Account} by adding signing capabilities through an {@link Ed25519PrivateKey}.
*
* Note: Generating a signer instance does not create the account on-chain.
*/
export class AbstractedEd25519Account implements Account {
/**
* Private key associated with the account
*/
readonly privateKey: Ed25519PrivateKey;

readonly publicKey: Ed25519PublicKey;

readonly accountAddress: AccountAddress;

readonly signingScheme = SigningScheme.Abstraction;

// region Constructors

constructor(args: Ed25519SignerConstructorArgs) {
const { privateKey, address } = args;
this.privateKey = privateKey;
this.publicKey = privateKey.publicKey();
this.accountAddress = address ? AccountAddress.from(address) : this.publicKey.authKey().derivedAddress();
}

/**
* Derives a signer from a randomly generated private key
*/
static generate() {
const privateKey = Ed25519PrivateKey.generate();
return new AbstractedEd25519Account({ privateKey });
}

/**
* Derives an account with bip44 path and mnemonics
*
* @param args.path the BIP44 derive hardened path e.g. m/44'/637'/0'/0'/0'
* Detailed description: {@link https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki}
* @param args.mnemonic the mnemonic seed phrase of the account
*/
static fromDerivationPath(args: Ed25519SignerFromDerivationPathArgs) {
const { path, mnemonic } = args;
const privateKey = Ed25519PrivateKey.fromDerivationPath(path, mnemonic);
return new AbstractedEd25519Account({ privateKey });
}

// endregion

// region Account

/**
* Verify the given message and signature with the public key.
*
* @param args.message raw message data in HexInput format
* @param args.signature signed message Signature
* @returns
*/
verifySignature(args: VerifyEd25519SignatureArgs): boolean {
return this.publicKey.verifySignature(args);
}

/**
* Sign a message using the account's Ed25519 private key.
* @param message the signing message, as binary input
* @return the AccountAuthenticator containing the signature, together with the account's public key
*/
signWithAuthenticator(message: HexInput): AccountAuthenticatorAbstraction {
return new AccountAuthenticatorAbstraction(this.publicKey, new FunctionInfo(AccountAddress.ONE, "permissioned_delegation", "authenticate"), this.privateKey.sign(message));
}

/**
* Sign a transaction using the account's Ed25519 private key.
* @param transaction the raw transaction
* @return the AccountAuthenticator containing the signature of the transaction, together with the account's public key
*/
signTransactionWithAuthenticator(transaction: AnyRawTransaction): AccountAuthenticatorAbstraction {
return new AccountAuthenticatorAbstraction(this.publicKey, new FunctionInfo(AccountAddress.ONE, "permissioned_delegation", "authenticate"), this.signTransaction(transaction));
}

/**
* Sign the given message using the account's Ed25519 private key.
* @param message in HexInput format
* @returns Signature
*/
sign(message: HexInput): Ed25519Signature {
return this.privateKey.sign(message);
}

/**
* Sign the given transaction using the available signing capabilities.
* @param transaction the transaction to be signed
* @returns Signature
*/
signTransaction(transaction: AnyRawTransaction): Ed25519Signature {
const r = this.sign(new Uint8Array([1, 2, 3]));
console.log(r);
return r;
}

// endregion
}
29 changes: 28 additions & 1 deletion src/api/transactionSubmission/build.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0

import { get_wasm, initSync } from "@wgb5445/aptos-intent-npm";
import { AccountAddressInput } from "../../core";
import { generateTransaction } from "../../internal/transactionSubmission";
import { InputGenerateTransactionPayloadData, InputGenerateTransactionOptions } from "../../transactions";
import {
InputGenerateTransactionPayloadData,
InputGenerateTransactionOptions,
AptosIntentBuilder,
TransactionPayloadScript,
generateRawTransaction,
} from "../../transactions";
import { MultiAgentTransaction } from "../../transactions/instances/multiAgentTransaction";
import { SimpleTransaction } from "../../transactions/instances/simpleTransaction";
import { AptosConfig } from "../aptosConfig";
import { singleSignerED25519 } from "../../../tests/unit/helper";
import { Deserializer } from "../../bcs";

/**
* A class to handle all `Build` transaction operations
Expand Down Expand Up @@ -37,6 +46,24 @@ export class Build {
return generateTransaction({ aptosConfig: this.config, ...args });
}

async batched_intents(args: {
sender: AccountAddressInput;
builder: (builder: AptosIntentBuilder) => Promise<AptosIntentBuilder>;
options?: InputGenerateTransactionOptions;
withFeePayer?: boolean;
}): Promise<SimpleTransaction> {
initSync(await get_wasm());
let builder = new AptosIntentBuilder(this.config);
builder = await args.builder(builder);
const bytes = builder.build();
let raw_txn = await generateRawTransaction({
aptosConfig: this.config,
payload: TransactionPayloadScript.load(new Deserializer(bytes)),
...args,
});
return new SimpleTransaction(raw_txn);
}

/**
* Build a multi agent transaction
*
Expand Down
30 changes: 29 additions & 1 deletion src/bcs/serializable/movePrimitives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
import { Deserializer } from "../deserializer";
import { Serializable, Serializer, ensureBoolean, validateNumberInRange } from "../serializer";
import { TransactionArgument } from "../../transactions/instances/transactionArgument";
import { AnyNumber, Uint16, Uint32, Uint8, ScriptTransactionArgumentVariants } from "../../types";
import { AnyNumber, Uint16, Uint32, Uint8, ScriptTransactionArgumentVariants ,HexInput } from "../../types";
import { Hex } from "../../core";

export class Bool extends Serializable implements TransactionArgument {
public readonly value: boolean;
Expand Down Expand Up @@ -209,3 +210,30 @@ export class U256 extends Serializable implements TransactionArgument {
return new U256(deserializer.deserializeU256());
}
}

export class Raw extends Serializable implements TransactionArgument {
public readonly value: Uint8Array;

constructor(value: HexInput) {
super();
this.value = Hex.fromHexInput(value).toUint8Array();
}

serialize(serializer: Serializer): void {
serializer.serializeBytes(this.value);
}

serializeForEntryFunction(serializer: Serializer): void {
const bcsBytes = this.bcsToBytes();
serializer.serializeBytes(bcsBytes);
}

serializeForScriptFunction(serializer: Serializer): void {
serializer.serializeU32AsUleb128(ScriptTransactionArgumentVariants.Raw);
serializer.serialize(this);
}

static deserialize(deserializer: Deserializer): Raw {
return new Raw(deserializer.deserializeBytes());
}
}
4 changes: 2 additions & 2 deletions src/cli/localNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export class LocalNode {
* Starts the local testnet by running the aptos node run-local-testnet command
*/
start() {
const cliCommand = "npx";
const cliArgs = ["aptos", "node", "run-local-testnet", "--force-restart", "--assume-yes", "--with-indexer-api"];
const cliCommand = "aptos";
const cliArgs = ["node", "run-local-testnet", "--force-restart", "--assume-yes", "--with-indexer-api"];

const currentPlatform = platform();
let childProcess;
Expand Down
26 changes: 26 additions & 0 deletions src/internal/function_info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Deserializer, Serializable, Serializer } from "../bcs";
import { AccountAddress, Hex } from "../core";

export class FunctionInfo extends Serializable {
readonly module_address: AccountAddress;
readonly module_name: string;
readonly function_name: string;
constructor(module_address: AccountAddress, module_name: string, function_name: string) {
super();
this.module_address = module_address;
this.module_name = module_name;
this.function_name = function_name;
}

serialize(serializer: Serializer): void {
this.module_address.serialize(serializer);
serializer.serializeStr(this.module_name);
serializer.serializeStr(this.function_name);
}
static deserialize(deserializer: Deserializer): FunctionInfo {
const module_address = AccountAddress.deserialize(deserializer);
const module_name = deserializer.deserializeStr();
const function_name = deserializer.deserializeStr();
return new FunctionInfo(module_address, module_name, function_name);
}
}
Loading
Loading