@wishknish/knishio-client-js 0.7.4 → 0.7.6
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/client.cjs.js +90 -28
- package/dist/client.cjs.js.map +1 -1
- package/dist/client.es.mjs +1680 -892
- package/dist/client.es.mjs.map +1 -1
- package/dist/client.iife.js +90 -28
- package/dist/client.iife.js.map +1 -1
- package/package.json +1 -1
- package/src/KnishIOClient.js +74 -13
- package/src/Molecule.js +102 -14
- package/src/Wallet.js +48 -1
- package/src/index.js +233 -9
- package/src/libraries/CheckMolecule.js +211 -5
- package/src/query/QueryContinuId.js +8 -0
- package/src/query/QueryMetaTypeViaMolecule.js +223 -0
- package/src/query/QueryWalletList.js +2 -2
- package/src/response/ResponseContinuId.js +1 -1
- package/src/response/ResponseMetaTypeViaMolecule.js +210 -0
- package/src/response/ResponseRequestAuthorization.js +34 -1
- package/src/response/ResponseRequestAuthorizationGuest.js +32 -1
- package/src/response/ResponseWalletList.js +1 -1
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/*
|
|
2
|
+
(
|
|
3
|
+
(/(
|
|
4
|
+
(//(
|
|
5
|
+
(///(
|
|
6
|
+
(/////(
|
|
7
|
+
(//////( )
|
|
8
|
+
(////////( (/)
|
|
9
|
+
(////////( (///)
|
|
10
|
+
(//////////( (////)
|
|
11
|
+
(//////////( (//////)
|
|
12
|
+
(////////////( (///////)
|
|
13
|
+
(/////////////( (/////////)
|
|
14
|
+
(//////////////( (///////////)
|
|
15
|
+
(///////////////( (//////////////)
|
|
16
|
+
(////////////////( (///////////////)
|
|
17
|
+
((((((((((((((((((( (((((((((((((((
|
|
18
|
+
((((((((((((((((((( ((((((((((((((
|
|
19
|
+
((((((((((((((((((( ((((((((((((((
|
|
20
|
+
(((((((((((((((((((( (((((((((((((
|
|
21
|
+
(((((((((((((((((((( ((((((((((((
|
|
22
|
+
((((((((((((((((((( ((((((((((((
|
|
23
|
+
((((((((((((((((((( ((((((((((
|
|
24
|
+
((((((((((((((((((/ (((((((((
|
|
25
|
+
(((((((((((((((((( ((((((((
|
|
26
|
+
((((((((((((((((( (((((((
|
|
27
|
+
(((((((((((((((((( (((((
|
|
28
|
+
################# ##
|
|
29
|
+
################ #
|
|
30
|
+
################# ##
|
|
31
|
+
%################ ###
|
|
32
|
+
###############( ####
|
|
33
|
+
############### ####
|
|
34
|
+
############### ######
|
|
35
|
+
%#############( (#######
|
|
36
|
+
%############# #########
|
|
37
|
+
############( ##########
|
|
38
|
+
########### #############
|
|
39
|
+
######### ##############
|
|
40
|
+
%######
|
|
41
|
+
|
|
42
|
+
Powered by Knish.IO: Connecting a Decentralized World
|
|
43
|
+
|
|
44
|
+
Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
|
|
45
|
+
|
|
46
|
+
License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
|
|
47
|
+
*/
|
|
48
|
+
import Query from './Query.js'
|
|
49
|
+
import ResponseMetaTypeViaMolecule from '../response/ResponseMetaTypeViaMolecule.js'
|
|
50
|
+
import { gql } from '@urql/core'
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Query for retrieving Meta Asset information via Molecule data.
|
|
54
|
+
*
|
|
55
|
+
* Unlike QueryMetaTypeViaAtom, this query does NOT request the redundant
|
|
56
|
+
* instance-level `metas` field. Instead, metadata is extracted client-side
|
|
57
|
+
* from molecule atoms' `metasJson`, eliminating duplicate data transfer.
|
|
58
|
+
*/
|
|
59
|
+
export default class QueryMetaTypeViaMolecule extends Query {
|
|
60
|
+
/**
|
|
61
|
+
* @param {UrqlClientWrapper} graphQLClient
|
|
62
|
+
* @param {KnishIOClient} knishIOClient
|
|
63
|
+
*/
|
|
64
|
+
constructor (graphQLClient, knishIOClient) {
|
|
65
|
+
super(graphQLClient, knishIOClient)
|
|
66
|
+
|
|
67
|
+
this.$__query = gql`query ($metaTypes: [String!], $metaIds: [String!], $values: [String!], $keys: [String!], $latest: Boolean, $filter: [MetaFilter!], $queryArgs: QueryArgs, $countBy: String, $atomValues: [String!], $cellSlugs: [String!] ) {
|
|
68
|
+
MetaTypeViaAtom(
|
|
69
|
+
metaTypes: $metaTypes
|
|
70
|
+
metaIds: $metaIds
|
|
71
|
+
atomValues: $atomValues
|
|
72
|
+
cellSlugs: $cellSlugs
|
|
73
|
+
filter: $filter,
|
|
74
|
+
latest: $latest,
|
|
75
|
+
queryArgs: $queryArgs
|
|
76
|
+
countBy: $countBy
|
|
77
|
+
) {
|
|
78
|
+
metaType,
|
|
79
|
+
instanceCount {
|
|
80
|
+
key,
|
|
81
|
+
value
|
|
82
|
+
},
|
|
83
|
+
instances {
|
|
84
|
+
metaType,
|
|
85
|
+
metaId,
|
|
86
|
+
createdAt,
|
|
87
|
+
metas( values: $values, keys: $keys ) {
|
|
88
|
+
molecularHash,
|
|
89
|
+
position,
|
|
90
|
+
key,
|
|
91
|
+
value,
|
|
92
|
+
createdAt
|
|
93
|
+
},
|
|
94
|
+
molecule {
|
|
95
|
+
molecularHash,
|
|
96
|
+
bundleHash,
|
|
97
|
+
cellSlug,
|
|
98
|
+
status,
|
|
99
|
+
createdAt,
|
|
100
|
+
atoms {
|
|
101
|
+
position,
|
|
102
|
+
walletAddress,
|
|
103
|
+
isotope,
|
|
104
|
+
tokenSlug,
|
|
105
|
+
value,
|
|
106
|
+
batchId,
|
|
107
|
+
metaType,
|
|
108
|
+
metaId,
|
|
109
|
+
index,
|
|
110
|
+
createdAt,
|
|
111
|
+
otsFragment,
|
|
112
|
+
metasJson
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
paginatorInfo {
|
|
117
|
+
currentPage,
|
|
118
|
+
total
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}`
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Builds a GraphQL-friendly variables object based on input fields
|
|
126
|
+
*
|
|
127
|
+
* @param {string|array|null} metaType
|
|
128
|
+
* @param {string|array|null} metaId
|
|
129
|
+
* @param {string|null} key
|
|
130
|
+
* @param {string|null} value
|
|
131
|
+
* @param {array|null} values
|
|
132
|
+
* @param {array|null} keys
|
|
133
|
+
* @param {array|null} atomValues
|
|
134
|
+
* @param {boolean|null} latest
|
|
135
|
+
* @param {array|null} filter
|
|
136
|
+
* @param {object|null} queryArgs
|
|
137
|
+
* @param {string|null} countBy
|
|
138
|
+
* @param {string|null} cellSlug
|
|
139
|
+
* @return {{}}
|
|
140
|
+
*/
|
|
141
|
+
static createVariables ({
|
|
142
|
+
metaType = null,
|
|
143
|
+
metaId = null,
|
|
144
|
+
key = null,
|
|
145
|
+
value = null,
|
|
146
|
+
keys = null,
|
|
147
|
+
values = null,
|
|
148
|
+
atomValues = null,
|
|
149
|
+
latest = null,
|
|
150
|
+
filter = null,
|
|
151
|
+
queryArgs = null,
|
|
152
|
+
countBy = null,
|
|
153
|
+
cellSlug = null
|
|
154
|
+
}) {
|
|
155
|
+
const variables = {}
|
|
156
|
+
|
|
157
|
+
if (atomValues) {
|
|
158
|
+
variables.atomValues = atomValues
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (keys) {
|
|
162
|
+
variables.keys = keys
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (values) {
|
|
166
|
+
variables.values = values
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (metaType) {
|
|
170
|
+
variables.metaTypes = typeof metaType === 'string' ? [metaType] : metaType
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (metaId) {
|
|
174
|
+
variables.metaIds = typeof metaId === 'string' ? [metaId] : metaId
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (cellSlug) {
|
|
178
|
+
variables.cellSlugs = typeof cellSlug === 'string' ? [cellSlug] : cellSlug
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (countBy) {
|
|
182
|
+
variables.countBy = countBy
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (filter) {
|
|
186
|
+
variables.filter = filter
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (key && value) {
|
|
190
|
+
variables.filter = variables.filter || []
|
|
191
|
+
variables.filter.push({
|
|
192
|
+
key,
|
|
193
|
+
value,
|
|
194
|
+
comparison: '='
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
variables.latest = latest === true
|
|
199
|
+
|
|
200
|
+
if (queryArgs) {
|
|
201
|
+
if (typeof queryArgs.limit === 'undefined' || queryArgs.limit === 0) {
|
|
202
|
+
queryArgs.limit = '*'
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
variables.queryArgs = queryArgs
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return variables
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Returns a Response object
|
|
213
|
+
*
|
|
214
|
+
* @param {object} json
|
|
215
|
+
* @return {ResponseMetaTypeViaMolecule}
|
|
216
|
+
*/
|
|
217
|
+
createResponse (json) {
|
|
218
|
+
return new ResponseMetaTypeViaMolecule({
|
|
219
|
+
query: this,
|
|
220
|
+
json
|
|
221
|
+
})
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -60,8 +60,8 @@ export default class QueryWalletList extends Query {
|
|
|
60
60
|
constructor (graphQLClient, knishIOClient) {
|
|
61
61
|
super(graphQLClient, knishIOClient)
|
|
62
62
|
|
|
63
|
-
this.$__query = gql`query( $bundleHash: String, $
|
|
64
|
-
Wallet( bundleHash: $bundleHash,
|
|
63
|
+
this.$__query = gql`query( $bundleHash: String, $token: String ) {
|
|
64
|
+
Wallet( bundleHash: $bundleHash, token: $token ) {
|
|
65
65
|
address,
|
|
66
66
|
bundleHash,
|
|
67
67
|
token {
|
|
@@ -91,7 +91,7 @@ export default class ResponseContinuId extends Response {
|
|
|
91
91
|
wallet.batchId = continuId.batchId
|
|
92
92
|
wallet.characters = continuId.characters
|
|
93
93
|
wallet.pubkey = continuId.pubkey
|
|
94
|
-
wallet.balance = continuId.amount
|
|
94
|
+
wallet.balance = String(continuId.amount != null ? continuId.amount : 0)
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
return wallet
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/*
|
|
2
|
+
(
|
|
3
|
+
(/(
|
|
4
|
+
(//(
|
|
5
|
+
(///(
|
|
6
|
+
(/////(
|
|
7
|
+
(//////( )
|
|
8
|
+
(////////( (/)
|
|
9
|
+
(////////( (///)
|
|
10
|
+
(//////////( (////)
|
|
11
|
+
(//////////( (//////)
|
|
12
|
+
(////////////( (///////)
|
|
13
|
+
(/////////////( (/////////)
|
|
14
|
+
(//////////////( (///////////)
|
|
15
|
+
(///////////////( (//////////////)
|
|
16
|
+
(////////////////( (///////////////)
|
|
17
|
+
((((((((((((((((((( (((((((((((((((
|
|
18
|
+
((((((((((((((((((( ((((((((((((((
|
|
19
|
+
((((((((((((((((((( ((((((((((((((
|
|
20
|
+
(((((((((((((((((((( (((((((((((((
|
|
21
|
+
(((((((((((((((((((( ((((((((((((
|
|
22
|
+
((((((((((((((((((( ((((((((((((
|
|
23
|
+
((((((((((((((((((( ((((((((((
|
|
24
|
+
((((((((((((((((((/ (((((((((
|
|
25
|
+
(((((((((((((((((( ((((((((
|
|
26
|
+
((((((((((((((((( (((((((
|
|
27
|
+
(((((((((((((((((( (((((
|
|
28
|
+
################# ##
|
|
29
|
+
################ #
|
|
30
|
+
################# ##
|
|
31
|
+
%################ ###
|
|
32
|
+
###############( ####
|
|
33
|
+
############### ####
|
|
34
|
+
############### ######
|
|
35
|
+
%#############( (#######
|
|
36
|
+
%############# #########
|
|
37
|
+
############( ##########
|
|
38
|
+
########### #############
|
|
39
|
+
######### ##############
|
|
40
|
+
%######
|
|
41
|
+
|
|
42
|
+
Powered by Knish.IO: Connecting a Decentralized World
|
|
43
|
+
|
|
44
|
+
Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
|
|
45
|
+
|
|
46
|
+
License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
import Query from '../query/Query.js'
|
|
50
|
+
import Response from './Response.js'
|
|
51
|
+
import CheckMolecule from '../libraries/CheckMolecule.js'
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Response for MetaType queries via Molecule data.
|
|
55
|
+
*
|
|
56
|
+
* Instead of using the redundant instance-level `metas` field,
|
|
57
|
+
* this response extracts metadata from molecule atoms' `metasJson`,
|
|
58
|
+
* producing a payload format compatible with ResponseMetaType and
|
|
59
|
+
* ResponseMetaTypeViaAtom for drop-in replacement usage.
|
|
60
|
+
*/
|
|
61
|
+
export default class ResponseMetaTypeViaMolecule extends Response {
|
|
62
|
+
/**
|
|
63
|
+
* Class constructor
|
|
64
|
+
*
|
|
65
|
+
* @param {Query} query
|
|
66
|
+
* @param {object} json
|
|
67
|
+
*/
|
|
68
|
+
constructor ({
|
|
69
|
+
query,
|
|
70
|
+
json
|
|
71
|
+
}) {
|
|
72
|
+
super({
|
|
73
|
+
query,
|
|
74
|
+
json,
|
|
75
|
+
dataKey: 'data.MetaTypeViaAtom'
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Extracts metas from a molecule's atoms' metasJson for a specific instance.
|
|
81
|
+
* Filters atoms by matching metaType and metaId, then parses metasJson.
|
|
82
|
+
*
|
|
83
|
+
* @param {object} molecule - Molecule data with atoms array
|
|
84
|
+
* @param {string} metaType - Instance meta type to filter by
|
|
85
|
+
* @param {string} metaId - Instance meta ID to filter by
|
|
86
|
+
* @return {Array<{molecularHash: string, position: string, key: string, value: string, createdAt: string}>}
|
|
87
|
+
*/
|
|
88
|
+
static extractMetasFromMolecule (molecule, metaType, metaId) {
|
|
89
|
+
if (!molecule || !molecule.atoms) {
|
|
90
|
+
return []
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const metas = []
|
|
94
|
+
|
|
95
|
+
for (const atom of molecule.atoms) {
|
|
96
|
+
// Filter atoms to those matching this instance's metaType and metaId
|
|
97
|
+
if (atom.metaType !== metaType || atom.metaId !== metaId) {
|
|
98
|
+
continue
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!atom.metasJson) {
|
|
102
|
+
continue
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let parsed
|
|
106
|
+
try {
|
|
107
|
+
parsed = JSON.parse(atom.metasJson)
|
|
108
|
+
if (!Array.isArray(parsed)) {
|
|
109
|
+
continue
|
|
110
|
+
}
|
|
111
|
+
} catch (e) {
|
|
112
|
+
continue
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
for (const entry of parsed) {
|
|
116
|
+
metas.push({
|
|
117
|
+
molecularHash: molecule.molecularHash,
|
|
118
|
+
position: atom.position,
|
|
119
|
+
key: entry.key,
|
|
120
|
+
value: entry.value,
|
|
121
|
+
createdAt: atom.createdAt
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return metas
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Returns meta type instance results with metas synthesized from molecule data.
|
|
131
|
+
* Produces the same payload format as ResponseMetaType and ResponseMetaTypeViaAtom:
|
|
132
|
+
* { instances, instanceCount, paginatorInfo }
|
|
133
|
+
*
|
|
134
|
+
* @return {null|{instances: Array, instanceCount: Array, paginatorInfo: object}}
|
|
135
|
+
*/
|
|
136
|
+
payload () {
|
|
137
|
+
const metaTypeData = this.data()
|
|
138
|
+
|
|
139
|
+
if (!metaTypeData || metaTypeData.length === 0) {
|
|
140
|
+
return null
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const response = {
|
|
144
|
+
instances: {},
|
|
145
|
+
instanceCount: {},
|
|
146
|
+
paginatorInfo: {}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const metaData = metaTypeData.pop()
|
|
150
|
+
|
|
151
|
+
if (metaData.instances) {
|
|
152
|
+
response.instances = metaData.instances.map(instance => {
|
|
153
|
+
// Prefer server-filtered metas (from metas sub-field) when available
|
|
154
|
+
let metas = instance.metas
|
|
155
|
+
if (!metas || metas.length === 0) {
|
|
156
|
+
// Fallback: synthesize from molecule atoms' metasJson
|
|
157
|
+
metas = ResponseMetaTypeViaMolecule.extractMetasFromMolecule(
|
|
158
|
+
instance.molecule,
|
|
159
|
+
instance.metaType,
|
|
160
|
+
instance.metaId
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
...instance,
|
|
166
|
+
metas
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (metaData.instanceCount) {
|
|
172
|
+
response.instanceCount = metaData.instanceCount
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (metaData.paginatorInfo) {
|
|
176
|
+
response.paginatorInfo = metaData.paginatorInfo
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return response
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Verifies the cryptographic integrity of all molecules associated
|
|
184
|
+
* with meta instances in this response. For each instance, reconstructs
|
|
185
|
+
* the molecule from server data and runs CheckMolecule.verify() to validate
|
|
186
|
+
* the molecular hash and OTS signature.
|
|
187
|
+
*
|
|
188
|
+
* @return {{ verified: boolean, molecules: Array<{ molecularHash: string, verified: boolean, error: string|null }> }}
|
|
189
|
+
*/
|
|
190
|
+
verifyIntegrity () {
|
|
191
|
+
const results = []
|
|
192
|
+
const metaTypeData = this.data()
|
|
193
|
+
|
|
194
|
+
if (!metaTypeData || metaTypeData.length === 0) {
|
|
195
|
+
return { verified: true, molecules: results }
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const instances = metaTypeData[metaTypeData.length - 1]?.instances || []
|
|
199
|
+
|
|
200
|
+
for (const instance of instances) {
|
|
201
|
+
if (!instance.molecule) continue
|
|
202
|
+
results.push(CheckMolecule.verifyFromServerData(instance.molecule))
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
verified: results.length === 0 || results.every(r => r.verified),
|
|
207
|
+
molecules: results
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -76,7 +76,7 @@ export default class ResponseRequestAuthorization extends ResponseProposeMolecul
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* Returns
|
|
79
|
+
* Returns raw time value from payload
|
|
80
80
|
*
|
|
81
81
|
* @return {string}
|
|
82
82
|
*/
|
|
@@ -84,6 +84,39 @@ export default class ResponseRequestAuthorization extends ResponseProposeMolecul
|
|
|
84
84
|
return this.payloadKey('time')
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Returns the expiration timestamp as Unix seconds.
|
|
89
|
+
* Handles both server formats:
|
|
90
|
+
* - PHP server: time = lifetime in ms, expiresAt = Unix timestamp in payload
|
|
91
|
+
* - Rust server: time = Unix timestamp in seconds
|
|
92
|
+
*
|
|
93
|
+
* @return {number}
|
|
94
|
+
*/
|
|
95
|
+
expiresAt () {
|
|
96
|
+
// Try the explicit expiresAt payload key first (PHP server provides this)
|
|
97
|
+
try {
|
|
98
|
+
const ea = this.payloadKey('expiresAt')
|
|
99
|
+
if (ea) {
|
|
100
|
+
return Number(ea)
|
|
101
|
+
}
|
|
102
|
+
} catch (_e) {
|
|
103
|
+
// Not available in payload, fall back
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Use time field with heuristic detection
|
|
107
|
+
const timeValue = Number(this.time())
|
|
108
|
+
|
|
109
|
+
// If timeValue looks like a valid Unix timestamp (>= year 2020), use directly
|
|
110
|
+
// Rust server sets time = Unix timestamp in seconds
|
|
111
|
+
if (timeValue >= 1577836800) {
|
|
112
|
+
return timeValue
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Otherwise, time is a lifetime in milliseconds (PHP server format)
|
|
116
|
+
// Convert to Unix timestamp: now_seconds + lifetime_seconds
|
|
117
|
+
return Math.floor(Date.now() / 1000) + Math.floor(timeValue / 1000)
|
|
118
|
+
}
|
|
119
|
+
|
|
87
120
|
/**
|
|
88
121
|
*
|
|
89
122
|
* @return {string}
|
|
@@ -120,7 +120,7 @@ export default class ResponseRequestAuthorizationGuest extends Response {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
|
-
* Returns
|
|
123
|
+
* Returns raw time value from payload
|
|
124
124
|
*
|
|
125
125
|
* @return {*}
|
|
126
126
|
*/
|
|
@@ -128,6 +128,37 @@ export default class ResponseRequestAuthorizationGuest extends Response {
|
|
|
128
128
|
return this.payloadKey('time')
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Returns the expiration timestamp as Unix seconds.
|
|
133
|
+
* Handles both server formats:
|
|
134
|
+
* - PHP server: time = lifetime in ms, expiresAt = Unix timestamp in payload
|
|
135
|
+
* - Rust server: time = Unix timestamp in seconds
|
|
136
|
+
*
|
|
137
|
+
* @return {number}
|
|
138
|
+
*/
|
|
139
|
+
expiresAt () {
|
|
140
|
+
// Try the explicit expiresAt payload key first (PHP server provides this)
|
|
141
|
+
try {
|
|
142
|
+
const ea = this.payloadKey('expiresAt')
|
|
143
|
+
if (ea) {
|
|
144
|
+
return Number(ea)
|
|
145
|
+
}
|
|
146
|
+
} catch (_e) {
|
|
147
|
+
// Not available in payload, fall back
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Use time field with heuristic detection
|
|
151
|
+
const timeValue = Number(this.time())
|
|
152
|
+
|
|
153
|
+
// If timeValue looks like a valid Unix timestamp (>= year 2020), use directly
|
|
154
|
+
if (timeValue >= 1577836800) {
|
|
155
|
+
return timeValue
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Otherwise, time is a lifetime in milliseconds (PHP server format)
|
|
159
|
+
return Math.floor(Date.now() / 1000) + Math.floor(timeValue / 1000)
|
|
160
|
+
}
|
|
161
|
+
|
|
131
162
|
/**
|
|
132
163
|
* Returns timestamp
|
|
133
164
|
*
|
|
@@ -122,7 +122,7 @@ export default class ResponseWalletList extends Response {
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
wallet.balance =
|
|
125
|
+
wallet.balance = String(data.amount != null ? data.amount : 0)
|
|
126
126
|
wallet.pubkey = data.pubkey
|
|
127
127
|
wallet.createdAt = data.createdAt
|
|
128
128
|
|