@phantom/utils 1.0.0-beta.3 → 1.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.
- package/dist/index.d.ts +15 -1
- package/dist/index.js +90 -0
- package/dist/index.mjs +85 -0
- package/package.json +6 -1
package/dist/index.d.ts
CHANGED
|
@@ -15,4 +15,18 @@ declare function randomUUID(): string;
|
|
|
15
15
|
*/
|
|
16
16
|
declare function randomString(length: number): string;
|
|
17
17
|
|
|
18
|
-
|
|
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 getChainPrefix(networkId: string): string;
|
|
29
|
+
declare function isEthereumChain(networkId: string): boolean;
|
|
30
|
+
declare function isSolanaChain(networkId: string): boolean;
|
|
31
|
+
|
|
32
|
+
export { getChainPrefix, getSecureTimestamp, getSecureTimestampSync, isEthereumChain, isSolanaChain, randomString, randomUUID };
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
getChainPrefix: () => getChainPrefix,
|
|
24
|
+
getSecureTimestamp: () => getSecureTimestamp,
|
|
25
|
+
getSecureTimestampSync: () => getSecureTimestampSync,
|
|
26
|
+
isEthereumChain: () => isEthereumChain,
|
|
27
|
+
isSolanaChain: () => isSolanaChain,
|
|
23
28
|
randomString: () => randomString,
|
|
24
29
|
randomUUID: () => randomUUID
|
|
25
30
|
});
|
|
@@ -44,8 +49,93 @@ function randomString(length) {
|
|
|
44
49
|
}
|
|
45
50
|
return result;
|
|
46
51
|
}
|
|
52
|
+
|
|
53
|
+
// src/time.ts
|
|
54
|
+
var TimeService = class {
|
|
55
|
+
constructor() {
|
|
56
|
+
this.cache = null;
|
|
57
|
+
this.CACHE_DURATION = 3e4;
|
|
58
|
+
// 30 seconds cache
|
|
59
|
+
this.TIME_API_URL = "https://time.phantom.app/utc";
|
|
60
|
+
}
|
|
61
|
+
static getInstance() {
|
|
62
|
+
if (!TimeService.instance) {
|
|
63
|
+
TimeService.instance = new TimeService();
|
|
64
|
+
}
|
|
65
|
+
return TimeService.instance;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get current timestamp from Phantom's secure time API
|
|
69
|
+
* Includes basic caching to reduce API calls
|
|
70
|
+
*/
|
|
71
|
+
async now() {
|
|
72
|
+
const now = Date.now();
|
|
73
|
+
if (this.cache && now - this.cache.fetchedAt < this.CACHE_DURATION) {
|
|
74
|
+
const elapsed = now - this.cache.fetchedAt;
|
|
75
|
+
return this.cache.timestamp + elapsed;
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const response = await fetch(this.TIME_API_URL);
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
throw new Error(`Time API responded with status: ${response.status}`);
|
|
81
|
+
}
|
|
82
|
+
const timestampText = await response.text();
|
|
83
|
+
const timestamp = parseInt(timestampText, 10);
|
|
84
|
+
if (isNaN(timestamp)) {
|
|
85
|
+
throw new Error(`Invalid timestamp received: ${timestampText}`);
|
|
86
|
+
}
|
|
87
|
+
this.cache = {
|
|
88
|
+
timestamp,
|
|
89
|
+
fetchedAt: now
|
|
90
|
+
};
|
|
91
|
+
return timestamp;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
return Date.now();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Synchronous version that uses cached time if available,
|
|
98
|
+
* otherwise falls back to Date.now()
|
|
99
|
+
*/
|
|
100
|
+
nowSync() {
|
|
101
|
+
if (this.cache) {
|
|
102
|
+
const elapsed = Date.now() - this.cache.fetchedAt;
|
|
103
|
+
if (elapsed < this.CACHE_DURATION) {
|
|
104
|
+
return this.cache.timestamp + elapsed;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return Date.now();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Clear the cache (useful for testing)
|
|
111
|
+
*/
|
|
112
|
+
clearCache() {
|
|
113
|
+
this.cache = null;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
var timeService = TimeService.getInstance();
|
|
117
|
+
var getSecureTimestamp = () => timeService.now();
|
|
118
|
+
var getSecureTimestampSync = () => timeService.nowSync();
|
|
119
|
+
|
|
120
|
+
// src/network.ts
|
|
121
|
+
function getChainPrefix(networkId) {
|
|
122
|
+
return networkId.split(":")[0].toLowerCase();
|
|
123
|
+
}
|
|
124
|
+
function isEthereumChain(networkId) {
|
|
125
|
+
const network = getChainPrefix(networkId);
|
|
126
|
+
return network === "eip155";
|
|
127
|
+
}
|
|
128
|
+
function isSolanaChain(networkId) {
|
|
129
|
+
const network = getChainPrefix(networkId);
|
|
130
|
+
return network === "solana";
|
|
131
|
+
}
|
|
47
132
|
// Annotate the CommonJS export names for ESM import in node:
|
|
48
133
|
0 && (module.exports = {
|
|
134
|
+
getChainPrefix,
|
|
135
|
+
getSecureTimestamp,
|
|
136
|
+
getSecureTimestampSync,
|
|
137
|
+
isEthereumChain,
|
|
138
|
+
isSolanaChain,
|
|
49
139
|
randomString,
|
|
50
140
|
randomUUID
|
|
51
141
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -17,7 +17,92 @@ function randomString(length) {
|
|
|
17
17
|
}
|
|
18
18
|
return result;
|
|
19
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 getChainPrefix(networkId) {
|
|
90
|
+
return networkId.split(":")[0].toLowerCase();
|
|
91
|
+
}
|
|
92
|
+
function isEthereumChain(networkId) {
|
|
93
|
+
const network = getChainPrefix(networkId);
|
|
94
|
+
return network === "eip155";
|
|
95
|
+
}
|
|
96
|
+
function isSolanaChain(networkId) {
|
|
97
|
+
const network = getChainPrefix(networkId);
|
|
98
|
+
return network === "solana";
|
|
99
|
+
}
|
|
20
100
|
export {
|
|
101
|
+
getChainPrefix,
|
|
102
|
+
getSecureTimestamp,
|
|
103
|
+
getSecureTimestampSync,
|
|
104
|
+
isEthereumChain,
|
|
105
|
+
isSolanaChain,
|
|
21
106
|
randomString,
|
|
22
107
|
randomUUID
|
|
23
108
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/utils",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Utility functions for Phantom Wallet SDK",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/phantom/phantom-connect-sdk",
|
|
8
|
+
"directory": "packages/utils"
|
|
9
|
+
},
|
|
5
10
|
"main": "dist/index.js",
|
|
6
11
|
"module": "dist/index.mjs",
|
|
7
12
|
"types": "dist/index.d.ts",
|