@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,353 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/* eslint-disable no-bitwise */
|
|
5
|
+
import {
|
|
6
|
+
MAX_U128_BIG_INT,
|
|
7
|
+
MAX_U16_NUMBER,
|
|
8
|
+
MAX_U32_NUMBER,
|
|
9
|
+
MAX_U64_BIG_INT,
|
|
10
|
+
MAX_U8_NUMBER,
|
|
11
|
+
MAX_U256_BIG_INT,
|
|
12
|
+
} from "./consts";
|
|
13
|
+
import { Hex } from "../core/hex";
|
|
14
|
+
import { AnyNumber, Uint16, Uint32, Uint8 } from "../types";
|
|
15
|
+
|
|
16
|
+
// This class is intended to be used as a base class for all serializable types.
|
|
17
|
+
// It can be used to facilitate composable serialization of a complex type and
|
|
18
|
+
// in general to serialize a type to its BCS representation.
|
|
19
|
+
export abstract class Serializable {
|
|
20
|
+
abstract serialize(serializer: Serializer): void;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Serializes a `Serializable` value to its BCS representation.
|
|
24
|
+
* This function is the Typescript SDK equivalent of `bcs::to_bytes` in Move.
|
|
25
|
+
* @returns the BCS representation of the Serializable instance as a byte buffer
|
|
26
|
+
*/
|
|
27
|
+
bcsToBytes(): Uint8Array {
|
|
28
|
+
const serializer = new Serializer();
|
|
29
|
+
this.serialize(serializer);
|
|
30
|
+
return serializer.toUint8Array();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Helper function to get a value's BCS-serialized bytes as a Hex instance.
|
|
35
|
+
* @returns a Hex instance with the BCS-serialized bytes loaded into its underlying Uint8Array
|
|
36
|
+
*/
|
|
37
|
+
bcsToHex(): Hex {
|
|
38
|
+
const bcsBytes = this.bcsToBytes();
|
|
39
|
+
return Hex.fromHexInput(bcsBytes);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class Serializer {
|
|
44
|
+
private buffer: ArrayBuffer;
|
|
45
|
+
|
|
46
|
+
private offset: number;
|
|
47
|
+
|
|
48
|
+
// Constructs a serializer with a buffer of size `length` bytes, 64 bytes by default.
|
|
49
|
+
// `length` must be greater than 0.
|
|
50
|
+
constructor(length: number = 64) {
|
|
51
|
+
if (length <= 0) {
|
|
52
|
+
throw new Error("Length needs to be greater than 0");
|
|
53
|
+
}
|
|
54
|
+
this.buffer = new ArrayBuffer(length);
|
|
55
|
+
this.offset = 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private ensureBufferWillHandleSize(bytes: number) {
|
|
59
|
+
while (this.buffer.byteLength < this.offset + bytes) {
|
|
60
|
+
const newBuffer = new ArrayBuffer(this.buffer.byteLength * 2);
|
|
61
|
+
new Uint8Array(newBuffer).set(new Uint8Array(this.buffer));
|
|
62
|
+
this.buffer = newBuffer;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected appendToBuffer(values: Uint8Array) {
|
|
67
|
+
this.ensureBufferWillHandleSize(values.length);
|
|
68
|
+
new Uint8Array(this.buffer, this.offset).set(values);
|
|
69
|
+
this.offset += values.length;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private serializeWithFunction(
|
|
73
|
+
fn: (byteOffset: number, value: number, littleEndian?: boolean) => void,
|
|
74
|
+
bytesLength: number,
|
|
75
|
+
value: number,
|
|
76
|
+
) {
|
|
77
|
+
this.ensureBufferWillHandleSize(bytesLength);
|
|
78
|
+
const dv = new DataView(this.buffer, this.offset);
|
|
79
|
+
fn.apply(dv, [0, value, true]);
|
|
80
|
+
this.offset += bytesLength;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Serializes a string. UTF8 string is supported.
|
|
85
|
+
*
|
|
86
|
+
* The number of bytes in the string content is serialized first, as a uleb128-encoded u32 integer.
|
|
87
|
+
* Then the string content is serialized as UTF8 encoded bytes.
|
|
88
|
+
*
|
|
89
|
+
* BCS layout for "string": string_length | string_content
|
|
90
|
+
* where string_length is a u32 integer encoded as a uleb128 integer, equal to the number of bytes in string_content.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const serializer = new Serializer();
|
|
95
|
+
* serializer.serializeStr("1234abcd");
|
|
96
|
+
* assert(serializer.toUint8Array() === new Uint8Array([8, 49, 50, 51, 52, 97, 98, 99, 100]));
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
serializeStr(value: string) {
|
|
100
|
+
const textEncoder = new TextEncoder();
|
|
101
|
+
this.serializeBytes(textEncoder.encode(value));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Serializes an array of bytes.
|
|
106
|
+
*
|
|
107
|
+
* BCS layout for "bytes": bytes_length | bytes
|
|
108
|
+
* where bytes_length is a u32 integer encoded as a uleb128 integer, equal to the length of the bytes array.
|
|
109
|
+
*/
|
|
110
|
+
serializeBytes(value: Uint8Array) {
|
|
111
|
+
this.serializeU32AsUleb128(value.length);
|
|
112
|
+
this.appendToBuffer(value);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Serializes an array of bytes with known length. Therefore, length doesn't need to be
|
|
117
|
+
* serialized to help deserialization.
|
|
118
|
+
*
|
|
119
|
+
* When deserializing, the number of bytes to deserialize needs to be passed in.
|
|
120
|
+
*/
|
|
121
|
+
serializeFixedBytes(value: Uint8Array) {
|
|
122
|
+
this.appendToBuffer(value);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Serializes a boolean value.
|
|
127
|
+
*
|
|
128
|
+
* BCS layout for "boolean": One byte. "0x01" for true and "0x00" for false.
|
|
129
|
+
*/
|
|
130
|
+
serializeBool(value: boolean) {
|
|
131
|
+
ensureBoolean(value);
|
|
132
|
+
const byteValue = value ? 1 : 0;
|
|
133
|
+
this.appendToBuffer(new Uint8Array([byteValue]));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Serializes a uint8 number.
|
|
138
|
+
*
|
|
139
|
+
* BCS layout for "uint8": One byte. Binary format in little-endian representation.
|
|
140
|
+
*/
|
|
141
|
+
@checkNumberRange(0, MAX_U8_NUMBER)
|
|
142
|
+
serializeU8(value: Uint8) {
|
|
143
|
+
this.appendToBuffer(new Uint8Array([value]));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Serializes a uint16 number.
|
|
148
|
+
*
|
|
149
|
+
* BCS layout for "uint16": Two bytes. Binary format in little-endian representation.
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* const serializer = new Serializer();
|
|
153
|
+
* serializer.serializeU16(4660);
|
|
154
|
+
* assert(serializer.toUint8Array() === new Uint8Array([0x34, 0x12]));
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
@checkNumberRange(0, MAX_U16_NUMBER)
|
|
158
|
+
serializeU16(value: Uint16) {
|
|
159
|
+
this.serializeWithFunction(DataView.prototype.setUint16, 2, value);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Serializes a uint32 number.
|
|
164
|
+
*
|
|
165
|
+
* BCS layout for "uint32": Four bytes. Binary format in little-endian representation.
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* const serializer = new Serializer();
|
|
169
|
+
* serializer.serializeU32(305419896);
|
|
170
|
+
* assert(serializer.toUint8Array() === new Uint8Array([0x78, 0x56, 0x34, 0x12]));
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
@checkNumberRange(0, MAX_U32_NUMBER)
|
|
174
|
+
serializeU32(value: Uint32) {
|
|
175
|
+
this.serializeWithFunction(DataView.prototype.setUint32, 4, value);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Serializes a uint64 number.
|
|
180
|
+
*
|
|
181
|
+
* BCS layout for "uint64": Eight bytes. Binary format in little-endian representation.
|
|
182
|
+
* @example
|
|
183
|
+
* ```ts
|
|
184
|
+
* const serializer = new Serializer();
|
|
185
|
+
* serializer.serializeU64(1311768467750121216);
|
|
186
|
+
* assert(serializer.toUint8Array() === new Uint8Array([0x00, 0xEF, 0xCD, 0xAB, 0x78, 0x56, 0x34, 0x12]));
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
@checkNumberRange(BigInt(0), MAX_U64_BIG_INT)
|
|
190
|
+
serializeU64(value: AnyNumber) {
|
|
191
|
+
const low = BigInt(value) & BigInt(MAX_U32_NUMBER);
|
|
192
|
+
const high = BigInt(value) >> BigInt(32);
|
|
193
|
+
|
|
194
|
+
// write little endian number
|
|
195
|
+
this.serializeU32(Number(low));
|
|
196
|
+
this.serializeU32(Number(high));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Serializes a uint128 number.
|
|
201
|
+
*
|
|
202
|
+
* BCS layout for "uint128": Sixteen bytes. Binary format in little-endian representation.
|
|
203
|
+
*/
|
|
204
|
+
@checkNumberRange(BigInt(0), MAX_U128_BIG_INT)
|
|
205
|
+
serializeU128(value: AnyNumber) {
|
|
206
|
+
const low = BigInt(value) & MAX_U64_BIG_INT;
|
|
207
|
+
const high = BigInt(value) >> BigInt(64);
|
|
208
|
+
|
|
209
|
+
// write little endian number
|
|
210
|
+
this.serializeU64(low);
|
|
211
|
+
this.serializeU64(high);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Serializes a uint256 number.
|
|
216
|
+
*
|
|
217
|
+
* BCS layout for "uint256": Sixteen bytes. Binary format in little-endian representation.
|
|
218
|
+
*/
|
|
219
|
+
@checkNumberRange(BigInt(0), MAX_U256_BIG_INT)
|
|
220
|
+
serializeU256(value: AnyNumber) {
|
|
221
|
+
const low = BigInt(value) & MAX_U128_BIG_INT;
|
|
222
|
+
const high = BigInt(value) >> BigInt(128);
|
|
223
|
+
|
|
224
|
+
// write little endian number
|
|
225
|
+
this.serializeU128(low);
|
|
226
|
+
this.serializeU128(high);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Serializes a uint32 number with uleb128.
|
|
231
|
+
*
|
|
232
|
+
* BCS uses uleb128 encoding in two cases: (1) lengths of variable-length sequences and (2) tags of enum values
|
|
233
|
+
*/
|
|
234
|
+
@checkNumberRange(0, MAX_U32_NUMBER)
|
|
235
|
+
serializeU32AsUleb128(val: Uint32) {
|
|
236
|
+
let value = val;
|
|
237
|
+
const valueArray = [];
|
|
238
|
+
while (value >>> 7 !== 0) {
|
|
239
|
+
valueArray.push((value & 0x7f) | 0x80);
|
|
240
|
+
value >>>= 7;
|
|
241
|
+
}
|
|
242
|
+
valueArray.push(value);
|
|
243
|
+
this.appendToBuffer(new Uint8Array(valueArray));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Returns the buffered bytes
|
|
248
|
+
*/
|
|
249
|
+
toUint8Array(): Uint8Array {
|
|
250
|
+
return new Uint8Array(this.buffer).slice(0, this.offset);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Serializes a `Serializable` value, facilitating composable serialization.
|
|
255
|
+
*
|
|
256
|
+
* @param value The Serializable value to serialize
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* // Define the MoveStruct class that implements the Serializable interface
|
|
260
|
+
* class MoveStruct extends Serializable {
|
|
261
|
+
* constructor(
|
|
262
|
+
* public creatorAddress: AccountAddress, // where AccountAddress extends Serializable
|
|
263
|
+
* public collectionName: string,
|
|
264
|
+
* public tokenName: string
|
|
265
|
+
* ) {}
|
|
266
|
+
*
|
|
267
|
+
* serialize(serializer: Serializer): void {
|
|
268
|
+
* serializer.serialize(this.creatorAddress); // Composable serialization of another Serializable object
|
|
269
|
+
* serializer.serializeStr(this.collectionName);
|
|
270
|
+
* serializer.serializeStr(this.tokenName);
|
|
271
|
+
* }
|
|
272
|
+
* }
|
|
273
|
+
*
|
|
274
|
+
* // Construct a MoveStruct
|
|
275
|
+
* const moveStruct = new MoveStruct(new AccountAddress(...), "MyCollection", "TokenA");
|
|
276
|
+
*
|
|
277
|
+
* // Serialize a string, a u64 number, and a MoveStruct instance.
|
|
278
|
+
* const serializer = new Serializer();
|
|
279
|
+
* serializer.serializeStr("ExampleString");
|
|
280
|
+
* serializer.serializeU64(12345678);
|
|
281
|
+
* serializer.serialize(moveStruct);
|
|
282
|
+
*
|
|
283
|
+
* // Get the bytes from the Serializer instance
|
|
284
|
+
* const serializedBytes = serializer.toUint8Array();
|
|
285
|
+
*
|
|
286
|
+
* @returns the serializer instance
|
|
287
|
+
*/
|
|
288
|
+
serialize<T extends Serializable>(value: T): void {
|
|
289
|
+
// NOTE: The `serialize` method called by `value` is defined in `value`'s
|
|
290
|
+
// Serializable interface, not the one defined in this class.
|
|
291
|
+
value.serialize(this);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Serializes an array of BCS Serializable values to a serializer instance.
|
|
296
|
+
* Note that this does not return anything. The bytes are added to the serializer instance's byte buffer.
|
|
297
|
+
*
|
|
298
|
+
* @param values The array of BCS Serializable values
|
|
299
|
+
* @example
|
|
300
|
+
* const addresses = new Array<AccountAddress>(
|
|
301
|
+
* AccountAddress.fromHexInputRelaxed("0x1"),
|
|
302
|
+
* AccountAddress.fromHexInputRelaxed("0x2"),
|
|
303
|
+
* AccountAddress.fromHexInputRelaxed("0xa"),
|
|
304
|
+
* AccountAddress.fromHexInputRelaxed("0xb"),
|
|
305
|
+
* );
|
|
306
|
+
* const serializer = new Serializer();
|
|
307
|
+
* serializer.serializeVector(addresses);
|
|
308
|
+
* const serializedBytes = serializer.toUint8Array();
|
|
309
|
+
* // serializedBytes is now the BCS-serialized bytes
|
|
310
|
+
* // The equivalent value in Move would be:
|
|
311
|
+
* // `bcs::to_bytes(&vector<address> [@0x1, @0x2, @0xa, @0xb])`;
|
|
312
|
+
*/
|
|
313
|
+
serializeVector<T extends Serializable>(values: Array<T>): void {
|
|
314
|
+
this.serializeU32AsUleb128(values.length);
|
|
315
|
+
values.forEach((item) => {
|
|
316
|
+
item.serialize(this);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export function ensureBoolean(value: unknown): asserts value is boolean {
|
|
322
|
+
if (typeof value !== "boolean") {
|
|
323
|
+
throw new Error(`${value} is not a boolean value`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export const outOfRangeErrorMessage = (value: AnyNumber, min: AnyNumber, max: AnyNumber) =>
|
|
328
|
+
`${value} is out of range: [${min}, ${max}]`;
|
|
329
|
+
|
|
330
|
+
export function validateNumberInRange<T extends AnyNumber>(value: T, minValue: T, maxValue: T) {
|
|
331
|
+
const valueBigInt = BigInt(value);
|
|
332
|
+
if (valueBigInt > BigInt(maxValue) || valueBigInt < BigInt(minValue)) {
|
|
333
|
+
throw new Error(outOfRangeErrorMessage(value, minValue, maxValue));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* A decorator to ensure the input argument for a function is within a range.
|
|
339
|
+
* @param minValue The input argument must be >= minValue
|
|
340
|
+
* @param maxValue The input argument must be <= maxValue
|
|
341
|
+
*/
|
|
342
|
+
function checkNumberRange<T extends AnyNumber>(minValue: T, maxValue: T) {
|
|
343
|
+
return (target: unknown, propertyKey: string, descriptor: PropertyDescriptor) => {
|
|
344
|
+
const childFunction = descriptor.value;
|
|
345
|
+
// eslint-disable-next-line no-param-reassign
|
|
346
|
+
descriptor.value = function deco(value: AnyNumber) {
|
|
347
|
+
validateNumberInRange(value, minValue, maxValue);
|
|
348
|
+
return childFunction.apply(this, [value]);
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
return descriptor;
|
|
352
|
+
};
|
|
353
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import aptosClient from "@aptos-labs/aptos-client";
|
|
5
|
+
import { AptosConfig } from "../api/aptosConfig";
|
|
6
|
+
import { AptosApiError, AptosResponse } from "./types";
|
|
7
|
+
import { ClientConfig, AptosRequest, MimeType } from "../types";
|
|
8
|
+
import { VERSION } from "../version";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Meaningful errors map
|
|
12
|
+
*/
|
|
13
|
+
const errors: Record<number, string> = {
|
|
14
|
+
400: "Bad Request",
|
|
15
|
+
401: "Unauthorized",
|
|
16
|
+
403: "Forbidden",
|
|
17
|
+
404: "Not Found",
|
|
18
|
+
429: "Too Many Requests",
|
|
19
|
+
500: "Internal Server Error",
|
|
20
|
+
502: "Bad Gateway",
|
|
21
|
+
503: "Service Unavailable",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Given a url and method, sends the request with axios and
|
|
26
|
+
* returns the response.
|
|
27
|
+
*/
|
|
28
|
+
async function request<Req, Res>(
|
|
29
|
+
url: string,
|
|
30
|
+
method: "GET" | "POST",
|
|
31
|
+
body?: Req,
|
|
32
|
+
contentType?: string,
|
|
33
|
+
params?: any,
|
|
34
|
+
overrides?: ClientConfig,
|
|
35
|
+
): Promise<any> {
|
|
36
|
+
const headers: Record<string, string | string[] | undefined> = {
|
|
37
|
+
...overrides?.HEADERS,
|
|
38
|
+
"x-aptos-client": `aptos-ts-sdk/${VERSION}`,
|
|
39
|
+
"content-type": contentType ?? MimeType.JSON,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
if (overrides?.TOKEN) {
|
|
43
|
+
headers.Authorization = `Bearer ${overrides?.TOKEN}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
* make a call using the @aptos-labs/aptos-client package
|
|
48
|
+
* {@link https://www.npmjs.com/package/@aptos-labs/aptos-client}
|
|
49
|
+
*/
|
|
50
|
+
return aptosClient<Res>({
|
|
51
|
+
url,
|
|
52
|
+
method,
|
|
53
|
+
body,
|
|
54
|
+
params,
|
|
55
|
+
headers,
|
|
56
|
+
overrides,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The main function to use when doing an API request.
|
|
62
|
+
*
|
|
63
|
+
* @param options AptosRequest
|
|
64
|
+
* @param aptosConfig The config information for the SDK client instance
|
|
65
|
+
* @returns the response or AptosApiError
|
|
66
|
+
*/
|
|
67
|
+
export async function aptosRequest<Req, Res>(
|
|
68
|
+
options: AptosRequest,
|
|
69
|
+
aptosConfig: AptosConfig,
|
|
70
|
+
): Promise<AptosResponse<Req, Res>> {
|
|
71
|
+
const { url, path, method, body, contentType, params, overrides } = options;
|
|
72
|
+
const fullUrl = `${url}/${path ?? ""}`;
|
|
73
|
+
const response = await request<Req, Res>(fullUrl, method, body, contentType, params, overrides);
|
|
74
|
+
const result: AptosResponse<Req, Res> = {
|
|
75
|
+
status: response.status,
|
|
76
|
+
statusText: response.statusText!,
|
|
77
|
+
data: response.data,
|
|
78
|
+
headers: response.headers,
|
|
79
|
+
config: response.config,
|
|
80
|
+
url: fullUrl,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// to support both fullnode and indexer responses,
|
|
84
|
+
// check if it is an indexer query, and adjust response.data
|
|
85
|
+
if (aptosConfig.isIndexerRequest(url)) {
|
|
86
|
+
// errors from indexer
|
|
87
|
+
if ((result.data as any).errors) {
|
|
88
|
+
throw new AptosApiError(
|
|
89
|
+
options,
|
|
90
|
+
result,
|
|
91
|
+
response.data.errors[0].message ?? `Unhandled Error ${response.status} : ${response.statusText}`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
result.data = (result.data as any).data as Res;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (result.status >= 200 && result.status < 300) {
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
const errorMessage = errors[result.status];
|
|
101
|
+
throw new AptosApiError(
|
|
102
|
+
options,
|
|
103
|
+
result,
|
|
104
|
+
errorMessage ?? `Unhandled Error ${response.status} : ${response.statusText}`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { AptosConfig } from "../api/aptosConfig";
|
|
2
|
+
import { aptosRequest } from "./core";
|
|
3
|
+
import { AptosResponse } from "./types";
|
|
4
|
+
import { AnyNumber, ClientConfig, MimeType } from "../types";
|
|
5
|
+
import { AptosApiType } from "../utils/const";
|
|
6
|
+
|
|
7
|
+
export type GetRequestOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* The config for the API client
|
|
10
|
+
*/
|
|
11
|
+
aptosConfig: AptosConfig;
|
|
12
|
+
/**
|
|
13
|
+
* The type of API endpoint to call e.g. fullnode, indexer, etc
|
|
14
|
+
*/
|
|
15
|
+
type: AptosApiType;
|
|
16
|
+
/**
|
|
17
|
+
* The name of the API method
|
|
18
|
+
*/
|
|
19
|
+
originMethod: string;
|
|
20
|
+
/**
|
|
21
|
+
* The URL path to the API method
|
|
22
|
+
*/
|
|
23
|
+
path: string;
|
|
24
|
+
/**
|
|
25
|
+
* The content type of the request body
|
|
26
|
+
*/
|
|
27
|
+
contentType?: MimeType;
|
|
28
|
+
/**
|
|
29
|
+
* The accepted content type of the response of the API
|
|
30
|
+
*/
|
|
31
|
+
acceptType?: MimeType;
|
|
32
|
+
/**
|
|
33
|
+
* The query parameters for the request
|
|
34
|
+
*/
|
|
35
|
+
params?: Record<string, string | AnyNumber | boolean | undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* Specific client overrides for this request to override aptosConfig
|
|
38
|
+
*/
|
|
39
|
+
overrides?: ClientConfig;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type GetAptosRequestOptions = Omit<GetRequestOptions, "type">;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Main function to do a Get request
|
|
46
|
+
*
|
|
47
|
+
* @param options GetRequestOptions
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
export async function get<Req, Res>(options: GetRequestOptions): Promise<AptosResponse<Req, Res>> {
|
|
51
|
+
const { aptosConfig, overrides, params, contentType, acceptType, path, originMethod, type } = options;
|
|
52
|
+
const url = aptosConfig.getRequestUrl(type);
|
|
53
|
+
|
|
54
|
+
return aptosRequest<Req, Res>(
|
|
55
|
+
{
|
|
56
|
+
url,
|
|
57
|
+
method: "GET",
|
|
58
|
+
originMethod,
|
|
59
|
+
path,
|
|
60
|
+
contentType: contentType?.valueOf(),
|
|
61
|
+
acceptType: acceptType?.valueOf(),
|
|
62
|
+
params,
|
|
63
|
+
overrides: {
|
|
64
|
+
...aptosConfig,
|
|
65
|
+
...overrides,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
aptosConfig,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function getAptosFullNode<Req, Res>(options: GetAptosRequestOptions): Promise<AptosResponse<Req, Res>> {
|
|
73
|
+
return get<Req, Res>({ ...options, type: AptosApiType.FULLNODE });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// This function is a helper for paginating using a function wrapping an API
|
|
77
|
+
export async function paginateWithCursor<Req extends Record<string, any>, Res extends any[]>(
|
|
78
|
+
options: GetAptosRequestOptions,
|
|
79
|
+
): Promise<Res> {
|
|
80
|
+
const out = [];
|
|
81
|
+
let cursor: string | undefined;
|
|
82
|
+
const requestParams = options.params as Req & { start?: string; limit?: number };
|
|
83
|
+
// eslint-disable-next-line no-constant-condition
|
|
84
|
+
while (true) {
|
|
85
|
+
requestParams.start = cursor;
|
|
86
|
+
// eslint-disable-next-line no-await-in-loop
|
|
87
|
+
const response = await getAptosFullNode<Req, Res>({
|
|
88
|
+
aptosConfig: options.aptosConfig,
|
|
89
|
+
originMethod: options.originMethod,
|
|
90
|
+
path: options.path,
|
|
91
|
+
params: requestParams,
|
|
92
|
+
overrides: options.overrides,
|
|
93
|
+
});
|
|
94
|
+
/**
|
|
95
|
+
* the cursor is a "state key" from the API perspective. Client
|
|
96
|
+
* should not need to "care" what it represents but just use it
|
|
97
|
+
* to query the next chunk of data.
|
|
98
|
+
*/
|
|
99
|
+
cursor = response.headers["x-aptos-cursor"];
|
|
100
|
+
// Now that we have the cursor (if any), we remove the headers before
|
|
101
|
+
// adding these to the output of this function.
|
|
102
|
+
delete (response as any).headers;
|
|
103
|
+
out.push(...response.data);
|
|
104
|
+
if (cursor === null || cursor === undefined) {
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return out as any;
|
|
109
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { AptosConfig } from "../api/aptosConfig";
|
|
5
|
+
import { aptosRequest } from "./core";
|
|
6
|
+
import { AptosResponse } from "./types";
|
|
7
|
+
import { AnyNumber, ClientConfig, MimeType } from "../types";
|
|
8
|
+
import { AptosApiType } from "../utils/const";
|
|
9
|
+
|
|
10
|
+
export type PostRequestOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* The config for the API client
|
|
13
|
+
*/
|
|
14
|
+
aptosConfig: AptosConfig;
|
|
15
|
+
/**
|
|
16
|
+
* The type of API endpoint to call e.g. fullnode, indexer, etc
|
|
17
|
+
*/
|
|
18
|
+
type: AptosApiType;
|
|
19
|
+
/**
|
|
20
|
+
* The name of the API method
|
|
21
|
+
*/
|
|
22
|
+
originMethod: string;
|
|
23
|
+
/**
|
|
24
|
+
* The URL path to the API method
|
|
25
|
+
*/
|
|
26
|
+
path: string;
|
|
27
|
+
/**
|
|
28
|
+
* The content type of the request body
|
|
29
|
+
*/
|
|
30
|
+
contentType?: MimeType;
|
|
31
|
+
/**
|
|
32
|
+
* The accepted content type of the response of the API
|
|
33
|
+
*/
|
|
34
|
+
acceptType?: MimeType;
|
|
35
|
+
/**
|
|
36
|
+
* The query parameters for the request
|
|
37
|
+
*/
|
|
38
|
+
params?: Record<string, string | AnyNumber | boolean | undefined>;
|
|
39
|
+
/**
|
|
40
|
+
* The body of the request, should match teh content type of the request
|
|
41
|
+
*/
|
|
42
|
+
body?: any;
|
|
43
|
+
/**
|
|
44
|
+
* Specific client overrides for this request to override aptosConfig
|
|
45
|
+
*/
|
|
46
|
+
overrides?: ClientConfig;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type PostAptosRequestOptions = Omit<PostRequestOptions, "type">;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Main function to do a Post request
|
|
53
|
+
*
|
|
54
|
+
* @param options PostRequestOptions
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
57
|
+
export async function post<Req, Res>(options: PostRequestOptions): Promise<AptosResponse<Req, Res>> {
|
|
58
|
+
const { type, originMethod, path, body, acceptType, contentType, params, aptosConfig, overrides } = options;
|
|
59
|
+
const url = aptosConfig.getRequestUrl(type);
|
|
60
|
+
|
|
61
|
+
return aptosRequest<Req, Res>(
|
|
62
|
+
{
|
|
63
|
+
url,
|
|
64
|
+
method: "POST",
|
|
65
|
+
originMethod,
|
|
66
|
+
path,
|
|
67
|
+
body,
|
|
68
|
+
contentType: contentType?.valueOf(),
|
|
69
|
+
acceptType: acceptType?.valueOf(),
|
|
70
|
+
params,
|
|
71
|
+
overrides: {
|
|
72
|
+
...aptosConfig,
|
|
73
|
+
...overrides,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
aptosConfig,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function postAptosFullNode<Req, Res>(options: PostAptosRequestOptions): Promise<AptosResponse<Req, Res>> {
|
|
81
|
+
return post<Req, Res>({ ...options, type: AptosApiType.FULLNODE });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export async function postAptosIndexer<Req, Res>(options: PostAptosRequestOptions): Promise<AptosResponse<Req, Res>> {
|
|
85
|
+
return post<Req, Res>({ ...options, type: AptosApiType.INDEXER });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function postAptosFaucet<Req, Res>(options: PostAptosRequestOptions): Promise<AptosResponse<Req, Res>> {
|
|
89
|
+
return post<Req, Res>({ ...options, type: AptosApiType.FAUCET });
|
|
90
|
+
}
|