@stellar/typescript-wallet-sdk 4.0.1 → 5.0.0-beta.1788566740000

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 (38) hide show
  1. package/CHANGELOG.MD +26 -0
  2. package/examples/sep10/sep10Server.ts +1 -1
  3. package/examples/sep24/sep24.ts +1 -1
  4. package/examples/tsconfig.json +1 -0
  5. package/jest.e2e.config.js +2 -1
  6. package/jest.integration.config.js +2 -1
  7. package/lib/bundle.js +58575 -22165
  8. package/lib/bundle.js.map +1 -1
  9. package/lib/bundle_browser.js +49263 -12814
  10. package/lib/bundle_browser.js.map +1 -1
  11. package/lib/walletSdk/Customer/index.d.ts +4 -4
  12. package/lib/walletSdk/Exceptions/index.d.ts +3 -0
  13. package/lib/walletSdk/Horizon/AccountService.d.ts +2 -3
  14. package/lib/walletSdk/Horizon/Transaction/TransactionBuilder.d.ts +17 -14
  15. package/lib/walletSdk/Types/horizon.d.ts +11 -5
  16. package/lib/walletSdk/Types/sep12.d.ts +1 -2
  17. package/lib/walletSdk/Uri/Sep7Base.d.ts +1 -1
  18. package/package.json +7 -6
  19. package/src/walletSdk/Auth/AuthHeaderSigner.ts +11 -5
  20. package/src/walletSdk/Auth/WalletSigner.ts +1 -1
  21. package/src/walletSdk/Auth/index.ts +4 -3
  22. package/src/walletSdk/Customer/index.ts +6 -6
  23. package/src/walletSdk/Exceptions/index.ts +8 -0
  24. package/src/walletSdk/Horizon/AccountService.ts +2 -2
  25. package/src/walletSdk/Horizon/Stellar.ts +1 -1
  26. package/src/walletSdk/Horizon/Transaction/TransactionBuilder.ts +31 -19
  27. package/src/walletSdk/Recovery/AccountRecover.ts +1 -1
  28. package/src/walletSdk/Server/index.ts +2 -2
  29. package/src/walletSdk/Types/horizon.ts +16 -5
  30. package/src/walletSdk/Types/sep12.ts +1 -1
  31. package/src/walletSdk/Uri/Sep7Base.ts +10 -9
  32. package/src/walletSdk/Uri/Sep7Tx.ts +1 -1
  33. package/test/auth.test.ts +42 -0
  34. package/test/e2e/reactNative.test.ts +190 -0
  35. package/test/sep7.test.ts +72 -7
  36. package/test/transaction.test.ts +107 -4
  37. package/test/tsconfig.json +1 -0
  38. package/webpack.config.js +0 -4
package/test/auth.test.ts CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  MuxedAccount,
8
8
  Networks,
9
9
  StellarToml,
10
+ StrKey,
10
11
  Transaction,
11
12
  TransactionBuilder as SdkTransactionBuilder,
12
13
  Operation,
@@ -15,8 +16,12 @@ import {
15
16
  import { randomBytes } from "crypto";
16
17
  import axios from "axios";
17
18
  import sinon from "sinon";
19
+ import { base64ToString, base64ToUint8Array } from "uint8array-extras";
20
+ import { encode as utf8Encode } from "@stablelib/utf8";
21
+ import nacl from "tweetnacl";
18
22
 
19
23
  import { validateToken, Sep10, type WalletSigner } from "../src/walletSdk/Auth";
24
+ import { DefaultAuthHeaderSigner } from "../src/walletSdk/Auth/AuthHeaderSigner";
20
25
  import {
21
26
  Config,
22
27
  StellarConfiguration,
@@ -837,3 +842,40 @@ describe("Anchor.sep10() signing key handling", () => {
837
842
  expect(sep10).toBeDefined();
838
843
  });
839
844
  });
845
+
846
+ describe("auth header JWT encoding", () => {
847
+ it("signs with unpadded base64url and verifies against the public key", async () => {
848
+ const kp = SigningKeypair.fromSecret(Keypair.random().secret());
849
+ const signer = new DefaultAuthHeaderSigner();
850
+
851
+ const jwt = await signer.createToken({
852
+ claims: {
853
+ account: kp.publicKey,
854
+ home_domain: "test.com",
855
+ web_auth_endpoint: "https://test.com/auth",
856
+ },
857
+ issuer: kp,
858
+ });
859
+
860
+ const [header, payload, signature] = jwt.split(".");
861
+
862
+ // base64url: no +, / or = padding in any segment.
863
+ for (const segment of [header, payload, signature]) {
864
+ expect(segment).not.toMatch(/[+/=]/);
865
+ }
866
+
867
+ // The header must still decode to real JSON.
868
+ expect(JSON.parse(base64ToString(header))).toEqual({ alg: "EdDSA" });
869
+
870
+ // The signature must verify over "<header>.<payload>".
871
+ const naclKP = nacl.sign.keyPair.fromSeed(
872
+ StrKey.decodeEd25519SecretSeed(kp.secretKey),
873
+ );
874
+ const verified = nacl.sign.detached.verify(
875
+ utf8Encode(`${header}.${payload}`),
876
+ base64ToUint8Array(signature),
877
+ naclKP.publicKey,
878
+ );
879
+ expect(verified).toBe(true);
880
+ });
881
+ });
@@ -0,0 +1,190 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import * as vm from "vm";
4
+
5
+ /**
6
+ * React Native's Hermes runtime provides none of Buffer, Event, EventTarget or
7
+ * process. Loading each published bundle in a context without them catches the
8
+ * two failure modes this SDK has actually shipped: a reliance on the Buffer
9
+ * global, and dependencies that subclass the DOM Event globals at module scope.
10
+ *
11
+ * The sandbox also *grants* a few globals that a real RN app must supply
12
+ * itself, so this file is explicit about what environment it is modelling:
13
+ *
14
+ * - `crypto`: Hermes/RN does not provide this either. A real RN app needs
15
+ * `react-native-get-random-values` (or equivalent) for stellar-sdk's RNG
16
+ * path. This was already true under v16 and is not new to this migration.
17
+ * - `btoa`/`atob`: see the dedicated comment below.
18
+ * - `TextEncoder`/`TextDecoder`: see the dedicated comment below.
19
+ */
20
+ const BANNED = ["Buffer", "Event", "EventTarget", "process"];
21
+
22
+ const makeHermesLikeContext = ({
23
+ includeBase64 = true,
24
+ includeTextCodec = true,
25
+ } = {}) => {
26
+ const sandbox: Record<string, unknown> = {
27
+ console,
28
+ URL,
29
+ URLSearchParams,
30
+ setTimeout,
31
+ clearTimeout,
32
+ setInterval,
33
+ clearInterval,
34
+ crypto: globalThis.crypto,
35
+ fetch: globalThis.fetch,
36
+ module: { exports: {} },
37
+ exports: {},
38
+ };
39
+
40
+ if (includeTextCodec) {
41
+ // TextEncoder/TextDecoder are a real consumer requirement, not a test
42
+ // convenience, and the requirement is unavoidable: uint8array-extras@1.5.0
43
+ // — a direct dependency of ours and a transitive dependency of
44
+ // stellar-sdk — constructs both at module initialization, unguarded:
45
+ // `new globalThis.TextDecoder('utf8')` (index.js:113, inside a
46
+ // module-scope object literal) and `new globalThis.TextEncoder()`
47
+ // (index.js:128). By contrast, @exodus/bytes DOES guard this —
48
+ // fallback/platform.native.js only constructs them when
49
+ // `isNative(globalThis.TextDecoder)` holds, falling back to pure-JS
50
+ // decoding otherwise — so the requirement traces specifically to
51
+ // uint8array-extras, not to @exodus/bytes. Granting them here models an
52
+ // environment that satisfies this prerequisite. We cannot verify from
53
+ // here whether React Native itself provides them (this file makes no
54
+ // claim either way), but RN apps commonly polyfill TextEncoder/TextDecoder
55
+ // already for other libraries. Remove them and every bundle throws
56
+ // "TypeError: globalThis.TextDecoder is not a constructor" at load —
57
+ // before any of our own code runs. See the test below that enforces this.
58
+ sandbox.TextEncoder = TextEncoder;
59
+ sandbox.TextDecoder = TextDecoder;
60
+ }
61
+
62
+ if (includeBase64) {
63
+ // btoa/atob are a real consumer requirement of this release, not a test
64
+ // convenience. stellar-sdk v17's xdr.encodeBytes(bytes, "base64") routes
65
+ // through its own lib/cjs/base/util/base64.js, which calls the bare `btoa`
66
+ // identifier with no fallback, and Task 2 removed the browser bundle's
67
+ // Buffer polyfill that used to cover it. Hermes provides btoa/atob
68
+ // natively as of React Native 0.74 (facebook/hermes#1255, #1256); React
69
+ // Native's own JS layer has never defined them, so RN < 0.74 and
70
+ // non-Hermes engines (JSC, V8) need a polyfill such as `base-64`.
71
+ // Granting them here models a supported RN >= 0.74 Hermes app. Remove
72
+ // them and every base64 path throws "ReferenceError: btoa is not
73
+ // defined"; hex and base32/StrKey still work, being pure JS.
74
+ sandbox.btoa = globalThis.btoa;
75
+ sandbox.atob = globalThis.atob;
76
+ }
77
+
78
+ sandbox.global = sandbox;
79
+ sandbox.globalThis = sandbox;
80
+
81
+ const context = vm.createContext(sandbox);
82
+ for (const name of BANNED) {
83
+ vm.runInContext(
84
+ `if (typeof ${name} !== "undefined") { throw new Error("${name} leaked into the sandbox"); }`,
85
+ context,
86
+ );
87
+ }
88
+ return context;
89
+ };
90
+
91
+ const bundles = [
92
+ ["core SDK", "../../lib/bundle_browser.js"],
93
+ ["key manager", "../../../typescript-wallet-sdk-km/lib/bundle_browser.js"],
94
+ ["soroban", "../../../typescript-wallet-sdk-soroban/lib/bundle_browser.js"],
95
+ ] as const;
96
+
97
+ describe("React Native (Hermes-like) bundle compatibility", () => {
98
+ for (const [name, relativePath] of bundles) {
99
+ it(`loads the ${name} bundle without Buffer/Event/EventTarget/process`, () => {
100
+ const bundlePath = path.resolve(__dirname, relativePath);
101
+ expect(fs.existsSync(bundlePath)).toBe(true);
102
+
103
+ const context = makeHermesLikeContext();
104
+ const code = fs.readFileSync(bundlePath, "utf8");
105
+
106
+ expect(() =>
107
+ vm.runInContext(code, context, { filename: `${name}.js` }),
108
+ ).not.toThrow();
109
+ });
110
+ }
111
+
112
+ for (const [name, relativePath] of bundles) {
113
+ it(`fails to load the ${name} bundle without TextEncoder/TextDecoder`, () => {
114
+ const bundlePath = path.resolve(__dirname, relativePath);
115
+ const context = makeHermesLikeContext({ includeTextCodec: false });
116
+ const code = fs.readFileSync(bundlePath, "utf8");
117
+
118
+ // uint8array-extras constructs its TextDecoder/TextEncoder at module
119
+ // initialization (see the comment in makeHermesLikeContext), so the
120
+ // failure happens at load time, before any of our own code runs. This
121
+ // turns the assumption granted above into an enforced, documented
122
+ // contract rather than a silent one.
123
+ expect(() =>
124
+ vm.runInContext(code, context, { filename: `${name}.js` }),
125
+ ).toThrow(/TextDecoder is not a constructor/);
126
+ });
127
+ }
128
+
129
+ it("exercises the core SDK public API in the sandbox", () => {
130
+ const context = makeHermesLikeContext();
131
+ const code = fs.readFileSync(
132
+ path.resolve(__dirname, "../../lib/bundle_browser.js"),
133
+ "utf8",
134
+ );
135
+ vm.runInContext(code, context, { filename: "bundle_browser.js" });
136
+
137
+ // Sep7Pay.addSignature is the densest no-Buffer path in our own code: it
138
+ // runs concatUint8Arrays + stringToUint8Array to build the payload, signs
139
+ // it, then base64-encodes via xdr.encodeBytes.
140
+ const result = vm.runInContext(
141
+ `(() => {
142
+ const { Wallet, Sep7Pay } = module.exports;
143
+ const kp = Wallet.TestNet().stellar().account().createKeypair();
144
+ const uri = Sep7Pay.forDestination(kp.publicKey);
145
+ return { publicKey: kp.publicKey, signature: uri.addSignature(kp.keypair) };
146
+ })()`,
147
+ context,
148
+ ) as { publicKey: string; signature: string };
149
+
150
+ expect(result.publicKey).toMatch(/^G[A-Z2-7]{55}$/);
151
+ // The decisive assertion: base64 encoding worked without Buffer. A broken
152
+ // encoder yields comma-joined decimals.
153
+ expect(result.signature).toMatch(/^[A-Za-z0-9+/]+={0,2}$/);
154
+ expect(result.signature).toHaveLength(88);
155
+ });
156
+
157
+ it("requires btoa/atob for base64 paths, while base32/StrKey keypair creation stays pure JS", () => {
158
+ const context = makeHermesLikeContext({ includeBase64: false });
159
+ const code = fs.readFileSync(
160
+ path.resolve(__dirname, "../../lib/bundle_browser.js"),
161
+ "utf8",
162
+ );
163
+ vm.runInContext(code, context, { filename: "bundle_browser.js" });
164
+
165
+ // Keypair generation and the public key's StrKey encoding are pure JS
166
+ // (base32, not base64), so they must work even without btoa/atob.
167
+ const publicKey = vm.runInContext(
168
+ `(() => {
169
+ const { Wallet } = module.exports;
170
+ return Wallet.TestNet().stellar().account().createKeypair().publicKey;
171
+ })()`,
172
+ context,
173
+ ) as string;
174
+ expect(publicKey).toMatch(/^G[A-Z2-7]{55}$/);
175
+
176
+ // Sep7Pay.addSignature's base64 encode step has no fallback: without
177
+ // btoa this must fail loudly rather than silently degrade.
178
+ expect(() =>
179
+ vm.runInContext(
180
+ `(() => {
181
+ const { Wallet, Sep7Pay } = module.exports;
182
+ const kp = Wallet.TestNet().stellar().account().createKeypair();
183
+ const uri = Sep7Pay.forDestination(kp.publicKey);
184
+ return uri.addSignature(kp.keypair);
185
+ })()`,
186
+ context,
187
+ ),
188
+ ).toThrow(/btoa is not defined/);
189
+ });
190
+ });
package/test/sep7.test.ts CHANGED
@@ -1,4 +1,13 @@
1
- import { Keypair, Networks, StellarToml } from "@stellar/stellar-sdk";
1
+ import {
2
+ Account,
3
+ Asset,
4
+ BASE_FEE,
5
+ Keypair,
6
+ Networks,
7
+ Operation,
8
+ StellarToml,
9
+ TransactionBuilder,
10
+ } from "@stellar/stellar-sdk";
2
11
  import {
3
12
  NativeAssetId,
4
13
  Sep7Pay,
@@ -360,7 +369,7 @@ describe("Sep7Tx", () => {
360
369
  txBuilder.transfer(testKp2.publicKey, new NativeAssetId(), "1");
361
370
  const tx = txBuilder.build();
362
371
 
363
- const xdr = tx.toEnvelope().toXDR().toString("base64");
372
+ const xdr = tx.toEnvelope().toXdr("base64");
364
373
 
365
374
  const uri = Sep7Tx.forTransaction(tx);
366
375
  expect(uri.operationType).toBe("tx");
@@ -488,7 +497,7 @@ describe("Sep7Tx", () => {
488
497
  txBuilder.transfer(testKp2.publicKey, new NativeAssetId(), "1");
489
498
  const tx = txBuilder.build();
490
499
 
491
- const xdr = tx.toEnvelope().toXDR().toString("base64");
500
+ const xdr = tx.toEnvelope().toXdr("base64");
492
501
 
493
502
  const uri = Sep7Tx.forTransaction(tx);
494
503
 
@@ -553,13 +562,11 @@ describe("Sep7Tx", () => {
553
562
  txBuilder.transfer(testKp2.publicKey, new NativeAssetId(), "1");
554
563
  const tx = txBuilder.build();
555
564
 
556
- const xdr = tx.toEnvelope().toXDR().toString("base64");
565
+ const xdr = tx.toEnvelope().toXdr("base64");
557
566
 
558
567
  const uri = new Sep7Tx(`web+stellar:tx?xdr=${encodeURIComponent(xdr)}`);
559
568
 
560
- expect(uri.getTransaction().toEnvelope().toXDR().toString("base64")).toBe(
561
- xdr,
562
- );
569
+ expect(uri.getTransaction().toEnvelope().toXdr("base64")).toBe(xdr);
563
570
  });
564
571
  });
565
572
 
@@ -1002,3 +1009,61 @@ describe("sep7Parser", () => {
1002
1009
  expect(actual).toBe(expected);
1003
1010
  });
1004
1011
  });
1012
+
1013
+ describe("SEP-7 byte encoding regressions", () => {
1014
+ const BASE64_ONLY = /^[A-Za-z0-9+/]+={0,2}$/;
1015
+
1016
+ it("produces a base64 signature, not comma-joined decimals", () => {
1017
+ const keypair = Keypair.random();
1018
+ const uri = Sep7Pay.forDestination(
1019
+ "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
1020
+ );
1021
+
1022
+ const signature = uri.addSignature(keypair);
1023
+
1024
+ expect(signature).toMatch(BASE64_ONLY);
1025
+ expect(signature).not.toContain(",");
1026
+ // An ed25519 signature is 64 bytes => 88 base64 characters with padding.
1027
+ expect(signature).toHaveLength(88);
1028
+ });
1029
+
1030
+ it("round-trips a signature through verification", async () => {
1031
+ const keypair = Keypair.random();
1032
+ const uri = Sep7Pay.forDestination(
1033
+ "GCALNQQBXAPZ2WIRSDDBMSTAKCUH5SG6U76YBFLQLIXJTF7FE5AX7AOO",
1034
+ );
1035
+ uri.originDomain = "place.domain.com";
1036
+ uri.addSignature(keypair);
1037
+
1038
+ jest
1039
+ .spyOn(StellarToml.Resolver, "resolve")
1040
+ .mockResolvedValue({ URI_REQUEST_SIGNING_KEY: keypair.publicKey() });
1041
+
1042
+ await expect(uri.verifySignature()).resolves.toBe(true);
1043
+ });
1044
+
1045
+ it("puts parseable XDR in the uri, not comma-joined decimals", () => {
1046
+ const keypair = Keypair.random();
1047
+ const account = new Account(keypair.publicKey(), "1");
1048
+ const tx = new TransactionBuilder(account, {
1049
+ fee: BASE_FEE,
1050
+ networkPassphrase: Networks.TESTNET,
1051
+ })
1052
+ .addOperation(
1053
+ Operation.payment({
1054
+ destination: keypair.publicKey(),
1055
+ asset: Asset.native(),
1056
+ amount: "1",
1057
+ }),
1058
+ )
1059
+ .setTimeout(30)
1060
+ .build();
1061
+
1062
+ const uri = Sep7Tx.forTransaction(tx);
1063
+
1064
+ expect(uri.xdr).toMatch(BASE64_ONLY);
1065
+ expect(uri.xdr).not.toContain(",");
1066
+ // The decisive check: it must parse back into the same transaction.
1067
+ expect(uri.getTransaction().toXdr()).toEqual(tx.toXdr());
1068
+ });
1069
+ });
@@ -1,8 +1,24 @@
1
1
  import axios from "axios";
2
- import { Horizon, MuxedAccount } from "@stellar/stellar-sdk";
3
-
4
- import { AccountService, SigningKeypair, Stellar, Wallet } from "../src";
2
+ import {
3
+ Account,
4
+ Horizon,
5
+ Keypair,
6
+ MuxedAccount,
7
+ Operation,
8
+ } from "@stellar/stellar-sdk";
9
+
10
+ import {
11
+ AccountService,
12
+ ApplicationConfiguration,
13
+ Config,
14
+ SigningKeypair,
15
+ Stellar,
16
+ StellarConfiguration,
17
+ TransactionBuilder,
18
+ Wallet,
19
+ } from "../src";
5
20
  import { IssuedAssetId, NativeAssetId } from "../src/walletSdk/Asset";
21
+ import { PathPayBoundRequiredError } from "../src/walletSdk/Exceptions";
6
22
 
7
23
  describe("Muxed Transactions", () => {
8
24
  let wallet: Wallet;
@@ -289,6 +305,7 @@ describe("Path Payment", () => {
289
305
  sendAsset: new NativeAssetId(),
290
306
  destAsset: usdcAsset,
291
307
  sendAmount: "5",
308
+ destMin: "4.9",
292
309
  })
293
310
  .build();
294
311
  expect(txn.operations[0].type).toBe("pathPaymentStrictSend");
@@ -304,6 +321,7 @@ describe("Path Payment", () => {
304
321
  sendAsset: new NativeAssetId(),
305
322
  destAsset: usdcAsset,
306
323
  destAmount: "5",
324
+ sendMax: "5.1",
307
325
  })
308
326
  .build();
309
327
  expect(txn.operations[0].type).toBe("pathPaymentStrictReceive");
@@ -314,10 +332,95 @@ describe("Path Payment", () => {
314
332
  sourceAddress: sourceKp,
315
333
  });
316
334
  const txn = txBuilder
317
- .swap(new NativeAssetId(), new NativeAssetId(), ".1")
335
+ .swap(new NativeAssetId(), new NativeAssetId(), ".1", ".1")
318
336
  .build();
319
337
  sourceKp.sign(txn);
320
338
  const success = await stellar.submitTransaction(txn);
321
339
  expect(success).toBe(true);
322
340
  }, 15000);
323
341
  });
342
+
343
+ describe("Path Payment bounds", () => {
344
+ const usdcAsset = new IssuedAssetId(
345
+ "USDC",
346
+ "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
347
+ );
348
+ const destination = Keypair.random().publicKey();
349
+
350
+ // Builds a TransactionBuilder offline so these tests never touch Horizon
351
+ const newBuilder = () =>
352
+ new TransactionBuilder(
353
+ new Config({
354
+ stellarConfiguration: StellarConfiguration.TestNet(),
355
+ applicationConfiguration: new ApplicationConfiguration(),
356
+ }),
357
+ new Account(Keypair.random().publicKey(), "0"),
358
+ );
359
+
360
+ it("throws when sendAmount is given without destMin", () => {
361
+ expect(() =>
362
+ newBuilder().pathPay({
363
+ destinationAddress: destination,
364
+ sendAsset: new NativeAssetId(),
365
+ destAsset: usdcAsset,
366
+ sendAmount: "5",
367
+ } as any),
368
+ ).toThrow(PathPayBoundRequiredError);
369
+ });
370
+
371
+ it("throws when destAmount is given without sendMax", () => {
372
+ expect(() =>
373
+ newBuilder().pathPay({
374
+ destinationAddress: destination,
375
+ sendAsset: new NativeAssetId(),
376
+ destAsset: usdcAsset,
377
+ destAmount: "5",
378
+ } as any),
379
+ ).toThrow(PathPayBoundRequiredError);
380
+ });
381
+
382
+ it("throws when swap is called without destMin", () => {
383
+ expect(() =>
384
+ (newBuilder() as any).swap(new NativeAssetId(), usdcAsset, "1"),
385
+ ).toThrow(PathPayBoundRequiredError);
386
+ });
387
+
388
+ it("uses the destMin given to pathPay", () => {
389
+ const txn = newBuilder()
390
+ .pathPay({
391
+ destinationAddress: destination,
392
+ sendAsset: new NativeAssetId(),
393
+ destAsset: usdcAsset,
394
+ sendAmount: "5",
395
+ destMin: "4.9",
396
+ })
397
+ .build();
398
+ const op = txn.operations[0] as Operation.PathPaymentStrictSend;
399
+ expect(op.type).toBe("pathPaymentStrictSend");
400
+ expect(op.destMin).toBe("4.9000000");
401
+ });
402
+
403
+ it("uses the sendMax given to pathPay", () => {
404
+ const txn = newBuilder()
405
+ .pathPay({
406
+ destinationAddress: destination,
407
+ sendAsset: new NativeAssetId(),
408
+ destAsset: usdcAsset,
409
+ destAmount: "5",
410
+ sendMax: "5.1",
411
+ })
412
+ .build();
413
+ const op = txn.operations[0] as Operation.PathPaymentStrictReceive;
414
+ expect(op.type).toBe("pathPaymentStrictReceive");
415
+ expect(op.sendMax).toBe("5.1000000");
416
+ });
417
+
418
+ it("uses the destMin given to swap", () => {
419
+ const txn = newBuilder()
420
+ .swap(new NativeAssetId(), usdcAsset, "1", "0.9")
421
+ .build();
422
+ const op = txn.operations[0] as Operation.PathPaymentStrictSend;
423
+ expect(op.type).toBe("pathPaymentStrictSend");
424
+ expect(op.destMin).toBe("0.9000000");
425
+ });
426
+ });
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "esModuleInterop": true,
4
+ "skipLibCheck": true,
4
5
  "baseUrl": "./",
5
6
  "outDir": "lib",
6
7
  "declaration": true,
package/webpack.config.js CHANGED
@@ -40,7 +40,6 @@ module.exports = (env = { NODE: false }) => {
40
40
  util: require.resolve("util"),
41
41
  vm: require.resolve("vm-browserify"),
42
42
  "process/browser": require.resolve("process/browser"),
43
- buffer: require.resolve("buffer"),
44
43
  }
45
44
  : {},
46
45
  },
@@ -60,9 +59,6 @@ module.exports = (env = { NODE: false }) => {
60
59
  new webpack.ProvidePlugin({
61
60
  process: "process/browser",
62
61
  }),
63
- new webpack.ProvidePlugin({
64
- Buffer: ["buffer", "Buffer"],
65
- }),
66
62
  ]
67
63
  : [],
68
64
  };