@stellar/typescript-wallet-sdk 3.0.2 → 3.0.3-beta.1786398758713

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.
@@ -1,4 +1,5 @@
1
1
  import {
2
+ Account,
2
3
  Keypair,
3
4
  Memo,
4
5
  MemoText,
@@ -22,6 +23,7 @@ import {
22
23
  import { TransactionStatus, WithdrawTransaction } from "../src/walletSdk/Types";
23
24
  import {
24
25
  TransactionSubmitWithFeeIncreaseFailedError,
26
+ WithdrawalTxMemoError,
25
27
  WithdrawalTxMissingDestinationError,
26
28
  WithdrawalTxMissingMemoError,
27
29
  WithdrawalTxNotPendingUserTransferStartError,
@@ -43,7 +45,7 @@ describe("Stellar", () => {
43
45
  } catch (e) {
44
46
  await stellar.fundTestnetAccount(kp.publicKey);
45
47
  }
46
- }, 10000);
48
+ }, 120000);
47
49
 
48
50
  it("should create and submit a transaction", async () => {
49
51
  const now = Math.floor(Date.now() / 1000) - 5;
@@ -83,7 +85,7 @@ describe("Stellar", () => {
83
85
  }
84
86
  expect(failed).toBeFalsy();
85
87
  }
86
- }, 30000);
88
+ }, 120000);
87
89
 
88
90
  it("should resubmit with fee increase if txn fails", async () => {
89
91
  // mock 1 failed response and then 1 successful to test retry
@@ -128,7 +130,7 @@ describe("Stellar", () => {
128
130
  const feeBumpTx = stellar.makeFeeBump({ feeAddress: kp, transaction });
129
131
  kp.sign(feeBumpTx);
130
132
  await stellar.submitTransaction(feeBumpTx);
131
- }, 10000);
133
+ }, 120000);
132
134
 
133
135
  it("should be able to give a signing keypair", async () => {
134
136
  // mock 1 failed response and then 1 successful to test retry
@@ -240,7 +242,7 @@ describe("Stellar", () => {
240
242
  (b) => (b as Horizon.HorizonApi.BalanceLineAsset).asset_code === "USDC",
241
243
  );
242
244
  expect(balance).toBeFalsy();
243
- }, 20000);
245
+ }, 120000);
244
246
 
245
247
  it("should import and sign a transaction from xdr", () => {
246
248
  const txnXdr =
@@ -371,7 +373,7 @@ describe("Stellar", () => {
371
373
  .build();
372
374
  expect(txn).toBeTruthy();
373
375
  }
374
- }, 20000);
376
+ }, 120000);
375
377
 
376
378
  it("should throw if tx not in pending_user_transfer_start status", async () => {
377
379
  const walletTransaction = {
@@ -400,7 +402,7 @@ describe("Stellar", () => {
400
402
  .transferWithdrawalTransaction(walletTransaction, asset)
401
403
  .build();
402
404
  }).toThrowError(WithdrawalTxNotPendingUserTransferStartError);
403
- }, 5000);
405
+ }, 120000);
404
406
 
405
407
  it("should throw if tx is missing withdraw_anchor_account", async () => {
406
408
  const walletTransaction = {
@@ -428,7 +430,7 @@ describe("Stellar", () => {
428
430
  .transferWithdrawalTransaction(walletTransaction, asset)
429
431
  .build();
430
432
  }).toThrowError(WithdrawalTxMissingDestinationError);
431
- }, 5000);
433
+ }, 120000);
432
434
 
433
435
  it("should throw if tx is missing withdraw_memo_type", async () => {
434
436
  const walletTransaction = {
@@ -457,7 +459,7 @@ describe("Stellar", () => {
457
459
  .transferWithdrawalTransaction(walletTransaction, asset)
458
460
  .build();
459
461
  }).toThrowError(WithdrawalTxMissingMemoError);
460
- }, 5000);
462
+ }, 120000);
461
463
 
462
464
  it("should throw if tx is missing withdraw_memo", async () => {
463
465
  const walletTransaction = {
@@ -486,7 +488,7 @@ describe("Stellar", () => {
486
488
  .transferWithdrawalTransaction(walletTransaction, asset)
487
489
  .build();
488
490
  }).toThrowError(WithdrawalTxMissingMemoError);
489
- }, 5000);
491
+ }, 120000);
490
492
  });
491
493
  });
492
494
 
@@ -507,7 +509,7 @@ describe("SponsoringBuilder", () => {
507
509
  await axios.get(
508
510
  "https://friendbot.stellar.org/?addr=" + txnSourceKp.publicKey,
509
511
  );
510
- }, 15000);
512
+ }, 120000);
511
513
 
512
514
  it("should sponsor creating an account", async () => {
513
515
  const wal = Wallet.TestNet();
@@ -533,7 +535,7 @@ describe("SponsoringBuilder", () => {
533
535
  newKp.publicKey,
534
536
  )) as any;
535
537
  expect(sponsoredLoaded.num_sponsored).toBe(2);
536
- }, 15000);
538
+ }, 120000);
537
539
 
538
540
  it("should sponsor adding trustlines", async () => {
539
541
  const txBuilder = await stellar.transaction({
@@ -558,7 +560,7 @@ describe("SponsoringBuilder", () => {
558
560
  sponsorKp.publicKey,
559
561
  )) as any;
560
562
  expect(sponsorLoaded.num_sponsoring).toBe(3);
561
- }, 15000);
563
+ }, 120000);
562
564
 
563
565
  it("should allow sponsoring and regular operations in same transaction", async () => {
564
566
  const txBuilder = await stellar.transaction({
@@ -586,7 +588,7 @@ describe("SponsoringBuilder", () => {
586
588
  sponsorKp.publicKey,
587
589
  )) as any;
588
590
  expect(sponsorLoaded.num_sponsoring).toBe(3);
589
- }, 15000);
591
+ }, 120000);
590
592
  it("should sponsor account modification", async () => {
591
593
  const txBuilder = await stellar.transaction({
592
594
  sourceAddress: txnSourceKp,
@@ -608,7 +610,7 @@ describe("SponsoringBuilder", () => {
608
610
  sourceLoaded.signers.find((signer) => signer.key === otherKp.publicKey)
609
611
  .weight,
610
612
  ).toBe(2);
611
- }, 15000);
613
+ }, 120000);
612
614
  });
613
615
 
614
616
  describe("Asset", () => {
@@ -716,7 +718,7 @@ describe("Account Modifying", () => {
716
718
 
717
719
  resp = await stellar.server.loadAccount(sourceKp.publicKey);
718
720
  expect(resp.signers[0].weight).toBe(0);
719
- }, 45000);
721
+ }, 120000);
720
722
 
721
723
  it("should merge account", async () => {
722
724
  const wallet = Wallet.TestNet();
@@ -751,5 +753,68 @@ describe("Account Modifying", () => {
751
753
  expect(found).toBeFalsy();
752
754
  const accResp = await stellar.server.loadAccount(accountKp.publicKey);
753
755
  expect(parseInt(accResp.balances[0].balance)).toBeGreaterThan(19998);
754
- }, 30000);
756
+ }, 120000);
757
+ });
758
+
759
+ // Hermetic (no network): stellar-sdk v16 tightened Memo validation, so a
760
+ // malformed anchor-supplied withdrawal memo now throws when the Memo is
761
+ // constructed. transferWithdrawalTransaction must map that to the domain
762
+ // WithdrawalTxMemoError for every memo type, not just "hash".
763
+ describe("transferWithdrawalTransaction memo validation", () => {
764
+ const localKp = SigningKeypair.fromSecret(
765
+ "SAS372GXRG6U7FW6W2PRVELKPOJG2FZZUADCIELWU2U3A45TNWXEQUV5",
766
+ );
767
+ let stellarLocal: Stellar;
768
+
769
+ beforeEach(() => {
770
+ stellarLocal = Wallet.TestNet().stellar();
771
+ sinon
772
+ .stub(stellarLocal.server, "loadAccount")
773
+ .resolves(new Account(localKp.publicKey, "1") as any);
774
+ });
775
+
776
+ afterEach(() => {
777
+ sinon.restore();
778
+ });
779
+
780
+ const buildWithdrawal = (memoType: string, memo: string) =>
781
+ ({
782
+ status: TransactionStatus.pending_user_transfer_start,
783
+ withdraw_anchor_account: localKp.publicKey,
784
+ withdraw_memo_type: memoType,
785
+ withdraw_memo: memo,
786
+ amount_in: "10",
787
+ } as unknown as WithdrawTransaction);
788
+
789
+ const usdc = () => new IssuedAssetId("USDC", localKp.publicKey);
790
+
791
+ it("maps a malformed hash memo to WithdrawalTxMemoError", async () => {
792
+ const builder = await stellarLocal.transaction({ sourceAddress: localKp });
793
+ expect(() =>
794
+ builder.transferWithdrawalTransaction(
795
+ buildWithdrawal("hash", "not-a-valid-hash"),
796
+ usdc(),
797
+ ),
798
+ ).toThrow(WithdrawalTxMemoError);
799
+ });
800
+
801
+ it("maps a malformed id memo to WithdrawalTxMemoError", async () => {
802
+ const builder = await stellarLocal.transaction({ sourceAddress: localKp });
803
+ expect(() =>
804
+ builder.transferWithdrawalTransaction(
805
+ buildWithdrawal("id", "not-a-number"),
806
+ usdc(),
807
+ ),
808
+ ).toThrow(WithdrawalTxMemoError);
809
+ });
810
+
811
+ it("maps an over-long text memo to WithdrawalTxMemoError", async () => {
812
+ const builder = await stellarLocal.transaction({ sourceAddress: localKp });
813
+ expect(() =>
814
+ builder.transferWithdrawalTransaction(
815
+ buildWithdrawal("text", "x".repeat(29)),
816
+ usdc(),
817
+ ),
818
+ ).toThrow(WithdrawalTxMemoError);
819
+ });
755
820
  });
@@ -0,0 +1,102 @@
1
+ import { StellarToml } from "@stellar/stellar-sdk";
2
+ import { parse } from "smol-toml";
3
+
4
+ import { parseToml } from "../src/walletSdk/Utils/toml";
5
+
6
+ // Hermetic coverage for the SEP-1 TOML path. stellar-sdk v16's
7
+ // StellarToml.Resolver.resolve() fetches the raw text and returns
8
+ // `smol-toml`.parse(text) verbatim (no post-processing), so parsing a fixture
9
+ // string with the same parser here is a faithful, network-free stand-in for
10
+ // the whole pipeline: it exercises v16's strict TOML 1.0 parser and our
11
+ // TomlInfo mapping together.
12
+ const parseTomlString = (toml: string) =>
13
+ parseToml(parse(toml) as unknown as StellarToml.Api.StellarToml);
14
+
15
+ describe("parseToml", () => {
16
+ it("parses and maps a fully populated stellar.toml", () => {
17
+ const toml = `
18
+ VERSION = "2.0.0"
19
+ NETWORK_PASSPHRASE = "Test SDF Network ; September 2015"
20
+ SIGNING_KEY = "GBBM6BKZPEHWYO3E3YKREDPQXMS4VK35YLNU7NFBRI26RAN7GI5POFBB"
21
+ WEB_AUTH_ENDPOINT = "https://auth.example.com/auth"
22
+ TRANSFER_SERVER = "https://anchor.example.com/sep6"
23
+ TRANSFER_SERVER_SEP0024 = "https://anchor.example.com/sep24"
24
+ KYC_SERVER = "https://anchor.example.com/kyc"
25
+ HORIZON_URL = "https://horizon.example.com"
26
+ ACCOUNTS = ["GBBM6BKZPEHWYO3E3YKREDPQXMS4VK35YLNU7NFBRI26RAN7GI5POFBB"]
27
+
28
+ [DOCUMENTATION]
29
+ ORG_NAME = "Example Anchor"
30
+ ORG_URL = "https://example.com"
31
+
32
+ [[CURRENCIES]]
33
+ code = "USDC"
34
+ issuer = "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN"
35
+ display_decimals = 2
36
+ is_asset_anchored = true
37
+ anchor_asset_type = "fiat"
38
+ collateral_addresses = ["GADDR1"]
39
+
40
+ [[PRINCIPALS]]
41
+ name = "Jane Doe"
42
+ email = "jane@example.com"
43
+ id_photo_hash = "abc123"
44
+
45
+ [[VALIDATORS]]
46
+ PUBLIC_KEY = "GDVALIDATORXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
47
+ HOST = "core.example.com:11625"
48
+ `;
49
+
50
+ const info = parseTomlString(toml);
51
+
52
+ expect(info.version).toBe("2.0.0");
53
+ expect(info.networkPassphrase).toBe("Test SDF Network ; September 2015");
54
+ expect(info.webAuthEndpoint).toBe("https://auth.example.com/auth");
55
+ expect(info.transferServer).toBe("https://anchor.example.com/sep6");
56
+ expect(info.transferServerSep24).toBe("https://anchor.example.com/sep24");
57
+ expect(info.signingKey).toBe(
58
+ "GBBM6BKZPEHWYO3E3YKREDPQXMS4VK35YLNU7NFBRI26RAN7GI5POFBB",
59
+ );
60
+ expect(info.horizonUrl).toBe("https://horizon.example.com");
61
+
62
+ expect(info.documentation.orgName).toBe("Example Anchor");
63
+ expect(info.documentation.orgUrl).toBe("https://example.com");
64
+
65
+ expect(info.currencies).toHaveLength(1);
66
+ expect(info.currencies[0].code).toBe("USDC");
67
+ // display_decimals is a TOML integer; the mapping preserves the number.
68
+ expect(info.currencies[0].displayDecimals).toBe(2);
69
+ expect(info.currencies[0].isAssetAnchored).toBe(true);
70
+ expect(info.currencies[0].anchorAssetType).toBe("fiat");
71
+ expect(info.currencies[0].collateralAddresses).toEqual(["GADDR1"]);
72
+
73
+ expect(info.principals).toHaveLength(1);
74
+ expect(info.principals[0].name).toBe("Jane Doe");
75
+ expect(info.principals[0].idPhotoHash).toBe("abc123");
76
+
77
+ expect(info.validators).toHaveLength(1);
78
+ expect(info.validators[0].host).toBe("core.example.com:11625");
79
+ expect(info.validators[0].publicKey).toBe(
80
+ "GDVALIDATORXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
81
+ );
82
+ });
83
+
84
+ it("defaults optional array sections to [] when absent", () => {
85
+ const info = parseTomlString(`
86
+ [DOCUMENTATION]
87
+ ORG_NAME = "Example Anchor"
88
+ `);
89
+
90
+ expect(info.principals).toEqual([]);
91
+ expect(info.currencies).toEqual([]);
92
+ expect(info.validators).toEqual([]);
93
+ });
94
+
95
+ it("rejects malformed TOML (v16 smol-toml strict parsing)", () => {
96
+ // Duplicate keys are invalid under TOML 1.0; smol-toml throws where the
97
+ // previous lenient parser may not have.
98
+ expect(() =>
99
+ parseTomlString(`VERSION = "1"\nVERSION = "2"\n[DOCUMENTATION]\n`),
100
+ ).toThrow();
101
+ });
102
+ });
@@ -95,7 +95,7 @@ describe("Muxed Transactions", () => {
95
95
  }
96
96
 
97
97
  expect(didFail).toBeFalsy();
98
- }, 60000);
98
+ }, 120000);
99
99
 
100
100
  it("should send 'native' payment to valid Muxed account", async () => {
101
101
  const baseAccoutKp = SigningKeypair.fromSecret(
@@ -126,7 +126,7 @@ describe("Muxed Transactions", () => {
126
126
  const response = await stellar.submitTransaction(sendNativePaymentTx);
127
127
 
128
128
  expect(response).toBeTruthy();
129
- }, 30000);
129
+ }, 120000);
130
130
 
131
131
  it("should send non-native payment to valid Muxed account", async () => {
132
132
  const baseAccoutKp = SigningKeypair.fromSecret(
@@ -167,7 +167,7 @@ describe("Muxed Transactions", () => {
167
167
  const response = await stellar.submitTransaction(sendNonNativePaymentTx);
168
168
 
169
169
  expect(response).toBeTruthy();
170
- }, 30000);
170
+ }, 120000);
171
171
 
172
172
  it("should return 'op_no_trust' error for sending unsupported Asset to valid Muxed account", async () => {
173
173
  const baseAccoutKp = SigningKeypair.fromSecret(
@@ -206,7 +206,7 @@ describe("Muxed Transactions", () => {
206
206
 
207
207
  expect(resultCodeOperations).toContain("op_no_trust");
208
208
  }
209
- }, 30000);
209
+ }, 120000);
210
210
 
211
211
  it("should return error for sending payment to invalid Muxed address", async () => {
212
212
  const txBuilder = await stellar.transaction({
@@ -277,7 +277,7 @@ describe("Path Payment", () => {
277
277
  sourceKp.sign(txn);
278
278
  await stellar.submitTransaction(txn);
279
279
  }
280
- }, 20000);
280
+ }, 120000);
281
281
 
282
282
  it("should use path payment send", async () => {
283
283
  const txBuilder = await stellar.transaction({
@@ -292,7 +292,7 @@ describe("Path Payment", () => {
292
292
  })
293
293
  .build();
294
294
  expect(txn.operations[0].type).toBe("pathPaymentStrictSend");
295
- }, 15000);
295
+ }, 120000);
296
296
 
297
297
  it("should use path payment receive", async () => {
298
298
  const txBuilder = await stellar.transaction({
@@ -307,7 +307,7 @@ describe("Path Payment", () => {
307
307
  })
308
308
  .build();
309
309
  expect(txn.operations[0].type).toBe("pathPaymentStrictReceive");
310
- }, 15000);
310
+ }, 120000);
311
311
 
312
312
  it("should swap", async () => {
313
313
  const txBuilder = await stellar.transaction({
@@ -319,5 +319,5 @@ describe("Path Payment", () => {
319
319
  sourceKp.sign(txn);
320
320
  const success = await stellar.submitTransaction(txn);
321
321
  expect(success).toBe(true);
322
- }, 15000);
322
+ }, 120000);
323
323
  });
@@ -1932,7 +1932,7 @@ describe("AuthHeaderSigner", () => {
1932
1932
  });
1933
1933
 
1934
1934
  expect(authToken).toBeTruthy();
1935
- }, 15000);
1935
+ }, 120000);
1936
1936
 
1937
1937
  it("should match example implementation generated JWT", async () => {
1938
1938
  const generatedAuthToken =
package/tsconfig.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "esModuleInterop": true,
4
+ "skipLibCheck": true,
4
5
  "baseUrl": "src/",
5
6
  "outDir": "lib",
6
7
  "declaration": true,
package/webpack.config.js CHANGED
@@ -19,6 +19,17 @@ module.exports = (env = { NODE: false }) => {
19
19
  },
20
20
  resolve: {
21
21
  extensions: [".js", ".json", ".ts"],
22
+ alias: {
23
+ // eventsource v4, reached via stellar-sdk's Horizon CallBuilder,
24
+ // subclasses the DOM globals Event and EventTarget at module scope, so
25
+ // importing this package threw "Property 'Event' doesn't exist" on React
26
+ // Native. Unlike the km and soroban packages, this one exposes
27
+ // Horizon.Server publicly, so stubbing eventsource out would break
28
+ // .stream() on web and Node. Defer its evaluation to first use instead.
29
+ eventsource$: path.resolve(__dirname, "src/shims/eventsource.js"),
30
+ // The facade's load target; "eventsource" would resolve back to itself.
31
+ "eventsource-real$": require.resolve("eventsource"),
32
+ },
22
33
  fallback: isBrowser
23
34
  ? {
24
35
  crypto: require.resolve("crypto-browserify"),