1
1
import { ApiPromise } from '@polkadot/api' ;
2
- import { u8aToHex , hexToU8a , compactAddLength , bufferToU8a , u8aConcat , stringToU8a } from '@polkadot/util' ;
2
+ import { u8aToHex , hexToU8a , compactAddLength , bufferToU8a , u8aConcat } from '@polkadot/util' ;
3
3
import { Codec } from '@polkadot/types/types' ;
4
4
import { TypeRegistry } from '@polkadot/types' ;
5
5
import { Bytes } from '@polkadot/types-codec' ;
6
6
import { IntegrationTestContext , JsonRpcRequest } from './common-types' ;
7
- import { WorkerRpcReturnValue , TrustedCallSigned , Getter , CorePrimitivesIdentity } from 'parachain-api' ;
8
- import { encryptWithTeeShieldingKey , Signer , encryptWithAes , sleep } from './utils' ;
7
+ import type {
8
+ WorkerRpcReturnValue ,
9
+ TrustedCallSigned ,
10
+ Getter ,
11
+ CorePrimitivesIdentity ,
12
+ TrustedGetterSigned ,
13
+ TrustedCall ,
14
+ } from 'parachain-api' ;
15
+ import { encryptWithTeeShieldingKey , Signer , encryptWithAes , sleep , createLitentryMultiSignature } from './utils' ;
9
16
import { aesKey , decodeRpcBytesAsString , keyNonce } from './call' ;
10
17
import { createPublicKey , KeyObject } from 'crypto' ;
11
18
import WebSocketAsPromised from 'websocket-as-promised' ;
12
19
import { H256 , Index } from '@polkadot/types/interfaces' ;
13
- import { blake2AsHex , base58Encode } from '@polkadot/util-crypto' ;
14
- import { createJsonRpcRequest , nextRequestId } from './helpers' ;
20
+ import { blake2AsHex , base58Encode , blake2AsU8a } from '@polkadot/util-crypto' ;
21
+ import { createJsonRpcRequest , nextRequestId , stfErrorToString } from './helpers' ;
15
22
16
23
// Send the request to worker ws
17
24
// we should perform different actions based on the returned status:
@@ -45,6 +52,9 @@ async function sendRequest(
45
52
46
53
if ( res . status . isTrustedOperationStatus && res . status . asTrustedOperationStatus [ 0 ] . isInvalid ) {
47
54
console . log ( 'Rpc trusted operation execution failed, hash: ' , res . value . toHex ( ) ) ;
55
+ const stfError = api . createType ( 'StfError' , res . value ) ;
56
+ const msg = stfErrorToString ( stfError ) ;
57
+ console . log ( 'TrustedOperationStatus error: ' , msg ) ;
48
58
}
49
59
// sending every response we receive from websocket
50
60
if ( onMessageReceived ) onMessageReceived ( res ) ;
@@ -80,27 +90,37 @@ export const createSignedTrustedCall = async (
80
90
mrenclave : string ,
81
91
nonce : Codec ,
82
92
params : any ,
83
- withWrappedBytes = false
93
+ withWrappedBytes = false ,
94
+ withPrefix = false
84
95
) : Promise < TrustedCallSigned > => {
85
96
const [ variant , argType ] = trustedCall ;
86
- const call = parachainApi . createType ( 'TrustedCall' , {
97
+ const call : TrustedCall = parachainApi . createType ( 'TrustedCall' , {
87
98
[ variant ] : parachainApi . createType ( argType , params ) ,
88
99
} ) ;
89
- let payload = Uint8Array . from ( [
90
- ...call . toU8a ( ) ,
91
- ...nonce . toU8a ( ) ,
92
- ...hexToU8a ( mrenclave ) ,
93
- ...hexToU8a ( mrenclave ) , // should be shard, but it's the same as MRENCLAVE in our case
94
- ] ) ;
100
+ let payload : string = blake2AsHex (
101
+ u8aConcat (
102
+ call . toU8a ( ) ,
103
+ nonce . toU8a ( ) ,
104
+ hexToU8a ( mrenclave ) ,
105
+ hexToU8a ( mrenclave ) // should be shard, but it's the same as MRENCLAVE in our case
106
+ ) ,
107
+ 256
108
+ ) ;
109
+
95
110
if ( withWrappedBytes ) {
96
- payload = u8aConcat ( stringToU8a ( ' <Bytes>' ) , payload , stringToU8a ( ' </Bytes>' ) ) ;
111
+ payload = ` <Bytes>${ payload } </Bytes>` ;
97
112
}
98
113
99
- // for bitcoin signature, we expect a hex-encoded `string` without `0x` prefix
100
- const signature = parachainApi . createType ( 'LitentryMultiSignature' , {
101
- [ signer . type ( ) ] : u8aToHex (
102
- await signer . sign ( signer . type ( ) === 'bitcoin' ? u8aToHex ( payload ) . substring ( 2 ) : payload )
103
- ) ,
114
+ if ( withPrefix ) {
115
+ const prefix = getSignatureMessagePrefix ( call ) ;
116
+ const msg = prefix + payload ;
117
+ payload = msg ;
118
+ console . log ( 'Signing message: ' , payload ) ;
119
+ }
120
+
121
+ const signature = await createLitentryMultiSignature ( parachainApi , {
122
+ signer,
123
+ payload,
104
124
} ) ;
105
125
106
126
return parachainApi . createType ( 'TrustedCallSigned' , {
@@ -110,34 +130,44 @@ export const createSignedTrustedCall = async (
110
130
} ) ;
111
131
} ;
112
132
133
+ // See TrustedCall.signature_message_prefix
134
+ function getSignatureMessagePrefix ( call : TrustedCall ) : string {
135
+ if ( call . isLinkIdentity ) {
136
+ return "By linking your identity to our platform, you're taking a step towards a more integrated experience. Please be assured, this process is safe and involves no transactions of your assets. Token: " ;
137
+ }
138
+
139
+ if ( call . isRequestBatchVc ) {
140
+ const [ , , assertions ] = call . asRequestBatchVc ;
141
+ const length = assertions . length ;
142
+
143
+ return `We are going to help you generate ${ length } secure credential${
144
+ length > 1 ? 's' : ''
145
+ } . Please be assured, this process is safe and involves no transactions of your assets. Token: `;
146
+ }
147
+
148
+ return 'Token: ' ;
149
+ }
150
+
113
151
export const createSignedTrustedGetter = async (
114
152
parachainApi : ApiPromise ,
115
153
trustedGetter : [ string , string ] ,
116
154
signer : Signer ,
117
155
params : any
118
- ) => {
156
+ ) : Promise < TrustedGetterSigned > => {
119
157
const [ variant , argType ] = trustedGetter ;
120
158
const getter = parachainApi . createType ( 'TrustedGetter' , {
121
159
[ variant ] : parachainApi . createType ( argType , params ) ,
122
160
} ) ;
123
- const payload = getter . toU8a ( ) ;
161
+ const payload = blake2AsU8a ( getter . toU8a ( ) , 256 ) ;
124
162
125
- let signature ;
126
- if ( signer . type ( ) === 'bitcoin' ) {
127
- const payloadStr = u8aToHex ( payload ) . substring ( 2 ) ;
128
-
129
- signature = parachainApi . createType ( 'LitentryMultiSignature' , {
130
- [ signer . type ( ) ] : u8aToHex ( await signer . sign ( payloadStr ) ) ,
131
- } ) ;
132
- } else {
133
- signature = parachainApi . createType ( 'LitentryMultiSignature' , {
134
- [ signer . type ( ) ] : u8aToHex ( await signer . sign ( payload ) ) ,
135
- } ) ;
136
- }
163
+ let signature = await createLitentryMultiSignature ( parachainApi , {
164
+ signer,
165
+ payload,
166
+ } ) ;
137
167
138
168
return parachainApi . createType ( 'TrustedGetterSigned' , {
139
- getter : getter ,
140
- signature : signature ,
169
+ getter,
170
+ signature,
141
171
} ) ;
142
172
} ;
143
173
@@ -160,7 +190,8 @@ export async function createSignedTrustedCallLinkIdentity(
160
190
validationData : string ,
161
191
web3networks : string ,
162
192
aesKey : string ,
163
- hash : string
193
+ hash : string ,
194
+ options ?: { withWrappedBytes ?: boolean ; withPrefix ?: boolean }
164
195
) {
165
196
return createSignedTrustedCall (
166
197
parachainApi ,
@@ -171,7 +202,9 @@ export async function createSignedTrustedCallLinkIdentity(
171
202
signer ,
172
203
mrenclave ,
173
204
nonce ,
174
- [ primeIdentity . toHuman ( ) , primeIdentity . toHuman ( ) , identity , validationData , web3networks , aesKey , hash ]
205
+ [ primeIdentity . toHuman ( ) , primeIdentity . toHuman ( ) , identity , validationData , web3networks , aesKey , hash ] ,
206
+ options ?. withWrappedBytes ,
207
+ options ?. withPrefix
175
208
) ;
176
209
}
177
210
@@ -207,15 +240,18 @@ export async function createSignedTrustedCallRequestVc(
207
240
primeIdentity : CorePrimitivesIdentity ,
208
241
assertion : string ,
209
242
aesKey : string ,
210
- hash : string
243
+ hash : string ,
244
+ options ?: { withWrappedBytes ?: boolean ; withPrefix ?: boolean }
211
245
) {
212
246
return await createSignedTrustedCall (
213
247
parachainApi ,
214
248
[ 'request_vc' , '(LitentryIdentity, LitentryIdentity, Assertion, Option<RequestAesKey>, H256)' ] ,
215
249
signer ,
216
250
mrenclave ,
217
251
nonce ,
218
- [ primeIdentity . toHuman ( ) , primeIdentity . toHuman ( ) , assertion , aesKey , hash ]
252
+ [ primeIdentity . toHuman ( ) , primeIdentity . toHuman ( ) , assertion , aesKey , hash ] ,
253
+ options ?. withWrappedBytes ,
254
+ options ?. withPrefix
219
255
) ;
220
256
}
221
257
@@ -227,7 +263,8 @@ export async function createSignedTrustedCallRequestBatchVc(
227
263
primeIdentity : CorePrimitivesIdentity ,
228
264
assertion : string ,
229
265
aesKey : string ,
230
- hash : string
266
+ hash : string ,
267
+ options ?: { withWrappedBytes ?: boolean ; withPrefix ?: boolean }
231
268
) {
232
269
return await createSignedTrustedCall (
233
270
parachainApi ,
@@ -238,7 +275,9 @@ export async function createSignedTrustedCallRequestBatchVc(
238
275
signer ,
239
276
mrenclave ,
240
277
nonce ,
241
- [ primeIdentity . toHuman ( ) , primeIdentity . toHuman ( ) , assertion , aesKey , hash ]
278
+ [ primeIdentity . toHuman ( ) , primeIdentity . toHuman ( ) , assertion , aesKey , hash ] ,
279
+ options ?. withWrappedBytes ,
280
+ options ?. withPrefix
242
281
) ;
243
282
}
244
283
@@ -340,8 +379,7 @@ export const sendRequestFromTrustedCall = async (
340
379
) => {
341
380
// construct trusted operation
342
381
const trustedOperation = context . api . createType ( 'TrustedOperation' , { direct_call : call } ) ;
343
- console . log ( 'top: ' , trustedOperation . toJSON ( ) ) ;
344
- console . log ( 'top hash' , blake2AsHex ( trustedOperation . toU8a ( ) ) ) ;
382
+ console . log ( 'trustedOperation: ' , JSON . stringify ( trustedOperation . toHuman ( ) , null , 2 ) ) ;
345
383
// create the request parameter
346
384
const requestParam = await createAesRequest (
347
385
context . api ,
0 commit comments