@frak-labs/core-sdk 0.1.0-beta.8d103039 → 0.1.0-beta.d9302e66
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.
- package/package.json +20 -16
- package/src/actions/displayEmbeddedWallet.test.ts +194 -0
- package/src/actions/displayModal.test.ts +387 -0
- package/src/actions/getProductInformation.test.ts +133 -0
- package/src/actions/index.ts +19 -19
- package/src/actions/openSso.test.ts +407 -0
- package/src/actions/prepareSso.test.ts +223 -0
- package/src/actions/referral/processReferral.ts +1 -1
- package/src/actions/referral/referralInteraction.ts +1 -1
- package/src/actions/sendInteraction.test.ts +219 -0
- package/src/actions/trackPurchaseStatus.test.ts +287 -0
- package/src/actions/watchWalletStatus.test.ts +372 -0
- package/src/bundle.ts +1 -1
- package/src/clients/createIFrameFrakClient.ts +2 -2
- package/src/clients/index.ts +1 -1
- package/src/clients/setupClient.ts +3 -1
- package/src/clients/transports/iframeLifecycleManager.ts +3 -1
- package/src/index.ts +72 -74
- package/src/interactions/index.ts +2 -2
- package/src/interactions/pressEncoder.test.ts +215 -0
- package/src/interactions/pressEncoder.ts +1 -1
- package/src/interactions/purchaseEncoder.test.ts +291 -0
- package/src/interactions/purchaseEncoder.ts +8 -3
- package/src/interactions/referralEncoder.test.ts +170 -0
- package/src/interactions/retailEncoder.test.ts +107 -0
- package/src/interactions/retailEncoder.ts +1 -1
- package/src/interactions/webshopEncoder.test.ts +56 -0
- package/src/types/index.ts +51 -50
- package/src/types/lifecycle/index.ts +1 -1
- package/src/types/rpc/embedded/loggedIn.ts +1 -1
- package/src/types/rpc/embedded/loggedOut.ts +1 -1
- package/src/types/rpc/modal/index.ts +11 -11
- package/src/utils/FrakContext.test.ts +338 -0
- package/src/utils/FrakContext.ts +8 -2
- package/src/utils/compression/b64.test.ts +181 -0
- package/src/utils/compression/compress.test.ts +123 -0
- package/src/utils/compression/decompress.test.ts +145 -0
- package/src/utils/compression/index.ts +1 -1
- package/src/utils/computeProductId.test.ts +80 -0
- package/src/utils/constants.test.ts +23 -0
- package/src/utils/formatAmount.test.ts +113 -0
- package/src/utils/getCurrencyAmountKey.test.ts +44 -0
- package/src/utils/getSupportedCurrency.test.ts +51 -0
- package/src/utils/getSupportedLocale.test.ts +64 -0
- package/src/utils/iframeHelper.test.ts +450 -0
- package/src/utils/iframeHelper.ts +4 -3
- package/src/utils/index.ts +12 -12
- package/src/utils/sso.test.ts +361 -0
- package/src/utils/trackEvent.test.ts +162 -0
- package/cdn/bundle.js +0 -19
- package/cdn/bundle.js.LICENSE.txt +0 -10
- package/dist/actions.cjs +0 -1
- package/dist/actions.d.cts +0 -1481
- package/dist/actions.d.ts +0 -1481
- package/dist/actions.js +0 -1
- package/dist/bundle.cjs +0 -13
- package/dist/bundle.d.cts +0 -2087
- package/dist/bundle.d.ts +0 -2087
- package/dist/bundle.js +0 -13
- package/dist/index.cjs +0 -13
- package/dist/index.d.cts +0 -1387
- package/dist/index.d.ts +0 -1387
- package/dist/index.js +0 -13
- package/dist/interactions.cjs +0 -1
- package/dist/interactions.d.cts +0 -182
- package/dist/interactions.d.ts +0 -182
- package/dist/interactions.js +0 -1
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for PurchaseInteractionEncoder
|
|
3
|
+
* Tests encoding of purchase-related user interactions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Hex } from "viem";
|
|
7
|
+
import { encodeAbiParameters, pad, toHex } from "viem";
|
|
8
|
+
import { describe, expect, test } from "../../tests/vitest-fixtures";
|
|
9
|
+
import { interactionTypes } from "../constants/interactionTypes";
|
|
10
|
+
import { productTypes } from "../constants/productTypes";
|
|
11
|
+
import { PurchaseInteractionEncoder } from "./purchaseEncoder";
|
|
12
|
+
|
|
13
|
+
describe("PurchaseInteractionEncoder", () => {
|
|
14
|
+
describe("startPurchase", () => {
|
|
15
|
+
test("should encode start purchase interaction with correct structure", ({
|
|
16
|
+
mockPurchaseId,
|
|
17
|
+
}) => {
|
|
18
|
+
const interaction = PurchaseInteractionEncoder.startPurchase({
|
|
19
|
+
purchaseId: mockPurchaseId,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Should return PreparedInteraction structure
|
|
23
|
+
expect(interaction).toHaveProperty("handlerTypeDenominator");
|
|
24
|
+
expect(interaction).toHaveProperty("interactionData");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("should use purchase product type in handlerTypeDenominator", ({
|
|
28
|
+
mockPurchaseId,
|
|
29
|
+
}) => {
|
|
30
|
+
const interaction = PurchaseInteractionEncoder.startPurchase({
|
|
31
|
+
purchaseId: mockPurchaseId,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Should use purchase product type (31)
|
|
35
|
+
const expectedDenominator = toHex(productTypes.purchase);
|
|
36
|
+
expect(interaction.handlerTypeDenominator).toBe(
|
|
37
|
+
expectedDenominator
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("should include started interaction type in data", ({
|
|
42
|
+
mockPurchaseId,
|
|
43
|
+
}) => {
|
|
44
|
+
const interaction = PurchaseInteractionEncoder.startPurchase({
|
|
45
|
+
purchaseId: mockPurchaseId,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Should start with started interaction type
|
|
49
|
+
expect(interaction.interactionData).toContain(
|
|
50
|
+
interactionTypes.purchase.started
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("should pad purchase ID to 32 bytes", ({ mockPurchaseId }) => {
|
|
55
|
+
const interaction = PurchaseInteractionEncoder.startPurchase({
|
|
56
|
+
purchaseId: mockPurchaseId,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Purchase ID should be padded to 32 bytes
|
|
60
|
+
const paddedPurchaseId = pad(mockPurchaseId, { size: 32 });
|
|
61
|
+
expect(interaction.interactionData).toContain(
|
|
62
|
+
paddedPurchaseId.slice(2)
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("should produce consistent output for same purchase ID", ({
|
|
67
|
+
mockPurchaseId,
|
|
68
|
+
}) => {
|
|
69
|
+
const interaction1 = PurchaseInteractionEncoder.startPurchase({
|
|
70
|
+
purchaseId: mockPurchaseId,
|
|
71
|
+
});
|
|
72
|
+
const interaction2 = PurchaseInteractionEncoder.startPurchase({
|
|
73
|
+
purchaseId: mockPurchaseId,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Same input should produce same output
|
|
77
|
+
expect(interaction1).toEqual(interaction2);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("completedPurchase", () => {
|
|
82
|
+
test("should encode completed purchase with proof", ({
|
|
83
|
+
mockPurchaseId,
|
|
84
|
+
mockProof,
|
|
85
|
+
}) => {
|
|
86
|
+
const interaction = PurchaseInteractionEncoder.completedPurchase({
|
|
87
|
+
purchaseId: mockPurchaseId,
|
|
88
|
+
proof: mockProof,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Should return PreparedInteraction structure
|
|
92
|
+
expect(interaction).toHaveProperty("handlerTypeDenominator");
|
|
93
|
+
expect(interaction).toHaveProperty("interactionData");
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("should use purchase product type in handlerTypeDenominator", ({
|
|
97
|
+
mockPurchaseId,
|
|
98
|
+
mockProof,
|
|
99
|
+
}) => {
|
|
100
|
+
const interaction = PurchaseInteractionEncoder.completedPurchase({
|
|
101
|
+
purchaseId: mockPurchaseId,
|
|
102
|
+
proof: mockProof,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Should use purchase product type (31)
|
|
106
|
+
const expectedDenominator = toHex(productTypes.purchase);
|
|
107
|
+
expect(interaction.handlerTypeDenominator).toBe(
|
|
108
|
+
expectedDenominator
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("should include completed interaction type in data", ({
|
|
113
|
+
mockPurchaseId,
|
|
114
|
+
mockProof,
|
|
115
|
+
}) => {
|
|
116
|
+
const interaction = PurchaseInteractionEncoder.completedPurchase({
|
|
117
|
+
purchaseId: mockPurchaseId,
|
|
118
|
+
proof: mockProof,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Should start with completed interaction type
|
|
122
|
+
expect(interaction.interactionData).toContain(
|
|
123
|
+
interactionTypes.purchase.completed
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("should use ABI encoding for inner data", ({
|
|
128
|
+
mockPurchaseId,
|
|
129
|
+
mockProof,
|
|
130
|
+
}) => {
|
|
131
|
+
const interaction = PurchaseInteractionEncoder.completedPurchase({
|
|
132
|
+
purchaseId: mockPurchaseId,
|
|
133
|
+
proof: mockProof,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Inner data should be ABI encoded (uint256 + bytes32[])
|
|
137
|
+
const expectedInnerData = encodeAbiParameters(
|
|
138
|
+
[{ type: "uint256" }, { type: "bytes32[]" }],
|
|
139
|
+
[BigInt(mockPurchaseId), mockProof]
|
|
140
|
+
);
|
|
141
|
+
expect(interaction.interactionData).toContain(
|
|
142
|
+
expectedInnerData.slice(2)
|
|
143
|
+
);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("should handle empty proof array", ({ mockPurchaseId }) => {
|
|
147
|
+
const interaction = PurchaseInteractionEncoder.completedPurchase({
|
|
148
|
+
purchaseId: mockPurchaseId,
|
|
149
|
+
proof: [],
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Should still encode properly with empty proof
|
|
153
|
+
expect(interaction.interactionData).toBeDefined();
|
|
154
|
+
expect(interaction.handlerTypeDenominator).toBe(
|
|
155
|
+
toHex(productTypes.purchase)
|
|
156
|
+
);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test("should handle multiple proof elements", ({ mockPurchaseId }) => {
|
|
160
|
+
const largeProof: Hex[] = [
|
|
161
|
+
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
162
|
+
"0x0000000000000000000000000000000000000000000000000000000000000002",
|
|
163
|
+
"0x0000000000000000000000000000000000000000000000000000000000000003",
|
|
164
|
+
"0x0000000000000000000000000000000000000000000000000000000000000004",
|
|
165
|
+
"0x0000000000000000000000000000000000000000000000000000000000000005",
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
const interaction = PurchaseInteractionEncoder.completedPurchase({
|
|
169
|
+
purchaseId: mockPurchaseId,
|
|
170
|
+
proof: largeProof,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Should handle larger proof arrays
|
|
174
|
+
expect(interaction.interactionData).toBeDefined();
|
|
175
|
+
expect(interaction.handlerTypeDenominator).toBe(
|
|
176
|
+
toHex(productTypes.purchase)
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe("unsafeCompletedPurchase", () => {
|
|
182
|
+
test("should encode unsafe completed purchase", ({
|
|
183
|
+
mockPurchaseId,
|
|
184
|
+
}) => {
|
|
185
|
+
const interaction =
|
|
186
|
+
PurchaseInteractionEncoder.unsafeCompletedPurchase({
|
|
187
|
+
purchaseId: mockPurchaseId,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Should return PreparedInteraction structure
|
|
191
|
+
expect(interaction).toHaveProperty("handlerTypeDenominator");
|
|
192
|
+
expect(interaction).toHaveProperty("interactionData");
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test("should use purchase product type in handlerTypeDenominator", ({
|
|
196
|
+
mockPurchaseId,
|
|
197
|
+
}) => {
|
|
198
|
+
const interaction =
|
|
199
|
+
PurchaseInteractionEncoder.unsafeCompletedPurchase({
|
|
200
|
+
purchaseId: mockPurchaseId,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Should use purchase product type (31)
|
|
204
|
+
const expectedDenominator = toHex(productTypes.purchase);
|
|
205
|
+
expect(interaction.handlerTypeDenominator).toBe(
|
|
206
|
+
expectedDenominator
|
|
207
|
+
);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test("should include unsafeCompleted interaction type in data", ({
|
|
211
|
+
mockPurchaseId,
|
|
212
|
+
}) => {
|
|
213
|
+
const interaction =
|
|
214
|
+
PurchaseInteractionEncoder.unsafeCompletedPurchase({
|
|
215
|
+
purchaseId: mockPurchaseId,
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// Should start with unsafeCompleted interaction type
|
|
219
|
+
expect(interaction.interactionData).toContain(
|
|
220
|
+
interactionTypes.purchase.unsafeCompleted
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test("should pad purchase ID to 32 bytes", ({ mockPurchaseId }) => {
|
|
225
|
+
const interaction =
|
|
226
|
+
PurchaseInteractionEncoder.unsafeCompletedPurchase({
|
|
227
|
+
purchaseId: mockPurchaseId,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// Purchase ID should be padded to 32 bytes
|
|
231
|
+
const paddedPurchaseId = pad(mockPurchaseId, { size: 32 });
|
|
232
|
+
expect(interaction.interactionData).toContain(
|
|
233
|
+
paddedPurchaseId.slice(2)
|
|
234
|
+
);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
test("should differ from safe completed purchase", ({
|
|
238
|
+
mockPurchaseId,
|
|
239
|
+
}) => {
|
|
240
|
+
const safeInteraction =
|
|
241
|
+
PurchaseInteractionEncoder.completedPurchase({
|
|
242
|
+
purchaseId: mockPurchaseId,
|
|
243
|
+
proof: [],
|
|
244
|
+
});
|
|
245
|
+
const unsafeInteraction =
|
|
246
|
+
PurchaseInteractionEncoder.unsafeCompletedPurchase({
|
|
247
|
+
purchaseId: mockPurchaseId,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Unsafe and safe versions should be different
|
|
251
|
+
expect(unsafeInteraction.interactionData).not.toBe(
|
|
252
|
+
safeInteraction.interactionData
|
|
253
|
+
);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
describe("interaction data format", () => {
|
|
258
|
+
test("should produce valid hex strings", ({ mockPurchaseId }) => {
|
|
259
|
+
const startInteraction = PurchaseInteractionEncoder.startPurchase({
|
|
260
|
+
purchaseId: mockPurchaseId,
|
|
261
|
+
});
|
|
262
|
+
const unsafeInteraction =
|
|
263
|
+
PurchaseInteractionEncoder.unsafeCompletedPurchase({
|
|
264
|
+
purchaseId: mockPurchaseId,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// Both should be valid hex strings starting with 0x
|
|
268
|
+
expect(startInteraction.interactionData).toMatch(/^0x[0-9a-f]+$/);
|
|
269
|
+
expect(unsafeInteraction.interactionData).toMatch(/^0x[0-9a-f]+$/);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
test("should handle different purchase IDs correctly", () => {
|
|
273
|
+
const purchaseId1 =
|
|
274
|
+
"0x0000000000000000000000000000000000000000000000000000000000000001" as const;
|
|
275
|
+
const purchaseId2 =
|
|
276
|
+
"0x0000000000000000000000000000000000000000000000000000000000000002" as const;
|
|
277
|
+
|
|
278
|
+
const interaction1 = PurchaseInteractionEncoder.startPurchase({
|
|
279
|
+
purchaseId: purchaseId1,
|
|
280
|
+
});
|
|
281
|
+
const interaction2 = PurchaseInteractionEncoder.startPurchase({
|
|
282
|
+
purchaseId: purchaseId2,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// Different purchase IDs should produce different interaction data
|
|
286
|
+
expect(interaction1.interactionData).not.toBe(
|
|
287
|
+
interaction2.interactionData
|
|
288
|
+
);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { concatHex, encodeAbiParameters, type Hex, pad, toHex } from "viem";
|
|
2
2
|
import { interactionTypes } from "../constants/interactionTypes";
|
|
3
3
|
import { productTypes } from "../constants/productTypes";
|
|
4
4
|
import type { PreparedInteraction } from "../types";
|
|
@@ -59,7 +59,10 @@ export const PurchaseInteractionEncoder = {
|
|
|
59
59
|
completedPurchase({
|
|
60
60
|
purchaseId,
|
|
61
61
|
proof,
|
|
62
|
-
}: {
|
|
62
|
+
}: {
|
|
63
|
+
purchaseId: Hex;
|
|
64
|
+
proof: Hex[];
|
|
65
|
+
}): PreparedInteraction {
|
|
63
66
|
const innerData = encodeAbiParameters(
|
|
64
67
|
[{ type: "uint256" }, { type: "bytes32[]" }],
|
|
65
68
|
[BigInt(purchaseId), proof]
|
|
@@ -81,7 +84,9 @@ export const PurchaseInteractionEncoder = {
|
|
|
81
84
|
*/
|
|
82
85
|
unsafeCompletedPurchase({
|
|
83
86
|
purchaseId,
|
|
84
|
-
}: {
|
|
87
|
+
}: {
|
|
88
|
+
purchaseId: Hex;
|
|
89
|
+
}): PreparedInteraction {
|
|
85
90
|
const interactionData = concatHex([
|
|
86
91
|
interactionTypes.purchase.unsafeCompleted,
|
|
87
92
|
pad(purchaseId, { size: 32 }),
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for ReferralInteractionEncoder
|
|
3
|
+
* Tests encoding of referral-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 { ReferralInteractionEncoder } from "./referralEncoder";
|
|
11
|
+
|
|
12
|
+
describe("ReferralInteractionEncoder", () => {
|
|
13
|
+
describe("createLink", () => {
|
|
14
|
+
it("should encode create link interaction with correct structure", () => {
|
|
15
|
+
const interaction = ReferralInteractionEncoder.createLink();
|
|
16
|
+
|
|
17
|
+
// Should return PreparedInteraction structure
|
|
18
|
+
expect(interaction).toHaveProperty("handlerTypeDenominator");
|
|
19
|
+
expect(interaction).toHaveProperty("interactionData");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should use referral product type in handlerTypeDenominator", () => {
|
|
23
|
+
const interaction = ReferralInteractionEncoder.createLink();
|
|
24
|
+
|
|
25
|
+
// Should use referral product type (30)
|
|
26
|
+
const expectedDenominator = toHex(productTypes.referral);
|
|
27
|
+
expect(interaction.handlerTypeDenominator).toBe(
|
|
28
|
+
expectedDenominator
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("should use createLink interaction type in data", () => {
|
|
33
|
+
const interaction = ReferralInteractionEncoder.createLink();
|
|
34
|
+
|
|
35
|
+
// Should use createLink interaction type
|
|
36
|
+
expect(interaction.interactionData).toBe(
|
|
37
|
+
interactionTypes.referral.createLink
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should produce consistent output (no parameters)", () => {
|
|
42
|
+
const interaction1 = ReferralInteractionEncoder.createLink();
|
|
43
|
+
const interaction2 = ReferralInteractionEncoder.createLink();
|
|
44
|
+
|
|
45
|
+
// Should always produce the same output
|
|
46
|
+
expect(interaction1).toEqual(interaction2);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe("referred", () => {
|
|
51
|
+
test("should encode referred interaction with correct structure", ({
|
|
52
|
+
mockReferrerAddress,
|
|
53
|
+
}) => {
|
|
54
|
+
const interaction = ReferralInteractionEncoder.referred({
|
|
55
|
+
referrer: mockReferrerAddress,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Should return PreparedInteraction structure
|
|
59
|
+
expect(interaction).toHaveProperty("handlerTypeDenominator");
|
|
60
|
+
expect(interaction).toHaveProperty("interactionData");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("should use referral product type in handlerTypeDenominator", ({
|
|
64
|
+
mockReferrerAddress,
|
|
65
|
+
}) => {
|
|
66
|
+
const interaction = ReferralInteractionEncoder.referred({
|
|
67
|
+
referrer: mockReferrerAddress,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Should use referral product type (30)
|
|
71
|
+
const expectedDenominator = toHex(productTypes.referral);
|
|
72
|
+
expect(interaction.handlerTypeDenominator).toBe(
|
|
73
|
+
expectedDenominator
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("should include referred interaction type in data", ({
|
|
78
|
+
mockReferrerAddress,
|
|
79
|
+
}) => {
|
|
80
|
+
const interaction = ReferralInteractionEncoder.referred({
|
|
81
|
+
referrer: mockReferrerAddress,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Should start with referred interaction type
|
|
85
|
+
expect(interaction.interactionData).toContain(
|
|
86
|
+
interactionTypes.referral.referred
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("should pad referrer address to 32 bytes", ({
|
|
91
|
+
mockReferrerAddress,
|
|
92
|
+
}) => {
|
|
93
|
+
const interaction = ReferralInteractionEncoder.referred({
|
|
94
|
+
referrer: mockReferrerAddress,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Referrer address should be padded to 32 bytes
|
|
98
|
+
const paddedAddress = pad(mockReferrerAddress, { size: 32 });
|
|
99
|
+
expect(interaction.interactionData).toContain(
|
|
100
|
+
paddedAddress.slice(2)
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("should produce different output for different referrers", () => {
|
|
105
|
+
const referrer1 =
|
|
106
|
+
"0x1234567890123456789012345678901234567890" as const;
|
|
107
|
+
const referrer2 =
|
|
108
|
+
"0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as const;
|
|
109
|
+
|
|
110
|
+
const interaction1 = ReferralInteractionEncoder.referred({
|
|
111
|
+
referrer: referrer1,
|
|
112
|
+
});
|
|
113
|
+
const interaction2 = ReferralInteractionEncoder.referred({
|
|
114
|
+
referrer: referrer2,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Different referrers should produce different interaction data
|
|
118
|
+
expect(interaction1.interactionData).not.toBe(
|
|
119
|
+
interaction2.interactionData
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("should produce consistent output for same referrer", ({
|
|
124
|
+
mockReferrerAddress,
|
|
125
|
+
}) => {
|
|
126
|
+
const interaction1 = ReferralInteractionEncoder.referred({
|
|
127
|
+
referrer: mockReferrerAddress,
|
|
128
|
+
});
|
|
129
|
+
const interaction2 = ReferralInteractionEncoder.referred({
|
|
130
|
+
referrer: mockReferrerAddress,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Same referrer should produce same output
|
|
134
|
+
expect(interaction1).toEqual(interaction2);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe("interaction data format", () => {
|
|
139
|
+
test("should produce valid hex strings", ({ mockReferrerAddress }) => {
|
|
140
|
+
const createLinkInteraction =
|
|
141
|
+
ReferralInteractionEncoder.createLink();
|
|
142
|
+
const referredInteraction = ReferralInteractionEncoder.referred({
|
|
143
|
+
referrer: mockReferrerAddress,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Both should be valid hex strings starting with 0x
|
|
147
|
+
expect(createLinkInteraction.interactionData).toMatch(
|
|
148
|
+
/^0x[0-9a-f]+$/
|
|
149
|
+
);
|
|
150
|
+
expect(referredInteraction.interactionData).toMatch(
|
|
151
|
+
/^0x[0-9a-f]+$/
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("should have different interaction types", ({
|
|
156
|
+
mockReferrerAddress,
|
|
157
|
+
}) => {
|
|
158
|
+
const createLinkInteraction =
|
|
159
|
+
ReferralInteractionEncoder.createLink();
|
|
160
|
+
const referredInteraction = ReferralInteractionEncoder.referred({
|
|
161
|
+
referrer: mockReferrerAddress,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Different interaction types should produce different data
|
|
165
|
+
expect(createLinkInteraction.interactionData).not.toBe(
|
|
166
|
+
referredInteraction.interactionData
|
|
167
|
+
);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for RetailInteractionEncoder
|
|
3
|
+
* Tests encoding of retail-related user interactions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { pad, toHex } from "viem";
|
|
7
|
+
import { describe, expect, test } from "../../tests/vitest-fixtures";
|
|
8
|
+
import { interactionTypes } from "../constants/interactionTypes";
|
|
9
|
+
import { productTypes } from "../constants/productTypes";
|
|
10
|
+
import { RetailInteractionEncoder } from "./retailEncoder";
|
|
11
|
+
|
|
12
|
+
describe("RetailInteractionEncoder", () => {
|
|
13
|
+
describe("customerMeeting", () => {
|
|
14
|
+
test("should encode customer meeting interaction with correct structure", ({
|
|
15
|
+
mockAgencyId,
|
|
16
|
+
}) => {
|
|
17
|
+
const interaction = RetailInteractionEncoder.customerMeeting({
|
|
18
|
+
agencyId: mockAgencyId,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Should return PreparedInteraction structure
|
|
22
|
+
expect(interaction).toHaveProperty("handlerTypeDenominator");
|
|
23
|
+
expect(interaction).toHaveProperty("interactionData");
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("should use retail product type in handlerTypeDenominator", ({
|
|
27
|
+
mockAgencyId,
|
|
28
|
+
}) => {
|
|
29
|
+
const interaction = RetailInteractionEncoder.customerMeeting({
|
|
30
|
+
agencyId: mockAgencyId,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Should use retail product type (4)
|
|
34
|
+
const expectedDenominator = toHex(productTypes.retail);
|
|
35
|
+
expect(interaction.handlerTypeDenominator).toBe(
|
|
36
|
+
expectedDenominator
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("should include customerMeeting interaction type in data", ({
|
|
41
|
+
mockAgencyId,
|
|
42
|
+
}) => {
|
|
43
|
+
const interaction = RetailInteractionEncoder.customerMeeting({
|
|
44
|
+
agencyId: mockAgencyId,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Should start with customerMeeting interaction type
|
|
48
|
+
expect(interaction.interactionData).toContain(
|
|
49
|
+
interactionTypes.retail.customerMeeting
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("should pad agency ID to 32 bytes", ({ mockAgencyId }) => {
|
|
54
|
+
const interaction = RetailInteractionEncoder.customerMeeting({
|
|
55
|
+
agencyId: mockAgencyId,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Agency ID should be padded to 32 bytes
|
|
59
|
+
const paddedAgencyId = pad(mockAgencyId, { size: 32 });
|
|
60
|
+
expect(interaction.interactionData).toContain(
|
|
61
|
+
paddedAgencyId.slice(2)
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("should produce consistent output for same agency ID", ({
|
|
66
|
+
mockAgencyId,
|
|
67
|
+
}) => {
|
|
68
|
+
const interaction1 = RetailInteractionEncoder.customerMeeting({
|
|
69
|
+
agencyId: mockAgencyId,
|
|
70
|
+
});
|
|
71
|
+
const interaction2 = RetailInteractionEncoder.customerMeeting({
|
|
72
|
+
agencyId: mockAgencyId,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Same input should produce same output
|
|
76
|
+
expect(interaction1).toEqual(interaction2);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("should produce different output for different agency IDs", () => {
|
|
80
|
+
const agencyId1 =
|
|
81
|
+
"0x0000000000000000000000000000000000000000000000000000000000000001" as const;
|
|
82
|
+
const agencyId2 =
|
|
83
|
+
"0x0000000000000000000000000000000000000000000000000000000000000002" as const;
|
|
84
|
+
|
|
85
|
+
const interaction1 = RetailInteractionEncoder.customerMeeting({
|
|
86
|
+
agencyId: agencyId1,
|
|
87
|
+
});
|
|
88
|
+
const interaction2 = RetailInteractionEncoder.customerMeeting({
|
|
89
|
+
agencyId: agencyId2,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Different agency IDs should produce different interaction data
|
|
93
|
+
expect(interaction1.interactionData).not.toBe(
|
|
94
|
+
interaction2.interactionData
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("should produce valid hex string", ({ mockAgencyId }) => {
|
|
99
|
+
const interaction = RetailInteractionEncoder.customerMeeting({
|
|
100
|
+
agencyId: mockAgencyId,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Should be valid hex string starting with 0x
|
|
104
|
+
expect(interaction.interactionData).toMatch(/^0x[0-9a-f]+$/);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Hex,
|
|
1
|
+
import { concatHex, type Hex, pad, toHex } from "viem";
|
|
2
2
|
import { interactionTypes } from "../constants/interactionTypes";
|
|
3
3
|
import { productTypes } from "../constants/productTypes";
|
|
4
4
|
import type { PreparedInteraction } from "../types";
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for WebShopInteractionEncoder
|
|
3
|
+
* Tests encoding of webshop-related user interactions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { toHex } from "viem";
|
|
7
|
+
import { describe, expect, it } from "../../tests/vitest-fixtures";
|
|
8
|
+
import { interactionTypes } from "../constants/interactionTypes";
|
|
9
|
+
import { productTypes } from "../constants/productTypes";
|
|
10
|
+
import { WebShopInteractionEncoder } from "./webshopEncoder";
|
|
11
|
+
|
|
12
|
+
describe("WebShopInteractionEncoder", () => {
|
|
13
|
+
describe("open", () => {
|
|
14
|
+
it("should encode open webshop interaction with correct structure", () => {
|
|
15
|
+
const interaction = WebShopInteractionEncoder.open();
|
|
16
|
+
|
|
17
|
+
// Should return PreparedInteraction structure
|
|
18
|
+
expect(interaction).toHaveProperty("handlerTypeDenominator");
|
|
19
|
+
expect(interaction).toHaveProperty("interactionData");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should use webshop product type in handlerTypeDenominator", () => {
|
|
23
|
+
const interaction = WebShopInteractionEncoder.open();
|
|
24
|
+
|
|
25
|
+
// Should use webshop product type (3)
|
|
26
|
+
const expectedDenominator = toHex(productTypes.webshop);
|
|
27
|
+
expect(interaction.handlerTypeDenominator).toBe(
|
|
28
|
+
expectedDenominator
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("should use open interaction type in data", () => {
|
|
33
|
+
const interaction = WebShopInteractionEncoder.open();
|
|
34
|
+
|
|
35
|
+
// Should use open interaction type
|
|
36
|
+
expect(interaction.interactionData).toBe(
|
|
37
|
+
interactionTypes.webshop.open
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should produce consistent output (no parameters)", () => {
|
|
42
|
+
const interaction1 = WebShopInteractionEncoder.open();
|
|
43
|
+
const interaction2 = WebShopInteractionEncoder.open();
|
|
44
|
+
|
|
45
|
+
// Should always produce the same output
|
|
46
|
+
expect(interaction1).toEqual(interaction2);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("should produce valid hex string", () => {
|
|
50
|
+
const interaction = WebShopInteractionEncoder.open();
|
|
51
|
+
|
|
52
|
+
// Should be valid hex string starting with 0x
|
|
53
|
+
expect(interaction.interactionData).toMatch(/^0x[0-9a-f]+$/);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|