1010 */
1111
1212import type { KeyPair } from '@iroha2/crypto-core'
13- import { datamodel , signTransaction , transactionHash } from '@iroha2/data-model'
14- import { type Schema as DataModelSchema } from '@iroha2/data-model-schema'
13+ import { types , signTransaction , transactionHash , codecOf } from '@iroha2/data-model'
14+ import type { Schema as DataModelSchema } from '@iroha2/data-model-schema'
1515import defer from 'p-defer'
16- import type { z } from 'zod'
1716
1817import type { Except , RequiredKeysOf } from 'type-fest'
1918import type { SetupBlocksStreamParams } from './blocks-stream'
@@ -30,22 +29,22 @@ import {
3029import type { SetupEventsParams } from './events'
3130import { setupEvents } from './events'
3231import type { IsomorphicWebSocketAdapter } from './web-socket/types'
33- import { type QueryOutput , type QueryPayload , doRequest } from './query'
32+ import { type QueryOutput , type QueryParams , doRequest } from './query'
3433
3534type Fetch = typeof fetch
3635
3736export interface SetPeerConfigParams {
3837 logger : {
39- level : datamodel . LogLevel
38+ level : types . LogLevel
4039 }
4140}
4241
4342export interface CreateClientParams {
4443 http : Fetch
4544 ws : IsomorphicWebSocketAdapter
4645 toriiURL : string
47- chain : z . input < typeof datamodel . ChainId$schema >
48- accountDomain : z . input < typeof datamodel . DomainId$schema >
46+ chain : types . ChainId
47+ accountDomain : types . DomainId
4948 accountKeyPair : KeyPair
5049}
5150
@@ -56,7 +55,7 @@ export interface SubmitParams {
5655 */
5756 verify ?: boolean
5857 verifyAbort ?: AbortSignal
59- payload ?: Except < z . input < typeof datamodel . TransactionPayload$schema > , 'chain' | 'authority' | 'instructions' >
58+ payload ?: Except < types . TransactionPayload , 'chain' | 'authority' | 'instructions' >
6059}
6160
6261export class ResponseError extends Error {
@@ -76,9 +75,9 @@ export class ResponseError extends Error {
7675}
7776
7877export class TransactionRejectedError extends Error {
79- public reason : datamodel . TransactionRejectionReason
78+ public reason : types . TransactionRejectionReason
8079
81- public constructor ( reason : datamodel . TransactionRejectionReason ) {
80+ public constructor ( reason : types . TransactionRejectionReason ) {
8281 // TODO: parse reason into a specific message
8382 super ( 'Transaction rejected' )
8483 this . reason = reason
@@ -92,55 +91,55 @@ export class TransactionExpiredError extends Error {
9291}
9392
9493export class QueryValidationError extends Error {
95- public reason : datamodel . ValidationFail
94+ public reason : types . ValidationFail
9695
97- public constructor ( reason : datamodel . ValidationFail ) {
96+ public constructor ( reason : types . ValidationFail ) {
9897 super ( 'Query validation failed' )
9998 this . reason = reason
10099 }
101100}
102101
103102export class Client {
104103 public params : CreateClientParams
104+
105105 // public readonly signer: Signer
106106
107107 public constructor ( params : CreateClientParams ) {
108108 this . params = params
109109 }
110110
111- public accountId ( ) : datamodel . AccountId {
112- return datamodel . AccountId . parse ( {
113- domain : this . params . accountDomain ,
114- signatory : this . params . accountKeyPair . publicKey ( ) ,
115- } )
111+ public accountId ( ) : types . AccountId {
112+ return new types . AccountId (
113+ types . PublicKeyWrap . fromCrypto ( this . params . accountKeyPair . publicKey ( ) ) ,
114+ this . params . accountDomain ,
115+ )
116116 }
117117
118- public async submit ( instructions : z . input < typeof datamodel . Executable$schema > , params ?: SubmitParams ) {
119- const payload = datamodel . TransactionPayload ( {
118+ public async submit ( executable : types . Executable , params ?: SubmitParams ) {
119+ const payload : types . TransactionPayload = {
120120 chain : this . params . chain ,
121121 authority : this . accountId ( ) ,
122- instructions,
122+ instructions : executable ,
123+ creationTime : types . Timestamp . fromDate ( new Date ( ) ) ,
124+ timeToLive : types . NonZero . parse ( 100_000n as types . Duration ) ,
125+ nonce : null ,
126+ metadata : new Map ( ) ,
123127 ...params ?. payload ,
124- } )
128+ }
125129 const tx = signTransaction ( payload , this . params . accountKeyPair . privateKey ( ) )
126130
127131 if ( params ?. verify ) {
128- const hash = transactionHash ( tx ) . payload ( )
132+ const hash = transactionHash ( tx )
129133 const stream = await this . eventsStream ( {
130134 filters : [
131- // TODO: include "status" when Iroha API is fixed about it
132- datamodel . EventFilterBox ( {
133- t : 'Pipeline' ,
134- value : {
135- t : 'Transaction' ,
136- value : {
137- // FIXME: fix data model, allow `null | Hash`
138- hash : { Some : hash } ,
139- // FIXME: Iroha design issue
140- // If I want to filter by "rejected" status, I will also have to include a rejection reason into the
141- // filter. I could imagine users wanting to just watch for rejections with all possible reasons.
142- } ,
143- } ,
135+ types . EventFilterBox . Pipeline . Transaction ( {
136+ hash : types . HashWrap . fromCrypto ( hash ) ,
137+ blockHeight : null ,
138+ // TODO: include "status" when Iroha API is fixed about it
139+ // FIXME: Iroha design issue
140+ // If I want to filter by "rejected" status, I will also have to include a rejection reason into the
141+ // filter. I could imagine users wanting to just watch for rejections with all possible reasons.
142+ status : null ,
144143 } ) ,
145144 ] ,
146145 } )
@@ -179,6 +178,10 @@ export class Client {
179178 }
180179 }
181180
181+ public query < Q extends types . QueryBox > ( query : Q ) : AsyncGenerator < types . QueryOutputMap [ Q [ 'kind' ] ] > { }
182+
183+ public querySingular < Q extends types . SingularQueryBox > ( query : Q ) : Promise < types . SingularQueryOutputMap [ Q [ 'kind' ] ] > { }
184+
182185 // TODO: split to `query` and `querySingle`, make simpler types
183186 /**
184187 * Request data from Iroha using Query API.
@@ -214,10 +217,9 @@ export class Client {
214217 *
215218 * This function is a shortcut to {@link doRequest} with an addition of data stored in the client, i.e. {@link import('./query.ts').RequestBaseParams}.
216219 */
217- public request <
218- Q extends keyof datamodel . QueryOutputMap | keyof datamodel . SingularQueryOutputMap ,
219- P extends QueryPayload < Q > ,
220- > ( ...args : RequiredKeysOf < P > extends never ? [ query : Q , params ?: P ] : [ query : Q , params : P ] ) : QueryOutput < Q > {
220+ public request < Q extends keyof types . QueryOutputMap | keyof types . SingularQueryOutputMap , P extends QueryParams < Q > > (
221+ ...args : RequiredKeysOf < P > extends never ? [ query : Q , params ?: P ] : [ query : Q , params : P ]
222+ ) : QueryOutput < Q > {
221223 return doRequest ( args [ 0 ] , {
222224 ...args [ 1 ] ,
223225 authority : this . accountId ( ) ,
@@ -246,7 +248,7 @@ export class Client {
246248 } )
247249 }
248250
249- public async getStatus ( ) : Promise < datamodel . Status > {
251+ public async getStatus ( ) : Promise < types . Status > {
250252 return getStatus ( this . toriiRequestRequirements )
251253 }
252254
@@ -271,6 +273,24 @@ export class Client {
271273 }
272274}
273275
276+ declare const client : Client
277+
278+ client . query ( types . QueryBox . FindAccounts ( { predicate : types . CompoundPredicate . PASS , query : null } ) )
279+ client . query (
280+ types . QueryBox . FindAccountsWithAsset ( {
281+ query : {
282+ assetDefinition : types . AssetDefinitionId . parse ( 'rose#badland' ) ,
283+ } ,
284+ predicate : types . CompoundPredicate . Atom ( types . AccountPredicateBox . Id . DomainId . Name . EndsWith ( 'land' ) ) ,
285+ } ) ,
286+ )
287+ client . querySingular (
288+ types . SingularQueryBox . FindDomainMetadata ( {
289+ id : types . DomainId . parse ( 'badland' ) ,
290+ key : types . Name . parse ( 'badboy' ) ,
291+ } ) ,
292+ )
293+
274294export interface ToriiHttpParams {
275295 http : Fetch
276296 toriiURL : string
@@ -296,12 +316,12 @@ export async function getHealth({ http, toriiURL }: ToriiHttpParams): Promise<He
296316 return { t : 'ok' }
297317}
298318
299- export async function getStatus ( { http, toriiURL } : ToriiHttpParams ) : Promise < datamodel . Status > {
319+ export async function getStatus ( { http, toriiURL } : ToriiHttpParams ) : Promise < types . Status > {
300320 const response = await http ( toriiURL + ENDPOINT_STATUS , {
301321 headers : { accept : 'application/x-parity-scale' } ,
302322 } )
303323 await ResponseError . assertStatus ( response , 200 )
304- return response . arrayBuffer ( ) . then ( ( buffer ) => datamodel . Status$codec . decode ( new Uint8Array ( buffer ) ) )
324+ return response . arrayBuffer ( ) . then ( ( buffer ) => types . Status$codec . decode ( new Uint8Array ( buffer ) ) )
305325}
306326
307327export async function getMetrics ( { http, toriiURL } : ToriiHttpParams ) {
@@ -321,8 +341,8 @@ export async function setPeerConfig({ http, toriiURL }: ToriiHttpParams, params:
321341 await ResponseError . assertStatus ( response , 202 /* ACCEPTED */ )
322342}
323343
324- export async function submitTransaction ( { http, toriiURL } : ToriiHttpParams , tx : datamodel . SignedTransaction ) {
325- const body = datamodel . SignedTransaction$codec . encode ( tx )
344+ export async function submitTransaction ( { http, toriiURL } : ToriiHttpParams , tx : types . SignedTransaction ) {
345+ const body = codecOf ( types . SignedTransaction ) . encode ( tx )
326346 const response = await http ( toriiURL + ENDPOINT_TRANSACTION , { body, method : 'POST' } )
327347 await ResponseError . assertStatus ( response , 200 )
328348}
0 commit comments