1
- import {
2
- BytesLike ,
3
- arrayify ,
4
- hexlify ,
5
- isBytesLike ,
6
- } from '@ethersproject/bytes' ;
7
1
import * as cbor from 'cborg' ;
2
+ import { BytesLike , isBytesLike , hexlify , getBytes } from 'ethers' ;
8
3
import deoxysii from '@oasisprotocol/deoxysii' ;
9
- import { IncomingMessage } from 'http' ;
10
4
import { sha512_256 } from 'js-sha512' ;
11
5
import nacl , { BoxKeyPair } from 'tweetnacl' ;
12
6
import { Promisable } from 'type-fest' ;
13
7
14
- import { CallError , NETWORKS , OASIS_CALL_DATA_PUBLIC_KEY } from './index.js' ;
8
+ import { CallError } from './index.js' ;
15
9
16
10
export enum Kind {
17
11
Plain = 0 ,
@@ -66,7 +60,7 @@ export abstract class Cipher {
66
60
throw new Error ( 'Attempted to sign tx having non-byteslike data.' ) ;
67
61
}
68
62
if ( plaintext . length === 0 ) return ; // Txs without data are just balance transfers, and all data in those is public.
69
- const { data, nonce } = await this . encryptCallData ( arrayify ( plaintext ) ) ;
63
+ const { data, nonce } = await this . encryptCallData ( getBytes ( plaintext ) ) ;
70
64
const [ format , pk ] = await Promise . all ( [ this . kind , this . publicKey ] ) ;
71
65
const body = pk . length && nonce . length ? { pk, nonce, data } : data ;
72
66
if ( format === Kind . Plain ) return { body } ;
@@ -114,7 +108,7 @@ export abstract class Cipher {
114
108
/** Decrypts the data contained within a hex-encoded serialized envelope. */
115
109
public async decryptEncoded ( callResult : BytesLike ) : Promise < string > {
116
110
return hexlify (
117
- await this . decryptCallResult ( cbor . decode ( arrayify ( callResult ) ) ) ,
111
+ await this . decryptCallResult ( cbor . decode ( getBytes ( callResult ) ) ) ,
118
112
) ;
119
113
}
120
114
@@ -126,10 +120,10 @@ export abstract class Cipher {
126
120
}
127
121
if ( res . fail ) throw new CallError ( formatFailure ( res . fail ) , res . fail ) ;
128
122
if ( res . ok && ( typeof res . ok === 'string' || res . ok instanceof Uint8Array ) )
129
- return arrayify ( res . ok ) ;
123
+ return getBytes ( res . ok ) ;
130
124
const { nonce, data } = ( res . ok as AeadEnvelope ) ?? res . unknown ;
131
125
const inner = cbor . decode ( await this . decrypt ( nonce , data ) ) ;
132
- if ( inner . ok ) return arrayify ( inner . ok ) ;
126
+ if ( inner . ok ) return getBytes ( inner . ok ) ;
133
127
if ( inner . fail ) throw new CallError ( formatFailure ( inner . fail ) , inner . fail ) ;
134
128
throw new CallError (
135
129
`Unexpected inner call result: ${ JSON . stringify ( inner ) } ` ,
@@ -184,18 +178,15 @@ export class X25519DeoxysII extends Cipher {
184
178
/** Creates a new cipher using an ephemeral keypair stored in memory. */
185
179
static ephemeral ( peerPublicKey : BytesLike ) : X25519DeoxysII {
186
180
const keypair = nacl . box . keyPair ( ) ;
187
- return new X25519DeoxysII (
188
- keypair ,
189
- arrayify ( peerPublicKey , { allowMissingPrefix : true } ) ,
190
- ) ;
181
+ return new X25519DeoxysII ( keypair , getBytes ( peerPublicKey ) ) ;
191
182
}
192
183
193
184
static fromSecretKey (
194
185
secretKey : BytesLike ,
195
186
peerPublicKey : BytesLike ,
196
187
) : X25519DeoxysII {
197
- const keypair = nacl . box . keyPair . fromSecretKey ( arrayify ( secretKey ) ) ;
198
- return new X25519DeoxysII ( keypair , arrayify ( peerPublicKey ) ) ;
188
+ const keypair = nacl . box . keyPair . fromSecretKey ( getBytes ( secretKey ) ) ;
189
+ return new X25519DeoxysII ( keypair , getBytes ( peerPublicKey ) ) ;
199
190
}
200
191
201
192
public constructor ( keypair : BoxKeyPair , peerPublicKey : Uint8Array ) {
@@ -277,78 +268,3 @@ export function lazy(generator: () => Promisable<Cipher>): Cipher {
277
268
} ,
278
269
) as Cipher ;
279
270
}
280
-
281
- export async function fetchRuntimePublicKeyByChainId (
282
- chainId : number ,
283
- opts ?: { fetch ?: typeof fetch } ,
284
- ) : Promise < Uint8Array > {
285
- const { defaultGateway : gatewayUrl } = NETWORKS [ chainId ] ;
286
- if ( ! gatewayUrl )
287
- throw new Error (
288
- `Unable to fetch runtime public key for network with unknown ID: ${ chainId } .` ,
289
- ) ;
290
- const fetchImpl = globalThis ?. fetch ?? opts ?. fetch ;
291
- const res = await ( fetchImpl
292
- ? fetchRuntimePublicKeyBrowser ( gatewayUrl , fetchImpl )
293
- : fetchRuntimePublicKeyNode ( gatewayUrl ) ) ;
294
- return arrayify ( res . result . key ) ;
295
- }
296
-
297
- type CallDataPublicKeyResponse = {
298
- result : { key : string ; checksum : string ; signature : string } ;
299
- } ;
300
-
301
- async function fetchRuntimePublicKeyNode (
302
- gwUrl : string ,
303
- ) : Promise < CallDataPublicKeyResponse > {
304
- // Import http or https, depending on the URI scheme.
305
- const https = await import ( /* webpackIgnore: true */ gwUrl . split ( ':' ) [ 0 ] ) ;
306
-
307
- const body = makeCallDataPublicKeyBody ( ) ;
308
- return new Promise ( ( resolve , reject ) => {
309
- const opts = {
310
- method : 'POST' ,
311
- headers : {
312
- 'content-type' : 'application/json' ,
313
- 'content-length' : body . length ,
314
- } ,
315
- } ;
316
- const req = https . request ( gwUrl , opts , ( res : IncomingMessage ) => {
317
- const chunks : Buffer [ ] = [ ] ;
318
- res . on ( 'error' , ( err ) => reject ( err ) ) ;
319
- res . on ( 'data' , ( chunk ) => chunks . push ( chunk ) ) ;
320
- res . on ( 'end' , ( ) => {
321
- resolve ( JSON . parse ( Buffer . concat ( chunks ) . toString ( ) ) ) ;
322
- } ) ;
323
- } ) ;
324
- req . on ( 'error' , ( err : Error ) => reject ( err ) ) ;
325
- req . write ( body ) ;
326
- req . end ( ) ;
327
- } ) ;
328
- }
329
-
330
- async function fetchRuntimePublicKeyBrowser (
331
- gwUrl : string ,
332
- fetchImpl : typeof fetch ,
333
- ) : Promise < CallDataPublicKeyResponse > {
334
- const res = await fetchImpl ( gwUrl , {
335
- method : 'POST' ,
336
- headers : {
337
- 'content-type' : 'application/json' ,
338
- } ,
339
- body : makeCallDataPublicKeyBody ( ) ,
340
- } ) ;
341
- if ( ! res . ok ) {
342
- throw new CallError ( 'Failed to fetch runtime public key.' , res ) ;
343
- }
344
- return await res . json ( ) ;
345
- }
346
-
347
- function makeCallDataPublicKeyBody ( ) : string {
348
- return JSON . stringify ( {
349
- jsonrpc : '2.0' ,
350
- id : Math . floor ( Math . random ( ) * 1e9 ) ,
351
- method : OASIS_CALL_DATA_PUBLIC_KEY ,
352
- params : [ ] ,
353
- } ) ;
354
- }
0 commit comments