@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.
- package/README.md +58 -0
- package/cdn/bundle.js +14 -0
- package/dist/actions.cjs +1 -1
- package/dist/actions.d.cts +3 -3
- package/dist/actions.d.ts +3 -3
- package/dist/actions.js +1 -1
- package/dist/bundle.cjs +1 -1
- package/dist/bundle.d.cts +4 -6
- package/dist/bundle.d.ts +4 -6
- package/dist/bundle.js +1 -1
- package/dist/{index-CRsQWnTs.d.cts → computeLegacyProductId-BkyJ4rEY.d.ts} +197 -10
- package/dist/{index-Ck1hudEi.d.ts → computeLegacyProductId-Raks6FXg.d.cts} +197 -10
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1 -1
- package/dist/{openSso-D--Airj6.d.cts → openSso-BCJGchIb.d.cts} +135 -131
- package/dist/{openSso-DsKJ4y0j.d.ts → openSso-DG-_9CED.d.ts} +135 -131
- package/dist/setupClient-BEiAE56h.js +13 -0
- package/dist/setupClient-Ls3vKSlH.cjs +13 -0
- package/dist/{index-d8xS4ryI.d.ts → siweAuthenticate-BH7Dn7nZ.d.cts} +90 -65
- package/dist/siweAuthenticate-BJHbtty4.js +1 -0
- package/dist/{index-C6FxkWPC.d.cts → siweAuthenticate-Btem4QHs.d.ts} +90 -65
- package/dist/siweAuthenticate-Cwj3HP0m.cjs +1 -0
- package/dist/trackEvent-M2RLTQ2p.js +1 -0
- package/dist/trackEvent-T_R9ER2S.cjs +1 -0
- package/package.json +11 -22
- package/src/actions/displayEmbeddedWallet.ts +1 -0
- package/src/actions/displayModal.test.ts +12 -11
- package/src/actions/displayModal.ts +7 -18
- package/src/actions/ensureIdentity.ts +68 -0
- package/src/actions/{getProductInformation.test.ts → getMerchantInformation.test.ts} +33 -50
- package/src/actions/getMerchantInformation.ts +16 -0
- package/src/actions/index.ts +3 -2
- package/src/actions/openSso.ts +4 -2
- package/src/actions/referral/processReferral.test.ts +42 -151
- package/src/actions/referral/processReferral.ts +18 -42
- package/src/actions/referral/referralInteraction.test.ts +1 -7
- package/src/actions/referral/referralInteraction.ts +1 -6
- package/src/actions/sendInteraction.ts +46 -22
- package/src/actions/trackPurchaseStatus.test.ts +354 -141
- package/src/actions/trackPurchaseStatus.ts +48 -11
- package/src/actions/watchWalletStatus.ts +2 -3
- package/src/actions/wrapper/modalBuilder.test.ts +0 -14
- package/src/actions/wrapper/modalBuilder.ts +3 -12
- package/src/bundle.ts +0 -1
- package/src/clients/createIFrameFrakClient.ts +10 -5
- package/src/clients/transports/iframeLifecycleManager.test.ts +163 -4
- package/src/clients/transports/iframeLifecycleManager.ts +172 -33
- package/src/constants/interactionTypes.ts +12 -41
- package/src/index.ts +24 -16
- package/src/types/config.ts +6 -0
- package/src/types/index.ts +13 -10
- package/src/types/lifecycle/client.ts +24 -1
- package/src/types/lifecycle/iframe.ts +6 -0
- package/src/types/rpc/displayModal.ts +2 -4
- package/src/types/rpc/embedded/index.ts +2 -2
- package/src/types/rpc/interaction.ts +26 -39
- package/src/types/rpc/merchantInformation.ts +77 -0
- package/src/types/rpc/modal/index.ts +0 -4
- package/src/types/rpc/modal/login.ts +5 -1
- package/src/types/rpc/walletStatus.ts +1 -7
- package/src/types/rpc.ts +22 -30
- package/src/types/tracking.ts +60 -0
- package/src/utils/backendUrl.test.ts +83 -0
- package/src/utils/backendUrl.ts +62 -0
- package/src/utils/clientId.test.ts +41 -0
- package/src/utils/clientId.ts +43 -0
- package/src/utils/compression/compress.test.ts +1 -1
- package/src/utils/compression/compress.ts +2 -2
- package/src/utils/compression/decompress.test.ts +8 -4
- package/src/utils/compression/decompress.ts +2 -2
- package/src/utils/{computeProductId.ts → computeLegacyProductId.ts} +2 -2
- package/src/utils/constants.ts +5 -0
- package/src/utils/deepLinkWithFallback.test.ts +243 -0
- package/src/utils/deepLinkWithFallback.ts +103 -0
- package/src/utils/formatAmount.ts +6 -0
- package/src/utils/iframeHelper.test.ts +18 -5
- package/src/utils/iframeHelper.ts +10 -3
- package/src/utils/index.ts +16 -1
- package/src/utils/merchantId.test.ts +653 -0
- package/src/utils/merchantId.ts +143 -0
- package/src/utils/sso.ts +18 -11
- package/src/utils/trackEvent.test.ts +23 -5
- package/src/utils/trackEvent.ts +13 -0
- package/cdn/bundle.iife.js +0 -14
- package/dist/actions-B5j-i1p0.cjs +0 -1
- package/dist/actions-q090Z0oR.js +0 -1
- package/dist/index-7OZ39x1U.d.ts +0 -195
- package/dist/index-zDq-VlKx.d.cts +0 -195
- package/dist/interaction-DMJ3ZfaF.d.cts +0 -45
- package/dist/interaction-KX1h9a7V.d.ts +0 -45
- package/dist/interactions-DnfM3oe0.js +0 -1
- package/dist/interactions-EIXhNLf6.cjs +0 -1
- package/dist/interactions.cjs +0 -1
- package/dist/interactions.d.cts +0 -2
- package/dist/interactions.d.ts +0 -2
- package/dist/interactions.js +0 -1
- package/dist/productTypes-BUkXJKZ7.cjs +0 -1
- package/dist/productTypes-CGb1MmBF.js +0 -1
- package/dist/src-1LQ4eLq5.js +0 -13
- package/dist/src-hW71KjPN.cjs +0 -13
- package/dist/trackEvent-CHnYa85W.js +0 -1
- package/dist/trackEvent-GuQm_1Nm.cjs +0 -1
- package/src/actions/getProductInformation.ts +0 -14
- package/src/actions/openSso.test.ts +0 -407
- package/src/actions/sendInteraction.test.ts +0 -219
- package/src/constants/interactionTypes.test.ts +0 -128
- package/src/constants/productTypes.test.ts +0 -130
- package/src/constants/productTypes.ts +0 -33
- package/src/interactions/index.ts +0 -5
- package/src/interactions/pressEncoder.test.ts +0 -215
- package/src/interactions/pressEncoder.ts +0 -53
- package/src/interactions/purchaseEncoder.test.ts +0 -291
- package/src/interactions/purchaseEncoder.ts +0 -99
- package/src/interactions/referralEncoder.test.ts +0 -170
- package/src/interactions/referralEncoder.ts +0 -47
- package/src/interactions/retailEncoder.test.ts +0 -107
- package/src/interactions/retailEncoder.ts +0 -37
- package/src/interactions/webshopEncoder.test.ts +0 -56
- package/src/interactions/webshopEncoder.ts +0 -30
- package/src/types/rpc/modal/openSession.ts +0 -25
- package/src/types/rpc/productInformation.ts +0 -59
- package/src/utils/computeProductId.test.ts +0 -80
- package/src/utils/sso.test.ts +0 -361
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for getProductInformation action
|
|
3
|
-
* Tests fetching product information via RPC
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
1
|
import type { Address, Hex } from "viem";
|
|
7
2
|
import { describe, expect, it, vi } from "../../tests/vitest-fixtures";
|
|
8
|
-
import type { FrakClient,
|
|
9
|
-
import {
|
|
3
|
+
import type { FrakClient, GetMerchantInformationReturnType } from "../types";
|
|
4
|
+
import { getMerchantInformation } from "./getMerchantInformation";
|
|
10
5
|
|
|
11
|
-
describe("
|
|
6
|
+
describe("getMerchantInformation", () => {
|
|
12
7
|
describe("success cases", () => {
|
|
13
8
|
it("should call client.request with correct method", async () => {
|
|
14
|
-
const mockResponse:
|
|
9
|
+
const mockResponse: GetMerchantInformationReturnType = {
|
|
15
10
|
id: "0x1234567890123456789012345678901234567890123456789012345678901234" as Hex,
|
|
16
11
|
onChainMetadata: {
|
|
17
|
-
name: "Test
|
|
12
|
+
name: "Test Merchant",
|
|
18
13
|
domain: "example.com",
|
|
19
|
-
productTypes: ["press"],
|
|
20
14
|
},
|
|
21
15
|
rewards: [],
|
|
22
16
|
};
|
|
@@ -25,20 +19,19 @@ describe("getProductInformation", () => {
|
|
|
25
19
|
request: vi.fn().mockResolvedValue(mockResponse),
|
|
26
20
|
} as unknown as FrakClient;
|
|
27
21
|
|
|
28
|
-
await
|
|
22
|
+
await getMerchantInformation(mockClient);
|
|
29
23
|
|
|
30
24
|
expect(mockClient.request).toHaveBeenCalledWith({
|
|
31
|
-
method: "
|
|
25
|
+
method: "frak_getMerchantInformation",
|
|
32
26
|
});
|
|
33
27
|
});
|
|
34
28
|
|
|
35
|
-
it("should return
|
|
36
|
-
const mockResponse:
|
|
29
|
+
it("should return merchant information", async () => {
|
|
30
|
+
const mockResponse: GetMerchantInformationReturnType = {
|
|
37
31
|
id: "0x1234567890123456789012345678901234567890123456789012345678901234" as Hex,
|
|
38
32
|
onChainMetadata: {
|
|
39
|
-
name: "Test
|
|
33
|
+
name: "Test Merchant",
|
|
40
34
|
domain: "example.com",
|
|
41
|
-
productTypes: ["press"],
|
|
42
35
|
},
|
|
43
36
|
rewards: [],
|
|
44
37
|
};
|
|
@@ -47,48 +40,40 @@ describe("getProductInformation", () => {
|
|
|
47
40
|
request: vi.fn().mockResolvedValue(mockResponse),
|
|
48
41
|
} as unknown as FrakClient;
|
|
49
42
|
|
|
50
|
-
const result = await
|
|
43
|
+
const result = await getMerchantInformation(mockClient);
|
|
51
44
|
|
|
52
45
|
expect(result).toEqual(mockResponse);
|
|
53
46
|
});
|
|
54
47
|
|
|
55
|
-
it("should return
|
|
56
|
-
const mockResponse:
|
|
48
|
+
it("should return merchant information with rewards", async () => {
|
|
49
|
+
const mockResponse: GetMerchantInformationReturnType = {
|
|
57
50
|
id: "0x1234567890123456789012345678901234567890123456789012345678901234" as Hex,
|
|
58
51
|
onChainMetadata: {
|
|
59
|
-
name: "Test
|
|
52
|
+
name: "Test Merchant",
|
|
60
53
|
domain: "example.com",
|
|
61
|
-
productTypes: ["press", "purchase"],
|
|
62
|
-
},
|
|
63
|
-
maxReferrer: {
|
|
64
|
-
amount: 100,
|
|
65
|
-
eurAmount: 10,
|
|
66
|
-
usdAmount: 12,
|
|
67
|
-
gbpAmount: 9,
|
|
68
|
-
},
|
|
69
|
-
maxReferee: {
|
|
70
|
-
amount: 50,
|
|
71
|
-
eurAmount: 5,
|
|
72
|
-
usdAmount: 6,
|
|
73
|
-
gbpAmount: 4.5,
|
|
74
54
|
},
|
|
75
55
|
rewards: [
|
|
76
56
|
{
|
|
77
57
|
token: "0x1234567890123456789012345678901234567890" as Address,
|
|
78
|
-
campaign
|
|
79
|
-
|
|
80
|
-
interactionTypeKey: "press.readArticle",
|
|
58
|
+
campaignId: "campaign-1",
|
|
59
|
+
interactionTypeKey: "referral",
|
|
81
60
|
referrer: {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
61
|
+
payoutType: "fixed",
|
|
62
|
+
amount: {
|
|
63
|
+
amount: 10,
|
|
64
|
+
eurAmount: 1,
|
|
65
|
+
usdAmount: 1.2,
|
|
66
|
+
gbpAmount: 0.9,
|
|
67
|
+
},
|
|
86
68
|
},
|
|
87
69
|
referee: {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
70
|
+
payoutType: "fixed",
|
|
71
|
+
amount: {
|
|
72
|
+
amount: 5,
|
|
73
|
+
eurAmount: 0.5,
|
|
74
|
+
usdAmount: 0.6,
|
|
75
|
+
gbpAmount: 0.45,
|
|
76
|
+
},
|
|
92
77
|
},
|
|
93
78
|
},
|
|
94
79
|
],
|
|
@@ -98,12 +83,10 @@ describe("getProductInformation", () => {
|
|
|
98
83
|
request: vi.fn().mockResolvedValue(mockResponse),
|
|
99
84
|
} as unknown as FrakClient;
|
|
100
85
|
|
|
101
|
-
const result = await
|
|
86
|
+
const result = await getMerchantInformation(mockClient);
|
|
102
87
|
|
|
103
88
|
expect(result).toEqual(mockResponse);
|
|
104
89
|
expect(result.rewards).toHaveLength(1);
|
|
105
|
-
expect(result.maxReferrer).toBeDefined();
|
|
106
|
-
expect(result.maxReferee).toBeDefined();
|
|
107
90
|
});
|
|
108
91
|
});
|
|
109
92
|
|
|
@@ -114,7 +97,7 @@ describe("getProductInformation", () => {
|
|
|
114
97
|
request: vi.fn().mockRejectedValue(error),
|
|
115
98
|
} as unknown as FrakClient;
|
|
116
99
|
|
|
117
|
-
await expect(
|
|
100
|
+
await expect(getMerchantInformation(mockClient)).rejects.toThrow(
|
|
118
101
|
"RPC request failed"
|
|
119
102
|
);
|
|
120
103
|
});
|
|
@@ -125,7 +108,7 @@ describe("getProductInformation", () => {
|
|
|
125
108
|
request: vi.fn().mockRejectedValue(error),
|
|
126
109
|
} as unknown as FrakClient;
|
|
127
110
|
|
|
128
|
-
await expect(
|
|
111
|
+
await expect(getMerchantInformation(mockClient)).rejects.toThrow(
|
|
129
112
|
"Request timeout"
|
|
130
113
|
);
|
|
131
114
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FrakClient, GetMerchantInformationReturnType } from "../types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Fetch the current merchant information (name, rewards, tiers) from the wallet iframe
|
|
5
|
+
* @param client - The current Frak Client
|
|
6
|
+
* @returns The merchant information including available reward tiers
|
|
7
|
+
*
|
|
8
|
+
* @see {@link @frak-labs/core-sdk!index.GetMerchantInformationReturnType | `GetMerchantInformationReturnType`} for the return type shape
|
|
9
|
+
*/
|
|
10
|
+
export async function getMerchantInformation(
|
|
11
|
+
client: FrakClient
|
|
12
|
+
): Promise<GetMerchantInformationReturnType> {
|
|
13
|
+
return await client.request({
|
|
14
|
+
method: "frak_getMerchantInformation",
|
|
15
|
+
});
|
|
16
|
+
}
|
package/src/actions/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { displayEmbeddedWallet } from "./displayEmbeddedWallet";
|
|
2
2
|
export { displayModal } from "./displayModal";
|
|
3
|
-
export {
|
|
3
|
+
export { ensureIdentity } from "./ensureIdentity";
|
|
4
|
+
export { getMerchantInformation } from "./getMerchantInformation";
|
|
4
5
|
export { openSso } from "./openSso";
|
|
5
6
|
export { prepareSso } from "./prepareSso";
|
|
6
7
|
export {
|
|
@@ -13,6 +14,7 @@ export { sendInteraction } from "./sendInteraction";
|
|
|
13
14
|
// Helper to track the purchase status
|
|
14
15
|
export { trackPurchaseStatus } from "./trackPurchaseStatus";
|
|
15
16
|
export { watchWalletStatus } from "./watchWalletStatus";
|
|
17
|
+
// Modal wrappers
|
|
16
18
|
export {
|
|
17
19
|
type ModalBuilder,
|
|
18
20
|
type ModalStepBuilder,
|
|
@@ -22,7 +24,6 @@ export {
|
|
|
22
24
|
type SendTransactionParams,
|
|
23
25
|
sendTransaction,
|
|
24
26
|
} from "./wrapper/sendTransaction";
|
|
25
|
-
// Modal wrappers
|
|
26
27
|
export {
|
|
27
28
|
type SiweAuthenticateModalParams,
|
|
28
29
|
siweAuthenticate,
|
package/src/actions/openSso.ts
CHANGED
|
@@ -3,7 +3,8 @@ import type {
|
|
|
3
3
|
OpenSsoParamsType,
|
|
4
4
|
OpenSsoReturnType,
|
|
5
5
|
} from "../types";
|
|
6
|
-
import {
|
|
6
|
+
import { getClientId } from "../utils/clientId";
|
|
7
|
+
import { computeLegacyProductId } from "../utils/computeLegacyProductId";
|
|
7
8
|
import { generateSsoUrl } from "../utils/sso";
|
|
8
9
|
|
|
9
10
|
// SSO popup configuration
|
|
@@ -91,8 +92,9 @@ export async function openSso(
|
|
|
91
92
|
generateSsoUrl(
|
|
92
93
|
walletUrl ?? "https://wallet.frak.id",
|
|
93
94
|
args,
|
|
94
|
-
|
|
95
|
+
computeLegacyProductId(),
|
|
95
96
|
metadata.name,
|
|
97
|
+
getClientId(),
|
|
96
98
|
customizations?.css
|
|
97
99
|
);
|
|
98
100
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FrakRpcError, RpcErrorCodes } from "@frak-labs/frame-connector";
|
|
2
|
-
import type { Address
|
|
2
|
+
import type { Address } from "viem";
|
|
3
3
|
import { vi } from "vitest"; // Keep vi from vitest for vi.mock() hoisting
|
|
4
4
|
import {
|
|
5
5
|
afterEach,
|
|
@@ -15,18 +15,13 @@ import type {
|
|
|
15
15
|
} from "../../types";
|
|
16
16
|
import { processReferral } from "./processReferral";
|
|
17
17
|
|
|
18
|
-
// Mock computeProductId first
|
|
19
|
-
vi.mock("../../utils/computeProductId", () => ({
|
|
20
|
-
computeProductId: vi.fn(
|
|
21
|
-
() =>
|
|
22
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001" as Hex
|
|
23
|
-
),
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
18
|
// Mock dependencies
|
|
27
|
-
vi.mock("
|
|
19
|
+
vi.mock("../displayEmbeddedWallet", () => ({
|
|
28
20
|
displayEmbeddedWallet: vi.fn(),
|
|
29
|
-
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
vi.mock("../sendInteraction", () => ({
|
|
24
|
+
sendInteraction: vi.fn().mockResolvedValue(undefined),
|
|
30
25
|
}));
|
|
31
26
|
|
|
32
27
|
vi.mock("../../utils", () => ({
|
|
@@ -34,22 +29,13 @@ vi.mock("../../utils", () => ({
|
|
|
34
29
|
replaceUrl: vi.fn(),
|
|
35
30
|
},
|
|
36
31
|
trackEvent: vi.fn(),
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
vi.mock("../../interactions", () => ({
|
|
40
|
-
ReferralInteractionEncoder: {
|
|
41
|
-
referred: vi.fn(({ referrer }: { referrer: Address }) => ({
|
|
42
|
-
interactionData: `0x${referrer.slice(2)}` as Hex,
|
|
43
|
-
handlerTypeDenominator: "0x01" as Hex,
|
|
44
|
-
})),
|
|
45
|
-
},
|
|
32
|
+
resolveMerchantId: vi.fn().mockResolvedValue(undefined),
|
|
46
33
|
}));
|
|
47
34
|
|
|
48
35
|
describe("processReferral", () => {
|
|
49
36
|
let mockClient: FrakClient;
|
|
50
37
|
let mockAddress: Address;
|
|
51
38
|
let mockReferrerAddress: Address;
|
|
52
|
-
let mockProductId: Hex;
|
|
53
39
|
let mockWalletStatus: WalletStatusReturnType;
|
|
54
40
|
let mockFrakContext: Partial<FrakContext>;
|
|
55
41
|
|
|
@@ -59,8 +45,6 @@ describe("processReferral", () => {
|
|
|
59
45
|
mockAddress = "0x1234567890123456789012345678901234567890" as Address;
|
|
60
46
|
mockReferrerAddress =
|
|
61
47
|
"0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as Address;
|
|
62
|
-
mockProductId =
|
|
63
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001" as Hex;
|
|
64
48
|
|
|
65
49
|
mockClient = {
|
|
66
50
|
openPanel: {
|
|
@@ -78,10 +62,6 @@ describe("processReferral", () => {
|
|
|
78
62
|
mockWalletStatus = {
|
|
79
63
|
key: "connected" as const,
|
|
80
64
|
wallet: mockAddress,
|
|
81
|
-
interactionSession: {
|
|
82
|
-
startTimestamp: Date.now() - 3600000,
|
|
83
|
-
endTimestamp: Date.now() + 3600000,
|
|
84
|
-
},
|
|
85
65
|
};
|
|
86
66
|
|
|
87
67
|
mockFrakContext = {
|
|
@@ -102,16 +82,12 @@ describe("processReferral", () => {
|
|
|
102
82
|
});
|
|
103
83
|
|
|
104
84
|
it("should return 'no-referrer' when frakContext has no referrer", async () => {
|
|
105
|
-
const utils = await import("../../utils");
|
|
106
|
-
|
|
107
85
|
const result = await processReferral(mockClient, {
|
|
108
86
|
walletStatus: mockWalletStatus,
|
|
109
87
|
frakContext: {},
|
|
110
88
|
});
|
|
111
89
|
|
|
112
90
|
expect(result).toBe("no-referrer");
|
|
113
|
-
// sendInteraction should not be called when there's no referrer
|
|
114
|
-
expect(utils.FrakContextManager.replaceUrl).toHaveBeenCalled();
|
|
115
91
|
});
|
|
116
92
|
|
|
117
93
|
it("should return 'no-referrer' when frakContext is null", async () => {
|
|
@@ -121,7 +97,6 @@ describe("processReferral", () => {
|
|
|
121
97
|
});
|
|
122
98
|
|
|
123
99
|
expect(result).toBe("no-referrer");
|
|
124
|
-
// sendInteraction should not be called when there's no referrer
|
|
125
100
|
});
|
|
126
101
|
|
|
127
102
|
it("should return 'self-referral' when referrer equals current wallet", async () => {
|
|
@@ -133,140 +108,99 @@ describe("processReferral", () => {
|
|
|
133
108
|
});
|
|
134
109
|
|
|
135
110
|
expect(result).toBe("self-referral");
|
|
136
|
-
// sendInteraction should not be called for self-referrals
|
|
137
111
|
});
|
|
138
112
|
|
|
139
113
|
it("should successfully process referral when all conditions are met", async () => {
|
|
140
114
|
const utils = await import("../../utils");
|
|
141
115
|
|
|
142
|
-
// Mock client.request for sendInteraction
|
|
143
|
-
vi.mocked(mockClient.request).mockResolvedValue({
|
|
144
|
-
delegationId: "delegation-123",
|
|
145
|
-
} as any);
|
|
146
|
-
|
|
147
116
|
const result = await processReferral(mockClient, {
|
|
148
117
|
walletStatus: mockWalletStatus,
|
|
149
118
|
frakContext: mockFrakContext,
|
|
150
|
-
productId: mockProductId,
|
|
151
119
|
});
|
|
152
120
|
|
|
153
121
|
expect(result).toBe("success");
|
|
154
122
|
|
|
155
|
-
// sendInteraction uses client.request internally
|
|
156
|
-
expect(mockClient.request).toHaveBeenCalled();
|
|
157
123
|
expect(utils.trackEvent).toHaveBeenCalledWith(
|
|
158
124
|
mockClient,
|
|
159
|
-
"
|
|
125
|
+
"user_referred_started",
|
|
126
|
+
{
|
|
127
|
+
properties: {
|
|
128
|
+
referrer: mockReferrerAddress,
|
|
129
|
+
walletStatus: "connected",
|
|
130
|
+
},
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
expect(utils.trackEvent).toHaveBeenCalledWith(
|
|
135
|
+
mockClient,
|
|
136
|
+
"user_referred_completed",
|
|
160
137
|
{
|
|
161
138
|
properties: {
|
|
139
|
+
status: "success",
|
|
162
140
|
referrer: mockReferrerAddress,
|
|
141
|
+
wallet: mockAddress,
|
|
163
142
|
},
|
|
164
143
|
}
|
|
165
144
|
);
|
|
166
145
|
});
|
|
167
146
|
|
|
168
147
|
it("should handle wallet not connected scenario", async () => {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
wallet: mockAddress,
|
|
173
|
-
} as any)
|
|
174
|
-
.mockResolvedValueOnce({
|
|
175
|
-
delegationId: "delegation-123",
|
|
176
|
-
} as any);
|
|
177
|
-
|
|
178
|
-
const result = await processReferral(mockClient, {
|
|
179
|
-
walletStatus: undefined,
|
|
180
|
-
frakContext: mockFrakContext,
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
expect(result).toBe("success");
|
|
184
|
-
expect(mockClient.request).toHaveBeenCalled();
|
|
185
|
-
});
|
|
148
|
+
const { displayEmbeddedWallet } = await import(
|
|
149
|
+
"../displayEmbeddedWallet"
|
|
150
|
+
);
|
|
186
151
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
key: "connected" as const,
|
|
152
|
+
// Mock displayEmbeddedWallet to return a wallet
|
|
153
|
+
vi.mocked(displayEmbeddedWallet).mockResolvedValue({
|
|
190
154
|
wallet: mockAddress,
|
|
191
|
-
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
// Mock client.request for displayEmbeddedWallet and sendInteraction
|
|
195
|
-
vi.mocked(mockClient.request)
|
|
196
|
-
.mockResolvedValueOnce({
|
|
197
|
-
wallet: mockAddress,
|
|
198
|
-
} as any)
|
|
199
|
-
.mockResolvedValueOnce({
|
|
200
|
-
delegationId: "delegation-123",
|
|
201
|
-
} as any);
|
|
155
|
+
} as any);
|
|
202
156
|
|
|
203
157
|
const result = await processReferral(mockClient, {
|
|
204
|
-
walletStatus:
|
|
158
|
+
walletStatus: undefined,
|
|
205
159
|
frakContext: mockFrakContext,
|
|
206
160
|
});
|
|
207
161
|
|
|
208
162
|
expect(result).toBe("success");
|
|
209
|
-
expect(
|
|
163
|
+
expect(displayEmbeddedWallet).toHaveBeenCalled();
|
|
210
164
|
});
|
|
211
165
|
|
|
212
|
-
it("should return '
|
|
166
|
+
it("should return 'no-wallet' when wallet connection fails", async () => {
|
|
167
|
+
const { displayEmbeddedWallet } = await import(
|
|
168
|
+
"../displayEmbeddedWallet"
|
|
169
|
+
);
|
|
170
|
+
|
|
213
171
|
const error = new FrakRpcError(
|
|
214
172
|
RpcErrorCodes.walletNotConnected,
|
|
215
173
|
"Wallet not connected"
|
|
216
174
|
);
|
|
217
|
-
|
|
218
|
-
vi.mocked(mockClient.request).mockRejectedValue(error);
|
|
175
|
+
vi.mocked(displayEmbeddedWallet).mockRejectedValue(error);
|
|
219
176
|
|
|
220
177
|
const result = await processReferral(mockClient, {
|
|
221
178
|
walletStatus: undefined,
|
|
222
179
|
frakContext: mockFrakContext,
|
|
223
180
|
});
|
|
224
181
|
|
|
225
|
-
|
|
226
|
-
expect(["error", "no-wallet", "success"]).toContain(result);
|
|
182
|
+
expect(result).toBe("no-wallet");
|
|
227
183
|
});
|
|
228
184
|
|
|
229
|
-
it("should return '
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
"Server error"
|
|
185
|
+
it("should return 'error' for unknown errors", async () => {
|
|
186
|
+
const { displayEmbeddedWallet } = await import(
|
|
187
|
+
"../displayEmbeddedWallet"
|
|
233
188
|
);
|
|
234
|
-
// Mock client.request to throw error for sendInteraction
|
|
235
|
-
vi.mocked(mockClient.request).mockRejectedValue(error);
|
|
236
189
|
|
|
237
|
-
const result = await processReferral(mockClient, {
|
|
238
|
-
walletStatus: mockWalletStatus,
|
|
239
|
-
frakContext: mockFrakContext,
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// sendInteraction is in Promise.allSettled, so errors are caught
|
|
243
|
-
// The function might still succeed or return error depending on implementation
|
|
244
|
-
expect(["no-session", "error", "success"]).toContain(result);
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
it("should return 'error' for unknown errors", async () => {
|
|
248
190
|
const error = new Error("Unknown error");
|
|
249
|
-
|
|
250
|
-
vi.mocked(mockClient.request).mockRejectedValue(error);
|
|
191
|
+
vi.mocked(displayEmbeddedWallet).mockRejectedValue(error);
|
|
251
192
|
|
|
252
193
|
const result = await processReferral(mockClient, {
|
|
253
|
-
walletStatus:
|
|
194
|
+
walletStatus: undefined,
|
|
254
195
|
frakContext: mockFrakContext,
|
|
255
196
|
});
|
|
256
197
|
|
|
257
|
-
|
|
258
|
-
// So the error might be caught and the function might still succeed
|
|
259
|
-
expect(["error", "success"]).toContain(result);
|
|
198
|
+
expect(result).toBe("error");
|
|
260
199
|
});
|
|
261
200
|
|
|
262
201
|
it("should update URL context when alwaysAppendUrl is true", async () => {
|
|
263
202
|
const utils = await import("../../utils");
|
|
264
203
|
|
|
265
|
-
// Mock client.request for sendInteraction
|
|
266
|
-
vi.mocked(mockClient.request).mockResolvedValue({
|
|
267
|
-
delegationId: "delegation-123",
|
|
268
|
-
} as any);
|
|
269
|
-
|
|
270
204
|
await processReferral(mockClient, {
|
|
271
205
|
walletStatus: mockWalletStatus,
|
|
272
206
|
frakContext: mockFrakContext,
|
|
@@ -284,11 +218,6 @@ describe("processReferral", () => {
|
|
|
284
218
|
it("should remove URL context when alwaysAppendUrl is false", async () => {
|
|
285
219
|
const utils = await import("../../utils");
|
|
286
220
|
|
|
287
|
-
// Mock client.request for sendInteraction
|
|
288
|
-
vi.mocked(mockClient.request).mockResolvedValue({
|
|
289
|
-
delegationId: "delegation-123",
|
|
290
|
-
} as any);
|
|
291
|
-
|
|
292
221
|
await processReferral(mockClient, {
|
|
293
222
|
walletStatus: mockWalletStatus,
|
|
294
223
|
frakContext: mockFrakContext,
|
|
@@ -306,11 +235,6 @@ describe("processReferral", () => {
|
|
|
306
235
|
it("should remove URL context by default", async () => {
|
|
307
236
|
const utils = await import("../../utils");
|
|
308
237
|
|
|
309
|
-
// Mock client.request for sendInteraction
|
|
310
|
-
vi.mocked(mockClient.request).mockResolvedValue({
|
|
311
|
-
delegationId: "delegation-123",
|
|
312
|
-
} as any);
|
|
313
|
-
|
|
314
238
|
await processReferral(mockClient, {
|
|
315
239
|
walletStatus: mockWalletStatus,
|
|
316
240
|
frakContext: mockFrakContext,
|
|
@@ -321,37 +245,4 @@ describe("processReferral", () => {
|
|
|
321
245
|
context: null,
|
|
322
246
|
});
|
|
323
247
|
});
|
|
324
|
-
|
|
325
|
-
it("should handle sendInteraction failures gracefully", async () => {
|
|
326
|
-
const utils = await import("../../utils");
|
|
327
|
-
|
|
328
|
-
// Mock client.request to throw error only for sendInteraction call
|
|
329
|
-
// Note: sendInteraction uses Promise.allSettled, so errors are caught
|
|
330
|
-
// We use mockImplementation to ensure the rejection is properly handled
|
|
331
|
-
// by returning a rejected promise that will be caught by Promise.allSettled
|
|
332
|
-
vi.mocked(mockClient.request).mockImplementation(async (request) => {
|
|
333
|
-
// Only reject for frak_sendInteraction calls (sendInteraction)
|
|
334
|
-
if (request.method === "frak_sendInteraction") {
|
|
335
|
-
// Return a rejected promise that will be caught by Promise.allSettled
|
|
336
|
-
return Promise.reject(new Error("Network error"));
|
|
337
|
-
}
|
|
338
|
-
// For any other calls (e.g., displayEmbeddedWallet), resolve successfully
|
|
339
|
-
return { delegationId: "delegation-123" } as any;
|
|
340
|
-
});
|
|
341
|
-
// trackEvent errors are also caught in Promise.allSettled
|
|
342
|
-
// Even though trackEvent is synchronous (returns void), we return a rejected promise
|
|
343
|
-
// so that Promise.allSettled can properly catch it without causing unhandled rejections
|
|
344
|
-
vi.mocked(utils.trackEvent).mockImplementation(() => {
|
|
345
|
-
return Promise.reject(new Error("Track failed")) as any;
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
const result = await processReferral(mockClient, {
|
|
349
|
-
walletStatus: mockWalletStatus,
|
|
350
|
-
frakContext: mockFrakContext,
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
// sendInteraction is in Promise.allSettled, so errors are caught
|
|
354
|
-
// The function might still succeed or return error depending on implementation
|
|
355
|
-
expect(["error", "success"]).toContain(result);
|
|
356
|
-
});
|
|
357
248
|
});
|