@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
@@ -1,25 +1,50 @@
1
1
  import { Anchor } from "../Anchor";
2
- import { WatchTransactionParams, WatchTransactionsParams, WatcherResponse } from "../Types";
2
+ import { WatchTransactionParams, WatchTransactionsParams, WatcherResponse, WatcherSepType } from "../Types";
3
+ /**
4
+ * Used for watching transaction from an Anchor as part of sep-24.
5
+ * Do not create this object directly, use the Anchor class.
6
+ * @class
7
+ */
3
8
  export declare class Watcher {
4
9
  private anchor;
10
+ private sepType;
5
11
  private _oneTransactionWatcher;
6
12
  private _allTransactionsWatcher?;
7
13
  private _watchOneTransactionRegistry;
8
14
  private _watchAllTransactionsRegistry;
9
15
  private _transactionsRegistry;
10
16
  private _transactionsIgnoredRegistry;
11
- constructor(anchor: Anchor);
17
+ /**
18
+ * Creates a new instance of the Watcher class.
19
+ *
20
+ * @param {Anchor} anchor - The Anchor to watch from.
21
+ * @param {WatcherSepType} sepType - The Sep type the anchor being polled is using
22
+ * (ie. Sep-6 or Sep-24).
23
+ */
24
+ constructor(anchor: Anchor, sepType: WatcherSepType);
12
25
  /**
13
26
  * Watch all transactions returned from a transfer server. When new or
14
27
  * updated transactions come in, run an `onMessage` callback.
15
28
  *
16
29
  * On initial load, it'll return ALL pending transactions via onMessage.
17
30
  * Subsequent messages will be any one of these events:
18
- * - Any new transaction appears
19
- * - Any of the initial pending transactions change any state
31
+ * - Any new transaction appears
32
+ * - Any of the initial pending transactions change any state
20
33
  *
21
34
  * You may also provide an array of transaction ids, `watchlist`, and this
22
35
  * watcher will always react to transactions whose ids are in the watchlist.
36
+ * @param {WatchTransactionsParams} params - The Watch Transactions params.
37
+ * @param {AuthToken} params.authToken - The authentication token used for authenticating with the anchor.
38
+ * @param {string} params.assetCode - The asset code to filter transactions by.
39
+ * @param {Function} params.onMessage - A callback function to handle incoming transaction messages.
40
+ * @param {Function} params.onError - A callback function to handle errors during transaction streaming.
41
+ * @param {Array<string>} [params.watchlist=[]] - An optional array of specific transaction IDs to watch.
42
+ * @param {number} [params.timeout=5000] - The timeout duration for the streaming connection (in milliseconds).
43
+ * @param {boolean} [params.isRetry=false] - Indicates whether this is a retry attempt (optional).
44
+ * @param {string} [params.lang=this.anchor.language] - The desired language (localization) for transaction messages.
45
+ * @param {string} params.kind - The kind of transaction to filter by.
46
+ * @param {string} [params.noOlderThan] - A date and time specifying that transactions older than this value should not be included.
47
+ * @returns {WatcherResponse} An object holding the refresh and stop functions for the watcher.
23
48
  */
24
49
  watchAllTransactions({ authToken, assetCode, onMessage, onError, watchlist, timeout, isRetry, lang, kind, noOlderThan, }: WatchTransactionsParams): WatcherResponse;
25
50
  /**
@@ -28,6 +53,18 @@ export declare class Watcher {
28
53
  * * onSuccess - When the transaction comes back as completed / refunded / expired.
29
54
  * * onError - When there's a runtime error, or the transaction comes back as
30
55
  * no_market / too_small / too_large / error.
56
+ * @param {WatchTransactionParams} params - The Watch Transaction params.
57
+ * @param {AuthToken} params.authToken - The authentication token used for authenticating with th anchor.
58
+ * @param {string} params.assetCode - The asset code to filter transactions by.
59
+ * @param {string} params.id - The id of the transaction to watch.
60
+ * @param {Function} params.onMessage - A callback function to handle incoming transaction messages.
61
+ * @param {Function} params.onSuccess - If a transaction status is in a end state (eg. completed, refunded, expired) then this callback is called.
62
+ * @param {Function} params.onError - A callback function to handle errors during transaction streaming.
63
+ * @param {number} [params.timeout=5000] - The timeout duration for the streaming connection (in milliseconds).
64
+ * @param {boolean} [params.isRetry=false] - Indicates whether this is a retry attempt (optional).
65
+ * @param {string} [params.lang=this.anchor.language] - The desired language (localization) for transaction messages.
66
+ * @returns {WatcherResponse} An object holding the refresh and stop functions for the watcher.
31
67
  */
32
68
  watchOneTransaction({ authToken, assetCode, id, onMessage, onSuccess, onError, timeout, isRetry, lang, }: WatchTransactionParams): WatcherResponse;
33
69
  }
70
+ export * from "./getTransactions";
@@ -1,19 +1,56 @@
1
1
  import { AxiosInstance } from "axios";
2
- import { Networks, Server } from "stellar-sdk";
2
+ import { Networks, Horizon } from "stellar-sdk";
3
3
  import { Anchor } from "./Anchor";
4
4
  import { WalletSigner } from "./Auth";
5
5
  import { Stellar } from "./Horizon";
6
6
  import { Recovery } from "./Recovery";
7
- import { ConfigParams, StellarConfigurationParams, WalletAnchor, WalletParams, WalletRecovery } from "./Types";
7
+ import { ConfigParams, StellarConfigurationParams, WalletAnchor, WalletParams, WalletRecoveryServers } from "./Types";
8
+ /**
9
+ * The Wallet SDK main entry point class. From these class methods you can create a
10
+ * wallet on the Stellar network.
11
+ * @class
12
+ */
8
13
  export declare class Wallet {
9
14
  private cfg;
10
15
  private language;
16
+ /**
17
+ * Creates a Wallet instance configured to the test network.
18
+ * @returns {Wallet} A Wallet instance configured to the test network.
19
+ */
11
20
  static TestNet: () => Wallet;
21
+ /**
22
+ * Creates a Wallet instance configured to the public network.
23
+ * @returns {Wallet} A Wallet instance configured to the public network.
24
+ */
12
25
  static MainNet: () => Wallet;
26
+ /**
27
+ * Creates a new Wallet instance.
28
+ * @param {WalletParams} params - The Wallet params.
29
+ * @param {StellarConfiguration} params.stellarConfiguration - The Stellar configuration.
30
+ * @param {ApplicationConfiguration} params.applicationConfiguration - The Application configuration.
31
+ * @param {string} [params.language] - The default langauge to use.
32
+ */
13
33
  constructor({ stellarConfiguration, applicationConfiguration, language, }: WalletParams);
34
+ /**
35
+ * Create an Anchor instance for interacting with an Anchor.
36
+ * @param {WalletAnchor} params - The anchor params.
37
+ * @param {string} params.homeDomain - The home domain of the anchor. This domain will be used for
38
+ * things like getting the toml info.
39
+ * @param {string} [params.language=this.language] - The language setting for the Anchor.
40
+ * @returns {Anchor} An Anchor instance.
41
+ */
14
42
  anchor({ homeDomain, language }: WalletAnchor): Anchor;
43
+ /**
44
+ * Create a Stellar instance for interacting with the Stellar network.
45
+ * @returns {Stellar} A Stellar instance.
46
+ */
15
47
  stellar(): Stellar;
16
- recovery({ servers }: WalletRecovery): Recovery;
48
+ /**
49
+ * Create a Recovery instance for account recovery using SEP-30.
50
+ * @param {WalletRecoveryServers} servers - A map of recovery servers.
51
+ * @returns {Recovery} A Recovery instance.
52
+ */
53
+ recovery({ servers }: WalletRecoveryServers): Recovery;
17
54
  }
18
55
  export declare class Config {
19
56
  stellar: StellarConfiguration;
@@ -21,7 +58,7 @@ export declare class Config {
21
58
  constructor({ stellarConfiguration, applicationConfiguration, }: ConfigParams);
22
59
  }
23
60
  export declare class StellarConfiguration {
24
- server: Server;
61
+ server: Horizon.Server;
25
62
  network: Networks;
26
63
  horizonUrl: string;
27
64
  baseFee: number;
@@ -34,5 +71,6 @@ export declare const DefaultClient: AxiosInstance;
34
71
  export declare class ApplicationConfiguration {
35
72
  defaultSigner: WalletSigner;
36
73
  defaultClient: AxiosInstance;
37
- constructor(defaultSigner?: WalletSigner, defaultClient?: AxiosInstance);
74
+ defaultClientDomain?: string;
75
+ constructor(defaultSigner?: WalletSigner, defaultClient?: AxiosInstance, defaultClientDomain?: string);
38
76
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stellar/typescript-wallet-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "engines": {
5
5
  "node": ">=18"
6
6
  },
@@ -11,17 +11,22 @@
11
11
  "private": false,
12
12
  "devDependencies": {
13
13
  "@babel/preset-env": "^7.20.2",
14
- "@stellar/eslint-config": "^2.1.2",
15
14
  "@stellar/prettier-config": "^1.0.1",
16
15
  "@stellar/tsconfig": "^1.0.2",
17
16
  "@types/jest": "^29.4.0",
18
17
  "@types/lodash": "^4.14.194",
19
18
  "@types/sinon": "^10.0.15",
19
+ "@typescript-eslint/eslint-plugin": "^6.7.5",
20
+ "@typescript-eslint/parser": "^6.7.5",
20
21
  "babel-jest": "^29.4.1",
21
22
  "crypto-browserify": "^3.12.0",
22
- "eslint": "^8.33.0",
23
+ "dotenv": "^16.3.1",
24
+ "eslint": "^8.51.0",
25
+ "eslint-config-prettier": "^9.0.0",
26
+ "eslint-plugin-jsdoc": "^46.8.2",
23
27
  "husky": "^8.0.0",
24
28
  "jest": "^29.4.1",
29
+ "lint-staged": "^14.0.1",
25
30
  "npm-run-all": "^4.1.5",
26
31
  "prettier": "^2.0.5",
27
32
  "pretty-quick": "^2.0.1",
@@ -41,18 +46,26 @@
41
46
  "jws": "^4.0.0",
42
47
  "lodash": "^4.17.21",
43
48
  "query-string": "^7.1.3",
44
- "stellar-sdk": "^11.0.0-beta.3",
49
+ "stellar-sdk": "^11.0.0-beta.6",
45
50
  "stream-http": "^3.2.0",
46
51
  "url": "^0.11.0",
47
52
  "util": "^0.12.5",
48
53
  "utility-types": "^3.10.0"
49
54
  },
50
55
  "scripts": {
56
+ "lint": "eslint . --ext .ts",
51
57
  "prepare": "husky install",
52
58
  "test": "jest --watchAll",
59
+ "test:ci": "jest --ci",
60
+ "test:integration:ci": "jest --config jest.integration.config.js --ci",
53
61
  "build:web": "webpack --config webpack.config.js",
54
62
  "build:node": "webpack --env NODE=true --config webpack.config.js",
55
63
  "build": "run-p build:web build:node",
56
64
  "example:sep24": "ts-node examples/sep24/sep24.ts"
65
+ },
66
+ "lint-staged": {
67
+ "**/*.ts": [
68
+ "eslint --fix --max-warnings 0"
69
+ ]
57
70
  }
58
71
  }
package/src/index.ts CHANGED
@@ -18,10 +18,12 @@ export { Sep24 } from "./walletSdk/Anchor/Sep24";
18
18
  export { IssuedAssetId, NativeAssetId, FiatAssetId } from "./walletSdk/Asset";
19
19
  export { Sep10, WalletSigner, DefaultSigner } from "./walletSdk/Auth";
20
20
  export {
21
+ AccountKeypair,
21
22
  PublicKeypair,
22
23
  SigningKeypair,
23
24
  AccountService,
24
25
  Stellar,
26
+ CommonTransactionBuilder,
25
27
  TransactionBuilder,
26
28
  SponsoringBuilder,
27
29
  } from "./walletSdk/Horizon";
@@ -1,13 +1,10 @@
1
1
  import { AxiosInstance } from "axios";
2
- import queryString from "query-string";
3
2
 
4
3
  import { Anchor } from "../Anchor";
5
4
  import {
6
5
  AssetNotSupportedError,
7
6
  ServerRequestFailedError,
8
7
  MissingTransactionIdError,
9
- InvalidTransactionResponseError,
10
- InvalidTransactionsResponseError,
11
8
  } from "../Exceptions";
12
9
  import {
13
10
  FLOW_TYPE,
@@ -16,10 +13,14 @@ import {
16
13
  AnchorTransaction,
17
14
  GetTransactionParams,
18
15
  GetTransactionsParams,
19
- TransactionStatus,
20
16
  AnchorServiceInfo,
17
+ WatcherSepType,
21
18
  } from "../Types";
22
- import { Watcher } from "../Watcher";
19
+ import {
20
+ Watcher,
21
+ _getTransactionsForAsset,
22
+ _getTransactionBy,
23
+ } from "../Watcher";
23
24
  import { camelToSnakeCaseObject } from "../Utils";
24
25
 
25
26
  // Let's prevent exporting this constructor type as
@@ -29,11 +30,21 @@ type Sep24Params = {
29
30
  httpClient: AxiosInstance;
30
31
  };
31
32
 
32
- // Do not create this object directly, use the Wallet class.
33
+ /**
34
+ * Interactive flow for deposit and withdrawal using SEP-24.
35
+ * @see {@link https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md}
36
+ * Do not create this object directly, use the Anchor class.
37
+ * @class
38
+ */
33
39
  export class Sep24 {
34
40
  private anchor: Anchor;
35
41
  private httpClient: AxiosInstance;
36
42
 
43
+ /**
44
+ * Creates a new instance of the Sep24 class.
45
+ * @constructor
46
+ * @param {Sep24Params} params - Parameters to initialize the Sep24 instance.
47
+ */
37
48
  constructor(params: Sep24Params) {
38
49
  const { anchor, httpClient } = params;
39
50
 
@@ -41,11 +52,21 @@ export class Sep24 {
41
52
  this.httpClient = httpClient;
42
53
  }
43
54
 
55
+ /**
56
+ * Initiates a deposit request.
57
+ * @param {Sep24PostParams} params - The SEP-24 Post params.
58
+ * @param {string} params.assetCode - The asset to deposit.
59
+ * @param {AuthToken} params.authToken - Authentication token for the request.
60
+ * @param {string} [params.lang] - The language for the request (defaults to the Anchor's language).
61
+ * @param {ExtraFields} [params.extraFields] - Additional fields for the request.
62
+ * @param {Memo} [params.destinationMemo] - Memo information for the destination account.
63
+ * @param {string} [params.destinationAccount] - The destination account for the deposit.
64
+ * @returns {Promise<Sep24PostResponse>} The Sep24 response.
65
+ * @throws {AssetNotSupportedError} If the asset is not supported for deposit.
66
+ */
44
67
  async deposit({
45
68
  assetCode,
46
-
47
69
  authToken,
48
-
49
70
  lang,
50
71
  extraFields,
51
72
  destinationMemo,
@@ -62,6 +83,17 @@ export class Sep24 {
62
83
  });
63
84
  }
64
85
 
86
+ /**
87
+ * Initiates a withdrawal request.
88
+ * @param {Sep24PostParams} params - The SEP-24 Post params.
89
+ * @param {string} params.assetCode - The asset to withdraw.
90
+ * @param {AuthToken} params.authToken - Authentication token for the request.
91
+ * @param {string} [params.lang] - The language for the request (defaults to the Anchor's language).
92
+ * @param {ExtraFields} [params.extraFields] - Additional fields for the request.
93
+ * @param {string} [params.withdrawalAccount] - The withdrawal account.
94
+ * @returns {Promise<Sep24PostResponse>} The Sep24 response.
95
+ * @throws {AssetNotSupportedError} If the asset is not supported for withdrawal.
96
+ */
65
97
  async withdraw({
66
98
  assetCode,
67
99
  authToken,
@@ -106,7 +138,7 @@ export class Sep24 {
106
138
  if (!assets.includes(assetCode)) {
107
139
  throw new AssetNotSupportedError(type, assetCode);
108
140
  }
109
- let memoMap = {};
141
+ const memoMap = {};
110
142
  if (destinationMemo) {
111
143
  memoMap["memo_type"] = destinationMemo.type;
112
144
  memoMap["memo"] = destinationMemo.value;
@@ -125,7 +157,7 @@ export class Sep24 {
125
157
  {
126
158
  headers: {
127
159
  "Content-Type": "application/json",
128
- Authorization: `Bearer ${authToken}`,
160
+ Authorization: `Bearer ${authToken.token}`,
129
161
  },
130
162
  },
131
163
  );
@@ -138,26 +170,35 @@ export class Sep24 {
138
170
  }
139
171
  }
140
172
 
173
+ /**
174
+ * Retrieves information about the Anchor.
175
+ * @returns {Promise<AnchorServiceInfo>} An object containing information about the Anchor.
176
+ * @throws {ServerRequestFailedError} If the server request to fetch information fails.
177
+ */
141
178
  async getServicesInfo(): Promise<AnchorServiceInfo> {
142
179
  return this.anchor.getServicesInfo();
143
180
  }
144
181
 
182
+ /**
183
+ * Creates a new instance of the Watcher class, to watch sep24 transactions.
184
+ * @returns {Watcher} A new Watcher instance.
185
+ */
145
186
  watcher(): Watcher {
146
- return new Watcher(this.anchor);
187
+ return new Watcher(this.anchor, WatcherSepType.SEP24);
147
188
  }
148
189
 
149
190
  /**
150
- * Get single transaction's current status and details. One of the [id], [stellarTransactionId],
151
- * [externalTransactionId] must be provided.
152
- *
153
- * @param authToken auth token of the account authenticated with the anchor
154
- * @param id transaction ID
155
- * @param stellarTransactionId stellar transaction ID
156
- * @param externalTransactionId external transaction ID
157
- * @return transaction object
158
- * @throws [MissingTransactionIdError] if none of the id params is provided
159
- * @throws [InvalidTransactionResponseError] if Anchor returns an invalid transaction
160
- * @throws [ServerRequestFailedError] if server request fails
191
+ * Get single transaction's current status and details from the anchor.
192
+ * @param {GetTransactionParams} params - The Get Transactions params.
193
+ * @param {AuthToken} params.authToken - The authentication token for the account authenticated with the anchor.
194
+ * @param {string} [params.id] - The transaction ID.
195
+ * @param {string} [params.stellarTransactionId] - The Stellar transaction ID.
196
+ * @param {string} [params.externalTransactionId] - The external transaction ID.
197
+ * @param {string} [params.lang] - The language setting.
198
+ * @returns {Promise<AnchorTransaction>} The transaction object.
199
+ * @throws {MissingTransactionIdError} If none of the ID parameters is provided.
200
+ * @throws {InvalidTransactionResponseError} If the anchor returns an invalid transaction response.
201
+ * @throws {ServerRequestFailedError} If the server request fails.
161
202
  */
162
203
  async getTransactionBy({
163
204
  authToken,
@@ -173,53 +214,35 @@ export class Sep24 {
173
214
  const toml = await this.anchor.sep1();
174
215
  const transferServerEndpoint = toml.transferServerSep24;
175
216
 
176
- let qs: { [name: string]: string } = {};
177
-
178
- if (id) {
179
- qs = { id };
180
- } else if (stellarTransactionId) {
181
- qs = { stellar_transaction_id: stellarTransactionId };
182
- } else if (externalTransactionId) {
183
- qs = { external_transaction_id: externalTransactionId };
184
- }
185
-
186
- qs = { lang, ...qs };
187
-
188
- try {
189
- const resp = await this.httpClient.get(
190
- `${transferServerEndpoint}/transaction?${queryString.stringify(qs)}`,
191
- {
192
- headers: {
193
- Authorization: `Bearer ${authToken}`,
194
- },
195
- },
196
- );
197
-
198
- const transaction: AnchorTransaction = resp.data.transaction;
199
-
200
- if (!transaction || Object.keys(transaction).length === 0) {
201
- throw new InvalidTransactionResponseError(transaction);
202
- }
217
+ // Let's convert all params to snake case for the API call
218
+ const apiParams = camelToSnakeCaseObject({
219
+ id,
220
+ stellarTransactionId,
221
+ externalTransactionId,
222
+ lang,
223
+ });
203
224
 
204
- return transaction;
205
- } catch (e) {
206
- throw new ServerRequestFailedError(e);
207
- }
225
+ return _getTransactionBy<AnchorTransaction>(
226
+ authToken,
227
+ apiParams,
228
+ transferServerEndpoint,
229
+ this.httpClient,
230
+ );
208
231
  }
209
232
 
210
233
  /**
211
234
  * Get account's transactions specified by asset and other params.
212
- *
213
- * @param authToken auth token of the account authenticated with the anchor
214
- * @param assetCode target asset to query for
215
- * @param noOlderThan response should contain transactions starting on or after this date & time
216
- * @param limit response should contain at most 'limit' transactions
217
- * @param kind kind of transaction that is desired. E.g.: 'deposit', 'withdrawal'
218
- * @param pagingId response should contain transactions starting prior to this ID (exclusive)
219
- * @param lang desired language (localization), it can also accept locale in the format 'en-US'
220
- * @return list of transactions as requested by the client, sorted in time-descending order
221
- * @throws [InvalidTransactionsResponseError] if Anchor returns an invalid response
222
- * @throws [ServerRequestFailedError] if server request fails
235
+ * @param {GetTransactionParams} params - The Get Transactions params.
236
+ * @param {AuthToken} params.authToken - The authentication token for the account authenticated with the anchor.
237
+ * @param {string} params.assetCode - The target asset to query for.
238
+ * @param {string} [params.noOlderThan] - The response should contain transactions starting on or after this date & time.
239
+ * @param {string} [params.limit] - The response should contain at most 'limit' transactions.
240
+ * @param {string} [params.kind] - The kind of transaction that is desired. E.g.: 'deposit', 'withdrawal'.
241
+ * @param {string} [params.pagingId] - The response should contain transactions starting prior to this ID (exclusive).
242
+ * @param {string} [params.lang] - The desired language (localization), it can also accept locale in the format 'en-US'.
243
+ * @returns {Promise<AnchorTransaction[]>} A list of transactions as requested by the client, sorted in time-descending order.
244
+ * @throws {InvalidTransactionsResponseError} Anchor returns an invalid response.
245
+ * @throws {ServerRequestFailedError} If server request fails.
223
246
  */
224
247
  async getTransactionsForAsset({
225
248
  authToken,
@@ -243,27 +266,11 @@ export class Sep24 {
243
266
  lang,
244
267
  });
245
268
 
246
- try {
247
- const resp = await this.httpClient.get(
248
- `${transferServerEndpoint}/transactions?${queryString.stringify(
249
- apiParams,
250
- )}`,
251
- {
252
- headers: {
253
- Authorization: `Bearer ${authToken}`,
254
- },
255
- },
256
- );
257
-
258
- const transactions: AnchorTransaction[] = resp.data.transactions;
259
-
260
- if (!transactions || !Array.isArray(transactions)) {
261
- throw new InvalidTransactionsResponseError(transactions);
262
- }
263
-
264
- return transactions;
265
- } catch (e) {
266
- throw new ServerRequestFailedError(e);
267
- }
269
+ return _getTransactionsForAsset<AnchorTransaction>(
270
+ authToken,
271
+ apiParams,
272
+ transferServerEndpoint,
273
+ this.httpClient,
274
+ );
268
275
  }
269
276
  }
@@ -0,0 +1,180 @@
1
+ import { AxiosInstance } from "axios";
2
+ import queryString from "query-string";
3
+
4
+ import { Anchor } from "../Anchor";
5
+ import {
6
+ ServerRequestFailedError,
7
+ Sep38PriceOnlyOneAmountError,
8
+ } from "../Exceptions";
9
+ import {
10
+ AuthToken,
11
+ Sep38Info,
12
+ Sep38Params,
13
+ Sep38PricesParams,
14
+ Sep38PriceParams,
15
+ Sep38PricesResponse,
16
+ Sep38PriceResponse,
17
+ Sep38PostQuoteParams,
18
+ Sep38PostQuoteResponse,
19
+ HttpHeaders,
20
+ } from "../Types";
21
+ import { camelToSnakeCaseObject } from "../Utils";
22
+
23
+ /**
24
+ * Quote service using SEP-38. It can be used for getting price quotes from an anchor
25
+ * for exchanging assets.
26
+ * @see {@link https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0038.md}
27
+ * Do not create this object directly, use the Anchor class.
28
+ * @class
29
+ */
30
+ export class Sep38 {
31
+ private anchor: Anchor;
32
+ private httpClient: AxiosInstance;
33
+ private authToken: AuthToken;
34
+ private headers: HttpHeaders;
35
+ private sep38Info: Sep38Info;
36
+
37
+ /**
38
+ * Creates a new instance of the Sep38 class.
39
+ * @constructor
40
+ * @param {Sep38Params} params - Parameters to initialize the Sep38 instance.
41
+ */
42
+ constructor(params: Sep38Params) {
43
+ const { anchor, httpClient, authToken } = params;
44
+
45
+ this.anchor = anchor;
46
+ this.httpClient = httpClient;
47
+ this.authToken = authToken;
48
+ if (authToken) {
49
+ this.headers = {
50
+ "Content-Type": "application/json",
51
+ Authorization: `Bearer ${this.authToken.token}`,
52
+ };
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Get SEP-38 anchor information.
58
+ * If `shouldRefresh` is set to `true`, it fetches fresh values; otherwise, it returns cached values if available.
59
+ * @param {boolean} [shouldRefresh=false] - Flag to force a refresh of TOML values.
60
+ * @returns {Promise<Sep38Info>} - SEP-38 information about the anchor.
61
+ */
62
+ async info(shouldRefresh?: boolean): Promise<Sep38Info> {
63
+ if (this.sep38Info && !shouldRefresh) {
64
+ return this.sep38Info;
65
+ }
66
+
67
+ const { anchorQuoteServer } = await this.anchor.sep1();
68
+
69
+ try {
70
+ const resp = await this.httpClient.get(`${anchorQuoteServer}/info`, {
71
+ headers: this.headers,
72
+ });
73
+ this.sep38Info = resp.data;
74
+ return resp.data;
75
+ } catch (e) {
76
+ throw new ServerRequestFailedError(e);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Get indicative prices of off-chain assets in exchange for a Stellar asset, or vice versa,
82
+ * from an anchor using Sep-38.
83
+ * @param {Sep38PricesParams} params - The parameters for the GET prices request.
84
+ * if the anchor does not require it.
85
+ * @returns {Promise<Sep38PricesResponse>} - SEP-38 /prices response.
86
+ */
87
+ async prices(params: Sep38PricesParams): Promise<Sep38PricesResponse> {
88
+ const { anchorQuoteServer } = await this.anchor.sep1();
89
+
90
+ try {
91
+ const resp = await this.httpClient.get(
92
+ `${anchorQuoteServer}/prices?${queryString.stringify(
93
+ camelToSnakeCaseObject(params),
94
+ )}`,
95
+ {
96
+ headers: this.headers,
97
+ },
98
+ );
99
+ return resp.data;
100
+ } catch (e) {
101
+ throw new ServerRequestFailedError(e);
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Get an indicative price for an an asset pair from and anchor using SEP-38.
107
+ * @param {Sep38PriceParams} params - The parameters for the GET price request.
108
+ * if the anchor does not require it.
109
+ * @throws {Sep38PriceOnlyOneAmountError} Must give only sellAmount or buyAmount, and not both.
110
+ * @returns {Promise<Sep38PriceResponse>} - SEP-38 /price response.
111
+ */
112
+ async price(params: Sep38PriceParams): Promise<Sep38PriceResponse> {
113
+ if (
114
+ (params.sellAmount && params.buyAmount) ||
115
+ (!params.sellAmount && !params.buyAmount)
116
+ ) {
117
+ throw new Sep38PriceOnlyOneAmountError();
118
+ }
119
+ const { anchorQuoteServer } = await this.anchor.sep1();
120
+
121
+ try {
122
+ const resp = await this.httpClient.get(
123
+ `${anchorQuoteServer}/price?${queryString.stringify(
124
+ camelToSnakeCaseObject(params),
125
+ )}`,
126
+ {
127
+ headers: this.headers,
128
+ },
129
+ );
130
+ return resp.data;
131
+ } catch (e) {
132
+ throw new ServerRequestFailedError(e);
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Request a firm quote from the anchor.
138
+ * @param {Sep38PostQuoteParams} params - The parameters for the quote request.
139
+ * @returns {Promise<Sep38PostQuoteResponse>} - SEP-38 quote response.
140
+ */
141
+ async requestQuote(
142
+ params: Sep38PostQuoteParams,
143
+ ): Promise<Sep38PostQuoteResponse> {
144
+ const { anchorQuoteServer } = await this.anchor.sep1();
145
+
146
+ try {
147
+ const resp = await this.httpClient.post(
148
+ `${anchorQuoteServer}/quote`,
149
+ params,
150
+ {
151
+ headers: this.headers,
152
+ },
153
+ );
154
+ return resp.data;
155
+ } catch (e) {
156
+ throw new ServerRequestFailedError(e);
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Get a previously-provided quote from the anchor.
162
+ * @param {string} quoteId - The id of the quote to fetch.
163
+ * @returns {Promise<Sep38PostQuoteResponse>} - SEP-38 quote response.
164
+ */
165
+ async getQuote(quoteId: string): Promise<Sep38PostQuoteResponse> {
166
+ const { anchorQuoteServer } = await this.anchor.sep1();
167
+
168
+ try {
169
+ const resp = await this.httpClient.get(
170
+ `${anchorQuoteServer}/quote/${quoteId}`,
171
+ {
172
+ headers: this.headers,
173
+ },
174
+ );
175
+ return resp.data;
176
+ } catch (e) {
177
+ throw new ServerRequestFailedError(e);
178
+ }
179
+ }
180
+ }