@aptos-labs/ts-sdk 0.0.3 → 0.0.4
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/README.md +1 -0
- package/dist/browser/index.global.js +26 -25
- package/dist/browser/index.global.js.map +1 -1
- package/dist/cjs/index.d.ts +413 -227
- package/dist/cjs/index.js +451 -181
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.ts +413 -227
- package/dist/esm/index.mjs +440 -178
- package/dist/esm/index.mjs.map +1 -1
- package/dist/types/index.d.ts +11 -17
- package/dist/types/index.js.map +1 -1
- package/package.json +3 -2
- package/src/api/account.ts +17 -18
- package/src/api/ans.ts +58 -0
- package/src/api/aptos.ts +7 -1
- package/src/api/coin.ts +3 -3
- package/src/api/digitalAsset.ts +9 -8
- package/src/api/event.ts +4 -3
- package/src/api/faucet.ts +3 -2
- package/src/api/general.ts +2 -2
- package/src/api/staking.ts +5 -4
- package/src/api/transactionSubmission.ts +27 -18
- package/src/bcs/deserializer.ts +4 -4
- package/src/bcs/serializable/moveStructs.ts +5 -9
- package/src/bcs/serializer.ts +4 -4
- package/src/client/core.ts +14 -6
- package/src/core/account.ts +83 -29
- package/src/core/accountAddress.ts +34 -30
- package/src/core/authenticationKey.ts +11 -9
- package/src/core/crypto/ed25519.ts +48 -1
- package/src/core/crypto/hdKey.ts +105 -0
- package/src/core/crypto/index.ts +1 -0
- package/src/core/crypto/secp256k1.ts +36 -0
- package/src/index.ts +0 -1
- package/src/internal/account.ts +80 -58
- package/src/internal/ans.ts +177 -0
- package/src/internal/coin.ts +5 -5
- package/src/internal/digitalAsset.ts +16 -17
- package/src/internal/event.ts +7 -7
- package/src/internal/faucet.ts +4 -4
- package/src/internal/general.ts +3 -3
- package/src/internal/staking.ts +8 -8
- package/src/internal/transactionSubmission.ts +71 -18
- package/src/transactions/instances/index.ts +1 -0
- package/src/transactions/instances/moduleId.ts +1 -1
- package/src/transactions/instances/rotationProofChallenge.ts +58 -0
- package/src/transactions/transactionBuilder/helpers.ts +5 -1
- package/src/transactions/transactionBuilder/remoteAbi.ts +3 -3
- package/src/transactions/transactionBuilder/transactionBuilder.ts +31 -45
- package/src/transactions/typeTag/index.ts +10 -10
- package/src/transactions/typeTag/parser.ts +1 -1
- package/src/transactions/types.ts +28 -17
- package/src/types/index.ts +11 -16
- package/src/utils/apiEndpoints.ts +8 -0
- package/src/version.ts +1 -1
- package/src/utils/hdKey.ts +0 -113
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { AptosConfig } from "./aptosConfig";
|
|
5
|
-
import { Account } from "../core";
|
|
5
|
+
import { Account, AccountAddressInput, PrivateKey } from "../core";
|
|
6
6
|
import { AccountAuthenticator } from "../transactions/authenticator/account";
|
|
7
7
|
import {
|
|
8
8
|
AnyRawTransaction,
|
|
@@ -15,11 +15,13 @@ import {
|
|
|
15
15
|
InputSingleSignerTransaction,
|
|
16
16
|
InputSimulateTransactionData,
|
|
17
17
|
InputGenerateTransactionOptions,
|
|
18
|
+
InputSubmitTransactionData,
|
|
18
19
|
} from "../transactions/types";
|
|
19
|
-
import { UserTransactionResponse, PendingTransactionResponse, HexInput } from "../types";
|
|
20
|
+
import { UserTransactionResponse, PendingTransactionResponse, HexInput, TransactionResponse } from "../types";
|
|
20
21
|
import {
|
|
21
22
|
generateTransaction,
|
|
22
23
|
publicPackageTransaction,
|
|
24
|
+
rotateAuthKey,
|
|
23
25
|
signAndSubmitTransaction,
|
|
24
26
|
signTransaction,
|
|
25
27
|
simulateTransaction,
|
|
@@ -47,7 +49,7 @@ export class TransactionSubmission {
|
|
|
47
49
|
/**
|
|
48
50
|
* Generates any transaction by passing in the required arguments
|
|
49
51
|
*
|
|
50
|
-
* @param args.sender The transaction sender's account address as a
|
|
52
|
+
* @param args.sender The transaction sender's account address as a AccountAddressInput
|
|
51
53
|
* @param args.data EntryFunctionData | ScriptData | MultiSigData
|
|
52
54
|
* @param args.feePayerAddress optional. For a fee payer (aka sponsored) transaction
|
|
53
55
|
* @param args.secondarySignerAddresses optional. For a multi-agent or fee payer (aka sponsored) transactions
|
|
@@ -75,10 +77,10 @@ export class TransactionSubmission {
|
|
|
75
77
|
* }
|
|
76
78
|
* ```
|
|
77
79
|
*
|
|
78
|
-
* @return
|
|
80
|
+
* @return An instance of a RawTransaction, plus optional secondary/fee payer addresses
|
|
79
81
|
* ```
|
|
80
82
|
* {
|
|
81
|
-
* rawTransaction:
|
|
83
|
+
* rawTransaction: RawTransaction,
|
|
82
84
|
* secondarySignerAddresses? : Array<AccountAddress>,
|
|
83
85
|
* feePayerAddress?: AccountAddress
|
|
84
86
|
* }
|
|
@@ -92,10 +94,10 @@ export class TransactionSubmission {
|
|
|
92
94
|
* Sign a transaction that can later be submitted to chain
|
|
93
95
|
*
|
|
94
96
|
* @param args.signer The signer account to sign the transaction
|
|
95
|
-
* @param args.transaction
|
|
97
|
+
* @param args.transaction An instance of a RawTransaction, plus optional secondary/fee payer addresses
|
|
96
98
|
* ```
|
|
97
99
|
* {
|
|
98
|
-
* rawTransaction:
|
|
100
|
+
* rawTransaction: RawTransaction,
|
|
99
101
|
* secondarySignerAddresses? : Array<AccountAddress>,
|
|
100
102
|
* feePayerAddress?: AccountAddress
|
|
101
103
|
* }
|
|
@@ -130,14 +132,7 @@ export class TransactionSubmission {
|
|
|
130
132
|
*
|
|
131
133
|
* @return PendingTransactionResponse
|
|
132
134
|
*/
|
|
133
|
-
async submitTransaction(args: {
|
|
134
|
-
transaction: AnyRawTransaction;
|
|
135
|
-
senderAuthenticator: AccountAuthenticator;
|
|
136
|
-
secondarySignerAuthenticators?: {
|
|
137
|
-
feePayerAuthenticator?: AccountAuthenticator;
|
|
138
|
-
additionalSignersAuthenticators?: Array<AccountAuthenticator>;
|
|
139
|
-
};
|
|
140
|
-
}): Promise<PendingTransactionResponse> {
|
|
135
|
+
async submitTransaction(args: InputSubmitTransactionData): Promise<PendingTransactionResponse> {
|
|
141
136
|
return submitTransaction({ aptosConfig: this.config, ...args });
|
|
142
137
|
}
|
|
143
138
|
|
|
@@ -145,10 +140,10 @@ export class TransactionSubmission {
|
|
|
145
140
|
* Sign and submit a single signer transaction to chain
|
|
146
141
|
*
|
|
147
142
|
* @param args.signer The signer account to sign the transaction
|
|
148
|
-
* @param args.transaction
|
|
143
|
+
* @param args.transaction An instance of a RawTransaction, plus optional secondary/fee payer addresses
|
|
149
144
|
* ```
|
|
150
145
|
* {
|
|
151
|
-
* rawTransaction:
|
|
146
|
+
* rawTransaction: RawTransaction,
|
|
152
147
|
* secondarySignerAddresses? : Array<AccountAddress>,
|
|
153
148
|
* feePayerAddress?: AccountAddress
|
|
154
149
|
* }
|
|
@@ -182,11 +177,25 @@ export class TransactionSubmission {
|
|
|
182
177
|
* @returns A SingleSignerTransaction that can be simulated or submitted to chain
|
|
183
178
|
*/
|
|
184
179
|
async publishPackageTransaction(args: {
|
|
185
|
-
account:
|
|
180
|
+
account: AccountAddressInput;
|
|
186
181
|
metadataBytes: HexInput;
|
|
187
182
|
moduleBytecode: Array<HexInput>;
|
|
188
183
|
options?: InputGenerateTransactionOptions;
|
|
189
184
|
}): Promise<InputSingleSignerTransaction> {
|
|
190
185
|
return publicPackageTransaction({ aptosConfig: this.config, ...args });
|
|
191
186
|
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Rotate an account's auth key. After rotation, only the new private key can be used to sign txns for
|
|
190
|
+
* the account.
|
|
191
|
+
* Note: Only legacy Ed25519 scheme is supported for now.
|
|
192
|
+
* More info: {@link https://aptos.dev/guides/account-management/key-rotation/}
|
|
193
|
+
* @param args.fromAccount The account to rotate the auth key for
|
|
194
|
+
* @param args.toNewPrivateKey The new private key to rotate to
|
|
195
|
+
*
|
|
196
|
+
* @returns PendingTransactionResponse
|
|
197
|
+
*/
|
|
198
|
+
async rotateAuthKey(args: { fromAccount: Account; toNewPrivateKey: PrivateKey }): Promise<TransactionResponse> {
|
|
199
|
+
return rotateAuthKey({ aptosConfig: this.config, ...args });
|
|
200
|
+
}
|
|
192
201
|
}
|
package/src/bcs/deserializer.ts
CHANGED
|
@@ -222,10 +222,10 @@ export class Deserializer {
|
|
|
222
222
|
* @example
|
|
223
223
|
* // serialize a vector of addresses
|
|
224
224
|
* const addresses = new Array<AccountAddress>(
|
|
225
|
-
* AccountAddress.
|
|
226
|
-
* AccountAddress.
|
|
227
|
-
* AccountAddress.
|
|
228
|
-
* AccountAddress.
|
|
225
|
+
* AccountAddress.fromRelaxed("0x1"),
|
|
226
|
+
* AccountAddress.fromRelaxed("0x2"),
|
|
227
|
+
* AccountAddress.fromRelaxed("0xa"),
|
|
228
|
+
* AccountAddress.fromRelaxed("0xb"),
|
|
229
229
|
* );
|
|
230
230
|
* const serializer = new Serializer();
|
|
231
231
|
* serializer.serializeVector(addresses);
|
|
@@ -42,11 +42,6 @@ import { EntryFunctionArgument, TransactionArgument } from "../../transactions/i
|
|
|
42
42
|
* const vecOfStrings = new MoveVector([new MoveString("hello"), new MoveString("world")]);
|
|
43
43
|
* const vecOfStrings2 = MoveVector.MoveString(["hello", "world"]);
|
|
44
44
|
*
|
|
45
|
-
* // where MySerializableStruct is a class you've made that implements Serializable
|
|
46
|
-
* const vecOfSerializableValues = new MoveVector<MySerializableStruct>([
|
|
47
|
-
* new MySerializableStruct("hello", "world"),
|
|
48
|
-
* new MySerializableStruct("foo", "bar"),
|
|
49
|
-
* ]);
|
|
50
45
|
* @params
|
|
51
46
|
* values: an Array<T> of values where T is a class that implements Serializable
|
|
52
47
|
* @returns a `MoveVector<T>` with the values `values`
|
|
@@ -172,7 +167,7 @@ export class MoveVector<T extends Serializable & EntryFunctionArgument>
|
|
|
172
167
|
*
|
|
173
168
|
* @example
|
|
174
169
|
* const v = MoveVector.Bool([true, false, true, false]);
|
|
175
|
-
* @params values: an array of `
|
|
170
|
+
* @params values: an array of `bools` to convert to Bools
|
|
176
171
|
* @returns a `MoveVector<Bool>`
|
|
177
172
|
*/
|
|
178
173
|
static Bool(values: Array<boolean>): MoveVector<Bool> {
|
|
@@ -184,7 +179,7 @@ export class MoveVector<T extends Serializable & EntryFunctionArgument>
|
|
|
184
179
|
*
|
|
185
180
|
* @example
|
|
186
181
|
* const v = MoveVector.MoveString(["hello", "world"]);
|
|
187
|
-
* @params values: an array of `
|
|
182
|
+
* @params values: an array of `strings` to convert to MoveStrings
|
|
188
183
|
* @returns a `MoveVector<MoveString>`
|
|
189
184
|
*/
|
|
190
185
|
static MoveString(values: Array<string>): MoveVector<MoveString> {
|
|
@@ -202,8 +197,9 @@ export class MoveVector<T extends Serializable & EntryFunctionArgument>
|
|
|
202
197
|
*
|
|
203
198
|
* NOTE: This will not work with types that aren't of the Serializable class.
|
|
204
199
|
*
|
|
205
|
-
* If you
|
|
206
|
-
*
|
|
200
|
+
* If you're looking for a more flexible deserialization function, you can use the deserializeVector function
|
|
201
|
+
* in the Deserializer class.
|
|
202
|
+
*
|
|
207
203
|
* @example
|
|
208
204
|
* const vec = MoveVector.deserialize(deserializer, U64);
|
|
209
205
|
* @params deserializer: the Deserializer instance to use, with bytes loaded into it already.
|
package/src/bcs/serializer.ts
CHANGED
|
@@ -298,10 +298,10 @@ export class Serializer {
|
|
|
298
298
|
* @param values The array of BCS Serializable values
|
|
299
299
|
* @example
|
|
300
300
|
* const addresses = new Array<AccountAddress>(
|
|
301
|
-
* AccountAddress.
|
|
302
|
-
* AccountAddress.
|
|
303
|
-
* AccountAddress.
|
|
304
|
-
* AccountAddress.
|
|
301
|
+
* AccountAddress.fromRelaxed("0x1"),
|
|
302
|
+
* AccountAddress.fromRelaxed("0x2"),
|
|
303
|
+
* AccountAddress.fromRelaxed("0xa"),
|
|
304
|
+
* AccountAddress.fromRelaxed("0xb"),
|
|
305
305
|
* );
|
|
306
306
|
* const serializer = new Serializer();
|
|
307
307
|
* serializer.serializeVector(addresses);
|
package/src/client/core.ts
CHANGED
|
@@ -94,11 +94,19 @@ export async function aptosRequest<Req, Res>(
|
|
|
94
94
|
return result;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
let errorMessage: string;
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
errorMessage
|
|
103
|
-
)
|
|
99
|
+
// If it is the shape of an AptosApiError, convert it properly
|
|
100
|
+
if ("message" in response.data && "error_code" in response.data) {
|
|
101
|
+
const data = response.data as { message: string; error_code: string; vm_error_code?: string };
|
|
102
|
+
errorMessage = JSON.stringify(data);
|
|
103
|
+
} else if (result.status in errors) {
|
|
104
|
+
// If it's not an API type, it must come form infra, these are prehandled
|
|
105
|
+
errorMessage = errors[result.status];
|
|
106
|
+
} else {
|
|
107
|
+
// Everything else is unhandled
|
|
108
|
+
errorMessage = `Unhandled Error ${response.status} : ${response.statusText}`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
throw new AptosApiError(options, result, errorMessage);
|
|
104
112
|
}
|
package/src/core/account.ts
CHANGED
|
@@ -9,7 +9,6 @@ import { MultiEd25519PublicKey } from "./crypto/multiEd25519";
|
|
|
9
9
|
import { Secp256k1PrivateKey, Secp256k1PublicKey } from "./crypto/secp256k1";
|
|
10
10
|
import { Hex } from "./hex";
|
|
11
11
|
import { GenerateAccount, HexInput, SigningScheme, SigningSchemeInput } from "../types";
|
|
12
|
-
import { derivePrivateKeyFromMnemonic, KeyType } from "../utils/hdKey";
|
|
13
12
|
import { AnyPublicKey } from "./crypto/anyPublicKey";
|
|
14
13
|
|
|
15
14
|
/**
|
|
@@ -70,13 +69,14 @@ export class Account {
|
|
|
70
69
|
*/
|
|
71
70
|
private constructor(args: { privateKey: PrivateKey; address: AccountAddress; legacy?: boolean }) {
|
|
72
71
|
const { privateKey, address, legacy } = args;
|
|
72
|
+
const useLegacy = legacy ?? true;
|
|
73
73
|
|
|
74
74
|
// Derive the public key from the private key
|
|
75
75
|
this.publicKey = privateKey.publicKey();
|
|
76
76
|
|
|
77
77
|
// Derive the signing scheme from the public key
|
|
78
78
|
if (this.publicKey instanceof Ed25519PublicKey) {
|
|
79
|
-
if (
|
|
79
|
+
if (useLegacy) {
|
|
80
80
|
this.signingScheme = SigningScheme.Ed25519;
|
|
81
81
|
} else {
|
|
82
82
|
this.publicKey = new AnyPublicKey(this.publicKey);
|
|
@@ -97,7 +97,8 @@ export class Account {
|
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Derives an account with random private key and address.
|
|
100
|
-
*
|
|
100
|
+
*
|
|
101
|
+
* Default generation is using the Legacy ED25519 key
|
|
101
102
|
*
|
|
102
103
|
* @param args optional. Unify GenerateAccount type for Legacy and Unified keys
|
|
103
104
|
*
|
|
@@ -123,37 +124,75 @@ export class Account {
|
|
|
123
124
|
* @returns Account with the given signing scheme
|
|
124
125
|
*/
|
|
125
126
|
static generate(args?: GenerateAccount): Account {
|
|
127
|
+
const useLegacy = args?.legacy ?? true;
|
|
128
|
+
|
|
126
129
|
let privateKey: PrivateKey;
|
|
130
|
+
let publicKey: PublicKey;
|
|
127
131
|
|
|
128
132
|
switch (args?.scheme) {
|
|
129
133
|
case SigningSchemeInput.Secp256k1Ecdsa:
|
|
130
134
|
privateKey = Secp256k1PrivateKey.generate();
|
|
135
|
+
publicKey = new AnyPublicKey(privateKey.publicKey());
|
|
131
136
|
break;
|
|
132
137
|
default:
|
|
133
138
|
privateKey = Ed25519PrivateKey.generate();
|
|
139
|
+
if (useLegacy === false) {
|
|
140
|
+
publicKey = new AnyPublicKey(privateKey.publicKey());
|
|
141
|
+
} else {
|
|
142
|
+
publicKey = privateKey.publicKey();
|
|
143
|
+
}
|
|
134
144
|
}
|
|
145
|
+
const authKey = AuthenticationKey.fromPublicKey({ publicKey });
|
|
135
146
|
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
const address = authKey.derivedAddress();
|
|
148
|
+
return new Account({ privateKey, address, legacy: args?.legacy });
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Instantiates an account given a private key.
|
|
153
|
+
*
|
|
154
|
+
* This is used as a local calculation and therefore is used to instantiate an `Account`
|
|
155
|
+
* that has not had its authentication key rotated.
|
|
156
|
+
*
|
|
157
|
+
* @param privateKey PrivateKey - private key of the account
|
|
158
|
+
* @param args.legacy optional. If set to false, the keypair generated is a Unified keypair. Defaults
|
|
159
|
+
* to generating a Legacy Ed25519 keypair
|
|
160
|
+
*
|
|
161
|
+
* @returns Account
|
|
162
|
+
*/
|
|
163
|
+
static fromPrivateKey(args: { privateKey: PrivateKey; legacy?: boolean }): Account {
|
|
164
|
+
const { privateKey, legacy } = args;
|
|
165
|
+
const useLegacy = legacy ?? true;
|
|
166
|
+
|
|
167
|
+
let publicKey;
|
|
168
|
+
if (privateKey instanceof Secp256k1PrivateKey) {
|
|
169
|
+
// Secp256k1 single sender
|
|
138
170
|
publicKey = new AnyPublicKey(privateKey.publicKey());
|
|
171
|
+
} else if (privateKey instanceof Ed25519PrivateKey) {
|
|
172
|
+
// legacy Ed25519
|
|
173
|
+
if (useLegacy) {
|
|
174
|
+
publicKey = privateKey.publicKey();
|
|
175
|
+
} else {
|
|
176
|
+
// Ed25519 single sender
|
|
177
|
+
publicKey = new AnyPublicKey(privateKey.publicKey());
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
throw new Error(`Unsupported private key ${privateKey}`);
|
|
139
181
|
}
|
|
140
182
|
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}).toUint8Array(),
|
|
145
|
-
});
|
|
146
|
-
return new Account({ privateKey, address, legacy: args?.legacy });
|
|
183
|
+
const authKey = AuthenticationKey.fromPublicKey({ publicKey });
|
|
184
|
+
const address = authKey.derivedAddress();
|
|
185
|
+
return new Account({ privateKey, address, legacy: useLegacy });
|
|
147
186
|
}
|
|
148
187
|
|
|
149
188
|
/**
|
|
150
189
|
* Instantiates an account given a private key and a specified account address.
|
|
151
190
|
* This is primarily used to instantiate an `Account` that has had its authentication key rotated.
|
|
152
191
|
*
|
|
153
|
-
* @param privateKey PrivateKey - private key
|
|
154
|
-
* @param address The account address
|
|
155
|
-
* @param args.legacy optional. If set to
|
|
156
|
-
*
|
|
192
|
+
* @param args.privateKey PrivateKey - the underlying private key for the account
|
|
193
|
+
* @param args.address AccountAddress - The account address the `Account` will sign for
|
|
194
|
+
* @param args.legacy optional. If set to false, the keypair generated is a Unified keypair. Defaults
|
|
195
|
+
* to generating a Legacy Ed25519 keypair
|
|
157
196
|
*
|
|
158
197
|
* @returns Account
|
|
159
198
|
*/
|
|
@@ -169,19 +208,35 @@ export class Account {
|
|
|
169
208
|
/**
|
|
170
209
|
* Derives an account with bip44 path and mnemonics,
|
|
171
210
|
*
|
|
172
|
-
* @param args.
|
|
211
|
+
* @param args.scheme The signing scheme to derive with
|
|
212
|
+
* @param args.path the BIP44 derive hardened path (e.g. m/44'/637'/0'/0'/0') for Ed25519,
|
|
213
|
+
* or non-hardened path (e.g. m/44'/637'/0'/0/0) for secp256k1
|
|
173
214
|
* Detailed description: {@link https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki}
|
|
174
215
|
* @param args.mnemonic the mnemonic seed phrase of the account
|
|
175
|
-
* @
|
|
216
|
+
* @param args.legacy optional. If set to false, the keypair generated is a Unified keypair. Defaults
|
|
217
|
+
* to generating a Legacy Ed25519 keypair
|
|
218
|
+
*
|
|
219
|
+
* @returns Account
|
|
176
220
|
*/
|
|
177
|
-
static fromDerivationPath(args: {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const
|
|
184
|
-
|
|
221
|
+
static fromDerivationPath(args: {
|
|
222
|
+
scheme: SigningSchemeInput;
|
|
223
|
+
path: string;
|
|
224
|
+
mnemonic: string;
|
|
225
|
+
legacy?: boolean;
|
|
226
|
+
}): Account {
|
|
227
|
+
const { path, mnemonic, scheme, legacy } = args;
|
|
228
|
+
let privateKey: PrivateKey;
|
|
229
|
+
switch (scheme) {
|
|
230
|
+
case SigningSchemeInput.Secp256k1Ecdsa:
|
|
231
|
+
privateKey = Secp256k1PrivateKey.fromDerivationPath(path, mnemonic);
|
|
232
|
+
break;
|
|
233
|
+
case SigningSchemeInput.Ed25519:
|
|
234
|
+
privateKey = Ed25519PrivateKey.fromDerivationPath(path, mnemonic);
|
|
235
|
+
break;
|
|
236
|
+
default:
|
|
237
|
+
throw new Error(`Unsupported scheme ${scheme}`);
|
|
238
|
+
}
|
|
239
|
+
return Account.fromPrivateKey({ privateKey, legacy });
|
|
185
240
|
}
|
|
186
241
|
|
|
187
242
|
/**
|
|
@@ -190,12 +245,11 @@ export class Account {
|
|
|
190
245
|
* See here for more info: {@link https://aptos.dev/concepts/accounts#single-signer-authentication}
|
|
191
246
|
*
|
|
192
247
|
* @param args.publicKey PublicKey - public key of the account
|
|
193
|
-
* @returns
|
|
248
|
+
* @returns The authentication key for the associated account
|
|
194
249
|
*/
|
|
195
|
-
static authKey(args: { publicKey: PublicKey }):
|
|
250
|
+
static authKey(args: { publicKey: PublicKey }): AuthenticationKey {
|
|
196
251
|
const { publicKey } = args;
|
|
197
|
-
|
|
198
|
-
return authKey.data;
|
|
252
|
+
return AuthenticationKey.fromPublicKey({ publicKey });
|
|
199
253
|
}
|
|
200
254
|
|
|
201
255
|
/**
|
|
@@ -21,6 +21,8 @@ export enum AddressInvalidReason {
|
|
|
21
21
|
INVALID_PADDING_ZEROES = "INVALID_PADDING_ZEROES",
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
export type AccountAddressInput = HexInput | AccountAddress;
|
|
25
|
+
|
|
24
26
|
/**
|
|
25
27
|
* NOTE: Only use this class for account addresses. For other hex data, e.g. transaction
|
|
26
28
|
* hashes, use the Hex class.
|
|
@@ -53,30 +55,30 @@ export class AccountAddress extends Serializable implements TransactionArgument
|
|
|
53
55
|
*/
|
|
54
56
|
static readonly LONG_STRING_LENGTH: number = 64;
|
|
55
57
|
|
|
56
|
-
static ZERO: AccountAddress = AccountAddress.
|
|
58
|
+
static ZERO: AccountAddress = AccountAddress.from("0x0");
|
|
57
59
|
|
|
58
|
-
static ONE: AccountAddress = AccountAddress.
|
|
60
|
+
static ONE: AccountAddress = AccountAddress.from("0x1");
|
|
59
61
|
|
|
60
|
-
static TWO: AccountAddress = AccountAddress.
|
|
62
|
+
static TWO: AccountAddress = AccountAddress.from("0x2");
|
|
61
63
|
|
|
62
|
-
static THREE: AccountAddress = AccountAddress.
|
|
64
|
+
static THREE: AccountAddress = AccountAddress.from("0x3");
|
|
63
65
|
|
|
64
|
-
static FOUR: AccountAddress = AccountAddress.
|
|
66
|
+
static FOUR: AccountAddress = AccountAddress.from("0x4");
|
|
65
67
|
|
|
66
68
|
/**
|
|
67
69
|
* Creates an instance of AccountAddress from a Uint8Array.
|
|
68
70
|
*
|
|
69
71
|
* @param args.data A Uint8Array representing an account address.
|
|
70
72
|
*/
|
|
71
|
-
constructor(
|
|
73
|
+
constructor(input: Uint8Array) {
|
|
72
74
|
super();
|
|
73
|
-
if (
|
|
75
|
+
if (input.length !== AccountAddress.LENGTH) {
|
|
74
76
|
throw new ParsingError(
|
|
75
77
|
"AccountAddress data should be exactly 32 bytes long",
|
|
76
78
|
AddressInvalidReason.INCORRECT_NUMBER_OF_BYTES,
|
|
77
79
|
);
|
|
78
80
|
}
|
|
79
|
-
this.data =
|
|
81
|
+
this.data = input;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
/**
|
|
@@ -207,7 +209,7 @@ export class AccountAddress extends Serializable implements TransactionArgument
|
|
|
207
209
|
*/
|
|
208
210
|
static deserialize(deserializer: Deserializer): AccountAddress {
|
|
209
211
|
const bytes = deserializer.deserializeFixedBytes(AccountAddress.LENGTH);
|
|
210
|
-
return new AccountAddress(
|
|
212
|
+
return new AccountAddress(bytes);
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
// ===
|
|
@@ -331,37 +333,39 @@ export class AccountAddress extends Serializable implements TransactionArgument
|
|
|
331
333
|
throw new ParsingError(`Hex characters are invalid: ${error.message}`, AddressInvalidReason.INVALID_HEX_CHARS);
|
|
332
334
|
}
|
|
333
335
|
|
|
334
|
-
return new AccountAddress(
|
|
336
|
+
return new AccountAddress(addressBytes);
|
|
335
337
|
}
|
|
336
338
|
|
|
337
339
|
/**
|
|
338
|
-
* Convenience method for creating an AccountAddress from
|
|
339
|
-
* more information on how this works, see the constructor and fromString.
|
|
340
|
-
*
|
|
341
|
-
* @param input A hex string or Uint8Array representing an account address.
|
|
340
|
+
* Convenience method for creating an AccountAddress from all known inputs.
|
|
342
341
|
*
|
|
343
|
-
*
|
|
342
|
+
* This handles, Uint8array, string, and AccountAddress itself
|
|
343
|
+
* @param input
|
|
344
344
|
*/
|
|
345
|
-
static
|
|
345
|
+
static fromRelaxed(input: AccountAddressInput): AccountAddress {
|
|
346
|
+
if (input instanceof AccountAddress) {
|
|
347
|
+
return input;
|
|
348
|
+
}
|
|
346
349
|
if (input instanceof Uint8Array) {
|
|
347
|
-
return new AccountAddress(
|
|
350
|
+
return new AccountAddress(input);
|
|
348
351
|
}
|
|
349
|
-
return AccountAddress.
|
|
352
|
+
return AccountAddress.fromStringRelaxed(input);
|
|
350
353
|
}
|
|
351
354
|
|
|
352
355
|
/**
|
|
353
|
-
* Convenience method for creating an AccountAddress from
|
|
354
|
-
* more information on how this works, see the constructor and fromStringRelaxed.
|
|
356
|
+
* Convenience method for creating an AccountAddress from all known inputs.
|
|
355
357
|
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
* @returns An instance of AccountAddress.
|
|
358
|
+
* This handles, Uint8array, string, and AccountAddress itself
|
|
359
|
+
* @param input
|
|
359
360
|
*/
|
|
360
|
-
static
|
|
361
|
-
if (
|
|
362
|
-
return
|
|
361
|
+
static from(input: AccountAddressInput): AccountAddress {
|
|
362
|
+
if (input instanceof AccountAddress) {
|
|
363
|
+
return input;
|
|
363
364
|
}
|
|
364
|
-
|
|
365
|
+
if (input instanceof Uint8Array) {
|
|
366
|
+
return new AccountAddress(input);
|
|
367
|
+
}
|
|
368
|
+
return AccountAddress.fromString(input);
|
|
365
369
|
}
|
|
366
370
|
|
|
367
371
|
// ===
|
|
@@ -377,12 +381,12 @@ export class AccountAddress extends Serializable implements TransactionArgument
|
|
|
377
381
|
* @returns valid = true if the string is valid, valid = false if not. If the string
|
|
378
382
|
* is not valid, invalidReason will be set explaining why it is invalid.
|
|
379
383
|
*/
|
|
380
|
-
static isValid(args: { input:
|
|
384
|
+
static isValid(args: { input: AccountAddressInput; relaxed?: boolean }): ParsingResult<AddressInvalidReason> {
|
|
381
385
|
try {
|
|
382
386
|
if (args.relaxed) {
|
|
383
|
-
AccountAddress.
|
|
387
|
+
AccountAddress.fromRelaxed(args.input);
|
|
384
388
|
} else {
|
|
385
|
-
AccountAddress.
|
|
389
|
+
AccountAddress.from(args.input);
|
|
386
390
|
}
|
|
387
391
|
return { valid: true };
|
|
388
392
|
} catch (e) {
|
|
@@ -18,13 +18,13 @@ import { Deserializer } from "../bcs/deserializer";
|
|
|
18
18
|
* their private key(s) associated with the account without changing the address that hosts their account.
|
|
19
19
|
* @see {@link https://aptos.dev/concepts/accounts | Account Basics}
|
|
20
20
|
*
|
|
21
|
-
* Note: AuthenticationKey only supports Ed25519 and MultiEd25519 public keys for now.
|
|
22
|
-
*
|
|
23
21
|
* Account addresses can be derived from AuthenticationKey
|
|
24
22
|
*/
|
|
25
23
|
export class AuthenticationKey extends Serializable {
|
|
26
24
|
/**
|
|
27
25
|
* An authentication key is always a SHA3-256 hash of data, and is always 32 bytes.
|
|
26
|
+
*
|
|
27
|
+
* The data to hash depends on the underlying public key type and the derivation scheme.
|
|
28
28
|
*/
|
|
29
29
|
static readonly LENGTH: number = 32;
|
|
30
30
|
|
|
@@ -66,10 +66,11 @@ export class AuthenticationKey extends Serializable {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* Derives an AuthenticationKey from the public key seed bytes and an explicit derivation scheme.
|
|
70
|
+
*
|
|
71
|
+
* This facilitates targeting a specific scheme for deriving an authentication key from a public key.
|
|
70
72
|
*
|
|
71
|
-
*
|
|
72
|
-
* @param args
|
|
73
|
+
* @param args - the public key and scheme to use for the derivation
|
|
73
74
|
*/
|
|
74
75
|
public static fromPublicKeyAndScheme(args: { publicKey: PublicKey; scheme: AuthenticationKeyScheme }) {
|
|
75
76
|
const { publicKey, scheme } = args;
|
|
@@ -102,7 +103,8 @@ export class AuthenticationKey extends Serializable {
|
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
/**
|
|
105
|
-
* Converts a PublicKey(s) to AuthenticationKey
|
|
106
|
+
* Converts a PublicKey(s) to an AuthenticationKey, using the derivation scheme inferred from the
|
|
107
|
+
* instance of the PublicKey type passed in.
|
|
106
108
|
*
|
|
107
109
|
* @param args.publicKey
|
|
108
110
|
* @returns AuthenticationKey
|
|
@@ -129,12 +131,12 @@ export class AuthenticationKey extends Serializable {
|
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
/**
|
|
132
|
-
* Derives an account address from AuthenticationKey. Since
|
|
133
|
-
* AuthenticationKey bytes are directly translated to AccountAddress.
|
|
134
|
+
* Derives an account address from an AuthenticationKey. Since an AccountAddress is also 32 bytes,
|
|
135
|
+
* the AuthenticationKey bytes are directly translated to an AccountAddress.
|
|
134
136
|
*
|
|
135
137
|
* @returns AccountAddress
|
|
136
138
|
*/
|
|
137
139
|
derivedAddress(): AccountAddress {
|
|
138
|
-
return new AccountAddress(
|
|
140
|
+
return new AccountAddress(this.data.toUint8Array());
|
|
139
141
|
}
|
|
140
142
|
}
|
|
@@ -7,6 +7,7 @@ import { Deserializer } from "../../bcs/deserializer";
|
|
|
7
7
|
import { Serializer } from "../../bcs/serializer";
|
|
8
8
|
import { Hex } from "../hex";
|
|
9
9
|
import { HexInput } from "../../types";
|
|
10
|
+
import { CKDPriv, deriveKey, HARDENED_OFFSET, isValidHardenedPath, mnemonicToSeed, splitPath } from "./hdKey";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Represents the public key of an Ed25519 key pair.
|
|
@@ -70,7 +71,7 @@ export class Ed25519PublicKey extends PublicKey {
|
|
|
70
71
|
verifySignature(args: { message: HexInput; signature: Ed25519Signature }): boolean {
|
|
71
72
|
const { message, signature } = args;
|
|
72
73
|
const rawMessage = Hex.fromHexInput(message).toUint8Array();
|
|
73
|
-
const rawSignature =
|
|
74
|
+
const rawSignature = signature.toUint8Array();
|
|
74
75
|
return nacl.sign.detached.verify(rawMessage, rawSignature, this.key.toUint8Array());
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -98,6 +99,12 @@ export class Ed25519PrivateKey extends PrivateKey {
|
|
|
98
99
|
*/
|
|
99
100
|
static readonly LENGTH: number = 32;
|
|
100
101
|
|
|
102
|
+
/**
|
|
103
|
+
* The Ed25519 key seed to use for BIP-32 compatibility
|
|
104
|
+
* See more {@link https://github.com/satoshilabs/slips/blob/master/slip-0010.md}
|
|
105
|
+
*/
|
|
106
|
+
static readonly SLIP_0010_SEED = "ed25519 seed";
|
|
107
|
+
|
|
101
108
|
/**
|
|
102
109
|
* The Ed25519 signing key
|
|
103
110
|
* @private
|
|
@@ -179,6 +186,46 @@ export class Ed25519PrivateKey extends PrivateKey {
|
|
|
179
186
|
const bytes = this.signingKeyPair.publicKey;
|
|
180
187
|
return new Ed25519PublicKey(bytes);
|
|
181
188
|
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Derives a private key from a mnemonic seed phrase.
|
|
192
|
+
*
|
|
193
|
+
* To derive multiple keys from the same phrase, change the path
|
|
194
|
+
*
|
|
195
|
+
* IMPORTANT: Ed25519 supports hardened derivation only (since it lacks a key homomorphism,
|
|
196
|
+
* so non-hardened derivation cannot work)
|
|
197
|
+
*
|
|
198
|
+
* @param path the BIP44 path
|
|
199
|
+
* @param mnemonics the mnemonic seed phrase
|
|
200
|
+
*/
|
|
201
|
+
static fromDerivationPath(path: string, mnemonics: string): Ed25519PrivateKey {
|
|
202
|
+
if (!isValidHardenedPath(path)) {
|
|
203
|
+
throw new Error(`Invalid derivation path ${path}`);
|
|
204
|
+
}
|
|
205
|
+
return Ed25519PrivateKey.fromDerivationPathInner(path, mnemonicToSeed(mnemonics));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* A private inner function so we can separate from the main fromDerivationPath() method
|
|
210
|
+
* to add tests to verify we create the keys correctly.
|
|
211
|
+
*
|
|
212
|
+
* @param path the BIP44 path
|
|
213
|
+
* @param seed the seed phrase created by the mnemonics
|
|
214
|
+
* @param offset the offset used for key derivation, defaults to 0x80000000
|
|
215
|
+
* @returns
|
|
216
|
+
*/
|
|
217
|
+
private static fromDerivationPathInner(path: string, seed: Uint8Array, offset = HARDENED_OFFSET): Ed25519PrivateKey {
|
|
218
|
+
const { key, chainCode } = deriveKey(Ed25519PrivateKey.SLIP_0010_SEED, seed);
|
|
219
|
+
|
|
220
|
+
const segments = splitPath(path).map((el) => parseInt(el, 10));
|
|
221
|
+
|
|
222
|
+
// Derive the child key based on the path
|
|
223
|
+
const { key: privateKey } = segments.reduce((parentKeys, segment) => CKDPriv(parentKeys, segment + offset), {
|
|
224
|
+
key,
|
|
225
|
+
chainCode,
|
|
226
|
+
});
|
|
227
|
+
return new Ed25519PrivateKey(privateKey);
|
|
228
|
+
}
|
|
182
229
|
}
|
|
183
230
|
|
|
184
231
|
/**
|