@wishknish/knishio-client-ts 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/index.cjs +2670 -1039
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +336 -105
- package/dist/index.d.ts +336 -105
- package/dist/index.iife.js +22097 -20047
- package/dist/index.iife.js.map +1 -1
- package/dist/index.js +2667 -1040
- package/dist/index.js.map +1 -1
- package/package.json +10 -4
- package/src/AuthToken.ts +8 -2
- package/src/KnishIOClient.ts +306 -50
- package/src/constants.ts +5 -3
- package/src/core/Atom.ts +167 -100
- package/src/core/AtomMeta.ts +11 -28
- package/src/core/Meta.ts +18 -15
- package/src/core/Molecule.ts +582 -140
- package/src/core/Wallet.ts +19 -24
- package/src/index.ts +8 -0
- package/src/instance/rules/Rule.ts +128 -19
- package/src/libraries/CheckMolecule.ts +88 -1
- package/src/libraries/crypto.ts +14 -30
- package/src/libraries/strings.ts +26 -25
- package/src/mutation/MutationAppendRequest.ts +52 -0
- package/src/mutation/MutationCreateRule.ts +2 -2
- package/src/mutation/MutationPeering.ts +37 -0
- package/src/mutation/MutationRequestAuthorization.ts +3 -3
- package/src/query/QueryActiveSession.ts +0 -1
- package/src/query/QueryContinuId.ts +8 -0
- package/src/query/QueryMetaTypeViaMolecule.ts +221 -0
- package/src/query/QueryWalletList.ts +2 -2
- package/src/response/ResponseAppendRequest.ts +17 -0
- package/src/response/ResponseBalance.ts +8 -3
- package/src/response/ResponseContinuId.ts +1 -1
- package/src/response/ResponseMetaType.ts +32 -19
- package/src/response/ResponseMetaTypeViaMolecule.ts +224 -0
- package/src/response/ResponsePeering.ts +17 -0
- package/src/response/ResponsePolicy.ts +2 -3
- package/src/response/ResponseProposeMolecule.ts +0 -1
- package/src/response/ResponseRequestAuthorization.ts +32 -2
- package/src/response/ResponseRequestAuthorizationGuest.ts +25 -1
- package/src/response/ResponseWalletList.ts +1 -1
- package/src/types/guards.ts +18 -5
- package/src/types/index.ts +3 -3
|
@@ -0,0 +1,221 @@
|
|
|
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-TS for information.
|
|
45
|
+
|
|
46
|
+
License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
import Query from './Query'
|
|
50
|
+
import ResponseMetaTypeViaMolecule from '../response/ResponseMetaTypeViaMolecule'
|
|
51
|
+
import { gql } from '@urql/core'
|
|
52
|
+
import type { GraphQLClient } from '../types/graphql'
|
|
53
|
+
import type KnishIOClient from '../KnishIOClient'
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Query for retrieving Meta Asset information via Molecule data.
|
|
57
|
+
*
|
|
58
|
+
* Unlike QueryMetaTypeViaAtom, this query includes molecule data with atoms
|
|
59
|
+
* (including otsFragment and metasJson) for integrity verification and
|
|
60
|
+
* client-side metadata extraction.
|
|
61
|
+
*/
|
|
62
|
+
export default class QueryMetaTypeViaMolecule extends Query {
|
|
63
|
+
/**
|
|
64
|
+
* Create new QueryMetaTypeViaMolecule instance
|
|
65
|
+
*/
|
|
66
|
+
constructor(graphQLClient: GraphQLClient, knishIOClient: KnishIOClient) {
|
|
67
|
+
super(graphQLClient, knishIOClient)
|
|
68
|
+
|
|
69
|
+
this.$__query = gql`query ($metaTypes: [String!], $metaIds: [String!], $values: [String!], $keys: [String!], $latest: Boolean, $filter: [MetaFilter!], $queryArgs: QueryArgs, $countBy: String, $atomValues: [String!], $cellSlugs: [String!] ) {
|
|
70
|
+
MetaTypeViaAtom(
|
|
71
|
+
metaTypes: $metaTypes
|
|
72
|
+
metaIds: $metaIds
|
|
73
|
+
atomValues: $atomValues
|
|
74
|
+
cellSlugs: $cellSlugs
|
|
75
|
+
filter: $filter,
|
|
76
|
+
latest: $latest,
|
|
77
|
+
queryArgs: $queryArgs
|
|
78
|
+
countBy: $countBy
|
|
79
|
+
) {
|
|
80
|
+
metaType,
|
|
81
|
+
instanceCount {
|
|
82
|
+
key,
|
|
83
|
+
value
|
|
84
|
+
},
|
|
85
|
+
instances {
|
|
86
|
+
metaType,
|
|
87
|
+
metaId,
|
|
88
|
+
createdAt,
|
|
89
|
+
metas( values: $values, keys: $keys ) {
|
|
90
|
+
molecularHash,
|
|
91
|
+
position,
|
|
92
|
+
key,
|
|
93
|
+
value,
|
|
94
|
+
createdAt
|
|
95
|
+
},
|
|
96
|
+
molecule {
|
|
97
|
+
molecularHash,
|
|
98
|
+
bundleHash,
|
|
99
|
+
cellSlug,
|
|
100
|
+
status,
|
|
101
|
+
createdAt,
|
|
102
|
+
atoms {
|
|
103
|
+
position,
|
|
104
|
+
walletAddress,
|
|
105
|
+
isotope,
|
|
106
|
+
tokenSlug,
|
|
107
|
+
value,
|
|
108
|
+
batchId,
|
|
109
|
+
metaType,
|
|
110
|
+
metaId,
|
|
111
|
+
index,
|
|
112
|
+
createdAt,
|
|
113
|
+
otsFragment,
|
|
114
|
+
metasJson
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
paginatorInfo {
|
|
119
|
+
currentPage,
|
|
120
|
+
total
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}`
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Builds a GraphQL-friendly variables object based on input fields
|
|
128
|
+
*/
|
|
129
|
+
static createVariables({
|
|
130
|
+
metaType = null,
|
|
131
|
+
metaId = null,
|
|
132
|
+
key = null,
|
|
133
|
+
value = null,
|
|
134
|
+
keys = null,
|
|
135
|
+
values = null,
|
|
136
|
+
atomValues = null,
|
|
137
|
+
latest = null,
|
|
138
|
+
filter = null,
|
|
139
|
+
queryArgs = null,
|
|
140
|
+
countBy = null,
|
|
141
|
+
cellSlug = null
|
|
142
|
+
}: {
|
|
143
|
+
metaType?: string | string[] | null
|
|
144
|
+
metaId?: string | string[] | null
|
|
145
|
+
key?: string | null
|
|
146
|
+
value?: string | null
|
|
147
|
+
keys?: string[] | null
|
|
148
|
+
values?: string[] | null
|
|
149
|
+
atomValues?: string[] | null
|
|
150
|
+
latest?: boolean | null
|
|
151
|
+
filter?: any[] | null
|
|
152
|
+
queryArgs?: any | null
|
|
153
|
+
countBy?: string | null
|
|
154
|
+
cellSlug?: string | string[] | null
|
|
155
|
+
} = {}): Record<string, any> {
|
|
156
|
+
const variables: Record<string, any> = {}
|
|
157
|
+
|
|
158
|
+
if (atomValues) {
|
|
159
|
+
variables.atomValues = atomValues
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (keys) {
|
|
163
|
+
variables.keys = keys
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (values) {
|
|
167
|
+
variables.values = values
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (metaType) {
|
|
171
|
+
variables.metaTypes = typeof metaType === 'string' ? [metaType] : metaType
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (metaId) {
|
|
175
|
+
variables.metaIds = typeof metaId === 'string' ? [metaId] : metaId
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (cellSlug) {
|
|
179
|
+
variables.cellSlugs = typeof cellSlug === 'string' ? [cellSlug] : cellSlug
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (countBy) {
|
|
183
|
+
variables.countBy = countBy
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (filter) {
|
|
187
|
+
variables.filter = filter
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (key && value) {
|
|
191
|
+
variables.filter = variables.filter || []
|
|
192
|
+
variables.filter.push({
|
|
193
|
+
key,
|
|
194
|
+
value,
|
|
195
|
+
comparison: '='
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
variables.latest = latest === true
|
|
200
|
+
|
|
201
|
+
if (queryArgs) {
|
|
202
|
+
if (typeof queryArgs.limit === 'undefined' || queryArgs.limit === 0) {
|
|
203
|
+
queryArgs.limit = '*'
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
variables.queryArgs = queryArgs
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return variables
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Returns a Response object
|
|
214
|
+
*/
|
|
215
|
+
override createResponse(json: any): ResponseMetaTypeViaMolecule {
|
|
216
|
+
return new ResponseMetaTypeViaMolecule({
|
|
217
|
+
query: this,
|
|
218
|
+
json
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -64,8 +64,8 @@ export default class QueryWalletList extends Query {
|
|
|
64
64
|
constructor(graphQLClient: GraphQLClient, knishIOClient: KnishIOClient) {
|
|
65
65
|
super(graphQLClient, knishIOClient)
|
|
66
66
|
|
|
67
|
-
this.$__query = gql`query( $bundleHash: String, $
|
|
68
|
-
Wallet( bundleHash: $bundleHash,
|
|
67
|
+
this.$__query = gql`query( $bundleHash: String, $token: String ) {
|
|
68
|
+
Wallet( bundleHash: $bundleHash, token: $token ) {
|
|
69
69
|
address,
|
|
70
70
|
bundleHash,
|
|
71
71
|
token {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Powered by Knish.IO: Connecting a Decentralized World
|
|
3
|
+
|
|
4
|
+
Please visit https://github.com/WishKnish/KnishIO-Client-TS for information.
|
|
5
|
+
|
|
6
|
+
License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import ResponseProposeMolecule from './ResponseProposeMolecule'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Response for append requests via A-isotope
|
|
13
|
+
* Matches JavaScript SDK ResponseAppendRequest implementation exactly
|
|
14
|
+
*/
|
|
15
|
+
export default class ResponseAppendRequest extends ResponseProposeMolecule {
|
|
16
|
+
|
|
17
|
+
}
|
|
@@ -77,7 +77,10 @@ export default class ResponseBalance extends Response {
|
|
|
77
77
|
* Matches JavaScript SDK payload() method exactly
|
|
78
78
|
*/
|
|
79
79
|
override payload(): Wallet | null {
|
|
80
|
-
const
|
|
80
|
+
const balanceData = this.data() as any
|
|
81
|
+
|
|
82
|
+
// Balance query returns an array, get the first result
|
|
83
|
+
const walletData = Array.isArray(balanceData) ? balanceData[0] : balanceData
|
|
81
84
|
|
|
82
85
|
if (!walletData || !walletData.bundleHash || !walletData.tokenSlug) {
|
|
83
86
|
return null
|
|
@@ -102,7 +105,9 @@ export default class ResponseBalance extends Response {
|
|
|
102
105
|
}): Wallet {
|
|
103
106
|
let wallet: Wallet
|
|
104
107
|
|
|
105
|
-
|
|
108
|
+
// Handle null, undefined, or empty string positions
|
|
109
|
+
// Empty positions occur for shadow wallets created before this fix
|
|
110
|
+
if (!data.position) {
|
|
106
111
|
wallet = Wallet.create({
|
|
107
112
|
bundle: data.bundleHash,
|
|
108
113
|
token: data.tokenSlug,
|
|
@@ -144,7 +149,7 @@ export default class ResponseBalance extends Response {
|
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
// Set balance and other properties
|
|
147
|
-
wallet.balance =
|
|
152
|
+
wallet.balance = String(data.amount != null ? data.amount : 0)
|
|
148
153
|
wallet.pubkey = data.pubkey
|
|
149
154
|
wallet.createdAt = data.createdAt
|
|
150
155
|
|
|
@@ -93,7 +93,7 @@ export default class ResponseContinuId extends Response {
|
|
|
93
93
|
wallet.batchId = continuId.batchId
|
|
94
94
|
wallet.characters = continuId.characters
|
|
95
95
|
wallet.pubkey = continuId.pubkey
|
|
96
|
-
wallet.balance = continuId.amount
|
|
96
|
+
wallet.balance = String(continuId.amount != null ? continuId.amount : 0)
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
return wallet
|
|
@@ -72,37 +72,50 @@ export default class ResponseMetaType extends Response {
|
|
|
72
72
|
})
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Extracts payload from metaData object
|
|
77
|
+
*/
|
|
78
|
+
private extractPayload(metaData: any): any {
|
|
79
|
+
return {
|
|
80
|
+
instances: metaData?.instances || [],
|
|
81
|
+
instanceCount: metaData?.instanceCount || [],
|
|
82
|
+
paginatorInfo: metaData?.paginatorInfo || {}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
75
86
|
/**
|
|
76
87
|
* Returns meta type instance results
|
|
77
|
-
*
|
|
88
|
+
* Handles various response formats from server:
|
|
89
|
+
* - Array of results (normal case)
|
|
90
|
+
* - Single object (filtered queries)
|
|
91
|
+
* - null/undefined (no results)
|
|
92
|
+
* - Empty array (no matching data)
|
|
78
93
|
*/
|
|
79
94
|
override payload(): any | null {
|
|
80
95
|
const metaTypeData = this.data()
|
|
81
96
|
|
|
82
|
-
|
|
97
|
+
// Handle null/undefined responses
|
|
98
|
+
if (metaTypeData === null || metaTypeData === undefined) {
|
|
83
99
|
return null
|
|
84
100
|
}
|
|
85
101
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
response.instances = metaData.instances
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (metaData.instanceCount) {
|
|
99
|
-
response.instanceCount = metaData.instanceCount
|
|
102
|
+
// Handle array response (expected format)
|
|
103
|
+
if (Array.isArray(metaTypeData)) {
|
|
104
|
+
if (metaTypeData.length === 0) {
|
|
105
|
+
// Return empty structure instead of null for empty results
|
|
106
|
+
return this.extractPayload(null)
|
|
107
|
+
}
|
|
108
|
+
// Get last element without mutating the array
|
|
109
|
+
const metaData = metaTypeData[metaTypeData.length - 1]
|
|
110
|
+
return this.extractPayload(metaData)
|
|
100
111
|
}
|
|
101
112
|
|
|
102
|
-
|
|
103
|
-
|
|
113
|
+
// Handle single object response (some filtered queries)
|
|
114
|
+
if (typeof metaTypeData === 'object') {
|
|
115
|
+
return this.extractPayload(metaTypeData)
|
|
104
116
|
}
|
|
105
117
|
|
|
106
|
-
return
|
|
118
|
+
// Unknown format, return null
|
|
119
|
+
return null
|
|
107
120
|
}
|
|
108
121
|
}
|
|
@@ -0,0 +1,224 @@
|
|
|
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-TS for information.
|
|
45
|
+
|
|
46
|
+
License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
import type Query from '../query/Query'
|
|
50
|
+
import Response from './Response'
|
|
51
|
+
import CheckMolecule from '../libraries/CheckMolecule'
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Response for MetaType queries via Molecule data.
|
|
55
|
+
*
|
|
56
|
+
* Instead of relying solely on the instance-level `metas` field,
|
|
57
|
+
* this response can extract metadata from molecule atoms' `metasJson`,
|
|
58
|
+
* and provides cryptographic integrity verification via `verifyIntegrity()`.
|
|
59
|
+
*/
|
|
60
|
+
export default class ResponseMetaTypeViaMolecule extends Response {
|
|
61
|
+
/**
|
|
62
|
+
* Class constructor
|
|
63
|
+
*/
|
|
64
|
+
constructor({
|
|
65
|
+
query,
|
|
66
|
+
json
|
|
67
|
+
}: {
|
|
68
|
+
query: Query
|
|
69
|
+
json: any
|
|
70
|
+
}) {
|
|
71
|
+
super({
|
|
72
|
+
query,
|
|
73
|
+
json,
|
|
74
|
+
dataKey: 'data.MetaTypeViaAtom'
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Extracts metas from a molecule's atoms' metasJson for a specific instance.
|
|
80
|
+
* Filters atoms by matching metaType and metaId, then parses metasJson.
|
|
81
|
+
*/
|
|
82
|
+
static extractMetasFromMolecule(
|
|
83
|
+
molecule: any,
|
|
84
|
+
metaType: string,
|
|
85
|
+
metaId: string
|
|
86
|
+
): Array<{
|
|
87
|
+
molecularHash: string
|
|
88
|
+
position: string
|
|
89
|
+
key: string
|
|
90
|
+
value: string
|
|
91
|
+
createdAt: string
|
|
92
|
+
}> {
|
|
93
|
+
if (!molecule || !molecule.atoms) {
|
|
94
|
+
return []
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const metas: Array<{
|
|
98
|
+
molecularHash: string
|
|
99
|
+
position: string
|
|
100
|
+
key: string
|
|
101
|
+
value: string
|
|
102
|
+
createdAt: string
|
|
103
|
+
}> = []
|
|
104
|
+
|
|
105
|
+
for (const atom of molecule.atoms) {
|
|
106
|
+
if (atom.metaType !== metaType || atom.metaId !== metaId) {
|
|
107
|
+
continue
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!atom.metasJson) {
|
|
111
|
+
continue
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let parsed: any
|
|
115
|
+
try {
|
|
116
|
+
parsed = JSON.parse(atom.metasJson)
|
|
117
|
+
if (!Array.isArray(parsed)) {
|
|
118
|
+
continue
|
|
119
|
+
}
|
|
120
|
+
} catch (e) {
|
|
121
|
+
continue
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
for (const entry of parsed) {
|
|
125
|
+
metas.push({
|
|
126
|
+
molecularHash: molecule.molecularHash,
|
|
127
|
+
position: atom.position,
|
|
128
|
+
key: entry.key,
|
|
129
|
+
value: entry.value,
|
|
130
|
+
createdAt: atom.createdAt
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return metas
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Returns meta type instance results with metas synthesized from molecule data.
|
|
140
|
+
* Produces the same payload format as ResponseMetaType and ResponseMetaTypeViaAtom:
|
|
141
|
+
* { instances, instanceCount, paginatorInfo }
|
|
142
|
+
*/
|
|
143
|
+
override payload(): any | null {
|
|
144
|
+
const metaTypeData = this.data()
|
|
145
|
+
|
|
146
|
+
if (!metaTypeData || metaTypeData.length === 0) {
|
|
147
|
+
return null
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const response: any = {
|
|
151
|
+
instances: {},
|
|
152
|
+
instanceCount: {},
|
|
153
|
+
paginatorInfo: {}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const metaData = metaTypeData.pop()
|
|
157
|
+
|
|
158
|
+
if (metaData.instances) {
|
|
159
|
+
response.instances = metaData.instances.map((instance: any) => {
|
|
160
|
+
// Prefer server-filtered metas when available
|
|
161
|
+
let metas = instance.metas
|
|
162
|
+
if (!metas || metas.length === 0) {
|
|
163
|
+
// Fallback: synthesize from molecule atoms' metasJson
|
|
164
|
+
metas = ResponseMetaTypeViaMolecule.extractMetasFromMolecule(
|
|
165
|
+
instance.molecule,
|
|
166
|
+
instance.metaType,
|
|
167
|
+
instance.metaId
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
...instance,
|
|
173
|
+
metas
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (metaData.instanceCount) {
|
|
179
|
+
response.instanceCount = metaData.instanceCount
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (metaData.paginatorInfo) {
|
|
183
|
+
response.paginatorInfo = metaData.paginatorInfo
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return response
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Verifies the cryptographic integrity of all molecules associated
|
|
191
|
+
* with meta instances in this response.
|
|
192
|
+
*/
|
|
193
|
+
verifyIntegrity(): {
|
|
194
|
+
verified: boolean
|
|
195
|
+
molecules: Array<{
|
|
196
|
+
molecularHash: string | null
|
|
197
|
+
verified: boolean
|
|
198
|
+
error: string | null
|
|
199
|
+
}>
|
|
200
|
+
} {
|
|
201
|
+
const results: Array<{
|
|
202
|
+
molecularHash: string | null
|
|
203
|
+
verified: boolean
|
|
204
|
+
error: string | null
|
|
205
|
+
}> = []
|
|
206
|
+
const metaTypeData = this.data()
|
|
207
|
+
|
|
208
|
+
if (!metaTypeData || metaTypeData.length === 0) {
|
|
209
|
+
return { verified: true, molecules: results }
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const instances = metaTypeData[metaTypeData.length - 1]?.instances || []
|
|
213
|
+
|
|
214
|
+
for (const instance of instances) {
|
|
215
|
+
if (!instance.molecule) continue
|
|
216
|
+
results.push(CheckMolecule.verifyFromServerData(instance.molecule))
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
verified: results.length === 0 || results.every((r: any) => r.verified),
|
|
221
|
+
molecules: results
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Powered by Knish.IO: Connecting a Decentralized World
|
|
3
|
+
|
|
4
|
+
Please visit https://github.com/WishKnish/KnishIO-Client-TS for information.
|
|
5
|
+
|
|
6
|
+
License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import ResponseProposeMolecule from './ResponseProposeMolecule'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Response for peer registration via P-isotope
|
|
13
|
+
* Matches JavaScript SDK ResponsePeering implementation exactly
|
|
14
|
+
*/
|
|
15
|
+
export default class ResponsePeering extends ResponseProposeMolecule {
|
|
16
|
+
|
|
17
|
+
}
|
|
@@ -75,13 +75,43 @@ export default class ResponseRequestAuthorization extends ResponseProposeMolecul
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
|
-
* Returns
|
|
79
|
-
* Matches JavaScript SDK time method exactly
|
|
78
|
+
* Returns raw time value from payload
|
|
80
79
|
*/
|
|
81
80
|
time(): string {
|
|
82
81
|
return this.payloadKey('time')
|
|
83
82
|
}
|
|
84
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Returns the expiration timestamp as Unix seconds.
|
|
86
|
+
* Handles both server formats:
|
|
87
|
+
* - PHP server: time = lifetime in ms, expiresAt = Unix timestamp in payload
|
|
88
|
+
* - Rust server: time = Unix timestamp in seconds
|
|
89
|
+
*/
|
|
90
|
+
expiresAt(): number {
|
|
91
|
+
// Try the explicit expiresAt payload key first (PHP server provides this)
|
|
92
|
+
try {
|
|
93
|
+
const ea = this.payloadKey('expiresAt')
|
|
94
|
+
if (ea) {
|
|
95
|
+
return Number(ea)
|
|
96
|
+
}
|
|
97
|
+
} catch (_e) {
|
|
98
|
+
// Not available in payload, fall back
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Use time field with heuristic detection
|
|
102
|
+
const timeValue = Number(this.time())
|
|
103
|
+
|
|
104
|
+
// If timeValue looks like a valid Unix timestamp (>= year 2020), use directly
|
|
105
|
+
// Rust server sets time = Unix timestamp in seconds
|
|
106
|
+
if (timeValue >= 1577836800) {
|
|
107
|
+
return timeValue
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Otherwise, time is a lifetime in milliseconds (PHP server format)
|
|
111
|
+
// Convert to Unix timestamp: now_seconds + lifetime_seconds
|
|
112
|
+
return Math.floor(Date.now() / 1000) + Math.floor(timeValue / 1000)
|
|
113
|
+
}
|
|
114
|
+
|
|
85
115
|
/**
|
|
86
116
|
* Returns encryption info
|
|
87
117
|
* Matches JavaScript SDK encrypt method exactly
|