@stellar/typescript-wallet-sdk 1.1.3 → 1.2.1

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 (39) hide show
  1. package/examples/sep24/README.md +22 -0
  2. package/examples/sep24/sep24.ts +199 -0
  3. package/lib/bundle.js +369 -36
  4. package/lib/bundle.js.map +1 -1
  5. package/lib/bundle_browser.js +369 -36
  6. package/lib/bundle_browser.js.map +1 -1
  7. package/lib/index.d.ts +1 -1
  8. package/lib/walletSdk/Auth/WalletSigner.d.ts +23 -1
  9. package/lib/walletSdk/Exceptions/index.d.ts +5 -1
  10. package/lib/walletSdk/Horizon/Transaction/CommonTransactionBuilder.d.ts +18 -0
  11. package/lib/walletSdk/Horizon/Transaction/SponsoringBuilder.d.ts +10 -0
  12. package/lib/walletSdk/Horizon/Transaction/TransactionBuilder.d.ts +42 -9
  13. package/lib/walletSdk/Horizon/index.d.ts +1 -0
  14. package/lib/walletSdk/Types/auth.d.ts +3 -0
  15. package/lib/walletSdk/Types/horizon.d.ts +11 -1
  16. package/lib/walletSdk/Types/index.d.ts +7 -0
  17. package/lib/walletSdk/Utils/extractAxiosErrorData.d.ts +2 -0
  18. package/lib/walletSdk/Utils/index.d.ts +1 -0
  19. package/lib/walletSdk/index.d.ts +2 -1
  20. package/package.json +5 -3
  21. package/src/index.ts +1 -0
  22. package/src/walletSdk/Anchor/Sep24.ts +2 -0
  23. package/src/walletSdk/Auth/WalletSigner.ts +64 -1
  24. package/src/walletSdk/Auth/index.ts +1 -1
  25. package/src/walletSdk/Exceptions/index.ts +22 -2
  26. package/src/walletSdk/Horizon/Stellar.ts +1 -0
  27. package/src/walletSdk/Horizon/Transaction/CommonTransactionBuilder.ts +75 -0
  28. package/src/walletSdk/Horizon/Transaction/SponsoringBuilder.ts +58 -0
  29. package/src/walletSdk/Horizon/Transaction/TransactionBuilder.ts +116 -34
  30. package/src/walletSdk/Horizon/index.ts +1 -0
  31. package/src/walletSdk/Types/auth.ts +4 -0
  32. package/src/walletSdk/Types/horizon.ts +12 -1
  33. package/src/walletSdk/Types/index.ts +8 -1
  34. package/src/walletSdk/Utils/extractAxiosErrorData.ts +28 -0
  35. package/src/walletSdk/Utils/index.ts +1 -0
  36. package/src/walletSdk/index.ts +7 -1
  37. package/test/stellar.test.ts +198 -1
  38. package/test/transaction.test.ts +325 -0
  39. package/test/wallet.test.ts +43 -0
@@ -0,0 +1,325 @@
1
+ import axios from "axios";
2
+ import { Horizon, MuxedAccount } from "stellar-sdk";
3
+
4
+ import { AccountService, SigningKeypair, Stellar, Wallet } from "../src";
5
+ import { IssuedAssetId, NativeAssetId } from "../src/walletSdk/Asset";
6
+
7
+ describe("Muxed Transactions", () => {
8
+ let wallet: Wallet;
9
+ let stellar: Stellar;
10
+ let accountService: AccountService;
11
+ let testingDistributionKp: SigningKeypair;
12
+ let testingAsset: IssuedAssetId;
13
+
14
+ // Creates testing stellar account with testing TSWT asset
15
+ // in case it doesn't exist just yet
16
+ beforeAll(async () => {
17
+ wallet = Wallet.TestNet();
18
+ stellar = wallet.stellar();
19
+ accountService = stellar.account();
20
+
21
+ // Keys for accounts to issue and receive the new TSWT asset
22
+ var issuingKeys = SigningKeypair.fromSecret(
23
+ "SAJMJSEC44DWU22TJF6RWYLRPPXLY4G3L5PVGC7D2QDUCPJIFCOISNQE",
24
+ );
25
+ var receivingKeys = SigningKeypair.fromSecret(
26
+ "SAOQQ76UQFEYN4QAAAOIO45KNZZNQKSXAUB5GXKI6YOFLEDCWPWTCDM3",
27
+ );
28
+
29
+ // The "receiving" account is the distribution account
30
+ testingDistributionKp = receivingKeys;
31
+
32
+ // This is the testing asset we'll use to test sending non-native payments
33
+ testingAsset = new IssuedAssetId("TSWT", issuingKeys.publicKey);
34
+
35
+ let assetAlreadyCreated = false;
36
+ try {
37
+ const receivingAccountInfo = await accountService.getInfo({
38
+ accountAddress: receivingKeys.publicKey,
39
+ });
40
+
41
+ const tswtAssetBalance = receivingAccountInfo.balances.find(
42
+ (balanceLine) => {
43
+ const { asset_code, balance } =
44
+ balanceLine as Horizon.BalanceLineAsset;
45
+ return asset_code === testingAsset.code && Number(balance) > 1000;
46
+ },
47
+ );
48
+
49
+ if (tswtAssetBalance) {
50
+ assetAlreadyCreated = true;
51
+ }
52
+ } catch {}
53
+
54
+ if (assetAlreadyCreated) {
55
+ return;
56
+ }
57
+
58
+ // If the TSWT asset is not there yet, let's issue and distribute it!
59
+ try {
60
+ // First make sure both issuing and receiving(distribution) accounts
61
+ // are funded
62
+ await axios.get(
63
+ "https://friendbot.stellar.org/?addr=" + issuingKeys.publicKey,
64
+ );
65
+
66
+ await axios.get(
67
+ "https://friendbot.stellar.org/?addr=" + receivingKeys.publicKey,
68
+ );
69
+ } catch {}
70
+
71
+ let didFail = false;
72
+ try {
73
+ // Then, the receiving(distribution) account must trust the asset
74
+ const txBuilder = await stellar.transaction({
75
+ sourceAddress: receivingKeys,
76
+ baseFee: 100,
77
+ });
78
+ const addTswtTx = txBuilder.addAssetSupport(testingAsset).build();
79
+ addTswtTx.sign(receivingKeys.keypair);
80
+ await stellar.submitTransaction(addTswtTx);
81
+
82
+ // Finally, the issuing account actually sends a payment using the asset
83
+ // to fund the receiving(distribution) account
84
+ const txBuilder2 = await stellar.transaction({
85
+ sourceAddress: issuingKeys,
86
+ baseFee: 100,
87
+ });
88
+ const fundingPaymentTx = txBuilder2
89
+ .transfer(receivingKeys.publicKey, testingAsset, "100000000")
90
+ .build();
91
+ fundingPaymentTx.sign(issuingKeys.keypair);
92
+ await stellar.submitTransaction(fundingPaymentTx);
93
+ } catch {
94
+ didFail = true;
95
+ }
96
+
97
+ expect(didFail).toBeFalsy();
98
+ }, 60000);
99
+
100
+ it("should send 'native' payment to valid Muxed account", async () => {
101
+ const baseAccoutKp = SigningKeypair.fromSecret(
102
+ "SDC4SZWQDELBKWPBPBLZSKMWAIPNE27OF6BPJV7F7FCXTKHBACN3KWRO",
103
+ );
104
+
105
+ try {
106
+ await axios.get(
107
+ "https://friendbot.stellar.org/?addr=" + baseAccoutKp.publicKey,
108
+ );
109
+ } catch {}
110
+
111
+ const baseAccount = await stellar.server.loadAccount(
112
+ baseAccoutKp.publicKey,
113
+ );
114
+ const muxedAccount = new MuxedAccount(baseAccount, "123");
115
+
116
+ const txBuilder = await stellar.transaction({
117
+ sourceAddress: testingDistributionKp,
118
+ baseFee: 100,
119
+ });
120
+
121
+ const sendNativePaymentTx = txBuilder
122
+ .transfer(muxedAccount.accountId(), new NativeAssetId(), "1")
123
+ .build();
124
+ sendNativePaymentTx.sign(testingDistributionKp.keypair);
125
+
126
+ const response = await stellar.submitTransaction(sendNativePaymentTx);
127
+
128
+ expect(response).toBeTruthy();
129
+ }, 30000);
130
+
131
+ it("should send non-native payment to valid Muxed account", async () => {
132
+ const baseAccoutKp = SigningKeypair.fromSecret(
133
+ "SDFK2E4LSVZJGEWKFIX4SXOLDXQQWMDGNONERVBNFXDVWE2PTEKY6ZSI",
134
+ );
135
+
136
+ try {
137
+ await axios.get(
138
+ "https://friendbot.stellar.org/?addr=" + baseAccoutKp.publicKey,
139
+ );
140
+ } catch {}
141
+
142
+ const baseAccount = await stellar.server.loadAccount(
143
+ baseAccoutKp.publicKey,
144
+ );
145
+ const muxedAccount = new MuxedAccount(baseAccount, "456");
146
+
147
+ // First add support for the non-native asset
148
+ const txBuilder1 = await stellar.transaction({
149
+ sourceAddress: baseAccoutKp,
150
+ baseFee: 100,
151
+ });
152
+ const addTswtTx = txBuilder1.addAssetSupport(testingAsset).build();
153
+ addTswtTx.sign(baseAccoutKp.keypair);
154
+ await stellar.submitTransaction(addTswtTx);
155
+
156
+ // Then submit the non-native payment!
157
+ const txBuilder2 = await stellar.transaction({
158
+ sourceAddress: testingDistributionKp,
159
+ baseFee: 100,
160
+ });
161
+
162
+ const sendNonNativePaymentTx = txBuilder2
163
+ .transfer(muxedAccount.accountId(), testingAsset, "1")
164
+ .build();
165
+ sendNonNativePaymentTx.sign(testingDistributionKp.keypair);
166
+
167
+ const response = await stellar.submitTransaction(sendNonNativePaymentTx);
168
+
169
+ expect(response).toBeTruthy();
170
+ }, 30000);
171
+
172
+ it("should return 'op_no_trust' error for sending unsupported Asset to valid Muxed account", async () => {
173
+ const baseAccoutKp = SigningKeypair.fromSecret(
174
+ "SD4UETXJ2MJCIPSU72DAJDPL2YGDHF2FEIJVNARUGE6MFDPXNS5YHNGK",
175
+ );
176
+
177
+ try {
178
+ await axios.get(
179
+ "https://friendbot.stellar.org/?addr=" + baseAccoutKp.publicKey,
180
+ );
181
+ } catch {}
182
+
183
+ const baseAccount = await stellar.server.loadAccount(
184
+ baseAccoutKp.publicKey,
185
+ );
186
+ const muxedAccount = new MuxedAccount(baseAccount, "789");
187
+
188
+ // Try submitting the non-native payment without adding the trustline
189
+ const txBuilder = await stellar.transaction({
190
+ sourceAddress: testingDistributionKp,
191
+ baseFee: 100,
192
+ });
193
+
194
+ const sendNonNativePaymentTx = txBuilder
195
+ .transfer(muxedAccount.accountId(), testingAsset, "1")
196
+ .build();
197
+ sendNonNativePaymentTx.sign(testingDistributionKp.keypair);
198
+
199
+ try {
200
+ await stellar.submitTransaction(sendNonNativePaymentTx);
201
+ } catch (error) {
202
+ expect(error?.response?.status === 400).toBeTruthy();
203
+
204
+ const resultCodeOperations: Array<string> =
205
+ error?.response?.data?.extras?.result_codes?.operations || [];
206
+
207
+ expect(resultCodeOperations).toContain("op_no_trust");
208
+ }
209
+ }, 30000);
210
+
211
+ it("should return error for sending payment to invalid Muxed address", async () => {
212
+ const txBuilder = await stellar.transaction({
213
+ sourceAddress: testingDistributionKp,
214
+ baseFee: 100,
215
+ });
216
+
217
+ try {
218
+ txBuilder
219
+ .transfer(
220
+ // Invalid Muxed address ending in "XXXXXX"
221
+ "MBE3SABPOQFUSVCNDO5WNSS4N2KD7ZUFIYDRBP6Q3UBXBMYZFYWLSAAAAAAAAAAXXXXXX",
222
+ new NativeAssetId(),
223
+ "1",
224
+ )
225
+ .build();
226
+ } catch (error) {
227
+ const lowercaseError = error.toString().toLowerCase();
228
+ // Catches "Error: destination is invalid" error message
229
+ expect(lowercaseError.match(/destination.*invalid/)).toBeTruthy();
230
+ }
231
+ });
232
+ });
233
+
234
+ describe("Path Payment", () => {
235
+ let wallet: Wallet;
236
+ let stellar: Stellar;
237
+ let sourceKp;
238
+ let receivingKp;
239
+ const usdcAsset = new IssuedAssetId(
240
+ "USDC",
241
+ "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
242
+ );
243
+ beforeAll(async () => {
244
+ wallet = Wallet.TestNet();
245
+ stellar = wallet.stellar();
246
+
247
+ // set up accounts
248
+ sourceKp = SigningKeypair.fromSecret(
249
+ "SBTMCNDNPMJFEYUHLCAMFM5C2PWI7ZUI7PFMLI53O62CSSXFSAXEDTS6",
250
+ );
251
+ receivingKp = SigningKeypair.fromSecret(
252
+ "SDU4Z54AAFF3Y3GA6U27QSSYYX5FLDV6KWGFCCWSMSOSFWHSABJFBFOD",
253
+ );
254
+ try {
255
+ await stellar.server.loadAccount(sourceKp.publicKey);
256
+ await stellar.server.loadAccount(receivingKp.publicKey);
257
+ } catch (e) {
258
+ await axios.get(
259
+ "https://friendbot.stellar.org/?addr=" + sourceKp.publicKey,
260
+ );
261
+ await axios.get(
262
+ "https://friendbot.stellar.org/?addr=" + receivingKp.publicKey,
263
+ );
264
+
265
+ // add trustlines if new accounts
266
+ let txBuilder = await stellar.transaction({
267
+ sourceAddress: receivingKp,
268
+ });
269
+ let txn = txBuilder.addAssetSupport(usdcAsset).build();
270
+ receivingKp.sign(txn);
271
+ await stellar.submitTransaction(txn);
272
+
273
+ txBuilder = await stellar.transaction({
274
+ sourceAddress: sourceKp,
275
+ });
276
+ txn = txBuilder.addAssetSupport(usdcAsset).build();
277
+ sourceKp.sign(txn);
278
+ await stellar.submitTransaction(txn);
279
+ }
280
+ }, 20000);
281
+
282
+ it("should use path payment send", async () => {
283
+ const txBuilder = await stellar.transaction({
284
+ sourceAddress: sourceKp,
285
+ });
286
+ const txn = txBuilder
287
+ .pathPay({
288
+ destinationAddress: receivingKp.publicKey,
289
+ sendAsset: new NativeAssetId(),
290
+ destAsset: usdcAsset,
291
+ sendAmount: "5",
292
+ })
293
+ .build();
294
+ sourceKp.sign(txn);
295
+ const success = await stellar.submitTransaction(txn);
296
+ expect(success).toBe(true);
297
+ }, 15000);
298
+
299
+ it("should use path payment receive", async () => {
300
+ const txBuilder = await stellar.transaction({
301
+ sourceAddress: sourceKp,
302
+ });
303
+ const txn = txBuilder
304
+ .pathPay({
305
+ destinationAddress: receivingKp.publicKey,
306
+ sendAsset: new NativeAssetId(),
307
+ destAsset: usdcAsset,
308
+ destAmount: "5",
309
+ })
310
+ .build();
311
+ sourceKp.sign(txn);
312
+ const success = await stellar.submitTransaction(txn);
313
+ expect(success).toBe(true);
314
+ }, 15000);
315
+
316
+ it("should swap", async () => {
317
+ const txBuilder = await stellar.transaction({
318
+ sourceAddress: sourceKp,
319
+ });
320
+ const txn = txBuilder.swap(new NativeAssetId(), usdcAsset, "1").build();
321
+ sourceKp.sign(txn);
322
+ const success = await stellar.submitTransaction(txn);
323
+ expect(success).toBe(true);
324
+ }, 15000);
325
+ });
@@ -18,6 +18,7 @@ import {
18
18
  } from "../src/walletSdk/Auth/WalletSigner";
19
19
  import { SigningKeypair } from "../src/walletSdk/Horizon/Account";
20
20
  import { Sep24 } from "../src/walletSdk/Anchor/Sep24";
21
+ import { DomainSigner } from "../src/walletSdk/Auth/WalletSigner";
21
22
 
22
23
  import { TransactionsResponse } from "../test/fixtures/TransactionsResponse";
23
24
 
@@ -194,6 +195,25 @@ describe("Anchor", () => {
194
195
  expect(resp.id).toBeTruthy();
195
196
  });
196
197
 
198
+ it("should throw ServerRequestFailedError", async () => {
199
+ const assetCode = "SRT";
200
+ let didError = false;
201
+ try {
202
+ const resp = await anchor.sep24().withdraw({
203
+ withdrawalAccount: accountKp.publicKey,
204
+ assetCode,
205
+ authToken: "bad auth token",
206
+ });
207
+ } catch (e) {
208
+ didError = true;
209
+ expect(e.data.status).toBe(403);
210
+ expect(e.data.statusText).toBe("Forbidden");
211
+ expect(e.data.responseData.error).toBeTruthy();
212
+ expect(e.data.headers).toBeTruthy();
213
+ }
214
+ expect(didError).toBe(true);
215
+ });
216
+
197
217
  it("should fetch new transaction by id", async () => {
198
218
  const assetCode = "SRT";
199
219
 
@@ -1804,6 +1824,29 @@ describe("Anchor", () => {
1804
1824
  });
1805
1825
  });
1806
1826
 
1827
+ describe("DomainSigner", () => {
1828
+ it("should work", async () => {
1829
+ jest.spyOn(DefaultClient, "post").mockResolvedValue({
1830
+ data: {
1831
+ transaction:
1832
+ "AAAAAgAAAADVJRbxdB+qXZjUMLcrL/VVoS6megW1ReSxIO33pvO61AAAB9AAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAACwAAAAAAAAACAAAAAAAAAAA=",
1833
+ },
1834
+ });
1835
+ const signer = new DomainSigner("example url", {
1836
+ SampleHeader: "sample-header",
1837
+ });
1838
+
1839
+ const txn = await signer.signWithDomainAccount({
1840
+ transactionXDR: "test-xdr",
1841
+ networkPassphrase: "Test SDF Network ; September 2015",
1842
+ accountKp: SigningKeypair.fromSecret(
1843
+ "SBYAW5H46NNDGCECWMWWM32DE4DPNN3RHVMNTR3BXXZX2DJF6LZWBMWZ",
1844
+ ),
1845
+ });
1846
+ expect(txn).toBeTruthy();
1847
+ });
1848
+ });
1849
+
1807
1850
  describe("Http client", () => {
1808
1851
  it("should work with http", async () => {
1809
1852
  const accountKp = Keypair.fromSecret(