@stellar/typescript-wallet-sdk 1.1.0 → 1.1.2

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/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@stellar/typescript-wallet-sdk",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "engines": {
5
5
  "node": ">=18"
6
6
  },
7
+ "browser": "./lib/bundle_browser.js",
7
8
  "main": "./lib/bundle.js",
8
9
  "types": "./lib/index.d.ts",
9
10
  "license": "Apache-2.0",
@@ -21,6 +22,7 @@
21
22
  "eslint": "^8.33.0",
22
23
  "husky": "^8.0.0",
23
24
  "jest": "^29.4.1",
25
+ "npm-run-all": "^4.1.5",
24
26
  "prettier": "^2.0.5",
25
27
  "pretty-quick": "^2.0.1",
26
28
  "sinon": "^15.1.0",
@@ -47,6 +49,8 @@
47
49
  "scripts": {
48
50
  "prepare": "yarn build",
49
51
  "test": "jest --watchAll",
50
- "build": "webpack --config webpack.config.js"
52
+ "build:web": "webpack --config webpack.config.js",
53
+ "build:node": "webpack --env NODE=true --config webpack.config.js",
54
+ "build": "run-p build:web build:node"
51
55
  }
52
56
  }
@@ -1,5 +1,3 @@
1
- import isEqual from "lodash/isEqual";
2
-
3
1
  import { Anchor } from "../Anchor";
4
2
  import {
5
3
  AnchorTransaction,
@@ -151,9 +149,9 @@ export class Watcher {
151
149
  return isInProgress;
152
150
  }
153
151
 
154
- // if we've had the transaction before, only report updates
152
+ // if we've had the transaction before, only report updates if status changed
155
153
  if (registeredTransaction) {
156
- return !isEqual(registeredTransaction, transaction);
154
+ return registeredTransaction.status !== transaction.status;
157
155
  }
158
156
 
159
157
  // if it's NOT a registered transaction, and it's not the first
@@ -296,12 +294,13 @@ export class Watcher {
296
294
  const registeredTransaction =
297
295
  this._transactionsRegistry[assetCode][transaction.id];
298
296
 
299
- // if we've had the transaction before, only report if there is a change
297
+ // if we've had the transaction before, only report if there is a status change
298
+ let isChanged = true;
300
299
  if (
301
300
  registeredTransaction &&
302
- isEqual(registeredTransaction, transaction)
301
+ registeredTransaction.status === transaction.status
303
302
  ) {
304
- return;
303
+ isChanged = false;
305
304
  }
306
305
 
307
306
  this._transactionsRegistry[assetCode][transaction.id] = transaction;
@@ -320,7 +319,9 @@ export class Watcher {
320
319
  isRetry: true,
321
320
  });
322
321
  }, timeout);
323
- onMessage(transaction);
322
+ if (isChanged) {
323
+ onMessage(transaction);
324
+ }
324
325
  } else if (
325
326
  [
326
327
  TransactionStatus.completed,
@@ -64,6 +64,13 @@ describe("SEP-24 flow", () => {
64
64
  let anchor: Anchor;
65
65
  let accountKp: SigningKeypair;
66
66
  let authToken: string;
67
+ const makeTransaction = (eta: number, txStatus: TransactionStatus) => ({
68
+ kind: "deposit",
69
+ id: "TEST",
70
+ status: txStatus,
71
+ status_eta: eta,
72
+ message: "some message",
73
+ });
67
74
  describe("Anchor", () => {
68
75
  beforeAll(() => {
69
76
  const Wal = Wallet.TestNet();
@@ -809,6 +816,56 @@ describe("Anchor", () => {
809
816
  expect(onMessage.callCount).toBe(3);
810
817
  expect(onError.callCount).toBe(0);
811
818
 
819
+ // stops watching
820
+ stop();
821
+ });
822
+ it("should only report transactions with changed status", async () => {
823
+ const txn1 = makeTransaction(0, TransactionStatus.incomplete);
824
+ const txn2 = makeTransaction(0, TransactionStatus.incomplete);
825
+ txn2.message = "message changing";
826
+ const txn3 = makeTransaction(0, TransactionStatus.pending_anchor);
827
+
828
+ const onMessage = sinon.spy((m) => {
829
+ expect(m.message).toBe("some message");
830
+ expect(onMessage.callCount).toBeLessThan(3);
831
+ });
832
+
833
+ const onError = sinon.spy((e) => {
834
+ expect(e).toBeUndefined();
835
+ });
836
+
837
+ // mock default transactions response
838
+ jest
839
+ .spyOn(Sep24.prototype, "getTransactionsForAsset")
840
+ .mockResolvedValueOnce([txn1])
841
+ .mockResolvedValueOnce([txn2])
842
+ .mockResolvedValueOnce([txn3]);
843
+
844
+ // start watching
845
+ const watcher = anchor.sep24().watcher();
846
+ const { stop } = watcher.watchAllTransactions({
847
+ authToken,
848
+ assetCode: "SRT",
849
+ lang: "en-US",
850
+ onMessage,
851
+ onError,
852
+ timeout: 1,
853
+ });
854
+
855
+ // nothing should run at first (async api call in progress)
856
+ expect(onMessage.callCount).toBe(0);
857
+ expect(onError.callCount).toBe(0);
858
+
859
+ clock.next();
860
+ await sleep(1);
861
+ clock.next();
862
+ await sleep(1);
863
+ clock.next();
864
+ await sleep(1);
865
+
866
+ expect(onMessage.callCount).toBe(2);
867
+ expect(onError.callCount).toBe(0);
868
+
812
869
  // stops watching
813
870
  stop();
814
871
  });
@@ -818,13 +875,6 @@ describe("Anchor", () => {
818
875
  let clock: sinon.SinonFakeTimers;
819
876
  let watcher: Watcher;
820
877
 
821
- const makeTransaction = (eta: number, txStatus: TransactionStatus) => ({
822
- kind: "deposit",
823
- id: "TEST",
824
- status: txStatus,
825
- status_eta: eta,
826
- });
827
-
828
878
  beforeEach(async () => {
829
879
  clock = sinon.useFakeTimers(0);
830
880
  watcher = anchor.sep24().watcher();
@@ -1120,7 +1170,7 @@ describe("Anchor", () => {
1120
1170
  });
1121
1171
 
1122
1172
  test("Several pending transactions, one completed, no more after that", async () => {
1123
- const onMessage = sinon.spy(() => {
1173
+ const onMessage = sinon.spy((m) => {
1124
1174
  expect(onMessage.callCount).toBeLessThanOrEqual(8);
1125
1175
  });
1126
1176
 
@@ -1142,27 +1192,31 @@ describe("Anchor", () => {
1142
1192
  .mockResolvedValueOnce(
1143
1193
  makeTransaction(2, TransactionStatus.pending_anchor),
1144
1194
  )
1195
+ // should not be logged to onMessage
1145
1196
  .mockResolvedValueOnce(
1146
- makeTransaction(3, TransactionStatus.pending_external),
1197
+ makeTransaction(3, TransactionStatus.pending_anchor),
1147
1198
  )
1148
1199
  .mockResolvedValueOnce(
1149
- makeTransaction(4, TransactionStatus.pending_stellar),
1200
+ makeTransaction(4, TransactionStatus.pending_external),
1150
1201
  )
1151
1202
  .mockResolvedValueOnce(
1152
- makeTransaction(5, TransactionStatus.pending_trust),
1203
+ makeTransaction(5, TransactionStatus.pending_stellar),
1204
+ )
1205
+ .mockResolvedValueOnce(
1206
+ makeTransaction(6, TransactionStatus.pending_trust),
1153
1207
  )
1154
1208
  .mockResolvedValueOnce(
1155
- makeTransaction(6, TransactionStatus.pending_user_transfer_start),
1209
+ makeTransaction(7, TransactionStatus.pending_user_transfer_start),
1156
1210
  )
1157
1211
  .mockResolvedValueOnce(
1158
- makeTransaction(7, TransactionStatus.pending_user_transfer_complete),
1212
+ makeTransaction(8, TransactionStatus.pending_user_transfer_complete),
1159
1213
  )
1160
- .mockResolvedValueOnce(makeTransaction(8, TransactionStatus.completed))
1214
+ .mockResolvedValueOnce(makeTransaction(9, TransactionStatus.completed))
1161
1215
  .mockResolvedValueOnce(
1162
- makeTransaction(9, TransactionStatus.pending_anchor),
1216
+ makeTransaction(10, TransactionStatus.pending_anchor),
1163
1217
  )
1164
1218
  .mockResolvedValueOnce(
1165
- makeTransaction(10, TransactionStatus.pending_external),
1219
+ makeTransaction(11, TransactionStatus.pending_external),
1166
1220
  );
1167
1221
 
1168
1222
  // start watching
@@ -1206,6 +1260,9 @@ describe("Anchor", () => {
1206
1260
  clock.next();
1207
1261
  await sleep(1);
1208
1262
 
1263
+ clock.next();
1264
+ await sleep(1);
1265
+
1209
1266
  // 1 incomplete + 7 pending transactions
1210
1267
  expect(onMessage.callCount).toBe(8);
1211
1268
  expect(onSuccess.callCount).toBe(0);
@@ -1686,6 +1743,64 @@ describe("Anchor", () => {
1686
1743
  expect(onSuccess.callCount).toBe(0);
1687
1744
  expect(onError.callCount).toBe(1);
1688
1745
  });
1746
+
1747
+ it("should only report transactions with changed status", async () => {
1748
+ const txn1 = makeTransaction(0, TransactionStatus.incomplete);
1749
+ const txn2 = makeTransaction(0, TransactionStatus.incomplete);
1750
+ txn2.message = "message changing";
1751
+ const txn3 = makeTransaction(0, TransactionStatus.pending_anchor);
1752
+
1753
+ const onMessage = sinon.spy((m) => {
1754
+ expect(m.message).toBe("some message");
1755
+ expect(onMessage.callCount).toBeLessThan(3);
1756
+ });
1757
+
1758
+ const onSuccess = sinon.spy(() => {
1759
+ expect(onSuccess.callCount).toBe(0);
1760
+ });
1761
+
1762
+ const onError = sinon.spy((e) => {
1763
+ expect(e).toBeUndefined();
1764
+ });
1765
+
1766
+ // mock default transactions response
1767
+ jest
1768
+ .spyOn(Sep24.prototype, "getTransactionBy")
1769
+ .mockResolvedValueOnce(txn1)
1770
+ .mockResolvedValueOnce(txn2)
1771
+ .mockResolvedValueOnce(txn3);
1772
+
1773
+ // start watching
1774
+ const watcher = anchor.sep24().watcher();
1775
+ const { stop } = watcher.watchOneTransaction({
1776
+ authToken,
1777
+ assetCode: "SRT",
1778
+ id: "TEST",
1779
+ lang: "en-US",
1780
+ onMessage,
1781
+ onSuccess,
1782
+ onError,
1783
+ timeout: 1,
1784
+ });
1785
+
1786
+ // nothing should run at first (async api call in progress)
1787
+ expect(onMessage.callCount).toBe(0);
1788
+ expect(onError.callCount).toBe(0);
1789
+
1790
+ clock.next();
1791
+ await sleep(1);
1792
+ clock.next();
1793
+ await sleep(1);
1794
+ clock.next();
1795
+ await sleep(1);
1796
+
1797
+ expect(onMessage.callCount).toBe(2);
1798
+ expect(onError.callCount).toBe(0);
1799
+ expect(onSuccess.callCount).toBe(0);
1800
+
1801
+ // stops watching
1802
+ stop();
1803
+ });
1689
1804
  });
1690
1805
  });
1691
1806
 
package/webpack.config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const path = require("path");
2
2
 
3
- module.exports = {
3
+ module.exports = (env = { NODE: false }) => ({
4
4
  mode: "development",
5
5
  entry: "./src/index.ts",
6
6
  devtool: "source-map",
@@ -25,10 +25,11 @@ module.exports = {
25
25
  },
26
26
  },
27
27
  output: {
28
- library: "MyLibrary",
28
+ library: "WalletSDK",
29
29
  libraryTarget: "umd",
30
30
  globalObject: "this",
31
- filename: "bundle.js",
31
+ filename: `bundle${!env.NODE ? "_browser" : ""}.js`,
32
32
  path: path.resolve(__dirname, "lib"),
33
33
  },
34
- };
34
+ target: env.NODE ? "node" : "web",
35
+ });
@@ -1,65 +0,0 @@
1
- export declare enum TransactionStatus {
2
- /**
3
- * There is not yet enough information for this transaction to be initiated. Perhaps the user has
4
- * not yet entered necessary info in an interactive flow
5
- */
6
- incomplete = "incomplete",
7
- /**
8
- * The user has not yet initiated their transfer to the anchor. This is the next necessary step in
9
- * any deposit or withdrawal flow after transitioning from `incomplete`
10
- */
11
- pending_user_transfer_start = "pending_user_transfer_start",
12
- /**
13
- * The Stellar payment has been successfully received by the anchor and the off-chain funds are
14
- * available for the customer to pick up. Only used for withdrawal transactions.
15
- */
16
- pending_user_transfer_complete = "pending_user_transfer_complete",
17
- /**
18
- * Pending External deposit/withdrawal has been submitted to external network, but is not yet
19
- * confirmed. This is the status when waiting on Bitcoin or other external crypto network to
20
- * complete a transaction, or when waiting on a bank transfer.
21
- */
22
- pending_external = "pending_external",
23
- /**
24
- * Deposit/withdrawal is being processed internally by anchor. This can also be used when the
25
- * anchor must verify KYC information prior to deposit/withdrawal.
26
- */
27
- pending_anchor = "pending_anchor",
28
- /**
29
- * Deposit/withdrawal operation has been submitted to Stellar network, but is not yet confirmed.
30
- */
31
- pending_stellar = "pending_stellar",
32
- /** The user must add a trustline for the asset for the deposit to complete. */
33
- pending_trust = "pending_trust",
34
- /**
35
- * The user must take additional action before the deposit / withdrawal can complete, for example
36
- * an email or 2fa confirmation of a withdrawal.
37
- */
38
- pending_user = "pending_user",
39
- /** Deposit/withdrawal fully completed */
40
- completed = "completed",
41
- /** The deposit/withdrawal is fully refunded */
42
- refunded = "refunded",
43
- /**
44
- * Funds were never received by the anchor and the transaction is considered abandoned by the
45
- * user. Anchors are responsible for determining when transactions are considered expired.
46
- */
47
- expired = "expired",
48
- /**
49
- * Could not complete deposit because no satisfactory asset/XLM market was available to create the
50
- * account
51
- */
52
- no_market = "no_market",
53
- /** Deposit/withdrawal size less than min_amount. */
54
- too_small = "too_small",
55
- /** Deposit/withdrawal size exceeded max_amount. */
56
- too_large = "too_large",
57
- /** Catch-all for any error not enumerated above. */
58
- error = "error"
59
- }
60
- export type WatcherRefreshFunction = () => void;
61
- export type WatcherStopFunction = () => void;
62
- export interface WatcherResponse {
63
- refresh: WatcherRefreshFunction;
64
- stop: WatcherStopFunction;
65
- }
@@ -1,21 +0,0 @@
1
- export declare class ServerRequestFailedError extends Error {
2
- constructor(e: any);
3
- }
4
- export declare class AssetNotSupportedError extends Error {
5
- constructor(type: any, assetCode: any);
6
- }
7
- export declare class InvalidMemoError extends Error {
8
- constructor();
9
- }
10
- export declare class ClientDomainWithMemoError extends Error {
11
- constructor();
12
- }
13
- export declare class MissingTransactionIdError extends Error {
14
- constructor();
15
- }
16
- export declare class InvalidTransactionResponseError extends Error {
17
- constructor(transactionResponse: any);
18
- }
19
- export declare class InvalidTransactionsResponseError extends Error {
20
- constructor(transactionsResponse: any);
21
- }
@@ -1,4 +0,0 @@
1
- export declare enum NETWORK_URLS {
2
- PUBLIC = "https://horizon.stellar.org",
3
- TESTNET = "https://horizon-testnet.stellar.org"
4
- }
@@ -1,27 +0,0 @@
1
- type ExtraFields = {
2
- [api_key: string]: string;
3
- };
4
- type InteractiveParams = {
5
- accountAddress: string;
6
- assetCode: string;
7
- authToken: string;
8
- lang?: string;
9
- extraFields?: ExtraFields;
10
- fundsAccountAddress?: string;
11
- };
12
- export declare enum FLOW_TYPE {
13
- DEPOSIT = "deposit",
14
- WITHDRAW = "withdraw"
15
- }
16
- export declare class Interactive {
17
- private homeDomain;
18
- private anchor;
19
- private httpClient;
20
- constructor(homeDomain: any, anchor: any, httpClient: any);
21
- deposit(params: InteractiveParams): Promise<any>;
22
- withdraw(params: InteractiveParams): Promise<any>;
23
- flow(params: InteractiveParams & {
24
- type: FLOW_TYPE;
25
- }): Promise<any>;
26
- }
27
- export {};
@@ -1,3 +0,0 @@
1
- export declare class Recovery {
2
- constructor(cfg: any, stellar: any, client: any, servers: any);
3
- }
@@ -1,78 +0,0 @@
1
- export type TomlInfo = {
2
- version: string;
3
- networkPassphrase: string;
4
- federationServer: string;
5
- authServer: string;
6
- transferServer: string;
7
- transferServerSep24: string;
8
- kycServer: string;
9
- webAuthEndpoint: string;
10
- signingKey: string;
11
- horizonUrl: string;
12
- accounts: Array<string>;
13
- uriRequestSigningKey: string;
14
- directPaymentServer: string;
15
- anchorQuoteServer: string;
16
- documentation: {
17
- orgName: string;
18
- orgDba: string;
19
- orgUrl: string;
20
- orgLogo: string;
21
- orgDescription: string;
22
- orgPhysicalAddress: string;
23
- orgPhysicalAddressAttestation: string;
24
- orgPhoneNumber: string;
25
- orgPhoneNumberAttestation: string;
26
- orgKeybase: string;
27
- orgTwitter: string;
28
- orgGithub: string;
29
- orgOfficialEmail: string;
30
- orgSupportEmail: string;
31
- orgLicensingAuthority: string;
32
- orgLicenseType: string;
33
- orgLicenseNumber: string;
34
- };
35
- principals: Array<{
36
- name: string;
37
- email: string;
38
- keybase: string;
39
- telegram: string;
40
- twitter: string;
41
- github: string;
42
- idPhotoHash: string;
43
- verificationPhotoHash: string;
44
- }>;
45
- currencies: Array<{
46
- code: string;
47
- codeTemplate: string;
48
- issuer: string;
49
- status: string;
50
- displayDecimals: string;
51
- name: string;
52
- desc: string;
53
- conditions: string;
54
- image: string;
55
- fixedNumber: string;
56
- maxNumber: string;
57
- isUnlimited: boolean;
58
- isAssetAnchored: boolean;
59
- anchorAssetType: string;
60
- anchorAsset: string;
61
- attestationOfReserve: string;
62
- redemptionInstructions: string;
63
- collateralAddresses: Array<string>;
64
- collateralAddressMessages: Array<string>;
65
- collateralAddressSignatures: Array<string>;
66
- regulated: string;
67
- approvalServer: string;
68
- approvalCriteria: string;
69
- }>;
70
- validators: Array<{
71
- alias: string;
72
- displayName: string;
73
- publicKey: string;
74
- host: string;
75
- history: string;
76
- }>;
77
- };
78
- export declare const parseToml: (toml: any) => TomlInfo;
@@ -1,2 +0,0 @@
1
- export declare const camelToSnakeCaseKey: (key: string) => string;
2
- export declare const camelToSnakeCaseObject: (obj: any) => {};
@@ -1 +0,0 @@
1
- export declare const getUrlDomain: (url: any) => any;
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes