@phantom/utils 1.0.0-beta.19

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.
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Self-contained UUID v4 implementation for Phantom Wallet SDK
3
+ * No external dependencies to avoid ES module compatibility issues
4
+ */
5
+ /**
6
+ * Generate a random UUID v4 string
7
+ * RFC 4122 compliant UUID version 4
8
+ * @returns A UUID v4 string in the format xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
9
+ */
10
+ declare function randomUUID(): string;
11
+ /**
12
+ * Generate a random string of specified length using alphanumeric characters
13
+ * @param length - The length of the string to generate
14
+ * @returns A random alphanumeric string
15
+ */
16
+ declare function randomString(length: number): string;
17
+
18
+ /**
19
+ * Secure time service that fetches server time from Phantom's time API
20
+ * instead of relying on local machine time which can be manipulated
21
+ */
22
+ declare const getSecureTimestamp: () => Promise<number>;
23
+ declare const getSecureTimestampSync: () => number;
24
+
25
+ /**
26
+ * Network utility functions for working with blockchain network identifiers
27
+ */
28
+ declare function isEthereumChain(networkId: string): boolean;
29
+ declare function getChainPrefix(networkId: string): string;
30
+
31
+ export { getChainPrefix, getSecureTimestamp, getSecureTimestampSync, isEthereumChain, randomString, randomUUID };
package/dist/index.js ADDED
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ getChainPrefix: () => getChainPrefix,
24
+ getSecureTimestamp: () => getSecureTimestamp,
25
+ getSecureTimestampSync: () => getSecureTimestampSync,
26
+ isEthereumChain: () => isEthereumChain,
27
+ randomString: () => randomString,
28
+ randomUUID: () => randomUUID
29
+ });
30
+ module.exports = __toCommonJS(src_exports);
31
+
32
+ // src/uuid.ts
33
+ function randomUUID() {
34
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
35
+ return crypto.randomUUID();
36
+ }
37
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
38
+ const r = Math.random() * 16 | 0;
39
+ const v = c === "x" ? r : r & 3 | 8;
40
+ return v.toString(16);
41
+ });
42
+ }
43
+ function randomString(length) {
44
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
45
+ let result = "";
46
+ for (let i = 0; i < length; i++) {
47
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
48
+ }
49
+ return result;
50
+ }
51
+
52
+ // src/time.ts
53
+ var TimeService = class {
54
+ constructor() {
55
+ this.cache = null;
56
+ this.CACHE_DURATION = 3e4;
57
+ // 30 seconds cache
58
+ this.TIME_API_URL = "https://time.phantom.app/utc";
59
+ }
60
+ static getInstance() {
61
+ if (!TimeService.instance) {
62
+ TimeService.instance = new TimeService();
63
+ }
64
+ return TimeService.instance;
65
+ }
66
+ /**
67
+ * Get current timestamp from Phantom's secure time API
68
+ * Includes basic caching to reduce API calls
69
+ */
70
+ async now() {
71
+ const now = Date.now();
72
+ if (this.cache && now - this.cache.fetchedAt < this.CACHE_DURATION) {
73
+ const elapsed = now - this.cache.fetchedAt;
74
+ return this.cache.timestamp + elapsed;
75
+ }
76
+ try {
77
+ const response = await fetch(this.TIME_API_URL);
78
+ if (!response.ok) {
79
+ throw new Error(`Time API responded with status: ${response.status}`);
80
+ }
81
+ const timestampText = await response.text();
82
+ const timestamp = parseInt(timestampText, 10);
83
+ if (isNaN(timestamp)) {
84
+ throw new Error(`Invalid timestamp received: ${timestampText}`);
85
+ }
86
+ this.cache = {
87
+ timestamp,
88
+ fetchedAt: now
89
+ };
90
+ return timestamp;
91
+ } catch (error) {
92
+ return Date.now();
93
+ }
94
+ }
95
+ /**
96
+ * Synchronous version that uses cached time if available,
97
+ * otherwise falls back to Date.now()
98
+ */
99
+ nowSync() {
100
+ if (this.cache) {
101
+ const elapsed = Date.now() - this.cache.fetchedAt;
102
+ if (elapsed < this.CACHE_DURATION) {
103
+ return this.cache.timestamp + elapsed;
104
+ }
105
+ }
106
+ return Date.now();
107
+ }
108
+ /**
109
+ * Clear the cache (useful for testing)
110
+ */
111
+ clearCache() {
112
+ this.cache = null;
113
+ }
114
+ };
115
+ var timeService = TimeService.getInstance();
116
+ var getSecureTimestamp = () => timeService.now();
117
+ var getSecureTimestampSync = () => timeService.nowSync();
118
+
119
+ // src/network.ts
120
+ function isEthereumChain(networkId) {
121
+ const network = networkId.split(":")[0].toLowerCase();
122
+ return network === "eip155";
123
+ }
124
+ function getChainPrefix(networkId) {
125
+ return networkId.split(":")[0].toLowerCase();
126
+ }
127
+ // Annotate the CommonJS export names for ESM import in node:
128
+ 0 && (module.exports = {
129
+ getChainPrefix,
130
+ getSecureTimestamp,
131
+ getSecureTimestampSync,
132
+ isEthereumChain,
133
+ randomString,
134
+ randomUUID
135
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,103 @@
1
+ // src/uuid.ts
2
+ function randomUUID() {
3
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
4
+ return crypto.randomUUID();
5
+ }
6
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
7
+ const r = Math.random() * 16 | 0;
8
+ const v = c === "x" ? r : r & 3 | 8;
9
+ return v.toString(16);
10
+ });
11
+ }
12
+ function randomString(length) {
13
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
14
+ let result = "";
15
+ for (let i = 0; i < length; i++) {
16
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
17
+ }
18
+ return result;
19
+ }
20
+
21
+ // src/time.ts
22
+ var TimeService = class {
23
+ constructor() {
24
+ this.cache = null;
25
+ this.CACHE_DURATION = 3e4;
26
+ // 30 seconds cache
27
+ this.TIME_API_URL = "https://time.phantom.app/utc";
28
+ }
29
+ static getInstance() {
30
+ if (!TimeService.instance) {
31
+ TimeService.instance = new TimeService();
32
+ }
33
+ return TimeService.instance;
34
+ }
35
+ /**
36
+ * Get current timestamp from Phantom's secure time API
37
+ * Includes basic caching to reduce API calls
38
+ */
39
+ async now() {
40
+ const now = Date.now();
41
+ if (this.cache && now - this.cache.fetchedAt < this.CACHE_DURATION) {
42
+ const elapsed = now - this.cache.fetchedAt;
43
+ return this.cache.timestamp + elapsed;
44
+ }
45
+ try {
46
+ const response = await fetch(this.TIME_API_URL);
47
+ if (!response.ok) {
48
+ throw new Error(`Time API responded with status: ${response.status}`);
49
+ }
50
+ const timestampText = await response.text();
51
+ const timestamp = parseInt(timestampText, 10);
52
+ if (isNaN(timestamp)) {
53
+ throw new Error(`Invalid timestamp received: ${timestampText}`);
54
+ }
55
+ this.cache = {
56
+ timestamp,
57
+ fetchedAt: now
58
+ };
59
+ return timestamp;
60
+ } catch (error) {
61
+ return Date.now();
62
+ }
63
+ }
64
+ /**
65
+ * Synchronous version that uses cached time if available,
66
+ * otherwise falls back to Date.now()
67
+ */
68
+ nowSync() {
69
+ if (this.cache) {
70
+ const elapsed = Date.now() - this.cache.fetchedAt;
71
+ if (elapsed < this.CACHE_DURATION) {
72
+ return this.cache.timestamp + elapsed;
73
+ }
74
+ }
75
+ return Date.now();
76
+ }
77
+ /**
78
+ * Clear the cache (useful for testing)
79
+ */
80
+ clearCache() {
81
+ this.cache = null;
82
+ }
83
+ };
84
+ var timeService = TimeService.getInstance();
85
+ var getSecureTimestamp = () => timeService.now();
86
+ var getSecureTimestampSync = () => timeService.nowSync();
87
+
88
+ // src/network.ts
89
+ function isEthereumChain(networkId) {
90
+ const network = networkId.split(":")[0].toLowerCase();
91
+ return network === "eip155";
92
+ }
93
+ function getChainPrefix(networkId) {
94
+ return networkId.split(":")[0].toLowerCase();
95
+ }
96
+ export {
97
+ getChainPrefix,
98
+ getSecureTimestamp,
99
+ getSecureTimestampSync,
100
+ isEthereumChain,
101
+ randomString,
102
+ randomUUID
103
+ };
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@phantom/utils",
3
+ "version": "1.0.0-beta.19",
4
+ "description": "Utility functions for Phantom Wallet SDK",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "?pack-release": "When https://github.com/changesets/changesets/issues/432 has a solution we can remove this trick",
17
+ "pack-release": "rimraf ./_release && yarn pack && mkdir ./_release && tar zxvf ./package.tgz --directory ./_release && rm ./package.tgz",
18
+ "build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts",
19
+ "dev": "tsc --watch",
20
+ "clean": "rm -rf dist",
21
+ "test": "jest",
22
+ "test:watch": "jest --watch",
23
+ "lint": "tsc --noEmit && eslint --cache . --ext .ts,.tsx",
24
+ "check-types": "tsc --noEmit",
25
+ "prettier": "prettier --write \"src/**/*.{ts,tsx}\""
26
+ },
27
+ "devDependencies": {
28
+ "@types/jest": "^29.5.12",
29
+ "@types/node": "^20.11.0",
30
+ "eslint": "8.53.0",
31
+ "jest": "^29.7.0",
32
+ "prettier": "^3.5.2",
33
+ "rimraf": "^6.0.1",
34
+ "ts-jest": "^29.1.2",
35
+ "tsup": "^6.7.0",
36
+ "typescript": "^5.0.4"
37
+ },
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "publishConfig": {
42
+ "directory": "_release/package"
43
+ }
44
+ }