@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,128 +0,0 @@
1
- /**
2
- * Tests for interactionTypes constants
3
- * Tests interaction type definitions and type utilities
4
- */
5
-
6
- import { describe, expect, it } from "vitest";
7
- import { interactionTypes } from "./interactionTypes";
8
-
9
- describe("interactionTypes", () => {
10
- describe("structure", () => {
11
- it("should have all expected categories", () => {
12
- expect(interactionTypes).toHaveProperty("press");
13
- expect(interactionTypes).toHaveProperty("dapp");
14
- expect(interactionTypes).toHaveProperty("webshop");
15
- expect(interactionTypes).toHaveProperty("referral");
16
- expect(interactionTypes).toHaveProperty("purchase");
17
- expect(interactionTypes).toHaveProperty("retail");
18
- });
19
-
20
- it("should have press interactions", () => {
21
- expect(interactionTypes.press).toEqual({
22
- openArticle: "0xc0a24ffb",
23
- readArticle: "0xd5bd0fbe",
24
- });
25
- });
26
-
27
- it("should have dapp interactions", () => {
28
- expect(interactionTypes.dapp).toEqual({
29
- proofVerifiableStorageUpdate: "0x2ab2aeef",
30
- callableVerifiableStorageUpdate: "0xa07da986",
31
- });
32
- });
33
-
34
- it("should have webshop interactions", () => {
35
- expect(interactionTypes.webshop).toEqual({
36
- open: "0xb311798f",
37
- });
38
- });
39
-
40
- it("should have referral interactions", () => {
41
- expect(interactionTypes.referral).toEqual({
42
- referred: "0x010cc3b9",
43
- createLink: "0xb2c0f17c",
44
- });
45
- });
46
-
47
- it("should have purchase interactions", () => {
48
- expect(interactionTypes.purchase).toEqual({
49
- started: "0xd87e90c3",
50
- completed: "0x8403aeb4",
51
- unsafeCompleted: "0x4d5b14e0",
52
- });
53
- });
54
-
55
- it("should have retail interactions", () => {
56
- expect(interactionTypes.retail).toEqual({
57
- customerMeeting: "0x74489004",
58
- });
59
- });
60
- });
61
-
62
- describe("interaction values", () => {
63
- it("should have all interaction values as hex strings", () => {
64
- Object.values(interactionTypes).forEach((category) => {
65
- Object.values(category).forEach((value) => {
66
- expect(value).toMatch(/^0x[a-f0-9]{8}$/);
67
- });
68
- });
69
- });
70
-
71
- it("should have unique interaction values across all categories", () => {
72
- const allValues = Object.values(interactionTypes).flatMap(
73
- (category) => Object.values(category)
74
- );
75
- const uniqueValues = new Set(allValues);
76
- expect(allValues.length).toBe(uniqueValues.size);
77
- });
78
- });
79
-
80
- describe("specific interactions", () => {
81
- it("should have correct press.openArticle value", () => {
82
- expect(interactionTypes.press.openArticle).toBe("0xc0a24ffb");
83
- });
84
-
85
- it("should have correct press.readArticle value", () => {
86
- expect(interactionTypes.press.readArticle).toBe("0xd5bd0fbe");
87
- });
88
-
89
- it("should have correct webshop.open value", () => {
90
- expect(interactionTypes.webshop.open).toBe("0xb311798f");
91
- });
92
-
93
- it("should have correct referral.referred value", () => {
94
- expect(interactionTypes.referral.referred).toBe("0x010cc3b9");
95
- });
96
-
97
- it("should have correct purchase.completed value", () => {
98
- expect(interactionTypes.purchase.completed).toBe("0x8403aeb4");
99
- });
100
-
101
- it("should have correct purchase.unsafeCompleted value", () => {
102
- expect(interactionTypes.purchase.unsafeCompleted).toBe(
103
- "0x4d5b14e0"
104
- );
105
- });
106
-
107
- it("should have correct retail.customerMeeting value", () => {
108
- expect(interactionTypes.retail.customerMeeting).toBe("0x74489004");
109
- });
110
- });
111
-
112
- describe("type safety", () => {
113
- it("should be readonly (as const)", () => {
114
- // TypeScript ensures this is readonly, but we can verify structure
115
- expect(Object.isFrozen(interactionTypes)).toBe(false);
116
- // The values should be consistent
117
- expect(typeof interactionTypes.press.openArticle).toBe("string");
118
- });
119
-
120
- it("should have consistent structure across categories", () => {
121
- Object.values(interactionTypes).forEach((category) => {
122
- expect(typeof category).toBe("object");
123
- expect(category).not.toBeNull();
124
- expect(Array.isArray(category)).toBe(false);
125
- });
126
- });
127
- });
128
- });
@@ -1,130 +0,0 @@
1
- /**
2
- * Tests for productTypes constants
3
- * Tests product type definitions and bitmask calculations
4
- */
5
-
6
- import { describe, expect, it } from "vitest";
7
- import { productTypes, productTypesMask } from "./productTypes";
8
-
9
- describe("productTypes", () => {
10
- describe("structure", () => {
11
- it("should have all expected product types", () => {
12
- expect(productTypes).toHaveProperty("dapp");
13
- expect(productTypes).toHaveProperty("press");
14
- expect(productTypes).toHaveProperty("webshop");
15
- expect(productTypes).toHaveProperty("retail");
16
- expect(productTypes).toHaveProperty("referral");
17
- expect(productTypes).toHaveProperty("purchase");
18
- });
19
-
20
- it("should have correct numeric values", () => {
21
- expect(productTypes.dapp).toBe(1);
22
- expect(productTypes.press).toBe(2);
23
- expect(productTypes.webshop).toBe(3);
24
- expect(productTypes.retail).toBe(4);
25
- expect(productTypes.referral).toBe(30);
26
- expect(productTypes.purchase).toBe(31);
27
- });
28
- });
29
-
30
- describe("productTypesMask", () => {
31
- it("should have masks for all product types", () => {
32
- expect(productTypesMask).toHaveProperty("dapp");
33
- expect(productTypesMask).toHaveProperty("press");
34
- expect(productTypesMask).toHaveProperty("webshop");
35
- expect(productTypesMask).toHaveProperty("retail");
36
- expect(productTypesMask).toHaveProperty("referral");
37
- expect(productTypesMask).toHaveProperty("purchase");
38
- });
39
-
40
- it("should calculate correct bitmask for dapp (value 1)", () => {
41
- expect(productTypesMask.dapp).toBe(BigInt(1) << BigInt(1));
42
- expect(productTypesMask.dapp).toBe(BigInt(2));
43
- });
44
-
45
- it("should calculate correct bitmask for press (value 2)", () => {
46
- expect(productTypesMask.press).toBe(BigInt(1) << BigInt(2));
47
- expect(productTypesMask.press).toBe(BigInt(4));
48
- });
49
-
50
- it("should calculate correct bitmask for webshop (value 3)", () => {
51
- expect(productTypesMask.webshop).toBe(BigInt(1) << BigInt(3));
52
- expect(productTypesMask.webshop).toBe(BigInt(8));
53
- });
54
-
55
- it("should calculate correct bitmask for retail (value 4)", () => {
56
- expect(productTypesMask.retail).toBe(BigInt(1) << BigInt(4));
57
- expect(productTypesMask.retail).toBe(BigInt(16));
58
- });
59
-
60
- it("should calculate correct bitmask for referral (value 30)", () => {
61
- expect(productTypesMask.referral).toBe(BigInt(1) << BigInt(30));
62
- expect(productTypesMask.referral).toBe(BigInt(1073741824));
63
- });
64
-
65
- it("should calculate correct bitmask for purchase (value 31)", () => {
66
- expect(productTypesMask.purchase).toBe(BigInt(1) << BigInt(31));
67
- expect(productTypesMask.purchase).toBe(BigInt(2147483648));
68
- });
69
-
70
- it("should have all masks as BigInt values", () => {
71
- Object.values(productTypesMask).forEach((mask) => {
72
- expect(typeof mask).toBe("bigint");
73
- });
74
- });
75
-
76
- it("should have unique mask values", () => {
77
- const maskValues = Object.values(productTypesMask);
78
- const uniqueValues = new Set(maskValues);
79
- expect(maskValues.length).toBe(uniqueValues.size);
80
- });
81
- });
82
-
83
- describe("bitmask calculation", () => {
84
- it("should correctly calculate bitmask from product type value", () => {
85
- // Verify the formula: 1 << value
86
- expect(productTypesMask.dapp).toBe(
87
- BigInt(1) << BigInt(productTypes.dapp)
88
- );
89
- expect(productTypesMask.press).toBe(
90
- BigInt(1) << BigInt(productTypes.press)
91
- );
92
- expect(productTypesMask.webshop).toBe(
93
- BigInt(1) << BigInt(productTypes.webshop)
94
- );
95
- expect(productTypesMask.retail).toBe(
96
- BigInt(1) << BigInt(productTypes.retail)
97
- );
98
- expect(productTypesMask.referral).toBe(
99
- BigInt(1) << BigInt(productTypes.referral)
100
- );
101
- expect(productTypesMask.purchase).toBe(
102
- BigInt(1) << BigInt(productTypes.purchase)
103
- );
104
- });
105
-
106
- it("should have masks that are powers of 2", () => {
107
- Object.values(productTypesMask).forEach((mask) => {
108
- // A power of 2 has exactly one bit set
109
- // Check: mask & (mask - 1n) should be 0n
110
- const isPowerOfTwo = mask > 0n && (mask & (mask - 1n)) === 0n;
111
- expect(isPowerOfTwo).toBe(true);
112
- });
113
- });
114
- });
115
-
116
- describe("type safety", () => {
117
- it("should have consistent structure", () => {
118
- const productKeys = Object.keys(productTypes);
119
- const maskKeys = Object.keys(productTypesMask);
120
- expect(productKeys.sort()).toEqual(maskKeys.sort());
121
- });
122
-
123
- it("should have numeric values for product types", () => {
124
- Object.values(productTypes).forEach((value) => {
125
- expect(typeof value).toBe("number");
126
- expect(Number.isInteger(value)).toBe(true);
127
- });
128
- });
129
- });
130
- });
@@ -1,33 +0,0 @@
1
- /**
2
- * The keys for each product types
3
- * @inline
4
- */
5
- export type ProductTypesKey = keyof typeof productTypes;
6
-
7
- /**
8
- * List of the product types per denominator
9
- */
10
- export const productTypes = {
11
- // content type
12
- dapp: 1,
13
- press: 2,
14
- webshop: 3,
15
- retail: 4,
16
-
17
- // feature type
18
- referral: 30,
19
- purchase: 31,
20
- };
21
-
22
- /**
23
- * Bitmask for each product types
24
- */
25
- export const productTypesMask: Record<ProductTypesKey, bigint> = Object.entries(
26
- productTypes
27
- ).reduce(
28
- (acc, [key, value]) => {
29
- acc[key as ProductTypesKey] = BigInt(1) << BigInt(value);
30
- return acc;
31
- },
32
- {} as Record<ProductTypesKey, bigint>
33
- );
@@ -1,5 +0,0 @@
1
- export { PressInteractionEncoder } from "./pressEncoder";
2
- export { PurchaseInteractionEncoder } from "./purchaseEncoder";
3
- export { ReferralInteractionEncoder } from "./referralEncoder";
4
- export { RetailInteractionEncoder } from "./retailEncoder";
5
- export { WebShopInteractionEncoder } from "./webshopEncoder";
@@ -1,215 +0,0 @@
1
- /**
2
- * Tests for PressInteractionEncoder
3
- * Tests encoding of press-related user interactions
4
- */
5
-
6
- import { pad, toHex } from "viem";
7
- import { describe, expect, it, test } from "../../tests/vitest-fixtures";
8
- import { interactionTypes } from "../constants/interactionTypes";
9
- import { productTypes } from "../constants/productTypes";
10
- import { PressInteractionEncoder } from "./pressEncoder";
11
-
12
- describe("PressInteractionEncoder", () => {
13
- describe("openArticle", () => {
14
- test("should encode open article interaction with correct structure", ({
15
- mockArticleId,
16
- }) => {
17
- const interaction = PressInteractionEncoder.openArticle({
18
- articleId: mockArticleId,
19
- });
20
-
21
- // Should return PreparedInteraction structure
22
- expect(interaction).toHaveProperty("handlerTypeDenominator");
23
- expect(interaction).toHaveProperty("interactionData");
24
- });
25
-
26
- test("should use press product type in handlerTypeDenominator", ({
27
- mockArticleId,
28
- }) => {
29
- const interaction = PressInteractionEncoder.openArticle({
30
- articleId: mockArticleId,
31
- });
32
-
33
- // Should use press product type (2)
34
- const expectedDenominator = toHex(productTypes.press);
35
- expect(interaction.handlerTypeDenominator).toBe(
36
- expectedDenominator
37
- );
38
- });
39
-
40
- test("should include openArticle interaction type in data", ({
41
- mockArticleId,
42
- }) => {
43
- const interaction = PressInteractionEncoder.openArticle({
44
- articleId: mockArticleId,
45
- });
46
-
47
- // Should start with openArticle interaction type
48
- expect(interaction.interactionData).toContain(
49
- interactionTypes.press.openArticle
50
- );
51
- });
52
-
53
- test("should pad article ID to 32 bytes", ({ mockArticleId }) => {
54
- const interaction = PressInteractionEncoder.openArticle({
55
- articleId: mockArticleId,
56
- });
57
-
58
- // Article ID should be padded to 32 bytes (64 hex chars + 0x prefix = 66 chars)
59
- const paddedArticleId = pad(mockArticleId, { size: 32 });
60
- expect(interaction.interactionData).toContain(
61
- paddedArticleId.slice(2)
62
- );
63
- });
64
-
65
- it("should handle short article IDs by padding", () => {
66
- const shortArticleId = "0x01" as const;
67
- const interaction = PressInteractionEncoder.openArticle({
68
- articleId: shortArticleId,
69
- });
70
-
71
- // Should pad short IDs to 32 bytes
72
- expect(interaction.interactionData).toBeDefined();
73
- // Total length: openArticle (10 chars) + padded ID (64 chars) + 0x (2 chars) = 76 chars
74
- expect(interaction.interactionData.length).toBeGreaterThan(64);
75
- });
76
-
77
- test("should produce consistent output for same article ID", ({
78
- mockArticleId,
79
- }) => {
80
- const interaction1 = PressInteractionEncoder.openArticle({
81
- articleId: mockArticleId,
82
- });
83
- const interaction2 = PressInteractionEncoder.openArticle({
84
- articleId: mockArticleId,
85
- });
86
-
87
- // Same input should produce same output
88
- expect(interaction1).toEqual(interaction2);
89
- });
90
- });
91
-
92
- describe("readArticle", () => {
93
- test("should encode read article interaction with correct structure", ({
94
- mockArticleId,
95
- }) => {
96
- const interaction = PressInteractionEncoder.readArticle({
97
- articleId: mockArticleId,
98
- });
99
-
100
- // Should return PreparedInteraction structure
101
- expect(interaction).toHaveProperty("handlerTypeDenominator");
102
- expect(interaction).toHaveProperty("interactionData");
103
- });
104
-
105
- test("should use press product type in handlerTypeDenominator", ({
106
- mockArticleId,
107
- }) => {
108
- const interaction = PressInteractionEncoder.readArticle({
109
- articleId: mockArticleId,
110
- });
111
-
112
- // Should use press product type (2)
113
- const expectedDenominator = toHex(productTypes.press);
114
- expect(interaction.handlerTypeDenominator).toBe(
115
- expectedDenominator
116
- );
117
- });
118
-
119
- test("should include readArticle interaction type in data", ({
120
- mockArticleId,
121
- }) => {
122
- const interaction = PressInteractionEncoder.readArticle({
123
- articleId: mockArticleId,
124
- });
125
-
126
- // Should start with readArticle interaction type
127
- expect(interaction.interactionData).toContain(
128
- interactionTypes.press.readArticle
129
- );
130
- });
131
-
132
- test("should pad article ID to 32 bytes", ({ mockArticleId }) => {
133
- const interaction = PressInteractionEncoder.readArticle({
134
- articleId: mockArticleId,
135
- });
136
-
137
- // Article ID should be padded to 32 bytes
138
- const paddedArticleId = pad(mockArticleId, { size: 32 });
139
- expect(interaction.interactionData).toContain(
140
- paddedArticleId.slice(2)
141
- );
142
- });
143
-
144
- test("should produce different output than openArticle for same ID", ({
145
- mockArticleId,
146
- }) => {
147
- const openInteraction = PressInteractionEncoder.openArticle({
148
- articleId: mockArticleId,
149
- });
150
- const readInteraction = PressInteractionEncoder.readArticle({
151
- articleId: mockArticleId,
152
- });
153
-
154
- // Different interaction types should produce different data
155
- expect(openInteraction.interactionData).not.toBe(
156
- readInteraction.interactionData
157
- );
158
-
159
- // But should have same handlerTypeDenominator (both press)
160
- expect(openInteraction.handlerTypeDenominator).toBe(
161
- readInteraction.handlerTypeDenominator
162
- );
163
- });
164
- });
165
-
166
- describe("interaction data format", () => {
167
- test("should concatenate interaction type and padded article ID", ({
168
- mockArticleId,
169
- }) => {
170
- const interaction = PressInteractionEncoder.openArticle({
171
- articleId: mockArticleId,
172
- });
173
-
174
- // Should start with interaction type (10 chars including 0x)
175
- expect(interaction.interactionData.slice(0, 10)).toBe(
176
- interactionTypes.press.openArticle
177
- );
178
-
179
- // Should be followed by padded article ID (64 hex chars)
180
- expect(interaction.interactionData.length).toBe(74); // 0x + 8 (type) + 64 (padded ID)
181
- });
182
-
183
- test("should produce valid hex strings", ({ mockArticleId }) => {
184
- const openInteraction = PressInteractionEncoder.openArticle({
185
- articleId: mockArticleId,
186
- });
187
- const readInteraction = PressInteractionEncoder.readArticle({
188
- articleId: mockArticleId,
189
- });
190
-
191
- // Both should be valid hex strings starting with 0x
192
- expect(openInteraction.interactionData).toMatch(/^0x[0-9a-f]+$/);
193
- expect(readInteraction.interactionData).toMatch(/^0x[0-9a-f]+$/);
194
- });
195
-
196
- it("should handle different article IDs correctly", () => {
197
- const articleId1 =
198
- "0x0000000000000000000000000000000000000000000000000000000000000001" as const;
199
- const articleId2 =
200
- "0x0000000000000000000000000000000000000000000000000000000000000002" as const;
201
-
202
- const interaction1 = PressInteractionEncoder.openArticle({
203
- articleId: articleId1,
204
- });
205
- const interaction2 = PressInteractionEncoder.openArticle({
206
- articleId: articleId2,
207
- });
208
-
209
- // Different article IDs should produce different interaction data
210
- expect(interaction1.interactionData).not.toBe(
211
- interaction2.interactionData
212
- );
213
- });
214
- });
215
- });
@@ -1,53 +0,0 @@
1
- import { concatHex, type Hex, pad, toHex } from "viem";
2
- import { interactionTypes } from "../constants/interactionTypes";
3
- import { productTypes } from "../constants/productTypes";
4
- import type { PreparedInteraction } from "../types";
5
-
6
- /**
7
- * Press interactions allow you to track user engagement with articles or other press content on your platform.
8
- * After setting up these interactions, you can create acquisition campaign based on the user engagement with your press content.
9
- *
10
- * :::info
11
- * To properly handle press interactions, ensure that the "Press" product type is enabled in your Business dashboard.
12
- * :::
13
- *
14
- * @description Encode press related user interactions
15
- *
16
- * @group Interactions Encoder
17
- *
18
- * @see {@link PreparedInteraction} The prepared interaction object that can be sent
19
- * @see {@link !actions.sendInteraction | `sendInteraction()`} Action used to send the prepared interaction to the Frak Wallet
20
- */
21
- export const PressInteractionEncoder = {
22
- /**
23
- * Encode an open article interaction
24
- * @param args
25
- * @param args.articleId - The id of the article the user opened (32 bytes), could be a `keccak256` hash of the article slug, or your internal id
26
- */
27
- openArticle({ articleId }: { articleId: Hex }): PreparedInteraction {
28
- const interactionData = concatHex([
29
- interactionTypes.press.openArticle,
30
- pad(articleId, { size: 32 }),
31
- ]);
32
- return {
33
- handlerTypeDenominator: toHex(productTypes.press),
34
- interactionData,
35
- };
36
- },
37
-
38
- /**
39
- * Encode a read article interaction
40
- * @param args
41
- * @param args.articleId - The id of the article the user opened (32 bytes), could be a `keccak256` hash of the article slug, or your internal id
42
- */
43
- readArticle({ articleId }: { articleId: Hex }): PreparedInteraction {
44
- const interactionData = concatHex([
45
- interactionTypes.press.readArticle,
46
- pad(articleId, { size: 32 }),
47
- ]);
48
- return {
49
- handlerTypeDenominator: toHex(productTypes.press),
50
- interactionData,
51
- };
52
- },
53
- };