@frak-labs/core-sdk 0.1.1 → 0.2.0-beta.514ef378

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 (125) hide show
  1. package/README.md +58 -0
  2. package/cdn/bundle.js +14 -0
  3. package/dist/actions.cjs +1 -1
  4. package/dist/actions.d.cts +3 -3
  5. package/dist/actions.d.ts +3 -3
  6. package/dist/actions.js +1 -1
  7. package/dist/bundle.cjs +1 -1
  8. package/dist/bundle.d.cts +4 -6
  9. package/dist/bundle.d.ts +4 -6
  10. package/dist/bundle.js +1 -1
  11. package/dist/{index-CRsQWnTs.d.cts → computeLegacyProductId-BkyJ4rEY.d.ts} +197 -10
  12. package/dist/{index-Ck1hudEi.d.ts → computeLegacyProductId-Raks6FXg.d.cts} +197 -10
  13. package/dist/index.cjs +1 -1
  14. package/dist/index.d.cts +3 -4
  15. package/dist/index.d.ts +3 -4
  16. package/dist/index.js +1 -1
  17. package/dist/{openSso-D--Airj6.d.cts → openSso-BCJGchIb.d.cts} +135 -131
  18. package/dist/{openSso-DsKJ4y0j.d.ts → openSso-DG-_9CED.d.ts} +135 -131
  19. package/dist/setupClient-BEiAE56h.js +13 -0
  20. package/dist/setupClient-Ls3vKSlH.cjs +13 -0
  21. package/dist/{index-d8xS4ryI.d.ts → siweAuthenticate-BH7Dn7nZ.d.cts} +90 -65
  22. package/dist/siweAuthenticate-BJHbtty4.js +1 -0
  23. package/dist/{index-C6FxkWPC.d.cts → siweAuthenticate-Btem4QHs.d.ts} +90 -65
  24. package/dist/siweAuthenticate-Cwj3HP0m.cjs +1 -0
  25. package/dist/trackEvent-M2RLTQ2p.js +1 -0
  26. package/dist/trackEvent-T_R9ER2S.cjs +1 -0
  27. package/package.json +11 -22
  28. package/src/actions/displayEmbeddedWallet.ts +1 -0
  29. package/src/actions/displayModal.test.ts +12 -11
  30. package/src/actions/displayModal.ts +7 -18
  31. package/src/actions/ensureIdentity.ts +68 -0
  32. package/src/actions/{getProductInformation.test.ts → getMerchantInformation.test.ts} +33 -50
  33. package/src/actions/getMerchantInformation.ts +16 -0
  34. package/src/actions/index.ts +3 -2
  35. package/src/actions/openSso.ts +4 -2
  36. package/src/actions/referral/processReferral.test.ts +42 -151
  37. package/src/actions/referral/processReferral.ts +18 -42
  38. package/src/actions/referral/referralInteraction.test.ts +1 -7
  39. package/src/actions/referral/referralInteraction.ts +1 -6
  40. package/src/actions/sendInteraction.ts +46 -22
  41. package/src/actions/trackPurchaseStatus.test.ts +354 -141
  42. package/src/actions/trackPurchaseStatus.ts +48 -11
  43. package/src/actions/watchWalletStatus.ts +2 -3
  44. package/src/actions/wrapper/modalBuilder.test.ts +0 -14
  45. package/src/actions/wrapper/modalBuilder.ts +3 -12
  46. package/src/bundle.ts +0 -1
  47. package/src/clients/createIFrameFrakClient.ts +10 -5
  48. package/src/clients/transports/iframeLifecycleManager.test.ts +163 -4
  49. package/src/clients/transports/iframeLifecycleManager.ts +172 -33
  50. package/src/constants/interactionTypes.ts +12 -41
  51. package/src/index.ts +24 -16
  52. package/src/types/config.ts +6 -0
  53. package/src/types/index.ts +13 -10
  54. package/src/types/lifecycle/client.ts +24 -1
  55. package/src/types/lifecycle/iframe.ts +6 -0
  56. package/src/types/rpc/displayModal.ts +2 -4
  57. package/src/types/rpc/embedded/index.ts +2 -2
  58. package/src/types/rpc/interaction.ts +26 -39
  59. package/src/types/rpc/merchantInformation.ts +77 -0
  60. package/src/types/rpc/modal/index.ts +0 -4
  61. package/src/types/rpc/modal/login.ts +5 -1
  62. package/src/types/rpc/walletStatus.ts +1 -7
  63. package/src/types/rpc.ts +22 -30
  64. package/src/types/tracking.ts +60 -0
  65. package/src/utils/backendUrl.test.ts +83 -0
  66. package/src/utils/backendUrl.ts +62 -0
  67. package/src/utils/clientId.test.ts +41 -0
  68. package/src/utils/clientId.ts +43 -0
  69. package/src/utils/compression/compress.test.ts +1 -1
  70. package/src/utils/compression/compress.ts +2 -2
  71. package/src/utils/compression/decompress.test.ts +8 -4
  72. package/src/utils/compression/decompress.ts +2 -2
  73. package/src/utils/{computeProductId.ts → computeLegacyProductId.ts} +2 -2
  74. package/src/utils/constants.ts +5 -0
  75. package/src/utils/deepLinkWithFallback.test.ts +243 -0
  76. package/src/utils/deepLinkWithFallback.ts +103 -0
  77. package/src/utils/formatAmount.ts +6 -0
  78. package/src/utils/iframeHelper.test.ts +18 -5
  79. package/src/utils/iframeHelper.ts +10 -3
  80. package/src/utils/index.ts +16 -1
  81. package/src/utils/merchantId.test.ts +653 -0
  82. package/src/utils/merchantId.ts +143 -0
  83. package/src/utils/sso.ts +18 -11
  84. package/src/utils/trackEvent.test.ts +23 -5
  85. package/src/utils/trackEvent.ts +13 -0
  86. package/cdn/bundle.iife.js +0 -14
  87. package/dist/actions-B5j-i1p0.cjs +0 -1
  88. package/dist/actions-q090Z0oR.js +0 -1
  89. package/dist/index-7OZ39x1U.d.ts +0 -195
  90. package/dist/index-zDq-VlKx.d.cts +0 -195
  91. package/dist/interaction-DMJ3ZfaF.d.cts +0 -45
  92. package/dist/interaction-KX1h9a7V.d.ts +0 -45
  93. package/dist/interactions-DnfM3oe0.js +0 -1
  94. package/dist/interactions-EIXhNLf6.cjs +0 -1
  95. package/dist/interactions.cjs +0 -1
  96. package/dist/interactions.d.cts +0 -2
  97. package/dist/interactions.d.ts +0 -2
  98. package/dist/interactions.js +0 -1
  99. package/dist/productTypes-BUkXJKZ7.cjs +0 -1
  100. package/dist/productTypes-CGb1MmBF.js +0 -1
  101. package/dist/src-1LQ4eLq5.js +0 -13
  102. package/dist/src-hW71KjPN.cjs +0 -13
  103. package/dist/trackEvent-CHnYa85W.js +0 -1
  104. package/dist/trackEvent-GuQm_1Nm.cjs +0 -1
  105. package/src/actions/getProductInformation.ts +0 -14
  106. package/src/actions/openSso.test.ts +0 -407
  107. package/src/actions/sendInteraction.test.ts +0 -219
  108. package/src/constants/interactionTypes.test.ts +0 -128
  109. package/src/constants/productTypes.test.ts +0 -130
  110. package/src/constants/productTypes.ts +0 -33
  111. package/src/interactions/index.ts +0 -5
  112. package/src/interactions/pressEncoder.test.ts +0 -215
  113. package/src/interactions/pressEncoder.ts +0 -53
  114. package/src/interactions/purchaseEncoder.test.ts +0 -291
  115. package/src/interactions/purchaseEncoder.ts +0 -99
  116. package/src/interactions/referralEncoder.test.ts +0 -170
  117. package/src/interactions/referralEncoder.ts +0 -47
  118. package/src/interactions/retailEncoder.test.ts +0 -107
  119. package/src/interactions/retailEncoder.ts +0 -37
  120. package/src/interactions/webshopEncoder.test.ts +0 -56
  121. package/src/interactions/webshopEncoder.ts +0 -30
  122. package/src/types/rpc/modal/openSession.ts +0 -25
  123. package/src/types/rpc/productInformation.ts +0 -59
  124. package/src/utils/computeProductId.test.ts +0 -80
  125. package/src/utils/sso.test.ts +0 -361
@@ -1,407 +0,0 @@
1
- /**
2
- * Tests for openSso action
3
- * Tests SSO flows in both redirect and popup modes
4
- */
5
-
6
- import { vi } from "vitest";
7
-
8
- // Mock utilities before imports
9
- vi.mock("../utils/sso", () => ({
10
- generateSsoUrl: vi.fn((walletUrl, _args, productId, name, _css) => {
11
- return `${walletUrl}/sso?name=${name}&productId=${productId}`;
12
- }),
13
- }));
14
-
15
- vi.mock("../utils/computeProductId", () => ({
16
- computeProductId: vi.fn(
17
- () =>
18
- "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
19
- ),
20
- }));
21
-
22
- import {
23
- afterEach,
24
- beforeEach,
25
- describe,
26
- expect,
27
- it,
28
- } from "../../tests/vitest-fixtures";
29
- import type {
30
- FrakClient,
31
- OpenSsoParamsType,
32
- OpenSsoReturnType,
33
- } from "../types";
34
- import { openSso, ssoPopupFeatures, ssoPopupName } from "./openSso";
35
-
36
- describe("openSso", () => {
37
- describe("constants", () => {
38
- it("should have correct popup features", () => {
39
- expect(ssoPopupFeatures).toBe(
40
- "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800"
41
- );
42
- });
43
-
44
- it("should have correct popup name", () => {
45
- expect(ssoPopupName).toBe("frak-sso");
46
- });
47
- });
48
-
49
- describe("redirect mode", () => {
50
- it("should use redirect mode when openInSameWindow is true", async () => {
51
- const mockResponse: OpenSsoReturnType = {
52
- wallet: "0x1234567890123456789012345678901234567890",
53
- };
54
-
55
- const mockClient = {
56
- config: {
57
- metadata: { name: "Test App" },
58
- },
59
- request: vi.fn().mockResolvedValue(mockResponse),
60
- } as unknown as FrakClient;
61
-
62
- const params: OpenSsoParamsType = {
63
- openInSameWindow: true,
64
- metadata: {
65
- logoUrl: "https://example.com/logo.png",
66
- },
67
- };
68
-
69
- const result = await openSso(mockClient, params);
70
-
71
- expect(mockClient.request).toHaveBeenCalledWith({
72
- method: "frak_openSso",
73
- params: [params, "Test App", undefined],
74
- });
75
- expect(result).toEqual(mockResponse);
76
- });
77
-
78
- it("should use redirect mode when redirectUrl is provided", async () => {
79
- const mockResponse: OpenSsoReturnType = {
80
- wallet: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
81
- };
82
-
83
- const mockClient = {
84
- config: {
85
- metadata: { name: "Test App" },
86
- },
87
- request: vi.fn().mockResolvedValue(mockResponse),
88
- } as unknown as FrakClient;
89
-
90
- const params: OpenSsoParamsType = {
91
- redirectUrl: "https://example.com/callback",
92
- metadata: {
93
- logoUrl: "https://example.com/logo.png",
94
- },
95
- };
96
-
97
- const result = await openSso(mockClient, params);
98
-
99
- expect(mockClient.request).toHaveBeenCalledWith({
100
- method: "frak_openSso",
101
- params: [params, "Test App", undefined],
102
- });
103
- expect(result).toEqual(mockResponse);
104
- });
105
-
106
- it("should pass custom CSS in redirect mode", async () => {
107
- const mockResponse: OpenSsoReturnType = {};
108
-
109
- const mockClient = {
110
- config: {
111
- metadata: { name: "Test App" },
112
- customizations: {
113
- css: ":root { --primary: blue; }",
114
- },
115
- },
116
- request: vi.fn().mockResolvedValue(mockResponse),
117
- } as unknown as FrakClient;
118
-
119
- const params: OpenSsoParamsType = {
120
- openInSameWindow: true,
121
- metadata: {
122
- logoUrl: "https://example.com/logo.png",
123
- },
124
- };
125
-
126
- await openSso(mockClient, params);
127
-
128
- expect(mockClient.request).toHaveBeenCalledWith({
129
- method: "frak_openSso",
130
- params: [params, "Test App", ":root { --primary: blue; }"],
131
- });
132
- });
133
- });
134
-
135
- describe("popup mode", () => {
136
- let windowOpenSpy: any;
137
- let mockPopup: {
138
- focus: ReturnType<typeof vi.fn>;
139
- };
140
-
141
- beforeEach(() => {
142
- mockPopup = {
143
- focus: vi.fn(),
144
- };
145
- windowOpenSpy = vi
146
- .spyOn(window, "open")
147
- .mockReturnValue(mockPopup as unknown as Window);
148
- });
149
-
150
- afterEach(() => {
151
- windowOpenSpy.mockRestore();
152
- });
153
-
154
- it("should open popup with generated URL", async () => {
155
- const mockResponse: OpenSsoReturnType = {
156
- wallet: "0x1234567890123456789012345678901234567890",
157
- };
158
-
159
- const mockClient = {
160
- config: {
161
- metadata: { name: "Test App" },
162
- walletUrl: "https://wallet.frak.id",
163
- },
164
- request: vi.fn().mockResolvedValue(mockResponse),
165
- } as unknown as FrakClient;
166
-
167
- const params: OpenSsoParamsType = {
168
- metadata: {
169
- logoUrl: "https://example.com/logo.png",
170
- },
171
- };
172
-
173
- await openSso(mockClient, params);
174
-
175
- expect(window.open).toHaveBeenCalledWith(
176
- expect.stringContaining("https://wallet.frak.id/sso"),
177
- "frak-sso",
178
- "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800"
179
- );
180
- });
181
-
182
- it("should use custom ssoPopupUrl when provided", async () => {
183
- const mockResponse: OpenSsoReturnType = {};
184
-
185
- const mockClient = {
186
- config: {
187
- metadata: { name: "Test App" },
188
- },
189
- request: vi.fn().mockResolvedValue(mockResponse),
190
- } as unknown as FrakClient;
191
-
192
- const params: OpenSsoParamsType = {
193
- ssoPopupUrl: "https://custom-wallet.com/sso?custom=param",
194
- metadata: {
195
- logoUrl: "https://example.com/logo.png",
196
- },
197
- };
198
-
199
- await openSso(mockClient, params);
200
-
201
- expect(window.open).toHaveBeenCalledWith(
202
- "https://custom-wallet.com/sso?custom=param",
203
- "frak-sso",
204
- "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800"
205
- );
206
- });
207
-
208
- it("should focus popup after opening", async () => {
209
- const mockResponse: OpenSsoReturnType = {};
210
-
211
- const mockClient = {
212
- config: {
213
- metadata: { name: "Test App" },
214
- },
215
- request: vi.fn().mockResolvedValue(mockResponse),
216
- } as unknown as FrakClient;
217
-
218
- const params: OpenSsoParamsType = {
219
- metadata: {
220
- logoUrl: "https://example.com/logo.png",
221
- },
222
- };
223
-
224
- await openSso(mockClient, params);
225
-
226
- expect(mockPopup.focus).toHaveBeenCalled();
227
- });
228
-
229
- it("should wait for SSO completion via client.request", async () => {
230
- const mockResponse: OpenSsoReturnType = {
231
- wallet: "0x1234567890123456789012345678901234567890",
232
- };
233
-
234
- const mockClient = {
235
- config: {
236
- metadata: { name: "Test App" },
237
- },
238
- request: vi.fn().mockResolvedValue(mockResponse),
239
- } as unknown as FrakClient;
240
-
241
- const params: OpenSsoParamsType = {
242
- metadata: {
243
- logoUrl: "https://example.com/logo.png",
244
- },
245
- };
246
-
247
- const result = await openSso(mockClient, params);
248
-
249
- expect(mockClient.request).toHaveBeenCalledWith({
250
- method: "frak_openSso",
251
- params: [params, "Test App", undefined],
252
- });
253
- expect(result).toEqual(mockResponse);
254
- });
255
-
256
- it("should return empty object when result is null", async () => {
257
- const mockClient = {
258
- config: {
259
- metadata: { name: "Test App" },
260
- },
261
- request: vi.fn().mockResolvedValue(null),
262
- } as unknown as FrakClient;
263
-
264
- const params: OpenSsoParamsType = {
265
- metadata: {
266
- logoUrl: "https://example.com/logo.png",
267
- },
268
- };
269
-
270
- const result = await openSso(mockClient, params);
271
-
272
- expect(result).toEqual({});
273
- });
274
-
275
- it("should use default wallet URL when not configured", async () => {
276
- const mockResponse: OpenSsoReturnType = {};
277
-
278
- const mockClient = {
279
- config: {
280
- metadata: { name: "Test App" },
281
- },
282
- request: vi.fn().mockResolvedValue(mockResponse),
283
- } as unknown as FrakClient;
284
-
285
- const params: OpenSsoParamsType = {
286
- metadata: {
287
- logoUrl: "https://example.com/logo.png",
288
- },
289
- };
290
-
291
- await openSso(mockClient, params);
292
-
293
- expect(window.open).toHaveBeenCalledWith(
294
- expect.stringContaining("https://wallet.frak.id/sso"),
295
- expect.any(String),
296
- expect.any(String)
297
- );
298
- });
299
- });
300
-
301
- describe("popup blocker", () => {
302
- it("should throw error when popup is blocked", async () => {
303
- vi.spyOn(window, "open").mockReturnValue(null);
304
-
305
- const mockClient = {
306
- config: {
307
- metadata: { name: "Test App" },
308
- },
309
- request: vi.fn(),
310
- } as unknown as FrakClient;
311
-
312
- const params: OpenSsoParamsType = {
313
- metadata: {
314
- logoUrl: "https://example.com/logo.png",
315
- },
316
- };
317
-
318
- await expect(openSso(mockClient, params)).rejects.toThrow(
319
- "Popup was blocked. Please allow popups for this site."
320
- );
321
- });
322
-
323
- it("should not call client.request when popup is blocked", async () => {
324
- vi.spyOn(window, "open").mockReturnValue(null);
325
-
326
- const mockClient = {
327
- config: {
328
- metadata: { name: "Test App" },
329
- },
330
- request: vi.fn(),
331
- } as unknown as FrakClient;
332
-
333
- const params: OpenSsoParamsType = {
334
- metadata: {
335
- logoUrl: "https://example.com/logo.png",
336
- },
337
- };
338
-
339
- try {
340
- await openSso(mockClient, params);
341
- } catch {
342
- // Expected error
343
- }
344
-
345
- expect(mockClient.request).not.toHaveBeenCalled();
346
- });
347
- });
348
-
349
- describe("mode detection", () => {
350
- it("should prefer openInSameWindow over redirectUrl", async () => {
351
- const mockResponse: OpenSsoReturnType = {};
352
-
353
- const mockClient = {
354
- config: {
355
- metadata: { name: "Test App" },
356
- },
357
- request: vi.fn().mockResolvedValue(mockResponse),
358
- } as unknown as FrakClient;
359
-
360
- const params: OpenSsoParamsType = {
361
- openInSameWindow: false,
362
- redirectUrl: "https://example.com/callback",
363
- metadata: {
364
- logoUrl: "https://example.com/logo.png",
365
- },
366
- };
367
-
368
- const windowOpenSpy = vi.spyOn(window, "open").mockReturnValue({
369
- focus: vi.fn(),
370
- } as unknown as Window);
371
-
372
- await openSso(mockClient, params);
373
-
374
- // Should use popup mode because openInSameWindow=false
375
- expect(window.open).toHaveBeenCalled();
376
-
377
- windowOpenSpy.mockRestore();
378
- });
379
-
380
- it("should use popup mode when neither flag is set", async () => {
381
- const mockResponse: OpenSsoReturnType = {};
382
-
383
- const mockClient = {
384
- config: {
385
- metadata: { name: "Test App" },
386
- },
387
- request: vi.fn().mockResolvedValue(mockResponse),
388
- } as unknown as FrakClient;
389
-
390
- const params: OpenSsoParamsType = {
391
- metadata: {
392
- logoUrl: "https://example.com/logo.png",
393
- },
394
- };
395
-
396
- const windowOpenSpy = vi.spyOn(window, "open").mockReturnValue({
397
- focus: vi.fn(),
398
- } as unknown as Window);
399
-
400
- await openSso(mockClient, params);
401
-
402
- expect(window.open).toHaveBeenCalled();
403
-
404
- windowOpenSpy.mockRestore();
405
- });
406
- });
407
- });
@@ -1,219 +0,0 @@
1
- /**
2
- * Tests for sendInteraction action
3
- * Tests sending user interactions via RPC
4
- */
5
-
6
- import type { Hex } from "viem";
7
- import { vi } from "vitest";
8
-
9
- // Mock computeProductId - must be before imports
10
- vi.mock("../utils/computeProductId", () => ({
11
- computeProductId: vi.fn(
12
- () =>
13
- "0xcomputed1234567890123456789012345678901234567890123456789012" as Hex
14
- ),
15
- }));
16
-
17
- import { describe, expect, it } from "../../tests/vitest-fixtures";
18
- import type {
19
- FrakClient,
20
- PreparedInteraction,
21
- SendInteractionParamsType,
22
- SendInteractionReturnType,
23
- } from "../types";
24
- import { sendInteraction } from "./sendInteraction";
25
-
26
- describe("sendInteraction", () => {
27
- const mockInteraction: PreparedInteraction = {
28
- interactionData: "0xdata" as Hex,
29
- handlerTypeDenominator: "0x01" as Hex,
30
- };
31
-
32
- describe("with productId provided", () => {
33
- it("should use provided productId", async () => {
34
- const mockResponse: SendInteractionReturnType = {
35
- delegationId: "delegation-123",
36
- };
37
-
38
- const mockClient = {
39
- config: {
40
- domain: "example.com",
41
- },
42
- request: vi.fn().mockResolvedValue(mockResponse),
43
- } as unknown as FrakClient;
44
-
45
- const params: SendInteractionParamsType = {
46
- productId:
47
- "0xprovidedid567890123456789012345678901234567890123456789012" as Hex,
48
- interaction: mockInteraction,
49
- };
50
-
51
- await sendInteraction(mockClient, params);
52
-
53
- expect(mockClient.request).toHaveBeenCalledWith({
54
- method: "frak_sendInteraction",
55
- params: [
56
- "0xprovidedid567890123456789012345678901234567890123456789012",
57
- mockInteraction,
58
- undefined,
59
- ],
60
- });
61
- });
62
-
63
- it("should return delegationId", async () => {
64
- const mockResponse: SendInteractionReturnType = {
65
- delegationId: "delegation-456",
66
- };
67
-
68
- const mockClient = {
69
- config: {
70
- domain: "example.com",
71
- },
72
- request: vi.fn().mockResolvedValue(mockResponse),
73
- } as unknown as FrakClient;
74
-
75
- const params: SendInteractionParamsType = {
76
- productId:
77
- "0xprovidedid567890123456789012345678901234567890123456789012" as Hex,
78
- interaction: mockInteraction,
79
- };
80
-
81
- const result = await sendInteraction(mockClient, params);
82
-
83
- expect(result).toEqual(mockResponse);
84
- expect(result.delegationId).toBe("delegation-456");
85
- });
86
-
87
- it("should include validation signature when provided", async () => {
88
- const mockResponse: SendInteractionReturnType = {
89
- delegationId: "delegation-789",
90
- };
91
-
92
- const mockClient = {
93
- config: {
94
- domain: "example.com",
95
- },
96
- request: vi.fn().mockResolvedValue(mockResponse),
97
- } as unknown as FrakClient;
98
-
99
- const params: SendInteractionParamsType = {
100
- productId:
101
- "0xprovidedid567890123456789012345678901234567890123456789012" as Hex,
102
- interaction: mockInteraction,
103
- validation: "0xsignature1234567890" as Hex,
104
- };
105
-
106
- await sendInteraction(mockClient, params);
107
-
108
- expect(mockClient.request).toHaveBeenCalledWith({
109
- method: "frak_sendInteraction",
110
- params: [
111
- "0xprovidedid567890123456789012345678901234567890123456789012",
112
- mockInteraction,
113
- "0xsignature1234567890",
114
- ],
115
- });
116
- });
117
- });
118
-
119
- describe("without productId provided", () => {
120
- it("should compute productId from client.config", async () => {
121
- const { computeProductId } = await import(
122
- "../utils/computeProductId"
123
- );
124
-
125
- const mockResponse: SendInteractionReturnType = {
126
- delegationId: "delegation-computed",
127
- };
128
-
129
- const mockClient = {
130
- config: {
131
- domain: "example.com",
132
- },
133
- request: vi.fn().mockResolvedValue(mockResponse),
134
- } as unknown as FrakClient;
135
-
136
- const params: SendInteractionParamsType = {
137
- interaction: mockInteraction,
138
- };
139
-
140
- await sendInteraction(mockClient, params);
141
-
142
- expect(computeProductId).toHaveBeenCalledWith(mockClient.config);
143
- expect(mockClient.request).toHaveBeenCalledWith({
144
- method: "frak_sendInteraction",
145
- params: [
146
- "0xcomputed1234567890123456789012345678901234567890123456789012",
147
- mockInteraction,
148
- undefined,
149
- ],
150
- });
151
- });
152
-
153
- it("should work with different interaction types", async () => {
154
- const mockResponse: SendInteractionReturnType = {
155
- delegationId: "delegation-different",
156
- };
157
-
158
- const mockClient = {
159
- config: {
160
- domain: "example.com",
161
- },
162
- request: vi.fn().mockResolvedValue(mockResponse),
163
- } as unknown as FrakClient;
164
-
165
- const differentInteraction: PreparedInteraction = {
166
- interactionData: "0xdifferentdata" as Hex,
167
- handlerTypeDenominator: "0x02" as Hex,
168
- };
169
-
170
- const params: SendInteractionParamsType = {
171
- interaction: differentInteraction,
172
- };
173
-
174
- const result = await sendInteraction(mockClient, params);
175
-
176
- expect(result).toEqual(mockResponse);
177
- });
178
- });
179
-
180
- describe("error handling", () => {
181
- it("should propagate errors from client.request", async () => {
182
- const error = new Error("Send interaction failed");
183
- const mockClient = {
184
- config: {
185
- domain: "example.com",
186
- },
187
- request: vi.fn().mockRejectedValue(error),
188
- } as unknown as FrakClient;
189
-
190
- const params: SendInteractionParamsType = {
191
- productId:
192
- "0xprovidedid567890123456789012345678901234567890123456789012" as Hex,
193
- interaction: mockInteraction,
194
- };
195
-
196
- await expect(sendInteraction(mockClient, params)).rejects.toThrow(
197
- "Send interaction failed"
198
- );
199
- });
200
-
201
- it("should handle network errors", async () => {
202
- const error = new Error("Network timeout");
203
- const mockClient = {
204
- config: {
205
- domain: "example.com",
206
- },
207
- request: vi.fn().mockRejectedValue(error),
208
- } as unknown as FrakClient;
209
-
210
- const params: SendInteractionParamsType = {
211
- interaction: mockInteraction,
212
- };
213
-
214
- await expect(sendInteraction(mockClient, params)).rejects.toThrow(
215
- "Network timeout"
216
- );
217
- });
218
- });
219
- });