@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,58 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { AptosRequest } from "../types";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The API response type
|
|
8
|
+
*
|
|
9
|
+
* @param status - the response status. i.e. 200
|
|
10
|
+
* @param statusText - the response message
|
|
11
|
+
* @param data the response data
|
|
12
|
+
* @param url the url the request was made to
|
|
13
|
+
* @param headers the response headers
|
|
14
|
+
* @param config (optional) - the request object
|
|
15
|
+
* @param request (optional) - the request object
|
|
16
|
+
*/
|
|
17
|
+
export interface AptosResponse<Req, Res> {
|
|
18
|
+
status: number;
|
|
19
|
+
statusText: string;
|
|
20
|
+
data: Res;
|
|
21
|
+
url: string;
|
|
22
|
+
headers: any;
|
|
23
|
+
config?: any;
|
|
24
|
+
request?: Req;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The type returned from an API error
|
|
29
|
+
*
|
|
30
|
+
* @param name - the error name "AptosApiError"
|
|
31
|
+
* @param url the url the request was made to
|
|
32
|
+
* @param status - the response status. i.e. 400
|
|
33
|
+
* @param statusText - the response message
|
|
34
|
+
* @param data the response data
|
|
35
|
+
* @param request - the AptosRequest
|
|
36
|
+
*/
|
|
37
|
+
export class AptosApiError extends Error {
|
|
38
|
+
readonly url: string;
|
|
39
|
+
|
|
40
|
+
readonly status: number;
|
|
41
|
+
|
|
42
|
+
readonly statusText: string;
|
|
43
|
+
|
|
44
|
+
readonly data: any;
|
|
45
|
+
|
|
46
|
+
readonly request: AptosRequest;
|
|
47
|
+
|
|
48
|
+
constructor(request: AptosRequest, response: AptosResponse<any, any>, message: string) {
|
|
49
|
+
super(message);
|
|
50
|
+
|
|
51
|
+
this.name = "AptosApiError";
|
|
52
|
+
this.url = response.url;
|
|
53
|
+
this.status = response.status;
|
|
54
|
+
this.statusText = response.statusText;
|
|
55
|
+
this.data = response.data;
|
|
56
|
+
this.request = request;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { AccountAddress } from "./accountAddress";
|
|
5
|
+
import { AuthenticationKey } from "./authenticationKey";
|
|
6
|
+
import { PrivateKey, PublicKey, Signature } from "./crypto/asymmetricCrypto";
|
|
7
|
+
import { Ed25519PrivateKey, Ed25519PublicKey } from "./crypto/ed25519";
|
|
8
|
+
import { MultiEd25519PublicKey } from "./crypto/multiEd25519";
|
|
9
|
+
import { Secp256k1PrivateKey, Secp256k1PublicKey } from "./crypto/secp256k1";
|
|
10
|
+
import { Hex } from "./hex";
|
|
11
|
+
import { HexInput, SigningScheme } from "../types";
|
|
12
|
+
import { derivePrivateKeyFromMnemonic, KeyType } from "../utils/hdKey";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Class for creating and managing account on Aptos network
|
|
16
|
+
*
|
|
17
|
+
* Use this class to create accounts, sign transactions, and more.
|
|
18
|
+
* Note: Creating an account instance does not create the account on-chain.
|
|
19
|
+
*/
|
|
20
|
+
export class Account {
|
|
21
|
+
/**
|
|
22
|
+
* Public key associated with the account
|
|
23
|
+
*/
|
|
24
|
+
readonly publicKey: PublicKey;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Private key associated with the account
|
|
28
|
+
*/
|
|
29
|
+
readonly privateKey: PrivateKey;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Account address associated with the account
|
|
33
|
+
*/
|
|
34
|
+
readonly accountAddress: AccountAddress;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Signing scheme used to sign transactions
|
|
38
|
+
*/
|
|
39
|
+
readonly signingScheme: SigningScheme;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* constructor for Account
|
|
43
|
+
*
|
|
44
|
+
* Need to update this to use the new crypto library if new schemes are added.
|
|
45
|
+
*
|
|
46
|
+
* @param args.privateKey PrivateKey - private key of the account
|
|
47
|
+
* @param args.address AccountAddress - address of the account
|
|
48
|
+
*
|
|
49
|
+
* This method is private because it should only be called by the factory static methods.
|
|
50
|
+
* @returns Account
|
|
51
|
+
*/
|
|
52
|
+
private constructor(args: { privateKey: PrivateKey; address: AccountAddress }) {
|
|
53
|
+
const { privateKey, address } = args;
|
|
54
|
+
|
|
55
|
+
// Derive the public key from the private key
|
|
56
|
+
this.publicKey = privateKey.publicKey();
|
|
57
|
+
|
|
58
|
+
// Derive the signing scheme from the public key
|
|
59
|
+
if (this.publicKey instanceof Ed25519PublicKey) {
|
|
60
|
+
this.signingScheme = SigningScheme.Ed25519;
|
|
61
|
+
} else if (this.publicKey instanceof MultiEd25519PublicKey) {
|
|
62
|
+
this.signingScheme = SigningScheme.MultiEd25519;
|
|
63
|
+
} else if (this.publicKey instanceof Secp256k1PublicKey) {
|
|
64
|
+
this.signingScheme = SigningScheme.Secp256k1Ecdsa;
|
|
65
|
+
} else {
|
|
66
|
+
throw new Error("Can not create new Account, unsupported public key type");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
this.privateKey = privateKey;
|
|
70
|
+
this.accountAddress = address;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Derives an account with random private key and address
|
|
75
|
+
*
|
|
76
|
+
* @param scheme optional SigningScheme - type of SigningScheme to use. Default to Ed25519
|
|
77
|
+
* Currently only Ed25519 and Secp256k1 are supported
|
|
78
|
+
*
|
|
79
|
+
* @returns Account with the given signing scheme
|
|
80
|
+
*/
|
|
81
|
+
static generate(scheme?: SigningScheme): Account {
|
|
82
|
+
let privateKey: PrivateKey;
|
|
83
|
+
|
|
84
|
+
switch (scheme) {
|
|
85
|
+
case SigningScheme.Secp256k1Ecdsa:
|
|
86
|
+
privateKey = Secp256k1PrivateKey.generate();
|
|
87
|
+
break;
|
|
88
|
+
// TODO: Add support for MultiEd25519
|
|
89
|
+
default:
|
|
90
|
+
privateKey = Ed25519PrivateKey.generate();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const address = new AccountAddress({
|
|
94
|
+
data: Account.authKey({
|
|
95
|
+
publicKey: privateKey.publicKey(),
|
|
96
|
+
}).toUint8Array(),
|
|
97
|
+
});
|
|
98
|
+
return new Account({ privateKey, address });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Derives an account with provided private key
|
|
103
|
+
*
|
|
104
|
+
* @param privateKey Hex - private key of the account
|
|
105
|
+
* @returns Account
|
|
106
|
+
*/
|
|
107
|
+
static fromPrivateKey(privateKey: PrivateKey): Account {
|
|
108
|
+
const publicKey = privateKey.publicKey();
|
|
109
|
+
const authKey = Account.authKey({ publicKey });
|
|
110
|
+
const address = new AccountAddress({ data: authKey.toUint8Array() });
|
|
111
|
+
return Account.fromPrivateKeyAndAddress({ privateKey, address });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Derives an account with provided private key and address
|
|
116
|
+
* This is intended to be used for account that has it's key rotated
|
|
117
|
+
*
|
|
118
|
+
* @param args.privateKey Hex - private key of the account
|
|
119
|
+
* @param args.address AccountAddress - address of the account
|
|
120
|
+
* @returns Account
|
|
121
|
+
*/
|
|
122
|
+
static fromPrivateKeyAndAddress(args: { privateKey: PrivateKey; address: AccountAddress }): Account {
|
|
123
|
+
return new Account(args);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Derives an account with bip44 path and mnemonics,
|
|
128
|
+
*
|
|
129
|
+
* @param args.path the BIP44 derive path (e.g. m/44'/637'/0'/0'/0')
|
|
130
|
+
* Detailed description: {@link https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki}
|
|
131
|
+
* @param args.mnemonic the mnemonic seed phrase of the account
|
|
132
|
+
* @returns AptosAccount
|
|
133
|
+
*/
|
|
134
|
+
static fromDerivationPath(args: { path: string; mnemonic: string }): Account {
|
|
135
|
+
const { path, mnemonic } = args;
|
|
136
|
+
|
|
137
|
+
const { key } = derivePrivateKeyFromMnemonic(KeyType.ED25519, path, mnemonic);
|
|
138
|
+
const privateKey = new Ed25519PrivateKey(key);
|
|
139
|
+
return Account.fromPrivateKey(privateKey);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* This key enables account owners to rotate their private key(s)
|
|
144
|
+
* associated with the account without changing the address that hosts their account.
|
|
145
|
+
* See here for more info: {@link https://aptos.dev/concepts/accounts#single-signer-authentication}
|
|
146
|
+
*
|
|
147
|
+
* @param args.publicKey PublicKey - public key of the account
|
|
148
|
+
* @returns Authentication key for the associated account
|
|
149
|
+
*/
|
|
150
|
+
static authKey(args: { publicKey: PublicKey }): Hex {
|
|
151
|
+
const { publicKey } = args;
|
|
152
|
+
const authKey = AuthenticationKey.fromPublicKey({ publicKey });
|
|
153
|
+
return authKey.data;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Sign the given message with the private key.
|
|
158
|
+
*
|
|
159
|
+
* TODO: Add sign transaction or specific types
|
|
160
|
+
*
|
|
161
|
+
* @param data in HexInput format
|
|
162
|
+
* @returns Signature
|
|
163
|
+
*/
|
|
164
|
+
sign(data: HexInput): Signature {
|
|
165
|
+
return this.privateKey.sign(data);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Verify the given message and signature with the public key.
|
|
170
|
+
*
|
|
171
|
+
* @param args.message raw message data in HexInput format
|
|
172
|
+
* @param args.signature signed message Signature
|
|
173
|
+
* @returns
|
|
174
|
+
*/
|
|
175
|
+
verifySignature(args: { message: HexInput; signature: Signature }): boolean {
|
|
176
|
+
const { message, signature } = args;
|
|
177
|
+
const rawMessage = Hex.fromHexInput(message).toUint8Array();
|
|
178
|
+
return this.publicKey.verifySignature({ message: rawMessage, signature });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
|
|
5
|
+
import { Serializable, Serializer } from "../bcs/serializer";
|
|
6
|
+
import { Deserializer } from "../bcs/deserializer";
|
|
7
|
+
import { ParsingError, ParsingResult } from "./common";
|
|
8
|
+
import { TransactionArgument } from "../transactions/instances/transactionArgument";
|
|
9
|
+
import { HexInput, ScriptTransactionArgumentVariants } from "../types";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This enum is used to explain why an address was invalid.
|
|
13
|
+
*/
|
|
14
|
+
export enum AddressInvalidReason {
|
|
15
|
+
INCORRECT_NUMBER_OF_BYTES = "incorrect_number_of_bytes",
|
|
16
|
+
INVALID_HEX_CHARS = "invalid_hex_chars",
|
|
17
|
+
TOO_SHORT = "too_short",
|
|
18
|
+
TOO_LONG = "too_long",
|
|
19
|
+
LEADING_ZERO_X_REQUIRED = "leading_zero_x_required",
|
|
20
|
+
LONG_FORM_REQUIRED_UNLESS_SPECIAL = "long_form_required_unless_special",
|
|
21
|
+
INVALID_PADDING_ZEROES = "INVALID_PADDING_ZEROES",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* NOTE: Only use this class for account addresses. For other hex data, e.g. transaction
|
|
26
|
+
* hashes, use the Hex class.
|
|
27
|
+
*
|
|
28
|
+
* AccountAddress is used for working with account addresses. Account addresses, when
|
|
29
|
+
* represented as a string, generally look like these examples:
|
|
30
|
+
* - 0x1
|
|
31
|
+
* - 0xaa86fe99004361f747f91342ca13c426ca0cccb0c1217677180c9493bad6ef0c
|
|
32
|
+
*
|
|
33
|
+
* Proper formatting and parsing of account addresses is defined by AIP-40.
|
|
34
|
+
* To learn more about the standard, read the AIP here:
|
|
35
|
+
* https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-40.md.
|
|
36
|
+
*
|
|
37
|
+
* The comments in this class make frequent reference to the LONG and SHORT formats,
|
|
38
|
+
* as well as "special" addresses. To learn what these refer to see AIP-40.
|
|
39
|
+
*/
|
|
40
|
+
export class AccountAddress extends Serializable implements TransactionArgument {
|
|
41
|
+
/**
|
|
42
|
+
* This is the internal representation of an account address.
|
|
43
|
+
*/
|
|
44
|
+
readonly data: Uint8Array;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The number of bytes that make up an account address.
|
|
48
|
+
*/
|
|
49
|
+
static readonly LENGTH: number = 32;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The length of an address string in LONG form without a leading 0x.
|
|
53
|
+
*/
|
|
54
|
+
static readonly LONG_STRING_LENGTH: number = 64;
|
|
55
|
+
|
|
56
|
+
static ONE: AccountAddress = AccountAddress.fromString("0x1");
|
|
57
|
+
|
|
58
|
+
static TWO: AccountAddress = AccountAddress.fromString("0x2");
|
|
59
|
+
|
|
60
|
+
static THREE: AccountAddress = AccountAddress.fromString("0x3");
|
|
61
|
+
|
|
62
|
+
static FOUR: AccountAddress = AccountAddress.fromString("0x4");
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Creates an instance of AccountAddress from a Uint8Array.
|
|
66
|
+
*
|
|
67
|
+
* @param args.data A Uint8Array representing an account address.
|
|
68
|
+
*/
|
|
69
|
+
constructor(args: { data: Uint8Array }) {
|
|
70
|
+
super();
|
|
71
|
+
if (args.data.length !== AccountAddress.LENGTH) {
|
|
72
|
+
throw new ParsingError(
|
|
73
|
+
"AccountAddress data should be exactly 32 bytes long",
|
|
74
|
+
AddressInvalidReason.INCORRECT_NUMBER_OF_BYTES,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
this.data = args.data;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Returns whether an address is special, where special is defined as 0x0 to 0xf
|
|
82
|
+
* inclusive. In other words, the last byte of the address must be < 0b10000 (16)
|
|
83
|
+
* and every other byte must be zero.
|
|
84
|
+
*
|
|
85
|
+
* For more information on how special addresses are defined see AIP-40:
|
|
86
|
+
* https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-40.md.
|
|
87
|
+
*
|
|
88
|
+
* @returns true if the address is special, false if not.
|
|
89
|
+
*/
|
|
90
|
+
isSpecial(): boolean {
|
|
91
|
+
return (
|
|
92
|
+
this.data.slice(0, this.data.length - 1).every((byte) => byte === 0) && this.data[this.data.length - 1] < 0b10000
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ===
|
|
97
|
+
// Methods for representing an instance of AccountAddress as other types.
|
|
98
|
+
// ===
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Return the AccountAddress as a string as per AIP-40.
|
|
102
|
+
* https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-40.md.
|
|
103
|
+
*
|
|
104
|
+
* In short, it means that special addresses are represented in SHORT form, meaning
|
|
105
|
+
* 0x0 through to 0xf inclusive, and every other address is represented in LONG form,
|
|
106
|
+
* meaning 0x + 64 hex characters.
|
|
107
|
+
*
|
|
108
|
+
* @returns AccountAddress as a string conforming to AIP-40.
|
|
109
|
+
*/
|
|
110
|
+
toString(): string {
|
|
111
|
+
return `0x${this.toStringWithoutPrefix()}`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* NOTE: Prefer to use `toString` where possible.
|
|
116
|
+
*
|
|
117
|
+
* Return the AccountAddress as a string as per AIP-40 but without the leading 0x.
|
|
118
|
+
*
|
|
119
|
+
* Learn more by reading the docstring of `toString`.
|
|
120
|
+
*
|
|
121
|
+
* @returns AccountAddress as a string conforming to AIP-40 but without the leading 0x.
|
|
122
|
+
*/
|
|
123
|
+
toStringWithoutPrefix(): string {
|
|
124
|
+
let hex = bytesToHex(this.data);
|
|
125
|
+
if (this.isSpecial()) {
|
|
126
|
+
hex = hex[hex.length - 1];
|
|
127
|
+
}
|
|
128
|
+
return hex;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* NOTE: Prefer to use `toString` where possible.
|
|
133
|
+
*
|
|
134
|
+
* Whereas toString will format special addresses (as defined by isSpecial) using the
|
|
135
|
+
* SHORT form (no leading 0s), this format the address in the LONG format
|
|
136
|
+
* unconditionally.
|
|
137
|
+
*
|
|
138
|
+
* This means it will be 0x + 64 hex characters.
|
|
139
|
+
*
|
|
140
|
+
* @returns AccountAddress as a string in LONG form.
|
|
141
|
+
*/
|
|
142
|
+
toStringLong(): string {
|
|
143
|
+
return `0x${this.toStringLongWithoutPrefix()}`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* NOTE: Prefer to use `toString` where possible.
|
|
148
|
+
*
|
|
149
|
+
* Whereas toString will format special addresses (as defined by isSpecial) using the
|
|
150
|
+
* SHORT form (no leading 0s), this function will include leading zeroes. The string
|
|
151
|
+
* will not have a leading zero.
|
|
152
|
+
*
|
|
153
|
+
* This means it will be 64 hex characters without a leading 0x.
|
|
154
|
+
*
|
|
155
|
+
* @returns AccountAddress as a string in LONG form without a leading 0x.
|
|
156
|
+
*/
|
|
157
|
+
toStringLongWithoutPrefix(): string {
|
|
158
|
+
return bytesToHex(this.data);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Get the inner hex data. The inner data is already a Uint8Array so no conversion
|
|
163
|
+
* is taking place here, it just returns the inner data.
|
|
164
|
+
*
|
|
165
|
+
* @returns Hex data as Uint8Array
|
|
166
|
+
*/
|
|
167
|
+
toUint8Array(): Uint8Array {
|
|
168
|
+
return this.data;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Serialize the AccountAddress to a Serializer instance's data buffer.
|
|
173
|
+
* @param serializer The serializer to serialize the AccountAddress to.
|
|
174
|
+
* @returns void
|
|
175
|
+
* @example
|
|
176
|
+
* const serializer = new Serializer();
|
|
177
|
+
* const address = AccountAddress.fromString("0x1");
|
|
178
|
+
* address.serialize(serializer);
|
|
179
|
+
* const bytes = serializer.toUint8Array();
|
|
180
|
+
* // `bytes` is now the BCS-serialized address.
|
|
181
|
+
*/
|
|
182
|
+
serialize(serializer: Serializer): void {
|
|
183
|
+
serializer.serializeFixedBytes(this.data);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
serializeForEntryFunction(serializer: Serializer): void {
|
|
187
|
+
const bcsBytes = this.bcsToBytes();
|
|
188
|
+
serializer.serializeBytes(bcsBytes);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
serializeForScriptFunction(serializer: Serializer): void {
|
|
192
|
+
serializer.serializeU32AsUleb128(ScriptTransactionArgumentVariants.Address);
|
|
193
|
+
serializer.serialize(this);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Deserialize an AccountAddress from the byte buffer in a Deserializer instance.
|
|
198
|
+
* @param deserializer The deserializer to deserialize the AccountAddress from.
|
|
199
|
+
* @returns An instance of AccountAddress.
|
|
200
|
+
* @example
|
|
201
|
+
* const bytes = hexToBytes("0x0102030405060708091011121314151617181920212223242526272829303132");
|
|
202
|
+
* const deserializer = new Deserializer(bytes);
|
|
203
|
+
* const address = AccountAddress.deserialize(deserializer);
|
|
204
|
+
* // `address` is now an instance of AccountAddress.
|
|
205
|
+
*/
|
|
206
|
+
static deserialize(deserializer: Deserializer): AccountAddress {
|
|
207
|
+
const bytes = deserializer.deserializeFixedBytes(AccountAddress.LENGTH);
|
|
208
|
+
return new AccountAddress({ data: bytes });
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ===
|
|
212
|
+
// Methods for creating an instance of AccountAddress from other types.
|
|
213
|
+
// ===
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* NOTE: This function has strict parsing behavior. For relaxed behavior, please use
|
|
217
|
+
* the `fromStringRelaxed` function.
|
|
218
|
+
*
|
|
219
|
+
* Creates an instance of AccountAddress from a hex string.
|
|
220
|
+
*
|
|
221
|
+
* This function allows only the strictest formats defined by AIP-40. In short this
|
|
222
|
+
* means only the following formats are accepted:
|
|
223
|
+
*
|
|
224
|
+
* - LONG
|
|
225
|
+
* - SHORT for special addresses
|
|
226
|
+
*
|
|
227
|
+
* Where:
|
|
228
|
+
* - LONG is defined as 0x + 64 hex characters.
|
|
229
|
+
* - SHORT for special addresses is 0x0 to 0xf inclusive without padding zeroes.
|
|
230
|
+
*
|
|
231
|
+
* This means the following are not accepted:
|
|
232
|
+
* - SHORT for non-special addresses.
|
|
233
|
+
* - Any address without a leading 0x.
|
|
234
|
+
*
|
|
235
|
+
* Learn more about the different address formats by reading AIP-40:
|
|
236
|
+
* https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-40.md.
|
|
237
|
+
*
|
|
238
|
+
* @param input A hex string representing an account address.
|
|
239
|
+
*
|
|
240
|
+
* @returns An instance of AccountAddress.
|
|
241
|
+
*/
|
|
242
|
+
static fromString(input: string): AccountAddress {
|
|
243
|
+
// Assert the string starts with 0x.
|
|
244
|
+
if (!input.startsWith("0x")) {
|
|
245
|
+
throw new ParsingError("Hex string must start with a leading 0x.", AddressInvalidReason.LEADING_ZERO_X_REQUIRED);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const address = AccountAddress.fromStringRelaxed(input);
|
|
249
|
+
|
|
250
|
+
// Check if the address is in LONG form. If it is not, this is only allowed for
|
|
251
|
+
// special addresses, in which case we check it is in proper SHORT form.
|
|
252
|
+
if (input.length !== AccountAddress.LONG_STRING_LENGTH + 2) {
|
|
253
|
+
if (!address.isSpecial()) {
|
|
254
|
+
throw new ParsingError(
|
|
255
|
+
`The given hex string ${address} is not a special address, it must be represented as 0x + 64 chars.`,
|
|
256
|
+
AddressInvalidReason.LONG_FORM_REQUIRED_UNLESS_SPECIAL,
|
|
257
|
+
);
|
|
258
|
+
} else if (input.length !== 3) {
|
|
259
|
+
// 0x + one hex char is the only valid SHORT form for special addresses.
|
|
260
|
+
throw new ParsingError(
|
|
261
|
+
// eslint-disable-next-line max-len
|
|
262
|
+
`The given hex string ${input} is a special address not in LONG form, it must be 0x0 to 0xf without padding zeroes.`,
|
|
263
|
+
AddressInvalidReason.INVALID_PADDING_ZEROES,
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return address;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* NOTE: This function has relaxed parsing behavior. For strict behavior, please use
|
|
273
|
+
* the `fromString` function. Where possible use `fromString` rather than this
|
|
274
|
+
* function, `fromStringRelaxed` is only provided for backwards compatibility.
|
|
275
|
+
*
|
|
276
|
+
* Creates an instance of AccountAddress from a hex string.
|
|
277
|
+
*
|
|
278
|
+
* This function allows all formats defined by AIP-40. In short this means the
|
|
279
|
+
* following formats are accepted:
|
|
280
|
+
*
|
|
281
|
+
* - LONG, with or without leading 0x
|
|
282
|
+
* - SHORT, with or without leading 0x
|
|
283
|
+
*
|
|
284
|
+
* Where:
|
|
285
|
+
* - LONG is 64 hex characters.
|
|
286
|
+
* - SHORT is 1 to 63 hex characters inclusive.
|
|
287
|
+
* - Padding zeroes are allowed, e.g. 0x0123 is valid.
|
|
288
|
+
*
|
|
289
|
+
* Learn more about the different address formats by reading AIP-40:
|
|
290
|
+
* https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-40.md.
|
|
291
|
+
*
|
|
292
|
+
* @param input A hex string representing an account address.
|
|
293
|
+
*
|
|
294
|
+
* @returns An instance of AccountAddress.
|
|
295
|
+
*/
|
|
296
|
+
static fromStringRelaxed(input: string): AccountAddress {
|
|
297
|
+
let parsedInput = input;
|
|
298
|
+
// Remove leading 0x for parsing.
|
|
299
|
+
if (input.startsWith("0x")) {
|
|
300
|
+
parsedInput = input.slice(2);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Ensure the address string is at least 1 character long.
|
|
304
|
+
if (parsedInput.length === 0) {
|
|
305
|
+
throw new ParsingError(
|
|
306
|
+
"Hex string is too short, must be 1 to 64 chars long, excluding the leading 0x.",
|
|
307
|
+
AddressInvalidReason.TOO_SHORT,
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Ensure the address string is not longer than 64 characters.
|
|
312
|
+
if (parsedInput.length > 64) {
|
|
313
|
+
throw new ParsingError(
|
|
314
|
+
"Hex string is too long, must be 1 to 64 chars long, excluding the leading 0x.",
|
|
315
|
+
AddressInvalidReason.TOO_LONG,
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
let addressBytes: Uint8Array;
|
|
320
|
+
try {
|
|
321
|
+
// Pad the address with leading zeroes, so it is 64 chars long and then convert
|
|
322
|
+
// the hex string to bytes. Every two characters in a hex string constitutes a
|
|
323
|
+
// single byte. So a 64 length hex string becomes a 32 byte array.
|
|
324
|
+
addressBytes = hexToBytes(parsedInput.padStart(64, "0"));
|
|
325
|
+
} catch (e) {
|
|
326
|
+
const error = e as Error;
|
|
327
|
+
// At this point the only way this can fail is if the hex string contains
|
|
328
|
+
// invalid characters.
|
|
329
|
+
throw new ParsingError(`Hex characters are invalid: ${error.message}`, AddressInvalidReason.INVALID_HEX_CHARS);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return new AccountAddress({ data: addressBytes });
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Convenience method for creating an AccountAddress from HexInput. For
|
|
337
|
+
* more information on how this works, see the constructor and fromString.
|
|
338
|
+
*
|
|
339
|
+
* @param input A hex string or Uint8Array representing an account address.
|
|
340
|
+
*
|
|
341
|
+
* @returns An instance of AccountAddress.
|
|
342
|
+
*/
|
|
343
|
+
static fromHexInput(input: HexInput): AccountAddress {
|
|
344
|
+
if (input instanceof Uint8Array) {
|
|
345
|
+
return new AccountAddress({ data: input });
|
|
346
|
+
}
|
|
347
|
+
return AccountAddress.fromString(input);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Convenience method for creating an AccountAddress from HexInput. For
|
|
352
|
+
* more information on how this works, see the constructor and fromStringRelaxed.
|
|
353
|
+
*
|
|
354
|
+
* @param hexInput A hex string or Uint8Array representing an account address.
|
|
355
|
+
*
|
|
356
|
+
* @returns An instance of AccountAddress.
|
|
357
|
+
*/
|
|
358
|
+
static fromHexInputRelaxed(hexInput: HexInput): AccountAddress {
|
|
359
|
+
if (hexInput instanceof Uint8Array) {
|
|
360
|
+
return new AccountAddress({ data: hexInput });
|
|
361
|
+
}
|
|
362
|
+
return AccountAddress.fromStringRelaxed(hexInput);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// ===
|
|
366
|
+
// Methods for checking validity.
|
|
367
|
+
// ===
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Check if the string is a valid AccountAddress.
|
|
371
|
+
*
|
|
372
|
+
* @param args.input A hex string representing an account address.
|
|
373
|
+
* @param args.relaxed If true, use relaxed parsing behavior. If false, use strict parsing behavior.
|
|
374
|
+
*
|
|
375
|
+
* @returns valid = true if the string is valid, valid = false if not. If the string
|
|
376
|
+
* is not valid, invalidReason will be set explaining why it is invalid.
|
|
377
|
+
*/
|
|
378
|
+
static isValid(args: { input: string; relaxed?: boolean }): ParsingResult<AddressInvalidReason> {
|
|
379
|
+
try {
|
|
380
|
+
if (args.relaxed) {
|
|
381
|
+
AccountAddress.fromStringRelaxed(args.input);
|
|
382
|
+
} else {
|
|
383
|
+
AccountAddress.fromString(args.input);
|
|
384
|
+
}
|
|
385
|
+
return { valid: true };
|
|
386
|
+
} catch (e) {
|
|
387
|
+
const error = e as ParsingError<AddressInvalidReason>;
|
|
388
|
+
return {
|
|
389
|
+
valid: false,
|
|
390
|
+
invalidReason: error.invalidReason,
|
|
391
|
+
invalidReasonMessage: error.message,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Return whether AccountAddresses are equal. AccountAddresses are considered equal
|
|
398
|
+
* if their underlying byte data is identical.
|
|
399
|
+
*
|
|
400
|
+
* @param other The AccountAddress to compare to.
|
|
401
|
+
* @returns true if the AccountAddresses are equal, false if not.
|
|
402
|
+
*/
|
|
403
|
+
equals(other: AccountAddress): boolean {
|
|
404
|
+
if (this.data.length !== other.data.length) return false;
|
|
405
|
+
return this.data.every((value, index) => value === other.data[index]);
|
|
406
|
+
}
|
|
407
|
+
}
|