zh-web-sdk 2.16.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +239 -34
  3. package/dist/__mocks__/@zerohash-sdk/sdk-react-mock.d.ts +1 -0
  4. package/dist/__tests__/explicit-env.test.d.ts +1 -0
  5. package/dist/__tests__/message-router-origins.test.d.ts +1 -0
  6. package/dist/__tests__/sdk-version-attribution.test.d.ts +1 -0
  7. package/dist/__tests__/styles.test.d.ts +1 -0
  8. package/dist/api/convert-token.d.ts +12 -0
  9. package/dist/iframe-container/AppContainer.d.ts +13 -3
  10. package/dist/iframe-container/__tests__/get-new-sdk-env.test.d.ts +1 -0
  11. package/dist/iframe-container/hooks/use-style-updates.d.ts +1 -0
  12. package/dist/index.d.ts +30 -2
  13. package/dist/index.js +56 -54
  14. package/dist/index.js.map +4 -4
  15. package/dist/new-sdk/env.d.ts +35 -0
  16. package/dist/redux/__tests__/set-theme.test.d.ts +1 -0
  17. package/dist/redux/__tests__/set-use-new-sdk.test.d.ts +1 -0
  18. package/dist/redux/actions/index.d.ts +13 -1
  19. package/dist/redux/reducers/constants.d.ts +2 -0
  20. package/dist/redux/reducers/index.d.ts +3 -1
  21. package/dist/redux/reducers/new-sdk-flags.d.ts +11 -0
  22. package/dist/redux/reducers/theme.d.ts +10 -0
  23. package/dist/redux/store/index.d.ts +3 -1
  24. package/dist/styles.d.ts +7 -0
  25. package/dist/types.d.ts +42 -0
  26. package/dist/utils/test-utils.d.ts +48 -48
  27. package/dist/version.d.ts +1 -0
  28. package/package.json +32 -13
  29. package/.eslintrc.js +0 -12
  30. package/.github/CHANGELOG_TEMPLATE.md +0 -73
  31. package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
  32. package/.github/backup/publish-tag.yaml +0 -14
  33. package/.github/workflows/build.yaml +0 -13
  34. package/.github/workflows/pr.yaml +0 -14
  35. package/.github/workflows/publish.yaml +0 -13
  36. package/.github/workflows/security.yml +0 -15
  37. package/.github/workflows/tag.yaml +0 -14
  38. package/RELEASING.md +0 -39
  39. package/jest.config.js +0 -8
  40. package/jest.setup.js +0 -24
  41. package/scripts/build.js +0 -34
  42. package/scripts/zip.js +0 -49
  43. package/src/__tests__/jwt-auth-detection.test.ts +0 -96
  44. package/src/api/convert-token.ts +0 -23
  45. package/src/constants.ts +0 -2
  46. package/src/hooks/__tests__/use-window-size.test.tsx +0 -26
  47. package/src/hooks/use-window-size.ts +0 -19
  48. package/src/iframe-container/AppContainer.tsx +0 -495
  49. package/src/iframe-container/__tests__/AppContainer.test.tsx +0 -300
  50. package/src/iframe-container/hooks/__tests__/use-style-updates.test.ts +0 -430
  51. package/src/iframe-container/hooks/use-style-updates.ts +0 -82
  52. package/src/index.tsx +0 -645
  53. package/src/redux/actions/index.ts +0 -27
  54. package/src/redux/reducers/constants.ts +0 -10
  55. package/src/redux/reducers/crypto-account-link-payouts.ts +0 -60
  56. package/src/redux/reducers/crypto-account-link.ts +0 -60
  57. package/src/redux/reducers/crypto-buy.ts +0 -75
  58. package/src/redux/reducers/crypto-sell.ts +0 -64
  59. package/src/redux/reducers/crypto-withdrawals.ts +0 -64
  60. package/src/redux/reducers/fiat-account-link.ts +0 -60
  61. package/src/redux/reducers/fiat-deposits.ts +0 -64
  62. package/src/redux/reducers/fiat-withdrawals.ts +0 -64
  63. package/src/redux/reducers/fund.ts +0 -75
  64. package/src/redux/reducers/index.ts +0 -35
  65. package/src/redux/reducers/onboarding.ts +0 -74
  66. package/src/redux/reducers/pay.ts +0 -64
  67. package/src/redux/reducers/payouts.ts +0 -64
  68. package/src/redux/reducers/profile.ts +0 -63
  69. package/src/redux/store/index.ts +0 -10
  70. package/src/styles.ts +0 -108
  71. package/src/types.ts +0 -578
  72. package/src/utils/auth-to-fund-mapper.ts +0 -174
  73. package/src/utils/strings.ts +0 -19
  74. package/src/utils/test-utils.tsx +0 -36
  75. package/src/utils/world-app-utils.ts +0 -8
  76. package/src/utils.ts +0 -27
  77. package/tsconfig.json +0 -26
package/RELEASING.md DELETED
@@ -1,39 +0,0 @@
1
- # Release Process
2
-
3
- This document describes the process for releasing new versions of the zerohash Web SDK.
4
-
5
- ## Release Steps
6
-
7
- ### 1. Update CHANGELOG.md
8
-
9
- Add a new version section at the top of `CHANGELOG.md`:
10
-
11
- ```markdown
12
- ## [X.Y.Z] - YYYY-MM-DD
13
-
14
- ### Added
15
- - New feature description [#PR_NUMBER]
16
-
17
- ### Fixed
18
- - Bug fix description [#PR_NUMBER]
19
-
20
- ### Changed
21
- - Behavior change description
22
- ```
23
-
24
- See `.github/CHANGELOG_TEMPLATE.md` for detailed guidelines.
25
-
26
- **Commit the changelog:**
27
-
28
- ```bash
29
- git add CHANGELOG.md
30
- git commit -m "docs: update CHANGELOG for vX.Y.Z"
31
- git push origin main
32
- ```
33
-
34
- ### 2. Update ReadMe Changelog
35
-
36
- 1. Go to ReadMe dashboard: https://dash.readme.com/
37
- 2. Navigate to the Changelog section
38
- 3. Create new changelog entry with content from `CHANGELOG.md`
39
- 4. Publish the entry
package/jest.config.js DELETED
@@ -1,8 +0,0 @@
1
- module.exports = {
2
- testEnvironment: "jsdom",
3
- transform: {
4
- "^.+.tsx?$": ["ts-jest",{}],
5
- },
6
- modulePathIgnorePatterns: ["<rootDir>/dist/", "<rootDir>/build/", "<rootDir>/node_modules/"],
7
- setupFiles: ["<rootDir>/jest.setup.js"],
8
- };
package/jest.setup.js DELETED
@@ -1,24 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */
2
- /* eslint-disable @typescript-eslint/no-var-requires */
3
- /* eslint-disable no-undef */
4
-
5
- const { TextEncoder, TextDecoder } = require('util');
6
-
7
- Object.assign(global, { TextDecoder, TextEncoder })
8
- global.CSS = {
9
- supports: (k, v) => true,
10
- }
11
-
12
- Object.defineProperty(window, 'matchMedia', {
13
- writable: true,
14
- value: jest.fn().mockImplementation(query => ({
15
- matches: false,
16
- media: query,
17
- onchange: null,
18
- addListener: jest.fn(), // Deprecated
19
- removeListener: jest.fn(), // Deprecated
20
- addEventListener: jest.fn(),
21
- removeEventListener: jest.fn(),
22
- dispatchEvent: jest.fn(),
23
- })),
24
- });
package/scripts/build.js DELETED
@@ -1,34 +0,0 @@
1
- const esbuild = require("esbuild");
2
- const {name, version} = require("../package.json");
3
-
4
- const build = async () => {
5
- console.log(`Building ${name}@${version}`);
6
-
7
- const outputDir = "./dist/";
8
- const minFileName = `${outputDir}zerohash_sdk.min.js`;
9
- const bundleFileName = `${outputDir}zerohash_sdk.js`;
10
-
11
- // Build minified dist
12
- await esbuild
13
- .build({
14
- entryPoints: ['src/index.tsx'],
15
- outdir: 'dist',
16
- bundle: true,
17
- sourcemap: true,
18
- minify: true,
19
- splitting: false,
20
- format: 'esm',
21
- target: ['esnext']
22
- })
23
- .catch(err => {
24
- console.error('Error: build failed - unable to build minified dist');
25
- throw err;
26
- });
27
- }
28
-
29
- build()
30
- .then(() => console.log("successfully built"))
31
- .catch(err => {
32
- console.error(err);
33
- process.exit(1);
34
- });
package/scripts/zip.js DELETED
@@ -1,49 +0,0 @@
1
- const fs = require("fs");
2
- const archiver = require("archiver");
3
- const {name, version} = require("../package.json");
4
-
5
- const zip = async () => {
6
- const zipFile = `./build/zh_web_sdk_v${version}.zip`;
7
- console.log(`Zipping to ${zipFile}`);
8
-
9
- // create the directory forcibly
10
- fs.mkdirSync("./build", {recursive: true});
11
-
12
- // zip output as a package
13
- const output = fs.createWriteStream(zipFile);
14
- const archive = archiver('zip', {
15
- zlib: { level: 9 }
16
- });
17
- output.on('close', () => {
18
- console.log(archive.pointer() + ' total bytes');
19
- console.log('archiver has been finalized and the output file descriptor has closed.');
20
- });
21
- output.on('end', () => {
22
- console.log('Data has been drained');
23
- });
24
- archive.on('warning', (err) => {
25
- if (err.code === "ENOENT") {
26
- console.warn("ENOENT: ", err);
27
- } else {
28
- console.error(err);
29
- throw err;
30
- }
31
- });
32
- archive.on('error', (err) => {
33
- console.error(err);
34
- throw err;
35
- });
36
- archive.pipe(output);
37
- archive.file("README.md");
38
- archive.file("package.json");
39
- archive.file("package-lock.json");
40
- archive.directory("./dist/");
41
- await archive.finalize();
42
- }
43
-
44
- zip()
45
- .then(() => console.log("successfully zipped"))
46
- .catch(err => {
47
- console.error(err);
48
- process.exit(1);
49
- });
@@ -1,96 +0,0 @@
1
- import { decodeJWT } from "../api/convert-token";
2
-
3
- describe("JWT Auth Detection", () => {
4
- describe("decodeJWT", () => {
5
- it("should decode a valid JWT with Connect issuer", () => {
6
- // JWT with iss: "https://connect-xyz.us.auth0.com/"
7
- const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL2Nvbm5lY3QueHl6L29yZ2FuaXphdGlvbiI6eyJpZCI6ImY0NDZmMTRjLTQwMzUtNDEwNS04OTJiLTE2NDliZmYxNjQyNCJ9LCJodHRwczovL2Nvbm5lY3QueHl6L2FjY291bnQiOnsiaWQiOiI1MzVhNzEyYS0wZmE0LTRjNmMtYjc4Zi01M2NiYTM1NmRkY2QiLCJyZWZlcmVuY2VJZCI6InJlZl8xNzY4MjYzNjg1NTM2X3ExM2tmdXc2ciJ9LCJodHRwczovL2Nvbm5lY3QueHl6L3VzZXIiOnsiaWQiOiJjZWU5ZmMzZS1lNjRmLTQ1OTItODQzZS1kN2ZhNzY2OWVmNGYifSwiaHR0cHM6Ly9jb25uZWN0Lnh5ei9zZXNzaW9uIjp7ImNyZWF0ZWRBdCI6IjIwMjYtMDEtMTNUMDA6MjE6MjZaIiwiaWQiOiI2MGQzZjkyYS1kNDlhLTQzM2EtOGU2OC1iMmZiNjE5ZDlmNTAiLCJtZXRhZGF0YSI6eyJ0ZXN0IjoidGVzdCJ9LCJzY29wZXMiOlsidXNlcjpkZXBvc2l0OnNlbmQiXSwic2V0dGluZ3MiOnsiemVyb19oYXNoIjp7ImVuYWJsZWQiOmZhbHNlfX19LCJpc3MiOiJodHRwczovL2Nvbm5lY3QteHl6LnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJuTHBXSjU3U0Foa2JIODFST1ZKT0p3WVVYeDE5cjdYTkBjbGllbnRzIiwiYXVkIjoiaHR0cHM6Ly91c2Vycy5jZXJ0LmNvbm5lY3QueHl6IiwiaWF0IjoxNzY4MjYzNjg2LCJleHAiOjE3NjgzNTAwODYsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyIsImF6cCI6Im5McFdKNTdTQWhrYkg4MVJPVkpPSndZVVh4MTlyN1hOIn0.test";
8
-
9
- const payload = decodeJWT(jwt);
10
-
11
- expect(payload).toBeDefined();
12
- expect(payload?.iss).toBe("https://connect-xyz.us.auth0.com/");
13
- expect(payload?.iss).toContain("connect");
14
- });
15
-
16
- it("should decode a valid JWT without Connect issuer", () => {
17
- // JWT with iss: "https://zerohash.com/"
18
- const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3plcm9oYXNoLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.test";
19
-
20
- const payload = decodeJWT(jwt);
21
-
22
- expect(payload).toBeDefined();
23
- expect(payload?.iss).toBe("https://zerohash.com/");
24
- expect(payload?.iss).not.toContain("connect");
25
- });
26
-
27
- it("should return null for invalid JWT format", () => {
28
- const invalidJwt = "invalid.jwt";
29
-
30
- const payload = decodeJWT(invalidJwt);
31
-
32
- expect(payload).toBeNull();
33
- });
34
-
35
- it("should return null for malformed JWT", () => {
36
- const malformedJwt = "header.payload.signature.extra";
37
-
38
- const payload = decodeJWT(malformedJwt);
39
-
40
- expect(payload).toBeNull();
41
- });
42
- });
43
-
44
- describe("useAuth determination logic", () => {
45
- it("should determine useAuth=true when JWT has Connect issuer", () => {
46
- const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2Nvbm5lY3QteHl6LnVzLmF1dGgwLmNvbS8ifQ.test";
47
- const payload = decodeJWT(jwt);
48
-
49
- const useAuth = payload && payload.iss && typeof payload.iss === 'string' && payload.iss.includes('connect');
50
-
51
- expect(useAuth).toBe(true);
52
- });
53
-
54
- it("should determine useAuth=false when JWT does not have Connect issuer", () => {
55
- const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3plcm9oYXNoLmNvbS8ifQ.test";
56
- const payload = decodeJWT(jwt);
57
-
58
- const useAuth = payload && payload.iss && typeof payload.iss === 'string' && payload.iss.includes('connect');
59
-
60
- expect(useAuth).toBe(false);
61
- });
62
-
63
- it("should determine useAuth=false when JWT has no issuer", () => {
64
- const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.test";
65
- const payload = decodeJWT(jwt);
66
-
67
- const useAuth = payload && payload.iss && typeof payload.iss === 'string' && payload.iss.includes('connect');
68
-
69
- expect(useAuth).toBeFalsy();
70
- });
71
-
72
- it("should determine useAuth=false when JWT is invalid", () => {
73
- const jwt = "invalid";
74
- const payload = decodeJWT(jwt);
75
-
76
- const useAuth = payload && payload.iss && typeof payload.iss === 'string' && payload.iss.includes('connect');
77
-
78
- expect(useAuth).toBeFalsy();
79
- });
80
-
81
- it("should match Connect issuer variations", () => {
82
- const testCases = [
83
- { jwt: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2Nvbm5lY3QteHl6LnVzLmF1dGgwLmNvbS8ifQ.test", expected: true },
84
- { jwt: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2Nvbm5lY3QteHl6LmV1LmF1dGgwLmNvbS8ifQ.test", expected: true },
85
- { jwt: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2Nvbm5lY3QueHl6L2FwaS8ifQ.test", expected: true },
86
- { jwt: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3plcm9oYXNoLmNvbS8ifQ.test", expected: false },
87
- ];
88
-
89
- testCases.forEach(({ jwt, expected }) => {
90
- const payload = decodeJWT(jwt);
91
- const useAuth = payload && payload.iss && typeof payload.iss === 'string' && payload.iss.includes('connect');
92
- expect(useAuth).toBe(expected);
93
- });
94
- });
95
- });
96
- });
@@ -1,23 +0,0 @@
1
- export interface JWTPayload {
2
- auth_embedded?: boolean;
3
- reference_id?: string;
4
- [key: string]: unknown;
5
- }
6
-
7
- export function decodeJWT(token: string): JWTPayload | null {
8
- try {
9
- const parts = token.split('.');
10
- if (parts.length !== 3) {
11
- console.error('[zh-web-sdk] Invalid JWT format');
12
- return null;
13
- }
14
-
15
- const payload = parts[1];
16
- const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
17
- return JSON.parse(decoded);
18
- } catch (error) {
19
- console.error('[zh-web-sdk] Error decoding JWT:', error);
20
- return null;
21
- }
22
- }
23
-
package/src/constants.ts DELETED
@@ -1,2 +0,0 @@
1
- export const DEFAULT_ZH_APPS_URL = "https://web-sdk.zerohash.com/";
2
- export const DEFAULT_ROOT_ID_PREFIX = "zerohash"
@@ -1,26 +0,0 @@
1
- import {useWindowSize} from "../use-window-size";
2
- import {act, renderHook, waitFor} from "@testing-library/react";
3
-
4
- describe("useWindowSize", () => {
5
- it("Returns correct window dimensions on redirect", async () => {
6
- const { result } = renderHook(() => useWindowSize());
7
-
8
- // Asset initial values.
9
- expect(result.current.height).toBe(768);
10
- expect(result.current.width).toBe(1024);
11
-
12
-
13
- // Change the viewport to 500px.
14
- global.innerWidth = 500;
15
- global.innerHeight = 500;
16
-
17
- act(() => {
18
- global.dispatchEvent(new Event('resize'));
19
- })
20
-
21
- await waitFor(() => {
22
- expect(result.current.width).toBe(500);
23
- expect(result.current.height).toBe(500);
24
- })
25
- })
26
- })
@@ -1,19 +0,0 @@
1
- import {useLayoutEffect, useState} from "react";
2
-
3
- export const useWindowSize = () => {
4
- const [height, setHeight] = useState(0);
5
- const [width, setWidth] = useState(0);
6
- useLayoutEffect(() => {
7
- function updateSize() {
8
- setWidth(window.innerWidth);
9
- setHeight(window.innerHeight);
10
- }
11
- window.addEventListener('resize', updateSize);
12
- updateSize();
13
- return () => window.removeEventListener('resize', updateSize);
14
- }, []);
15
- return {
16
- height,
17
- width
18
- };
19
- }