@frak-labs/core-sdk 0.1.0-beta.8d103039 → 0.1.0-beta.b0bd1f8a
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/cdn/bundle.iife.js +14 -0
- package/dist/actions-CEEObPYc.js +1 -0
- package/dist/actions-DbQhWYx8.cjs +1 -0
- package/dist/actions.cjs +1 -1
- package/dist/actions.d.cts +3 -1481
- package/dist/actions.d.ts +3 -1481
- package/dist/actions.js +1 -1
- package/dist/bundle.cjs +1 -13
- package/dist/bundle.d.cts +6 -2087
- package/dist/bundle.d.ts +6 -2087
- package/dist/bundle.js +1 -13
- package/dist/index-7OZ39x1U.d.ts +195 -0
- package/dist/index-C6FxkWPC.d.cts +511 -0
- package/dist/index-UFX7xCg3.d.ts +351 -0
- package/dist/index-d8xS4ryI.d.ts +511 -0
- package/dist/index-p4FqSp8z.d.cts +351 -0
- package/dist/index-zDq-VlKx.d.cts +195 -0
- package/dist/index.cjs +1 -13
- package/dist/index.d.cts +4 -1387
- package/dist/index.d.ts +4 -1387
- package/dist/index.js +1 -13
- package/dist/interaction-DMJ3ZfaF.d.cts +45 -0
- package/dist/interaction-KX1h9a7V.d.ts +45 -0
- package/dist/interactions-DnfM3oe0.js +1 -0
- package/dist/interactions-EIXhNLf6.cjs +1 -0
- package/dist/interactions.cjs +1 -1
- package/dist/interactions.d.cts +2 -182
- package/dist/interactions.d.ts +2 -182
- package/dist/interactions.js +1 -1
- package/dist/openSso-D--Airj6.d.cts +1018 -0
- package/dist/openSso-DsKJ4y0j.d.ts +1018 -0
- package/dist/productTypes-BUkXJKZ7.cjs +1 -0
- package/dist/productTypes-CGb1MmBF.js +1 -0
- package/dist/src-B_xO0AR6.cjs +13 -0
- package/dist/src-D2d52OZa.js +13 -0
- package/dist/trackEvent-CHnYa85W.js +1 -0
- package/dist/trackEvent-GuQm_1Nm.cjs +1 -0
- package/package.json +21 -17
- 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.test.ts +343 -0
- package/src/clients/setupClient.ts +3 -1
- package/src/clients/transports/iframeLifecycleManager.test.ts +399 -0
- 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 +407 -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
|
@@ -0,0 +1,215 @@
|
|
|
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,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,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 }),
|