@stellar/typescript-wallet-sdk 1.2.0 → 1.3.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.
Files changed (96) hide show
  1. package/.eslintrc.js +76 -0
  2. package/.github/workflows/integrationTest.yml +19 -0
  3. package/.github/workflows/runTests.yml +14 -0
  4. package/.husky/pre-commit +1 -0
  5. package/README.md +19 -12
  6. package/examples/sep24/.env.example +4 -0
  7. package/examples/sep24/README.md +17 -0
  8. package/examples/sep24/sep24.ts +69 -14
  9. package/examples/tsconfig.json +10 -0
  10. package/jest.config.js +1 -0
  11. package/jest.integration.config.js +9 -0
  12. package/lib/bundle.js +6929 -2377
  13. package/lib/bundle.js.map +1 -1
  14. package/lib/bundle_browser.js +6915 -2410
  15. package/lib/bundle_browser.js.map +1 -1
  16. package/lib/index.d.ts +1 -1
  17. package/lib/walletSdk/Anchor/Sep24.d.ts +65 -22
  18. package/lib/walletSdk/Anchor/Sep38.d.ts +56 -0
  19. package/lib/walletSdk/Anchor/Sep6.d.ts +127 -0
  20. package/lib/walletSdk/Anchor/index.d.ts +91 -1
  21. package/lib/walletSdk/Asset/index.d.ts +11 -1
  22. package/lib/walletSdk/Auth/WalletSigner.d.ts +41 -1
  23. package/lib/walletSdk/Auth/index.d.ts +21 -0
  24. package/lib/walletSdk/Customer/index.d.ts +70 -0
  25. package/lib/walletSdk/Exceptions/index.d.ts +45 -2
  26. package/lib/walletSdk/Horizon/AccountService.d.ts +30 -20
  27. package/lib/walletSdk/Horizon/Stellar.d.ts +79 -2
  28. package/lib/walletSdk/Horizon/Transaction/CommonTransactionBuilder.d.ts +57 -0
  29. package/lib/walletSdk/Horizon/Transaction/SponsoringBuilder.d.ts +38 -0
  30. package/lib/walletSdk/Horizon/Transaction/TransactionBuilder.d.ts +112 -11
  31. package/lib/walletSdk/Horizon/index.d.ts +3 -1
  32. package/lib/walletSdk/Recovery/AccountRecover.d.ts +58 -0
  33. package/lib/walletSdk/Recovery/index.d.ts +69 -7
  34. package/lib/walletSdk/Types/anchor.d.ts +17 -2
  35. package/lib/walletSdk/Types/auth.d.ts +14 -1
  36. package/lib/walletSdk/Types/horizon.d.ts +17 -6
  37. package/lib/walletSdk/Types/index.d.ts +15 -3
  38. package/lib/walletSdk/Types/recovery.d.ts +128 -0
  39. package/lib/walletSdk/Types/sep12.d.ts +57 -0
  40. package/lib/walletSdk/Types/sep38.d.ts +93 -0
  41. package/lib/walletSdk/Types/sep6.d.ts +160 -0
  42. package/lib/walletSdk/Types/watcher.d.ts +7 -2
  43. package/lib/walletSdk/Utils/extractAxiosErrorData.d.ts +2 -0
  44. package/lib/walletSdk/Utils/index.d.ts +1 -0
  45. package/lib/walletSdk/Utils/toml.d.ts +2 -2
  46. package/lib/walletSdk/Watcher/getTransactions.d.ts +8 -0
  47. package/lib/walletSdk/Watcher/index.d.ts +41 -4
  48. package/lib/walletSdk/index.d.ts +43 -5
  49. package/package.json +17 -4
  50. package/src/index.ts +2 -0
  51. package/src/walletSdk/Anchor/Sep24.ts +93 -86
  52. package/src/walletSdk/Anchor/Sep38.ts +180 -0
  53. package/src/walletSdk/Anchor/Sep6.ts +291 -0
  54. package/src/walletSdk/Anchor/index.ts +138 -5
  55. package/src/walletSdk/Asset/index.ts +21 -4
  56. package/src/walletSdk/Auth/WalletSigner.ts +23 -5
  57. package/src/walletSdk/Auth/index.ts +24 -5
  58. package/src/walletSdk/Customer/index.ts +174 -0
  59. package/src/walletSdk/Exceptions/index.ts +115 -4
  60. package/src/walletSdk/Horizon/AccountService.ts +33 -21
  61. package/src/walletSdk/Horizon/Stellar.ts +89 -5
  62. package/src/walletSdk/Horizon/Transaction/CommonTransactionBuilder.ts +43 -4
  63. package/src/walletSdk/Horizon/Transaction/SponsoringBuilder.ts +30 -7
  64. package/src/walletSdk/Horizon/Transaction/TransactionBuilder.ts +88 -15
  65. package/src/walletSdk/Horizon/index.ts +2 -1
  66. package/src/walletSdk/Recovery/AccountRecover.ts +255 -0
  67. package/src/walletSdk/Recovery/index.ts +314 -13
  68. package/src/walletSdk/Types/anchor.ts +23 -2
  69. package/src/walletSdk/Types/auth.ts +36 -2
  70. package/src/walletSdk/Types/horizon.ts +7 -5
  71. package/src/walletSdk/Types/index.ts +17 -4
  72. package/src/walletSdk/Types/recovery.ts +152 -0
  73. package/src/walletSdk/Types/sep12.ts +61 -0
  74. package/src/walletSdk/Types/sep38.ts +106 -0
  75. package/src/walletSdk/Types/sep6.ts +168 -0
  76. package/src/walletSdk/Types/watcher.ts +8 -2
  77. package/src/walletSdk/Utils/camelToSnakeCase.ts +1 -0
  78. package/src/walletSdk/Utils/extractAxiosErrorData.ts +28 -0
  79. package/src/walletSdk/Utils/index.ts +1 -0
  80. package/src/walletSdk/Utils/toml.ts +2 -2
  81. package/src/walletSdk/Watcher/getTransactions.ts +65 -0
  82. package/src/walletSdk/Watcher/index.ts +70 -9
  83. package/src/walletSdk/index.ts +45 -8
  84. package/test/README.md +18 -0
  85. package/test/accountService.test.ts +21 -3
  86. package/test/customer.test.ts +82 -0
  87. package/test/docker/docker-compose.yml +97 -0
  88. package/test/integration.test.ts +166 -0
  89. package/test/recovery.test.ts +107 -0
  90. package/test/sep38.test.ts +71 -0
  91. package/test/sep6.test.ts +240 -0
  92. package/test/stellar.test.ts +57 -12
  93. package/test/transaction.test.ts +8 -10
  94. package/test/tsconfig.json +10 -0
  95. package/test/utils/index.ts +12 -0
  96. package/test/wallet.test.ts +60 -21
@@ -0,0 +1,174 @@
1
+ import { AxiosInstance } from "axios";
2
+ import queryString from "query-string";
3
+ import { Sep9InfoRequiredError, CustomerNotFoundError } from "../Exceptions";
4
+ import {
5
+ CustomerInfoMap,
6
+ GetCustomerParams,
7
+ GetCustomerResponse,
8
+ AddCustomerResponse,
9
+ AddCustomerParams,
10
+ AuthToken,
11
+ } from "../Types";
12
+
13
+ /**
14
+ * KYC management with Sep-12.
15
+ * @see {@link https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md}
16
+ * Do not create this object directly, use the Anchor class.
17
+ * @class
18
+ */
19
+ export class Sep12 {
20
+ private authToken;
21
+ private baseUrl;
22
+ private httpClient;
23
+ private headers;
24
+
25
+ /**
26
+ * Creates a new instance of the Sep12 class.
27
+ * @constructor
28
+ * @param {AuthToken} authToken - The authentication token for authenticating with the server.
29
+ * @param {string} baseUrl - The KYC url.
30
+ * @param {AxiosInstance} httpClient - An Axios instance for making HTTP requests.
31
+ */
32
+ constructor(
33
+ authToken: AuthToken,
34
+ baseUrl: string,
35
+ httpClient: AxiosInstance,
36
+ ) {
37
+ this.authToken = authToken;
38
+ this.baseUrl = baseUrl;
39
+ this.httpClient = httpClient;
40
+ this.headers = {
41
+ "Content-Type": "application/json",
42
+ Authorization: `Bearer ${this.authToken.token}`,
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Retrieve customer information. All arguments are optional, but at least one
48
+ * must be given. For more information:
49
+ * @see {@link https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md#request}
50
+ * @param {object} params - The parameters for retrieving customer information.
51
+ * @param {string} [params.id] - The id of the customer .
52
+ * @param {string} [params.type] - The type of action the customer is being KYCd for.
53
+ * @see {@link https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md#type-specification}
54
+ * @param {string} [params.memo] - A memo associated with the customer.
55
+ * @param {string} [params.lang] - The desired language. Defaults to "en".
56
+ * @returns {Promise<GetCustomerResponse>} The customer information.
57
+ * @throws {CustomerNotFoundError} If the customer is not found.
58
+ */
59
+ async getCustomer(params: GetCustomerParams): Promise<GetCustomerResponse> {
60
+ const qs = queryString.stringify(params);
61
+ const resp = await this.httpClient.get(`${this.baseUrl}/customer?${qs}`, {
62
+ headers: this.headers,
63
+ });
64
+ if (!resp.data.id) {
65
+ throw new CustomerNotFoundError(params);
66
+ }
67
+ return resp;
68
+ }
69
+
70
+ /**
71
+ * Add a new customer. Customer info is given in sep9Info param. If it
72
+ * is binary type (eg. Buffer of an image) include it in sep9BinaryInfo.
73
+ * @param {AddCustomerParams} params - The parameters for adding a customer.
74
+ * @param {CustomerInfoMap} [params.sep9Info] - Customer information. What fields you should
75
+ * give is indicated by the anchor.
76
+ * @param {CustomerInfoMap} [params.sep9BinaryInfo] - Customer information that is in binary
77
+ * format (eg. Buffer of an image).
78
+ * @param {string} [params.type] - The type of the customer.
79
+ * @param {string} [params.memo] - A memo associated with the customer.
80
+ * @returns {Promise<AddCustomerResponse>} Add customer response.
81
+ */
82
+ async add({
83
+ sep9Info,
84
+ sep9BinaryInfo,
85
+ type,
86
+ memo,
87
+ }: AddCustomerParams): Promise<AddCustomerResponse> {
88
+ let customerMap: CustomerInfoMap = { ...sep9Info, ...sep9BinaryInfo };
89
+ if (type) {
90
+ customerMap = { type, ...customerMap };
91
+ }
92
+ if (memo) {
93
+ customerMap["memo"] = memo;
94
+ }
95
+
96
+ // Check if binary data given so can adjust headers
97
+ const includesBinary = sep9BinaryInfo && Object.keys(sep9BinaryInfo).length;
98
+ const resp = await this.httpClient.put(
99
+ `${this.baseUrl}/customer`,
100
+ customerMap,
101
+ {
102
+ headers: includesBinary
103
+ ? { ...this.headers, "Content-Type": "multipart/form-data" }
104
+ : this.headers,
105
+ },
106
+ );
107
+ return resp;
108
+ }
109
+
110
+ /**
111
+ * Updates an existing customer. Customer info is given in sep9Info param. If it
112
+ * is binary type (eg. Buffer of an image) include it in sep9BinaryInfo.
113
+ * @param {AddCustomerParams} params - The parameters for adding a customer.
114
+ * @param {CustomerInfoMap} [params.sep9Info] - Customer information. What fields you should
115
+ * give is indicated by the anchor.
116
+ * @param {CustomerInfoMap} [params.sep9BinaryInfo] - Customer information that is in binary
117
+ * format (eg. Buffer of an image).
118
+ * @param {string} [params.id] - The id of the customer.
119
+ * @param {string} [params.type] - The type of the customer.
120
+ * @param {string} [params.memo] - A memo associated with the customer.
121
+ * @returns {Promise<AddCustomerResponse>} Add customer response.
122
+ * @throws {Sep9InfoRequiredError} If no SEP-9 info is given.
123
+ */
124
+ async update({
125
+ sep9Info,
126
+ sep9BinaryInfo,
127
+ id,
128
+ type,
129
+ memo,
130
+ }: AddCustomerParams): Promise<AddCustomerResponse> {
131
+ let customerMap: CustomerInfoMap = {};
132
+ if (id) {
133
+ customerMap["id"] = id;
134
+ }
135
+ if (type) {
136
+ customerMap["type"] = type;
137
+ }
138
+ if (memo) {
139
+ customerMap["memo"] = memo;
140
+ }
141
+ if (!Object.keys({ ...sep9Info, ...sep9BinaryInfo }).length) {
142
+ throw new Sep9InfoRequiredError();
143
+ }
144
+ customerMap = { ...customerMap, ...sep9Info, ...sep9BinaryInfo };
145
+
146
+ // Check if binary data given so can adjust headers
147
+ const includesBinary = sep9BinaryInfo && Object.keys(sep9BinaryInfo).length;
148
+ const resp = await this.httpClient.put(
149
+ `${this.baseUrl}/customer`,
150
+ customerMap,
151
+ {
152
+ headers: includesBinary
153
+ ? { ...this.headers, "Content-Type": "multipart/form-data" }
154
+ : this.headers,
155
+ },
156
+ );
157
+ return resp;
158
+ }
159
+
160
+ /**
161
+ * Deletes a customer.
162
+ * @param {string} accountAddress - The account address of the customer to delete.
163
+ * @param {string} [memo] - An optional memo for customer identification.
164
+ */
165
+ async delete(accountAddress?: string, memo?: string) {
166
+ await this.httpClient.delete(
167
+ `${this.baseUrl}/customer/${accountAddress || this.authToken.account}`,
168
+ {
169
+ data: { memo },
170
+ headers: this.headers,
171
+ },
172
+ );
173
+ }
174
+ }
@@ -1,9 +1,28 @@
1
1
  import { Networks, Horizon } from "stellar-sdk";
2
- import { AnchorTransaction, FLOW_TYPE } from "../Types";
2
+ import axios from "axios";
3
+ import {
4
+ AnchorTransaction,
5
+ FLOW_TYPE,
6
+ AxiosErrorData,
7
+ GetCustomerParams,
8
+ } from "../Types";
9
+ import { extractAxiosErrorData } from "../Utils";
3
10
 
4
11
  export class ServerRequestFailedError extends Error {
12
+ data: AxiosErrorData;
13
+
5
14
  constructor(e: Error) {
6
- super(`Server request failed with error: ${e}`);
15
+ if (axios.isAxiosError(e)) {
16
+ const errorData = extractAxiosErrorData(e);
17
+ const message =
18
+ errorData.responseData && Object.keys(errorData.responseData).length > 0
19
+ ? JSON.stringify(errorData.responseData)
20
+ : errorData.statusText;
21
+ super(`Server request failed with error: ${errorData.status} ${message}`);
22
+ this.data = errorData;
23
+ } else {
24
+ super(`Server request failed with error: ${e}`);
25
+ }
7
26
  Object.setPrototypeOf(this, ServerRequestFailedError.prototype);
8
27
  }
9
28
  }
@@ -68,8 +87,8 @@ export class AccountDoesNotExistError extends Error {
68
87
  }
69
88
 
70
89
  export class TransactionSubmitFailedError extends Error {
71
- constructor(response: Horizon.SubmitTransactionResponse) {
72
- super(`Submit transaction failed ${response}`);
90
+ constructor(response: Horizon.HorizonApi.SubmitTransactionResponse) {
91
+ super(`Submit transaction failed ${JSON.stringify(response)}`);
73
92
  Object.setPrototypeOf(this, TransactionSubmitFailedError.prototype);
74
93
  }
75
94
  }
@@ -153,9 +172,101 @@ export class PathPayOnlyOneAmountError extends Error {
153
172
  Object.setPrototypeOf(this, PathPayOnlyOneAmountError.prototype);
154
173
  }
155
174
  }
175
+
156
176
  export class WithdrawalTxMemoError extends Error {
157
177
  constructor() {
158
178
  super(`Error parsing withdrawal transaction memo`);
159
179
  Object.setPrototypeOf(this, WithdrawalTxMemoError.prototype);
160
180
  }
161
181
  }
182
+
183
+ export class Sep9InfoRequiredError extends Error {
184
+ constructor() {
185
+ super(`Sep-9 info required`);
186
+ Object.setPrototypeOf(this, Sep9InfoRequiredError.prototype);
187
+ }
188
+ }
189
+
190
+ export class CustomerNotFoundError extends Error {
191
+ constructor(params: GetCustomerParams) {
192
+ super(`Customer not found using params ${JSON.stringify(params)}`);
193
+ Object.setPrototypeOf(this, CustomerNotFoundError.prototype);
194
+ }
195
+ }
196
+
197
+ export class KYCServerNotFoundError extends Error {
198
+ constructor() {
199
+ super(`Required KYC server URL not found`);
200
+ Object.setPrototypeOf(this, KYCServerNotFoundError.prototype);
201
+ }
202
+ }
203
+
204
+ export class RecoveryServerNotFoundError extends Error {
205
+ constructor(serverKey: string) {
206
+ super(`Server with key ${serverKey} was not found`);
207
+ Object.setPrototypeOf(this, RecoveryServerNotFoundError.prototype);
208
+ }
209
+ }
210
+
211
+ export class RecoveryIdentityNotFoundError extends Error {
212
+ constructor(serverKey: string) {
213
+ super(`Account identity for server ${serverKey} was not specified`);
214
+ Object.setPrototypeOf(this, RecoveryIdentityNotFoundError.prototype);
215
+ }
216
+ }
217
+
218
+ export class NotAllSignaturesFetchedError extends Error {
219
+ constructor() {
220
+ super(`Didn't get all recovery server signatures`);
221
+ Object.setPrototypeOf(this, NotAllSignaturesFetchedError.prototype);
222
+ }
223
+ }
224
+
225
+ export class LostSignerKeyNotFound extends Error {
226
+ constructor() {
227
+ super(`Lost key doesn't belong to the account`);
228
+ Object.setPrototypeOf(this, LostSignerKeyNotFound.prototype);
229
+ }
230
+ }
231
+
232
+ export class NoDeviceKeyForAccountError extends Error {
233
+ constructor() {
234
+ super(`No device key is setup for this account`);
235
+ Object.setPrototypeOf(this, NoDeviceKeyForAccountError.prototype);
236
+ }
237
+ }
238
+
239
+ export class UnableToDeduceKeyError extends Error {
240
+ constructor() {
241
+ super(`Couldn't deduce lost key. Please provide lost key explicitly`);
242
+ Object.setPrototypeOf(this, UnableToDeduceKeyError.prototype);
243
+ }
244
+ }
245
+
246
+ export class NoAccountSignersError extends Error {
247
+ constructor() {
248
+ super(`There are no signers on this recovery server`);
249
+ Object.setPrototypeOf(this, NoAccountSignersError.prototype);
250
+ }
251
+ }
252
+
253
+ export class DeviceKeyEqualsMasterKeyError extends Error {
254
+ constructor() {
255
+ super(`Device key must be different from master (account) key`);
256
+ Object.setPrototypeOf(this, DeviceKeyEqualsMasterKeyError.prototype);
257
+ }
258
+ }
259
+
260
+ export class NoAccountAndNoSponsorError extends Error {
261
+ constructor() {
262
+ super(`Account does not exist and is not sponsored`);
263
+ Object.setPrototypeOf(this, NoAccountAndNoSponsorError.prototype);
264
+ }
265
+ }
266
+
267
+ export class Sep38PriceOnlyOneAmountError extends Error {
268
+ constructor() {
269
+ super("Must give sellAmount or buyAmount value, but not both");
270
+ Object.setPrototypeOf(this, Sep38PriceOnlyOneAmountError.prototype);
271
+ }
272
+ }
@@ -1,4 +1,4 @@
1
- import { Keypair, Networks, Server, ServerApi } from "stellar-sdk";
1
+ import { Keypair, Networks, Horizon } from "stellar-sdk";
2
2
 
3
3
  import { Config } from "walletSdk";
4
4
  import { SigningKeypair } from "./Account";
@@ -10,10 +10,21 @@ import {
10
10
  import { OperationsLimitExceededError } from "../Exceptions";
11
11
 
12
12
  // Do not create this object directly, use the Wallet class.
13
+ /**
14
+ * KYC management with Sep-12.
15
+ * @see {@link https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md}
16
+ * Do not create this object directly, use the Stellar class.
17
+ * @class
18
+ */
13
19
  export class AccountService {
14
- private server: Server;
20
+ private server: Horizon.Server;
15
21
  private network: Networks;
16
22
 
23
+ /**
24
+ * Creates a new instance of the AccountService class.
25
+ * @constructor
26
+ * @param {Config} cfg - Configuration for the service.
27
+ */
17
28
  constructor(cfg: Config) {
18
29
  this.server = cfg.stellar.server;
19
30
  this.network = cfg.stellar.network;
@@ -22,8 +33,7 @@ export class AccountService {
22
33
  /**
23
34
  * Generate new account keypair (public and secret key). This key pair can be
24
35
  * used to create a Stellar account.
25
- *
26
- * @return public key and secret key
36
+ * @returns {SigningKeypair} Keypair capable of signing.
27
37
  */
28
38
  createKeypair(): SigningKeypair {
29
39
  return new SigningKeypair(Keypair.random());
@@ -32,8 +42,8 @@ export class AccountService {
32
42
  /**
33
43
  * Generate new account keypair (public and secret key) from random bytes. This key pair can be
34
44
  * used to create a Stellar account.
35
- *
36
- * @return public key and secret key
45
+ * @param {Buffer} randomBytes - Random bytes to create keypair from.
46
+ * @returns {SigningKeypair} Keypair capable of signing.
37
47
  */
38
48
  createKeypairFromRandom(randomBytes: Buffer): SigningKeypair {
39
49
  return new SigningKeypair(Keypair.fromRawEd25519Seed(randomBytes));
@@ -41,31 +51,31 @@ export class AccountService {
41
51
 
42
52
  /**
43
53
  * Get account information from the Stellar network.
44
- *
45
- * @param accountAddress Stellar address of the account
46
- * @param serverInstance optional Horizon server instance when default doesn't work
47
- * @return account information
54
+ * @param {object} params - The parameters for retrieving account information.
55
+ * @param {string} params.accountAddress - Stellar address of the account.
56
+ * @param {Horizon.HorizonApi.Server} [params.serverInstance=this.server] - Horizon server instance when default doesn't work.
57
+ * @returns {Promise<Horizon.ServerApi.AccountRecord>} Account information.
48
58
  */
49
59
  async getInfo({
50
60
  accountAddress,
51
61
  serverInstance = this.server,
52
62
  }: {
53
63
  accountAddress: string;
54
- serverInstance?: Server;
55
- }): Promise<ServerApi.AccountRecord> {
64
+ serverInstance?: Horizon.Server;
65
+ }): Promise<Horizon.ServerApi.AccountRecord> {
56
66
  return serverInstance.accounts().accountId(accountAddress).call();
57
67
  }
58
68
 
59
69
  /**
60
70
  * Get account operations for the specified Stellar address.
61
- *
62
- * @param accountAddress Stellar address of the account
63
- * @param limit optional how many operations to fetch, maximum is 200, default is 10
64
- * @param order optional data order, ascending or descending, defaults to descending
65
- * @param cursor optional cursor to specify a starting point
66
- * @param includeFailed optional flag to include failed operations, defaults to false
67
- * @return a list of operations
68
- * @throws [OperationsLimitExceededException] when maximum limit of 200 is exceeded
71
+ * @param {object} params - The parameters for retrieving account history.
72
+ * @param {string} params.accountAddress - Stellar address of the account
73
+ * @param {number} [params.limit=HORIZON_LIMIT_DEFAULT] - How many operations to fetch, maximum is 200, default is 10
74
+ * @param {HORIZON_ORDER} [params.order=HORIZON_ORDER.DESC] - Data order, ascending or descending, defaults to descending
75
+ * @param {string} [params.cursor] - Cursor to specify a starting point
76
+ * @param {boolean} [params.includeFailed=false] - Flag to include failed operations.
77
+ * @returns {Promise<Horizon.ServerApi.CollectionPage<Horizon.ServerApi.OperationRecord>>} A list of operations.
78
+ * @throws {OperationsLimitExceededError} when maximum limit of 200 is exceeded.
69
79
  */
70
80
  async getHistory({
71
81
  accountAddress,
@@ -79,7 +89,9 @@ export class AccountService {
79
89
  order?: HORIZON_ORDER;
80
90
  cursor?: string;
81
91
  includeFailed?: boolean;
82
- }): Promise<ServerApi.CollectionPage<ServerApi.OperationRecord>> {
92
+ }): Promise<
93
+ Horizon.ServerApi.CollectionPage<Horizon.ServerApi.OperationRecord>
94
+ > {
83
95
  if (limit > HORIZON_LIMIT_MAX) {
84
96
  throw new OperationsLimitExceededError(HORIZON_LIMIT_MAX);
85
97
  }
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  Account as StellarAccount,
3
- Server,
3
+ Horizon,
4
4
  Transaction,
5
5
  TransactionBuilder as StellarTransactionBuilder,
6
6
  FeeBumpTransaction,
7
7
  } from "stellar-sdk";
8
+ import axios from "axios";
8
9
 
9
10
  import { Config } from "walletSdk";
10
11
  import { AccountService } from "./AccountService";
@@ -23,20 +24,44 @@ import {
23
24
  import { getResultCode } from "../Utils/getResultCode";
24
25
  import { SigningKeypair } from "./Account";
25
26
 
26
- // Do not create this object directly, use the Wallet class.
27
+ /**
28
+ * Interaction with the Stellar Network.
29
+ * Do not create this object directly, use the Wallet class.
30
+ * @class
31
+ */
27
32
  export class Stellar {
28
33
  private cfg: Config;
29
- server: Server;
34
+ server: Horizon.Server;
30
35
 
36
+ /**
37
+ * Creates a new instance of the Stellar class.
38
+ * @constructor
39
+ * @param {Config} cfg - Configuration object.
40
+ */
31
41
  constructor(cfg: Config) {
32
42
  this.cfg = cfg;
33
43
  this.server = cfg.stellar.server;
34
44
  }
35
45
 
46
+ /**
47
+ * Returns an AccountService instance for managing Stellar accounts.
48
+ * @returns {AccountService} An AccountService instance.
49
+ */
36
50
  account(): AccountService {
37
51
  return new AccountService(this.cfg);
38
52
  }
39
53
 
54
+ /**
55
+ * Construct a Stellar transaction.
56
+ * @param {TransactionParams} params - The Transaction params.
57
+ * @param {AccountKeypair} params.sourceAddress - The source account keypair.
58
+ * @param {Horizon.Server.Timebounds | number} [params.timebounds] - The timebounds for the transaction.
59
+ * If a number is given, then timebounds constructed from now to now + number in seconds.
60
+ * @param {number} [params.baseFee] - The base fee for the transaction. Defaults to the config base fee.
61
+ * @param {Memo} [params.memo] - The memo for the transaction.
62
+ * @returns {TransactionBuilder} A TransactionBuilder instance.
63
+ * @throws {AccountDoesNotExistError} If the source account does not exist.
64
+ */
40
65
  async transaction({
41
66
  sourceAddress,
42
67
  baseFee,
@@ -52,7 +77,7 @@ export class Stellar {
52
77
  throw new AccountDoesNotExistError(this.cfg.stellar.network);
53
78
  }
54
79
 
55
- let formattedTimebounds: Server.Timebounds | undefined;
80
+ let formattedTimebounds: Horizon.Server.Timebounds | undefined;
56
81
  if (typeof timebounds === "number") {
57
82
  formattedTimebounds = {
58
83
  minTime: 0,
@@ -71,6 +96,14 @@ export class Stellar {
71
96
  );
72
97
  }
73
98
 
99
+ /**
100
+ * Creates a FeeBumpTransaction instance for increasing the fee of an existing transaction.
101
+ * @param {FeeBumpTransactionParams} params - The Fee Bump Transaction params.
102
+ * @param {AccountKeypair} params.feeAddress - The account that will pay for the transaction's fee.
103
+ * @param {Transaction} params.transaction - The transaction to be fee bumped.
104
+ * @param {number} [params.baseFee] - The base fee (stroops) for the fee bump transaction. Defaults to the config base fee.
105
+ * @returns {FeeBumpTransaction} A FeeBumpTransaction instance.
106
+ */
74
107
  makeFeeBump({
75
108
  feeAddress,
76
109
  transaction,
@@ -84,6 +117,13 @@ export class Stellar {
84
117
  );
85
118
  }
86
119
 
120
+ /**
121
+ * Submits a signed transaction to the server. If the submission fails with status
122
+ * 504 indicating a timeout error, it will automatically retry.
123
+ * @param {Transaction|FeeBumpTransaction} signedTransaction - The signed transaction to submit.
124
+ * @returns {boolean} `true` if the transaction was successfully submitted.
125
+ * @throws {TransactionSubmitFailedError} If the transaction submission fails.
126
+ */
87
127
  async submitTransaction(
88
128
  signedTransaction: Transaction | FeeBumpTransaction,
89
129
  ): Promise<boolean> {
@@ -104,6 +144,25 @@ export class Stellar {
104
144
  }
105
145
  }
106
146
 
147
+ /**
148
+ * Submits a signed transaction. If the submission fails with error code: tx_too_late,
149
+ * then resubmit with an increased base fee.
150
+ * @see {@link https://developers.stellar.org/docs/encyclopedia/error-handling#retrying-until-success-strategy}
151
+ * for more info on this strategy.
152
+ * @param {SubmitWithFeeIncreaseParams} params - The SubmitWithFeeIncrease params.
153
+ * @param {AccountKeypair} params.sourceAddress - The source account keypair.
154
+ * @param {number} params.timeout - The number of seconds from now the transaction is allowed to be submitted.
155
+ * @param {number} params.baseFeeIncrease - The amount to increase base fee (in stroops) if submission fails.
156
+ * @param {(builder: TransactionBuilder) => TransactionBuilder} params.buildingFunction - Function for building the
157
+ * operations of the transactions.
158
+ * @param {(builder: TransactionBuilder) => TransactionBuilder} [params.signerFunction] - Function for signing the transaction.
159
+ * If not given, will use the soure keypair to sign.
160
+ * @param {number} [params.baseFee] - The base fee (stroops) of the transaction.
161
+ * @param {Memo} [params.memo] - The memo of the transaction.
162
+ * @param {number} [params.maxFee] - The max fee allowed (stroops) of the transaction, afterward will stop submitting and throw error.
163
+ * @returns {Transaction} The submitted transaction.
164
+ * @throws {TransactionSubmitWithFeeIncreaseFailedError} If the transaction submission with fee increase fails.
165
+ */
107
166
  async submitWithFeeIncrease({
108
167
  sourceAddress,
109
168
  timeout,
@@ -133,7 +192,7 @@ export class Stellar {
133
192
  }
134
193
 
135
194
  try {
136
- const success = await this.submitTransaction(transaction);
195
+ await this.submitTransaction(transaction);
137
196
  return transaction;
138
197
  } catch (e) {
139
198
  const resultCode = getResultCode(e);
@@ -158,7 +217,32 @@ export class Stellar {
158
217
  }
159
218
  }
160
219
 
220
+ /**
221
+ * Decodes a Stellar transaction from xdr.
222
+ * @param {string} xdr - The XDR representation of the transaction.
223
+ * @returns {Transaction|FeeBumpTransaction} The decoded transaction.
224
+ */
161
225
  decodeTransaction(xdr: string): Transaction | FeeBumpTransaction {
162
226
  return StellarTransactionBuilder.fromXDR(xdr, this.cfg.stellar.network);
163
227
  }
228
+
229
+ /**
230
+ * Returns the recommended fee (stroops) to use in a transaction based on the current
231
+ * stellar network fee stats.
232
+ * @returns {string} The recommended fee amount in stroops.
233
+ */
234
+ async getRecommendedFee(): Promise<string> {
235
+ const stats = await this.server.feeStats();
236
+ return stats.max_fee.mode;
237
+ }
238
+
239
+ /**
240
+ * Funds an account on the stellar test network. If it is already funded then call will error.
241
+ * Please note: only funds on the testnet network.
242
+ * @see {@link https://developers.stellar.org/docs/fundamentals-and-concepts/testnet-and-pubnet#friendbot}
243
+ * @param {string} address - The stellar address.
244
+ */
245
+ async fundTestnetAccount(address: string) {
246
+ await axios.get(`https://friendbot.stellar.org/?addr=${address}`);
247
+ }
164
248
  }
@@ -11,6 +11,12 @@ export abstract class CommonTransactionBuilder<T> {
11
11
  this.operations = operations;
12
12
  }
13
13
 
14
+ /**
15
+ * Add a trustline for an asset so can receive or send it.
16
+ * @param {IssuedAssetId} asset - The asset for which support is added.
17
+ * @param {string} [trustLimit] - The trust limit for the asset.
18
+ * @returns {T} The builder class instance called with.
19
+ */
14
20
  addAssetSupport(asset: IssuedAssetId, trustLimit?: string): T {
15
21
  this.operations.push(
16
22
  StellarSdk.Operation.changeTrust({
@@ -19,13 +25,25 @@ export abstract class CommonTransactionBuilder<T> {
19
25
  source: this.sourceAddress,
20
26
  }),
21
27
  );
22
- return this as any as T;
28
+ return this as unknown as T;
23
29
  }
24
30
 
31
+ /**
32
+ * Remove a trustline for an asset.
33
+ * @param {IssuedAssetId} asset - The asset for which support is added.
34
+ * @returns {T} The builder class instance called with.
35
+ */
25
36
  removeAssetSupport(asset: IssuedAssetId): T {
26
37
  return this.addAssetSupport(asset, "0");
27
38
  }
28
39
 
40
+ /**
41
+ * Add a signer to the account.
42
+ * @see {@link https://developers.stellar.org/docs/encyclopedia/signatures-multisig}
43
+ * @param {AccountKeypair} signerAddress - The new account being added
44
+ * @param {number} signerWeight - The weight given to the new signer.
45
+ * @returns {T} The builder class instance called with.
46
+ */
29
47
  addAccountSigner(signerAddress: AccountKeypair, signerWeight: number): T {
30
48
  this.operations.push(
31
49
  StellarSdk.Operation.setOptions({
@@ -36,13 +54,25 @@ export abstract class CommonTransactionBuilder<T> {
36
54
  },
37
55
  }),
38
56
  );
39
- return this as any as T;
57
+ return this as unknown as T;
40
58
  }
41
59
 
60
+ /**
61
+ * Removes a signer from an account.
62
+ * @see {@link https://developers.stellar.org/docs/encyclopedia/signatures-multisig}
63
+ * @param {AccountKeypair} signerAddress - The new account being added
64
+ * @returns {T} The builder class instance called with.
65
+ */
42
66
  removeAccountSigner(signerAddress: AccountKeypair): T {
43
67
  return this.addAccountSigner(signerAddress, 0);
44
68
  }
45
69
 
70
+ /**
71
+ * Locking an account by setting the master key weight to 0.
72
+ * Be careful, if no other signers then the account will be locked and unable to
73
+ * sign new transactions permanently.
74
+ * @returns {T} The builder class instance called with.
75
+ */
46
76
  lockAccountMasterKey(): T {
47
77
  this.operations.push(
48
78
  StellarSdk.Operation.setOptions({
@@ -50,9 +80,18 @@ export abstract class CommonTransactionBuilder<T> {
50
80
  masterWeight: 0,
51
81
  }),
52
82
  );
53
- return this as any as T;
83
+ return this as unknown as T;
54
84
  }
55
85
 
86
+ /**
87
+ * Set thesholds for an account.
88
+ * @see {@link https://developers.stellar.org/docs/encyclopedia/signatures-multisig#thresholds}
89
+ * @param {object} options - The threshold options.
90
+ * @param {number} [options.low] - The low theshold level.
91
+ * @param {number} [options.medium] - The medium theshold level.
92
+ * @param {number} [options.high] - The high theshold level.
93
+ * @returns {T} The builder class instance called with.
94
+ */
56
95
  setThreshold({
57
96
  low,
58
97
  medium,
@@ -70,6 +109,6 @@ export abstract class CommonTransactionBuilder<T> {
70
109
  highThreshold: high,
71
110
  }),
72
111
  );
73
- return this as any as T;
112
+ return this as unknown as T;
74
113
  }
75
114
  }