@aptos-labs/ts-sdk 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +144 -0
- package/dist/browser/index.global.js +410 -0
- package/dist/browser/index.global.js.map +1 -0
- package/dist/cjs/index.d.ts +4965 -0
- package/dist/cjs/index.js +4762 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.d.ts +4965 -0
- package/dist/esm/index.mjs +4645 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/types/index.d.ts +1247 -0
- package/dist/types/index.js +151 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +79 -0
- package/src/api/account.ts +360 -0
- package/src/api/aptos.ts +103 -0
- package/src/api/aptosConfig.ts +77 -0
- package/src/api/coin.ts +39 -0
- package/src/api/digitalAsset.ts +192 -0
- package/src/api/event.ts +78 -0
- package/src/api/faucet.ts +30 -0
- package/src/api/fungibleAsset.ts +82 -0
- package/src/api/general.ts +188 -0
- package/src/api/index.ts +5 -0
- package/src/api/staking.ts +58 -0
- package/src/api/transaction.ts +135 -0
- package/src/api/transactionSubmission.ts +168 -0
- package/src/bcs/consts.ts +12 -0
- package/src/bcs/deserializer.ts +248 -0
- package/src/bcs/index.ts +9 -0
- package/src/bcs/serializable/entryFunctionBytes.ts +61 -0
- package/src/bcs/serializable/fixedBytes.ts +65 -0
- package/src/bcs/serializable/movePrimitives.ts +211 -0
- package/src/bcs/serializable/moveStructs.ts +462 -0
- package/src/bcs/serializer.ts +353 -0
- package/src/client/core.ts +106 -0
- package/src/client/get.ts +109 -0
- package/src/client/index.ts +7 -0
- package/src/client/post.ts +90 -0
- package/src/client/types.ts +58 -0
- package/src/core/account.ts +180 -0
- package/src/core/accountAddress.ts +407 -0
- package/src/core/authenticationKey.ts +102 -0
- package/src/core/common.ts +40 -0
- package/src/core/crypto/asymmetricCrypto.ts +77 -0
- package/src/core/crypto/ed25519.ts +224 -0
- package/src/core/crypto/index.ts +7 -0
- package/src/core/crypto/multiEd25519.ts +251 -0
- package/src/core/crypto/secp256k1.ts +227 -0
- package/src/core/hex.ts +177 -0
- package/src/core/index.ts +9 -0
- package/src/index.ts +12 -0
- package/src/internal/account.ts +484 -0
- package/src/internal/coin.ts +32 -0
- package/src/internal/digitalAsset.ts +302 -0
- package/src/internal/event.ts +88 -0
- package/src/internal/faucet.ts +41 -0
- package/src/internal/fungibleAsset.ts +114 -0
- package/src/internal/general.ts +160 -0
- package/src/internal/queries/TokenActivitiesFieldsFragment.graphql +17 -0
- package/src/internal/queries/currentTokenOwnershipFieldsFragment.graphql +45 -0
- package/src/internal/queries/getAccountCoinCount.graphql +7 -0
- package/src/internal/queries/getAccountCoinsData.graphql +32 -0
- package/src/internal/queries/getAccountCollectionsWithOwnedTokens.graphql +33 -0
- package/src/internal/queries/getAccountOwnedObjects.graphql +16 -0
- package/src/internal/queries/getAccountOwnedTokens.graphql +11 -0
- package/src/internal/queries/getAccountOwnedTokensByTokenData.graphql +11 -0
- package/src/internal/queries/getAccountOwnedTokensFromCollectionAddress.graphql +11 -0
- package/src/internal/queries/getAccountTokensCount.graphql +7 -0
- package/src/internal/queries/getAccountTransactionsCount.graphql +7 -0
- package/src/internal/queries/getChainTopUserTransactions.graphql +5 -0
- package/src/internal/queries/getCollectionData.graphql +20 -0
- package/src/internal/queries/getCurrentFungibleAssetBalances.graphql +17 -0
- package/src/internal/queries/getDelegatedStakingActivities.graphql +12 -0
- package/src/internal/queries/getEvents.graphql +12 -0
- package/src/internal/queries/getFungibleAssetActivities.graphql +20 -0
- package/src/internal/queries/getFungibleAssetMetadata.graphql +16 -0
- package/src/internal/queries/getNumberOfDelegatorsQuery.graphql +9 -0
- package/src/internal/queries/getProcessorStatus.graphql +7 -0
- package/src/internal/queries/getTokenActivity.graphql +11 -0
- package/src/internal/queries/getTokenCurrentOwner.graphql +11 -0
- package/src/internal/queries/getTokenData.graphql +38 -0
- package/src/internal/staking.ts +68 -0
- package/src/internal/transaction.ts +245 -0
- package/src/internal/transactionSubmission.ts +162 -0
- package/src/transactions/authenticator/account.ts +121 -0
- package/src/transactions/authenticator/transaction.ts +222 -0
- package/src/transactions/instances/chainId.ts +26 -0
- package/src/transactions/instances/identifier.ts +28 -0
- package/src/transactions/instances/index.ts +9 -0
- package/src/transactions/instances/moduleId.ts +53 -0
- package/src/transactions/instances/rawTransaction.ts +199 -0
- package/src/transactions/instances/signedTransaction.ts +43 -0
- package/src/transactions/instances/transactionArgument.ts +37 -0
- package/src/transactions/instances/transactionPayload.ts +407 -0
- package/src/transactions/transaction_builder/transaction_builder.ts +541 -0
- package/src/transactions/typeTag/typeTag.ts +487 -0
- package/src/transactions/types.ts +262 -0
- package/src/types/codegen.yaml +33 -0
- package/src/types/generated/operations.ts +623 -0
- package/src/types/generated/queries.ts +737 -0
- package/src/types/generated/types.ts +10387 -0
- package/src/types/index.ts +944 -0
- package/src/types/indexer.ts +93 -0
- package/src/utils/apiEndpoints.ts +36 -0
- package/src/utils/const.ts +51 -0
- package/src/utils/hdKey.ts +113 -0
- package/src/utils/helpers.ts +12 -0
- package/src/utils/memoize.ts +68 -0
- package/src/version.ts +9 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { sha3_256 as sha3Hash } from "@noble/hashes/sha3";
|
|
5
|
+
import { AccountAddress } from "./accountAddress";
|
|
6
|
+
import { PublicKey } from "./crypto/asymmetricCrypto";
|
|
7
|
+
import { Ed25519PublicKey } from "./crypto/ed25519";
|
|
8
|
+
import { MultiEd25519PublicKey } from "./crypto/multiEd25519";
|
|
9
|
+
import { Secp256k1PublicKey } from "./crypto/secp256k1";
|
|
10
|
+
import { Hex } from "./hex";
|
|
11
|
+
import { AuthenticationKeyScheme, HexInput, SigningScheme } from "../types";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Each account stores an authentication key. Authentication key enables account owners to rotate
|
|
15
|
+
* their private key(s) associated with the account without changing the address that hosts their account.
|
|
16
|
+
* @see {@link https://aptos.dev/concepts/accounts | Account Basics}
|
|
17
|
+
*
|
|
18
|
+
* Note: AuthenticationKey only supports Ed25519 and MultiEd25519 public keys for now.
|
|
19
|
+
*
|
|
20
|
+
* Account addresses can be derived from AuthenticationKey
|
|
21
|
+
*/
|
|
22
|
+
export class AuthenticationKey {
|
|
23
|
+
/**
|
|
24
|
+
* An authentication key is always a SHA3-256 hash of data, and is always 32 bytes.
|
|
25
|
+
*/
|
|
26
|
+
static readonly LENGTH: number = 32;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The raw bytes of the authentication key.
|
|
30
|
+
*/
|
|
31
|
+
public readonly data: Hex;
|
|
32
|
+
|
|
33
|
+
constructor(args: { data: HexInput }) {
|
|
34
|
+
const { data } = args;
|
|
35
|
+
const hex = Hex.fromHexInput(data);
|
|
36
|
+
if (hex.toUint8Array().length !== AuthenticationKey.LENGTH) {
|
|
37
|
+
throw new Error(`Authentication Key length should be ${AuthenticationKey.LENGTH}`);
|
|
38
|
+
}
|
|
39
|
+
this.data = hex;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
toString(): string {
|
|
43
|
+
return this.data.toString();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
toUint8Array(): Uint8Array {
|
|
47
|
+
return this.data.toUint8Array();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Creates an AuthenticationKey from seed bytes and a scheme
|
|
52
|
+
*
|
|
53
|
+
* This allows for the creation of AuthenticationKeys that are not derived from Public Keys directly
|
|
54
|
+
* @param args
|
|
55
|
+
*/
|
|
56
|
+
private static fromBytesAndScheme(args: { bytes: HexInput; scheme: AuthenticationKeyScheme }) {
|
|
57
|
+
const { bytes, scheme } = args;
|
|
58
|
+
const inputBytes = Hex.fromHexInput(bytes).toUint8Array();
|
|
59
|
+
const authKeyBytes = new Uint8Array(inputBytes.length + 1);
|
|
60
|
+
authKeyBytes.set(inputBytes);
|
|
61
|
+
authKeyBytes.set([scheme], inputBytes.length);
|
|
62
|
+
|
|
63
|
+
const hash = sha3Hash.create();
|
|
64
|
+
hash.update(authKeyBytes);
|
|
65
|
+
|
|
66
|
+
return new AuthenticationKey({ data: hash.digest() });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Converts a PublicKey(s) to AuthenticationKey
|
|
71
|
+
*
|
|
72
|
+
* @param args.publicKey
|
|
73
|
+
* @returns AuthenticationKey
|
|
74
|
+
*/
|
|
75
|
+
static fromPublicKey(args: { publicKey: PublicKey }): AuthenticationKey {
|
|
76
|
+
const { publicKey } = args;
|
|
77
|
+
|
|
78
|
+
let scheme: number;
|
|
79
|
+
if (publicKey instanceof Ed25519PublicKey) {
|
|
80
|
+
scheme = SigningScheme.Ed25519.valueOf();
|
|
81
|
+
} else if (publicKey instanceof MultiEd25519PublicKey) {
|
|
82
|
+
scheme = SigningScheme.MultiEd25519.valueOf();
|
|
83
|
+
} else if (publicKey instanceof Secp256k1PublicKey) {
|
|
84
|
+
scheme = SigningScheme.Secp256k1Ecdsa.valueOf();
|
|
85
|
+
} else {
|
|
86
|
+
throw new Error("No supported authentication scheme for public key");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const pubKeyBytes = publicKey.toUint8Array();
|
|
90
|
+
return AuthenticationKey.fromBytesAndScheme({ bytes: pubKeyBytes, scheme });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Derives an account address from AuthenticationKey. Since current AccountAddress is 32 bytes,
|
|
95
|
+
* AuthenticationKey bytes are directly translated to AccountAddress.
|
|
96
|
+
*
|
|
97
|
+
* @returns AccountAddress
|
|
98
|
+
*/
|
|
99
|
+
derivedAddress(): AccountAddress {
|
|
100
|
+
return new AccountAddress({ data: this.data.toUint8Array() });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This error is used to explain why parsing failed.
|
|
6
|
+
*/
|
|
7
|
+
export class ParsingError<T> extends Error {
|
|
8
|
+
/**
|
|
9
|
+
* This provides a programmatic way to access why parsing failed. Downstream devs
|
|
10
|
+
* might want to use this to build their own error messages if the default error
|
|
11
|
+
* messages are not suitable for their use case. This should be an enum.
|
|
12
|
+
*/
|
|
13
|
+
public invalidReason: T;
|
|
14
|
+
|
|
15
|
+
constructor(message: string, invalidReason: T) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.invalidReason = invalidReason;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Whereas ParsingError is thrown when parsing fails, e.g. in a fromString function,
|
|
23
|
+
* this type is returned from "defensive" functions like isValid.
|
|
24
|
+
*/
|
|
25
|
+
export type ParsingResult<T> = {
|
|
26
|
+
/**
|
|
27
|
+
* True if valid, false otherwise.
|
|
28
|
+
*/
|
|
29
|
+
valid: boolean;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* If valid is false, this will be a code explaining why parsing failed.
|
|
33
|
+
*/
|
|
34
|
+
invalidReason?: T;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* If valid is false, this will be a string explaining why parsing failed.
|
|
38
|
+
*/
|
|
39
|
+
invalidReasonMessage?: string;
|
|
40
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { Serializable, Serializer } from "../../bcs";
|
|
5
|
+
import { HexInput } from "../../types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* An abstract representation of a public key. All Asymmetric key pairs will use this to
|
|
9
|
+
* verify signatures and for authentication keys.
|
|
10
|
+
*/
|
|
11
|
+
export abstract class PublicKey extends Serializable {
|
|
12
|
+
/**
|
|
13
|
+
* Verifies that the private key associated with this public key signed the message with the given signature.
|
|
14
|
+
* @param args.message The message that was signed
|
|
15
|
+
* @param args.signature The signature to verify
|
|
16
|
+
*/
|
|
17
|
+
abstract verifySignature(args: { message: HexInput; signature: Signature }): boolean;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get the raw public key bytes
|
|
21
|
+
*/
|
|
22
|
+
abstract toUint8Array(): Uint8Array;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get the public key as a hex string with a 0x prefix e.g. 0x123456...
|
|
26
|
+
*/
|
|
27
|
+
abstract toString(): string;
|
|
28
|
+
|
|
29
|
+
abstract serialize(serializer: Serializer): void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* An abstract representation of a private key. This is used to sign transactions and
|
|
34
|
+
* derive the public key associated.
|
|
35
|
+
*/
|
|
36
|
+
export abstract class PrivateKey extends Serializable {
|
|
37
|
+
/**
|
|
38
|
+
* Sign a message with the key
|
|
39
|
+
* @param message The message to sign
|
|
40
|
+
*/
|
|
41
|
+
abstract sign(message: HexInput): Signature;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get the raw private key bytes
|
|
45
|
+
*/
|
|
46
|
+
abstract toUint8Array(): Uint8Array;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get the private key as a hex string with a 0x prefix e.g. 0x123456...
|
|
50
|
+
*/
|
|
51
|
+
abstract toString(): string;
|
|
52
|
+
|
|
53
|
+
abstract serialize(serializer: Serializer): void;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Derives the public key associated with the private key
|
|
57
|
+
*/
|
|
58
|
+
abstract publicKey(): PublicKey;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* An abstract representation of a signature. This is the product of signing a
|
|
63
|
+
* message and can be used with the PublicKey to verify the signature.
|
|
64
|
+
*/
|
|
65
|
+
export abstract class Signature extends Serializable {
|
|
66
|
+
/**
|
|
67
|
+
* Get the raw signature bytes
|
|
68
|
+
*/
|
|
69
|
+
abstract toUint8Array(): Uint8Array;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get the signature as a hex string with a 0x prefix e.g. 0x123456...
|
|
73
|
+
*/
|
|
74
|
+
abstract toString(): string;
|
|
75
|
+
|
|
76
|
+
abstract serialize(serializer: Serializer): void;
|
|
77
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import nacl from "tweetnacl";
|
|
5
|
+
import { PublicKey, PrivateKey, Signature } from "./asymmetricCrypto";
|
|
6
|
+
import { Deserializer } from "../../bcs/deserializer";
|
|
7
|
+
import { Serializer } from "../../bcs/serializer";
|
|
8
|
+
import { Hex } from "../hex";
|
|
9
|
+
import { HexInput } from "../../types";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Represents the public key of an Ed25519 key pair.
|
|
13
|
+
*/
|
|
14
|
+
export class Ed25519PublicKey extends PublicKey {
|
|
15
|
+
/**
|
|
16
|
+
* Length of an Ed25519 public key
|
|
17
|
+
*/
|
|
18
|
+
static readonly LENGTH: number = 32;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Bytes of the public key
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
private readonly key: Hex;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create a new PublicKey instance from a Uint8Array or String.
|
|
28
|
+
*
|
|
29
|
+
* @param hexInput A HexInput (string or Uint8Array)
|
|
30
|
+
*/
|
|
31
|
+
constructor(hexInput: HexInput) {
|
|
32
|
+
super();
|
|
33
|
+
|
|
34
|
+
const hex = Hex.fromHexInput(hexInput);
|
|
35
|
+
if (hex.toUint8Array().length !== Ed25519PublicKey.LENGTH) {
|
|
36
|
+
throw new Error(`PublicKey length should be ${Ed25519PublicKey.LENGTH}`);
|
|
37
|
+
}
|
|
38
|
+
this.key = hex;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get the public key in bytes (Uint8Array).
|
|
43
|
+
*
|
|
44
|
+
* @returns Uint8Array representation of the public key
|
|
45
|
+
*/
|
|
46
|
+
toUint8Array(): Uint8Array {
|
|
47
|
+
return this.key.toUint8Array();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get the public key as a hex string with the 0x prefix.
|
|
52
|
+
*
|
|
53
|
+
* @returns string representation of the public key
|
|
54
|
+
*/
|
|
55
|
+
toString(): string {
|
|
56
|
+
return this.key.toString();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Verifies a signed data with a public key
|
|
61
|
+
* @param args.message a signed message
|
|
62
|
+
* @param args.signature the signature of the message
|
|
63
|
+
*/
|
|
64
|
+
verifySignature(args: { message: HexInput; signature: Ed25519Signature }): boolean {
|
|
65
|
+
const { message, signature } = args;
|
|
66
|
+
const rawMessage = Hex.fromHexInput(message).toUint8Array();
|
|
67
|
+
const rawSignature = Hex.fromHexInput(signature.toUint8Array()).toUint8Array();
|
|
68
|
+
return nacl.sign.detached.verify(rawMessage, rawSignature, this.key.toUint8Array());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
serialize(serializer: Serializer): void {
|
|
72
|
+
serializer.serializeBytes(this.key.toUint8Array());
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static deserialize(deserializer: Deserializer): Ed25519PublicKey {
|
|
76
|
+
const bytes = deserializer.deserializeBytes();
|
|
77
|
+
return new Ed25519PublicKey(bytes);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Represents the private key of an Ed25519 key pair.
|
|
83
|
+
*/
|
|
84
|
+
export class Ed25519PrivateKey extends PrivateKey {
|
|
85
|
+
/**
|
|
86
|
+
* Length of an Ed25519 private key
|
|
87
|
+
*/
|
|
88
|
+
static readonly LENGTH: number = 32;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The Ed25519 signing key
|
|
92
|
+
* @private
|
|
93
|
+
*/
|
|
94
|
+
private readonly signingKeyPair: nacl.SignKeyPair;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Create a new PrivateKey instance from a Uint8Array or String.
|
|
98
|
+
*
|
|
99
|
+
* @param hexInput HexInput (string or Uint8Array)
|
|
100
|
+
*/
|
|
101
|
+
constructor(hexInput: HexInput) {
|
|
102
|
+
super();
|
|
103
|
+
|
|
104
|
+
const privateKeyHex = Hex.fromHexInput(hexInput);
|
|
105
|
+
if (privateKeyHex.toUint8Array().length !== Ed25519PrivateKey.LENGTH) {
|
|
106
|
+
throw new Error(`PrivateKey length should be ${Ed25519PrivateKey.LENGTH}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Create keyPair from Private key in Uint8Array format
|
|
110
|
+
this.signingKeyPair = nacl.sign.keyPair.fromSeed(privateKeyHex.toUint8Array().slice(0, Ed25519PrivateKey.LENGTH));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get the private key in bytes (Uint8Array).
|
|
115
|
+
*
|
|
116
|
+
* @returns Uint8Array representation of the private key
|
|
117
|
+
*/
|
|
118
|
+
toUint8Array(): Uint8Array {
|
|
119
|
+
return this.signingKeyPair.secretKey.slice(0, Ed25519PrivateKey.LENGTH);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get the private key as a hex string with the 0x prefix.
|
|
124
|
+
*
|
|
125
|
+
* @returns string representation of the private key
|
|
126
|
+
*/
|
|
127
|
+
toString(): string {
|
|
128
|
+
return Hex.fromHexInput(this.toUint8Array()).toString();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Sign the given message with the private key.
|
|
133
|
+
*
|
|
134
|
+
* @param message in HexInput format
|
|
135
|
+
* @returns Signature
|
|
136
|
+
*/
|
|
137
|
+
sign(message: HexInput): Ed25519Signature {
|
|
138
|
+
const hex = Hex.fromHexInput(message);
|
|
139
|
+
const signature = nacl.sign.detached(hex.toUint8Array(), this.signingKeyPair.secretKey);
|
|
140
|
+
return new Ed25519Signature(signature);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
serialize(serializer: Serializer): void {
|
|
144
|
+
serializer.serializeBytes(this.toUint8Array());
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static deserialize(deserializer: Deserializer): Ed25519PrivateKey {
|
|
148
|
+
const bytes = deserializer.deserializeBytes();
|
|
149
|
+
return new Ed25519PrivateKey(bytes);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Generate a new random private key.
|
|
154
|
+
*
|
|
155
|
+
* @returns Ed25519PrivateKey
|
|
156
|
+
*/
|
|
157
|
+
static generate(): Ed25519PrivateKey {
|
|
158
|
+
const keyPair = nacl.sign.keyPair();
|
|
159
|
+
return new Ed25519PrivateKey(keyPair.secretKey.slice(0, Ed25519PrivateKey.LENGTH));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Derive the Ed25519PublicKey for this private key.
|
|
164
|
+
*
|
|
165
|
+
* @returns Ed25519PublicKey
|
|
166
|
+
*/
|
|
167
|
+
publicKey(): Ed25519PublicKey {
|
|
168
|
+
const bytes = this.signingKeyPair.publicKey;
|
|
169
|
+
return new Ed25519PublicKey(bytes);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* A signature of a message signed using an Ed25519 private key
|
|
175
|
+
*/
|
|
176
|
+
export class Ed25519Signature extends Signature {
|
|
177
|
+
/**
|
|
178
|
+
* Length of an Ed25519 signature
|
|
179
|
+
*/
|
|
180
|
+
static readonly LENGTH = 64;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The signature bytes
|
|
184
|
+
* @private
|
|
185
|
+
*/
|
|
186
|
+
private readonly data: Hex;
|
|
187
|
+
|
|
188
|
+
constructor(hexInput: HexInput) {
|
|
189
|
+
super();
|
|
190
|
+
const hex = Hex.fromHexInput(hexInput);
|
|
191
|
+
if (hex.toUint8Array().length !== Ed25519Signature.LENGTH) {
|
|
192
|
+
throw new Error(`Signature length should be ${Ed25519Signature.LENGTH}`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
this.data = hex;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Get the signature in bytes (Uint8Array).
|
|
200
|
+
*
|
|
201
|
+
* @returns Uint8Array representation of the signature
|
|
202
|
+
*/
|
|
203
|
+
toUint8Array(): Uint8Array {
|
|
204
|
+
return this.data.toUint8Array();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Get the signature as a hex string with the 0x prefix.
|
|
209
|
+
*
|
|
210
|
+
* @returns string representation of the signature
|
|
211
|
+
*/
|
|
212
|
+
toString(): string {
|
|
213
|
+
return this.data.toString();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
serialize(serializer: Serializer): void {
|
|
217
|
+
serializer.serializeBytes(this.data.toUint8Array());
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
static deserialize(deserializer: Deserializer): Ed25519Signature {
|
|
221
|
+
const bytes = deserializer.deserializeBytes();
|
|
222
|
+
return new Ed25519Signature(bytes);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { PublicKey, Signature } from "./asymmetricCrypto";
|
|
5
|
+
import { Deserializer } from "../../bcs/deserializer";
|
|
6
|
+
import { Serializer } from "../../bcs/serializer";
|
|
7
|
+
import { Ed25519PublicKey, Ed25519Signature } from "./ed25519";
|
|
8
|
+
import { Hex } from "../hex";
|
|
9
|
+
import { HexInput } from "../../types";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Represents the public key of a K-of-N Ed25519 multi-sig transaction.
|
|
13
|
+
*/
|
|
14
|
+
export class MultiEd25519PublicKey extends PublicKey {
|
|
15
|
+
/**
|
|
16
|
+
* Maximum number of public keys supported
|
|
17
|
+
*/
|
|
18
|
+
static readonly MAX_KEYS = 32;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Minimum number of public keys needed
|
|
22
|
+
*/
|
|
23
|
+
static readonly MIN_KEYS = 2;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Minimum threshold for the number of valid signatures required
|
|
27
|
+
*/
|
|
28
|
+
static readonly MIN_THRESHOLD = 1;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* List of Ed25519 public keys for this MultiEd25519PublicKey
|
|
32
|
+
*/
|
|
33
|
+
public readonly publicKeys: Ed25519PublicKey[];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The minimum number of valid signatures required, for the number of public keys specified
|
|
37
|
+
*/
|
|
38
|
+
public readonly threshold: number;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Public key for a K-of-N multi-sig transaction. A K-of-N multi-sig transaction means that for such a
|
|
42
|
+
* transaction to be executed, at least K out of the N authorized signers have signed the transaction
|
|
43
|
+
* and passed the check conducted by the chain.
|
|
44
|
+
*
|
|
45
|
+
* @see {@link
|
|
46
|
+
* https://aptos.dev/integration/creating-a-signed-transaction/ | Creating a Signed Transaction}
|
|
47
|
+
*
|
|
48
|
+
* @param args.publicKeys A list of public keys
|
|
49
|
+
* @param args.threshold At least "threshold" signatures must be valid
|
|
50
|
+
*/
|
|
51
|
+
constructor(args: { publicKeys: Ed25519PublicKey[]; threshold: number }) {
|
|
52
|
+
super();
|
|
53
|
+
|
|
54
|
+
const { publicKeys, threshold } = args;
|
|
55
|
+
|
|
56
|
+
// Validate number of public keys
|
|
57
|
+
if (publicKeys.length > MultiEd25519PublicKey.MAX_KEYS || publicKeys.length < MultiEd25519PublicKey.MIN_KEYS) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`Must have between ${MultiEd25519PublicKey.MIN_KEYS} and ${MultiEd25519PublicKey.MAX_KEYS} public keys, inclusive`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Validate threshold: must be between 1 and the number of public keys, inclusive
|
|
64
|
+
if (threshold < MultiEd25519PublicKey.MIN_THRESHOLD || threshold > publicKeys.length) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Threshold must be between ${MultiEd25519PublicKey.MIN_THRESHOLD} and ${publicKeys.length}, inclusive`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.publicKeys = publicKeys;
|
|
71
|
+
this.threshold = threshold;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Converts a PublicKeys into Uint8Array (bytes) with: bytes = p1_bytes | ... | pn_bytes | threshold
|
|
76
|
+
*/
|
|
77
|
+
toUint8Array(): Uint8Array {
|
|
78
|
+
const bytes = new Uint8Array(this.publicKeys.length * Ed25519PublicKey.LENGTH + 1);
|
|
79
|
+
this.publicKeys.forEach((k: Ed25519PublicKey, i: number) => {
|
|
80
|
+
bytes.set(k.toUint8Array(), i * Ed25519PublicKey.LENGTH);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
bytes[this.publicKeys.length * Ed25519PublicKey.LENGTH] = this.threshold;
|
|
84
|
+
|
|
85
|
+
return bytes;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
toString(): string {
|
|
89
|
+
return Hex.fromHexInput(this.toUint8Array()).toString();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars
|
|
93
|
+
verifySignature(args: { message: HexInput; signature: MultiEd25519Signature }): boolean {
|
|
94
|
+
throw new Error("TODO - Method not implemented.");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
serialize(serializer: Serializer): void {
|
|
98
|
+
serializer.serializeBytes(this.toUint8Array());
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static deserialize(deserializer: Deserializer): MultiEd25519PublicKey {
|
|
102
|
+
const bytes = deserializer.deserializeBytes();
|
|
103
|
+
const threshold = bytes[bytes.length - 1];
|
|
104
|
+
|
|
105
|
+
const keys: Ed25519PublicKey[] = [];
|
|
106
|
+
|
|
107
|
+
for (let i = 0; i < bytes.length - 1; i += Ed25519PublicKey.LENGTH) {
|
|
108
|
+
const begin = i;
|
|
109
|
+
keys.push(new Ed25519PublicKey(bytes.subarray(begin, begin + Ed25519PublicKey.LENGTH)));
|
|
110
|
+
}
|
|
111
|
+
return new MultiEd25519PublicKey({ publicKeys: keys, threshold });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Represents the signature of a K-of-N Ed25519 multi-sig transaction.
|
|
117
|
+
*/
|
|
118
|
+
export class MultiEd25519Signature extends Signature {
|
|
119
|
+
/**
|
|
120
|
+
* Maximum number of Ed25519 signatures supported
|
|
121
|
+
*/
|
|
122
|
+
static MAX_SIGNATURES_SUPPORTED = 32;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Number of bytes in the bitmap representing who signed the transaction (32-bits)
|
|
126
|
+
*/
|
|
127
|
+
static BITMAP_LEN: number = 4;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The list of underlying Ed25519 signatures
|
|
131
|
+
*/
|
|
132
|
+
public readonly signatures: Ed25519Signature[];
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 32-bit Bitmap representing who signed the transaction
|
|
136
|
+
*
|
|
137
|
+
* This is represented where each public key can be masked to determine whether the message was signed by that key.
|
|
138
|
+
*/
|
|
139
|
+
public readonly bitmap: Uint8Array;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Signature for a K-of-N multi-sig transaction.
|
|
143
|
+
*
|
|
144
|
+
* @see {@link
|
|
145
|
+
* https://aptos.dev/integration/creating-a-signed-transaction/#multisignature-transactions | Creating a Signed Transaction}
|
|
146
|
+
*
|
|
147
|
+
* @param args.signatures A list of signatures
|
|
148
|
+
* @param args.bitmap 4 bytes, at most 32 signatures are supported. If Nth bit value is `1`, the Nth
|
|
149
|
+
* signature should be provided in `signatures`. Bits are read from left to right
|
|
150
|
+
*/
|
|
151
|
+
constructor(args: { signatures: Ed25519Signature[]; bitmap: Uint8Array }) {
|
|
152
|
+
super();
|
|
153
|
+
|
|
154
|
+
const { signatures, bitmap } = args;
|
|
155
|
+
if (bitmap.length !== MultiEd25519Signature.BITMAP_LEN) {
|
|
156
|
+
throw new Error(`"bitmap" length should be ${MultiEd25519Signature.BITMAP_LEN}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (signatures.length > MultiEd25519Signature.MAX_SIGNATURES_SUPPORTED) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`The number of signatures cannot be greater than ${MultiEd25519Signature.MAX_SIGNATURES_SUPPORTED}`,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
this.signatures = signatures;
|
|
166
|
+
this.bitmap = bitmap;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Converts a MultiSignature into Uint8Array (bytes) with `bytes = s1_bytes | ... | sn_bytes | bitmap`
|
|
171
|
+
*/
|
|
172
|
+
toUint8Array(): Uint8Array {
|
|
173
|
+
const bytes = new Uint8Array(this.signatures.length * Ed25519Signature.LENGTH + MultiEd25519Signature.BITMAP_LEN);
|
|
174
|
+
this.signatures.forEach((k: Ed25519Signature, i: number) => {
|
|
175
|
+
bytes.set(k.toUint8Array(), i * Ed25519Signature.LENGTH);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
bytes.set(this.bitmap, this.signatures.length * Ed25519Signature.LENGTH);
|
|
179
|
+
|
|
180
|
+
return bytes;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
toString(): string {
|
|
184
|
+
return Hex.fromHexInput(this.toUint8Array()).toString();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Helper method to create a bitmap out of the specified bit positions
|
|
189
|
+
* @param args.bits The bitmap positions that should be set. A position starts at index 0.
|
|
190
|
+
* Valid position should range between 0 and 31.
|
|
191
|
+
* @example
|
|
192
|
+
* Here's an example of valid `bits`
|
|
193
|
+
* ```
|
|
194
|
+
* [0, 2, 31]
|
|
195
|
+
* ```
|
|
196
|
+
* `[0, 2, 31]` means the 1st, 3rd and 32nd bits should be set in the bitmap.
|
|
197
|
+
* The result bitmap should be 0b1010000000000000000000000000001
|
|
198
|
+
*
|
|
199
|
+
* @returns bitmap that is 32bit long
|
|
200
|
+
*/
|
|
201
|
+
static createBitmap(args: { bits: number[] }): Uint8Array {
|
|
202
|
+
const { bits } = args;
|
|
203
|
+
// Bits are read from left to right. e.g. 0b10000000 represents the first bit is set in one byte.
|
|
204
|
+
// The decimal value of 0b10000000 is 128.
|
|
205
|
+
const firstBitInByte = 128;
|
|
206
|
+
const bitmap = new Uint8Array([0, 0, 0, 0]);
|
|
207
|
+
|
|
208
|
+
// Check if duplicates exist in bits
|
|
209
|
+
const dupCheckSet = new Set();
|
|
210
|
+
|
|
211
|
+
bits.forEach((bit: number) => {
|
|
212
|
+
if (bit >= MultiEd25519Signature.MAX_SIGNATURES_SUPPORTED) {
|
|
213
|
+
throw new Error(`Cannot have a signature larger than ${MultiEd25519Signature.MAX_SIGNATURES_SUPPORTED - 1}.`);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (dupCheckSet.has(bit)) {
|
|
217
|
+
throw new Error("Duplicate bits detected.");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
dupCheckSet.add(bit);
|
|
221
|
+
|
|
222
|
+
const byteOffset = Math.floor(bit / 8);
|
|
223
|
+
|
|
224
|
+
let byte = bitmap[byteOffset];
|
|
225
|
+
|
|
226
|
+
// eslint-disable-next-line no-bitwise
|
|
227
|
+
byte |= firstBitInByte >> bit % 8;
|
|
228
|
+
|
|
229
|
+
bitmap[byteOffset] = byte;
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
return bitmap;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
serialize(serializer: Serializer): void {
|
|
236
|
+
serializer.serializeBytes(this.toUint8Array());
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
static deserialize(deserializer: Deserializer): MultiEd25519Signature {
|
|
240
|
+
const bytes = deserializer.deserializeBytes();
|
|
241
|
+
const bitmap = bytes.subarray(bytes.length - 4);
|
|
242
|
+
|
|
243
|
+
const signatures: Ed25519Signature[] = [];
|
|
244
|
+
|
|
245
|
+
for (let i = 0; i < bytes.length - bitmap.length; i += Ed25519Signature.LENGTH) {
|
|
246
|
+
const begin = i;
|
|
247
|
+
signatures.push(new Ed25519Signature(bytes.subarray(begin, begin + Ed25519Signature.LENGTH)));
|
|
248
|
+
}
|
|
249
|
+
return new MultiEd25519Signature({ signatures, bitmap });
|
|
250
|
+
}
|
|
251
|
+
}
|