@frak-labs/core-sdk 0.1.0-beta.267778ad → 0.1.0-beta.278e9605
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 -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/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/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
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"url": "https://twitter.com/QNivelais"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
|
-
"version": "0.1.0-beta.
|
|
14
|
+
"version": "0.1.0-beta.278e9605",
|
|
15
15
|
"description": "Core SDK of the Frak wallet, low level library to interact directly with the frak ecosystem.",
|
|
16
16
|
"repository": {
|
|
17
17
|
"url": "https://github.com/frak-id/wallet",
|
|
@@ -87,34 +87,37 @@
|
|
|
87
87
|
"lint": "biome lint .",
|
|
88
88
|
"format:check": "biome check .",
|
|
89
89
|
"format": "biome check --write .",
|
|
90
|
-
"clean": "rimraf dist",
|
|
91
|
-
"build": "
|
|
92
|
-
"build:watch": "
|
|
90
|
+
"clean": "rimraf dist cdn",
|
|
91
|
+
"build": "tsdown",
|
|
92
|
+
"build:watch": "tsdown --watch",
|
|
93
93
|
"check-exports": "attw --pack --profile node16 .",
|
|
94
94
|
"typecheck": "tsc --noEmit",
|
|
95
|
+
"test": "vitest",
|
|
96
|
+
"test:ui": "vitest --ui",
|
|
97
|
+
"test:coverage": "vitest --coverage",
|
|
95
98
|
"prepublish": "bun run lint && bun run build",
|
|
96
99
|
"publish": "echo 'Publishing core...'"
|
|
97
100
|
},
|
|
98
101
|
"peerDependencies": {
|
|
99
|
-
"viem": "^2.
|
|
102
|
+
"viem": "^2.x"
|
|
100
103
|
},
|
|
101
104
|
"dependencies": {
|
|
102
105
|
"@frak-labs/frame-connector": "0.1.0",
|
|
103
|
-
"@jsonjoy.com/json-pack": "^1.
|
|
106
|
+
"@jsonjoy.com/json-pack": "^1.21.0",
|
|
104
107
|
"@openpanel/web": "^1.0.1"
|
|
105
108
|
},
|
|
106
109
|
"devDependencies": {
|
|
107
110
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
108
|
-
"@frak-labs/browserslist-config": "0.0.1",
|
|
109
111
|
"@frak-labs/dev-tooling": "0.0.0",
|
|
110
|
-
"@
|
|
111
|
-
"@
|
|
112
|
-
"@
|
|
113
|
-
"@
|
|
114
|
-
"
|
|
115
|
-
"
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
"
|
|
119
|
-
|
|
112
|
+
"@rolldown/plugin-node-polyfills": "^1.0.0",
|
|
113
|
+
"@types/jsdom": "^27.0.0",
|
|
114
|
+
"@types/node": "^24.10.0",
|
|
115
|
+
"@vitest/coverage-v8": "^4.0.8",
|
|
116
|
+
"@vitest/ui": "^4.0.8",
|
|
117
|
+
"jsdom": "^27.1.0",
|
|
118
|
+
"tsdown": "^0.16.1",
|
|
119
|
+
"typescript": "^5.9.3",
|
|
120
|
+
"viem": "^2.38.6",
|
|
121
|
+
"vitest": "^4.0.8"
|
|
122
|
+
}
|
|
120
123
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for displayEmbeddedWallet action
|
|
3
|
+
* Tests displaying embedded wallet via RPC
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Address } from "viem";
|
|
7
|
+
import { describe, expect, it, vi } from "../../tests/vitest-fixtures";
|
|
8
|
+
import type {
|
|
9
|
+
DisplayEmbeddedWalletParamsType,
|
|
10
|
+
DisplayEmbeddedWalletResultType,
|
|
11
|
+
FrakClient,
|
|
12
|
+
} from "../types";
|
|
13
|
+
import { displayEmbeddedWallet } from "./displayEmbeddedWallet";
|
|
14
|
+
|
|
15
|
+
describe("displayEmbeddedWallet", () => {
|
|
16
|
+
describe("success cases", () => {
|
|
17
|
+
it("should call client.request with correct method and params", async () => {
|
|
18
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
19
|
+
loggedIn: {
|
|
20
|
+
action: {
|
|
21
|
+
key: "sharing",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const mockResponse: DisplayEmbeddedWalletResultType = {
|
|
27
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const mockClient = {
|
|
31
|
+
config: {
|
|
32
|
+
metadata: {
|
|
33
|
+
name: "Test App",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
37
|
+
} as unknown as FrakClient;
|
|
38
|
+
|
|
39
|
+
await displayEmbeddedWallet(mockClient, mockParams);
|
|
40
|
+
|
|
41
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
42
|
+
method: "frak_displayEmbeddedWallet",
|
|
43
|
+
params: [mockParams, { name: "Test App" }],
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should return wallet address", async () => {
|
|
48
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
49
|
+
loggedIn: {
|
|
50
|
+
action: {
|
|
51
|
+
key: "sharing",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const mockResponse: DisplayEmbeddedWalletResultType = {
|
|
57
|
+
wallet: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as Address,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const mockClient = {
|
|
61
|
+
config: {
|
|
62
|
+
metadata: {
|
|
63
|
+
name: "Test App",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
67
|
+
} as unknown as FrakClient;
|
|
68
|
+
|
|
69
|
+
const result = await displayEmbeddedWallet(mockClient, mockParams);
|
|
70
|
+
|
|
71
|
+
expect(result).toEqual(mockResponse);
|
|
72
|
+
expect(result.wallet).toBe(
|
|
73
|
+
"0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should handle loggedOut view params", async () => {
|
|
78
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
79
|
+
loggedOut: {
|
|
80
|
+
metadata: {
|
|
81
|
+
text: "Login to get rewards",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const mockResponse: DisplayEmbeddedWalletResultType = {
|
|
87
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const mockClient = {
|
|
91
|
+
config: {
|
|
92
|
+
metadata: {
|
|
93
|
+
name: "Test App",
|
|
94
|
+
logoUrl: "https://example.com/logo.png",
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
98
|
+
} as unknown as FrakClient;
|
|
99
|
+
|
|
100
|
+
await displayEmbeddedWallet(mockClient, mockParams);
|
|
101
|
+
|
|
102
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
103
|
+
method: "frak_displayEmbeddedWallet",
|
|
104
|
+
params: [
|
|
105
|
+
mockParams,
|
|
106
|
+
{
|
|
107
|
+
name: "Test App",
|
|
108
|
+
logoUrl: "https://example.com/logo.png",
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("should handle referred action", async () => {
|
|
115
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
116
|
+
loggedIn: {
|
|
117
|
+
action: {
|
|
118
|
+
key: "referred",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const mockResponse: DisplayEmbeddedWalletResultType = {
|
|
124
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const mockClient = {
|
|
128
|
+
config: {
|
|
129
|
+
metadata: {
|
|
130
|
+
name: "Test App",
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
134
|
+
} as unknown as FrakClient;
|
|
135
|
+
|
|
136
|
+
const result = await displayEmbeddedWallet(mockClient, mockParams);
|
|
137
|
+
|
|
138
|
+
expect(result).toEqual(mockResponse);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("should pass client metadata to request", async () => {
|
|
142
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {};
|
|
143
|
+
|
|
144
|
+
const mockMetadata = {
|
|
145
|
+
name: "My App",
|
|
146
|
+
logoUrl: "https://example.com/logo.png",
|
|
147
|
+
css: "body { color: red; }",
|
|
148
|
+
lang: "fr" as const,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const mockClient = {
|
|
152
|
+
config: {
|
|
153
|
+
metadata: mockMetadata,
|
|
154
|
+
},
|
|
155
|
+
request: vi.fn().mockResolvedValue({
|
|
156
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
157
|
+
}),
|
|
158
|
+
} as unknown as FrakClient;
|
|
159
|
+
|
|
160
|
+
await displayEmbeddedWallet(mockClient, mockParams);
|
|
161
|
+
|
|
162
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
163
|
+
method: "frak_displayEmbeddedWallet",
|
|
164
|
+
params: [mockParams, mockMetadata],
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe("error handling", () => {
|
|
170
|
+
it("should propagate errors from client.request", async () => {
|
|
171
|
+
const mockParams: DisplayEmbeddedWalletParamsType = {
|
|
172
|
+
loggedIn: {
|
|
173
|
+
action: {
|
|
174
|
+
key: "sharing",
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const error = new Error("Display failed");
|
|
180
|
+
const mockClient = {
|
|
181
|
+
config: {
|
|
182
|
+
metadata: {
|
|
183
|
+
name: "Test App",
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
request: vi.fn().mockRejectedValue(error),
|
|
187
|
+
} as unknown as FrakClient;
|
|
188
|
+
|
|
189
|
+
await expect(
|
|
190
|
+
displayEmbeddedWallet(mockClient, mockParams)
|
|
191
|
+
).rejects.toThrow("Display failed");
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for displayModal action
|
|
3
|
+
* Tests modal display via RPC with various step configurations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Address } from "viem";
|
|
7
|
+
import { describe, expect, it, vi } from "../../tests/vitest-fixtures";
|
|
8
|
+
import type {
|
|
9
|
+
DisplayModalParamsType,
|
|
10
|
+
FrakClient,
|
|
11
|
+
ModalStepTypes,
|
|
12
|
+
} from "../types";
|
|
13
|
+
import { displayModal } from "./displayModal";
|
|
14
|
+
|
|
15
|
+
describe("displayModal", () => {
|
|
16
|
+
describe("basic modal display", () => {
|
|
17
|
+
it("should call client.request with correct method and params", async () => {
|
|
18
|
+
const mockResponse = {
|
|
19
|
+
login: {
|
|
20
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const mockClient = {
|
|
25
|
+
config: {
|
|
26
|
+
metadata: {
|
|
27
|
+
name: "Test App",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
31
|
+
} as unknown as FrakClient;
|
|
32
|
+
|
|
33
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
34
|
+
steps: {
|
|
35
|
+
login: { allowSso: true },
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
await displayModal(mockClient, params);
|
|
40
|
+
|
|
41
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
42
|
+
method: "frak_displayModal",
|
|
43
|
+
params: [params.steps, params.metadata, { name: "Test App" }],
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should return modal results", async () => {
|
|
48
|
+
const mockResponse = {
|
|
49
|
+
login: {
|
|
50
|
+
wallet: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as Address,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const mockClient = {
|
|
55
|
+
config: {
|
|
56
|
+
metadata: {
|
|
57
|
+
name: "Test App",
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
61
|
+
} as unknown as FrakClient;
|
|
62
|
+
|
|
63
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
64
|
+
steps: {
|
|
65
|
+
login: { allowSso: false },
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const result = await displayModal(mockClient, params);
|
|
70
|
+
|
|
71
|
+
expect(result).toEqual(mockResponse);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe("modal with multiple steps", () => {
|
|
76
|
+
it("should handle login + openSession steps", async () => {
|
|
77
|
+
const mockResponse = {
|
|
78
|
+
login: {
|
|
79
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
80
|
+
},
|
|
81
|
+
openSession: {
|
|
82
|
+
startTimestamp: 1234567890,
|
|
83
|
+
endTimestamp: 1234567900,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const mockClient = {
|
|
88
|
+
config: {
|
|
89
|
+
metadata: {
|
|
90
|
+
name: "Test App",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
94
|
+
} as unknown as FrakClient;
|
|
95
|
+
|
|
96
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
97
|
+
steps: {
|
|
98
|
+
login: { allowSso: true },
|
|
99
|
+
openSession: {},
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const result = await displayModal(mockClient, params);
|
|
104
|
+
|
|
105
|
+
expect(result).toEqual(mockResponse);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("should handle full modal flow", async () => {
|
|
109
|
+
const mockResponse = {
|
|
110
|
+
login: {
|
|
111
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
112
|
+
},
|
|
113
|
+
openSession: {
|
|
114
|
+
startTimestamp: 1234567890,
|
|
115
|
+
endTimestamp: 1234567900,
|
|
116
|
+
},
|
|
117
|
+
sendTransaction: {
|
|
118
|
+
hash: "0xtxhash" as `0x${string}`,
|
|
119
|
+
},
|
|
120
|
+
final: {},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const mockClient = {
|
|
124
|
+
config: {
|
|
125
|
+
metadata: {
|
|
126
|
+
name: "Test App",
|
|
127
|
+
logoUrl: "https://example.com/logo.png",
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
131
|
+
} as unknown as FrakClient;
|
|
132
|
+
|
|
133
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
134
|
+
steps: {
|
|
135
|
+
login: { allowSso: true },
|
|
136
|
+
openSession: {},
|
|
137
|
+
sendTransaction: {
|
|
138
|
+
tx: [
|
|
139
|
+
{
|
|
140
|
+
to: "0xdeadbeef" as Address,
|
|
141
|
+
data: "0xdata" as `0x${string}`,
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
final: {
|
|
146
|
+
action: { key: "reward" },
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const result = await displayModal(mockClient, params);
|
|
152
|
+
|
|
153
|
+
expect(result).toEqual(mockResponse);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe("modal with metadata", () => {
|
|
158
|
+
it("should pass metadata to request", async () => {
|
|
159
|
+
const mockResponse = {
|
|
160
|
+
login: {
|
|
161
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const mockClient = {
|
|
166
|
+
config: {
|
|
167
|
+
metadata: {
|
|
168
|
+
name: "Test App",
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
172
|
+
} as unknown as FrakClient;
|
|
173
|
+
|
|
174
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
175
|
+
steps: {
|
|
176
|
+
login: { allowSso: true },
|
|
177
|
+
},
|
|
178
|
+
metadata: {
|
|
179
|
+
header: {
|
|
180
|
+
title: "My Custom Title",
|
|
181
|
+
icon: "https://example.com/icon.png",
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
await displayModal(mockClient, params);
|
|
187
|
+
|
|
188
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
189
|
+
method: "frak_displayModal",
|
|
190
|
+
params: [
|
|
191
|
+
params.steps,
|
|
192
|
+
{
|
|
193
|
+
header: {
|
|
194
|
+
title: "My Custom Title",
|
|
195
|
+
icon: "https://example.com/icon.png",
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
{ name: "Test App" },
|
|
199
|
+
],
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("should work without metadata", async () => {
|
|
204
|
+
const mockResponse = {
|
|
205
|
+
login: {
|
|
206
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const mockClient = {
|
|
211
|
+
config: {
|
|
212
|
+
metadata: {
|
|
213
|
+
name: "Test App",
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
217
|
+
} as unknown as FrakClient;
|
|
218
|
+
|
|
219
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
220
|
+
steps: {
|
|
221
|
+
login: { allowSso: true },
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
await displayModal(mockClient, params);
|
|
226
|
+
|
|
227
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
228
|
+
method: "frak_displayModal",
|
|
229
|
+
params: [params.steps, undefined, { name: "Test App" }],
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
describe("modal with SSO metadata", () => {
|
|
235
|
+
it("should handle SSO metadata in login step", async () => {
|
|
236
|
+
const mockResponse = {
|
|
237
|
+
login: {
|
|
238
|
+
wallet: "0x1234567890123456789012345678901234567890" as Address,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const mockClient = {
|
|
243
|
+
config: {
|
|
244
|
+
metadata: {
|
|
245
|
+
name: "Test App",
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
249
|
+
} as unknown as FrakClient;
|
|
250
|
+
|
|
251
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
252
|
+
steps: {
|
|
253
|
+
login: {
|
|
254
|
+
allowSso: true,
|
|
255
|
+
ssoMetadata: {
|
|
256
|
+
logoUrl: "https://example.com/logo.png",
|
|
257
|
+
homepageLink: "https://example.com",
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
await displayModal(mockClient, params);
|
|
264
|
+
|
|
265
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
266
|
+
method: "frak_displayModal",
|
|
267
|
+
params: [params.steps, undefined, { name: "Test App" }],
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
describe("modal with sharing action", () => {
|
|
273
|
+
it("should handle sharing final action", async () => {
|
|
274
|
+
const mockResponse = {
|
|
275
|
+
final: {},
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const mockClient = {
|
|
279
|
+
config: {
|
|
280
|
+
metadata: {
|
|
281
|
+
name: "Test App",
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
285
|
+
} as unknown as FrakClient;
|
|
286
|
+
|
|
287
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
288
|
+
steps: {
|
|
289
|
+
final: {
|
|
290
|
+
action: {
|
|
291
|
+
key: "sharing",
|
|
292
|
+
options: {
|
|
293
|
+
popupTitle: "Share the app",
|
|
294
|
+
text: "Discover my app",
|
|
295
|
+
link: "https://example.com",
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
await displayModal(mockClient, params);
|
|
303
|
+
|
|
304
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
305
|
+
method: "frak_displayModal",
|
|
306
|
+
params: [params.steps, undefined, { name: "Test App" }],
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it("should handle reward final action", async () => {
|
|
311
|
+
const mockResponse = {
|
|
312
|
+
final: {},
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const mockClient = {
|
|
316
|
+
config: {
|
|
317
|
+
metadata: {
|
|
318
|
+
name: "Test App",
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
request: vi.fn().mockResolvedValue(mockResponse),
|
|
322
|
+
} as unknown as FrakClient;
|
|
323
|
+
|
|
324
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
325
|
+
steps: {
|
|
326
|
+
final: {
|
|
327
|
+
action: { key: "reward" },
|
|
328
|
+
autoSkip: true,
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
await displayModal(mockClient, params);
|
|
334
|
+
|
|
335
|
+
expect(mockClient.request).toHaveBeenCalledWith({
|
|
336
|
+
method: "frak_displayModal",
|
|
337
|
+
params: [params.steps, undefined, { name: "Test App" }],
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
describe("error handling", () => {
|
|
343
|
+
it("should propagate errors from client.request", async () => {
|
|
344
|
+
const error = new Error("Modal display failed");
|
|
345
|
+
const mockClient = {
|
|
346
|
+
config: {
|
|
347
|
+
metadata: {
|
|
348
|
+
name: "Test App",
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
request: vi.fn().mockRejectedValue(error),
|
|
352
|
+
} as unknown as FrakClient;
|
|
353
|
+
|
|
354
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
355
|
+
steps: {
|
|
356
|
+
login: { allowSso: true },
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
await expect(displayModal(mockClient, params)).rejects.toThrow(
|
|
361
|
+
"Modal display failed"
|
|
362
|
+
);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it("should handle network errors", async () => {
|
|
366
|
+
const error = new Error("Network timeout");
|
|
367
|
+
const mockClient = {
|
|
368
|
+
config: {
|
|
369
|
+
metadata: {
|
|
370
|
+
name: "Test App",
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
request: vi.fn().mockRejectedValue(error),
|
|
374
|
+
} as unknown as FrakClient;
|
|
375
|
+
|
|
376
|
+
const params: DisplayModalParamsType<ModalStepTypes[]> = {
|
|
377
|
+
steps: {
|
|
378
|
+
openSession: {},
|
|
379
|
+
},
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
await expect(displayModal(mockClient, params)).rejects.toThrow(
|
|
383
|
+
"Network timeout"
|
|
384
|
+
);
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
});
|