Skip to content

Commit b027efd

Browse files
authored
Merge pull request #1485 from Phala-Network/jssdk-random-improve
JSSDK: Preload metadata in `getClient` & bugfix
2 parents e8f0cfa + f3be121 commit b027efd

File tree

8 files changed

+57
-9
lines changed

8 files changed

+57
-9
lines changed

frontend/packages/sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@phala/sdk",
3-
"version": "0.5.7",
3+
"version": "0.5.8",
44
"description": "Phala Phat Contract JS SDK",
55
"license": "Apache-2.0",
66
"author": [

frontend/packages/sdk/src/OnChainRegistry.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ export class OnChainRegistry {
138138
pruntimeURL: options.pruntimeURL,
139139
}
140140
await instance.connect(workerInfo)
141+
} else if (options.clusterId && !options.strategy) {
142+
await instance.connect({
143+
clusterId: options.clusterId,
144+
strategy: 'ack-first',
145+
} as StrategicWorkerInfo)
141146
} else if (options.strategy) {
142147
await instance.connect({
143148
clusterId: options.clusterId,

frontend/packages/sdk/src/contracts/PinkBlueprint.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ export class PinkBlueprintPromise {
251251
throw new Error('Method not found')
252252
}
253253
return withMeta(meta[0], (options: PinkBlueprintSendOptions, ...arags: unknown[]) => {
254-
return this.#send(prop as string, options, ...arags)
254+
return this._send(prop as string, options, ...arags)
255255
})
256256
},
257257
}
@@ -356,7 +356,7 @@ export class PinkBlueprintPromise {
356356
}
357357
}
358358

359-
async #send(constructorOrId: string, options: PinkBlueprintSendOptions, ...args: unknown[]) {
359+
private async _send(constructorOrId: string, options: PinkBlueprintSendOptions, ...args: unknown[]) {
360360
const { cert: userCert, ...rest } = options
361361
const txOptions: PinkBlueprintOptions = {
362362
gasLimit: options.gasLimit,

frontend/packages/sdk/src/contracts/PinkContract.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ export class PinkContractPromise<
308308
throw new Error('Method not found')
309309
}
310310
return withMeta(meta[0], (options: PinkContractSendOptions, ...arags: unknown[]) => {
311-
return this.#send(prop as string, options, ...arags)
311+
return this._send(prop as string, options, ...arags)
312312
})
313313
},
314314
}
@@ -453,7 +453,7 @@ export class PinkContractPromise<
453453
})
454454
}
455455

456-
async #send(messageOrId: string, options: PinkContractSendOptions, ...args: unknown[]) {
456+
private async _send(messageOrId: string, options: PinkContractSendOptions, ...args: unknown[]) {
457457
const { cert: userCert, ...rest } = options
458458
const txOptions: PinkContractOptions = {
459459
gasLimit: options.gasLimit,

frontend/packages/sdk/src/factory_functions.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,34 @@
11
import { ApiPromise, Keyring, WsProvider } from '@polkadot/api'
22
import type { AccountId } from '@polkadot/types/interfaces'
3+
import type { HexString } from '@polkadot/util/types'
34
import { cryptoWaitReady } from '@polkadot/util-crypto'
45
import { PinkContractPromise } from './contracts/PinkContract'
56
import { PinkLoggerContractPromise } from './contracts/PinkLoggerContract'
67
import { type CreateOptions, OnChainRegistry } from './OnChainRegistry'
78
import { options } from './options'
89
import createPruntimeClient from './pruntime/createPruntimeClient'
910
import type { AbiLike } from './types'
11+
import { type LiteralRpc, fetchMetadata } from './utils/fetchMetadata'
1012

1113
export type GetClientOptions = {
12-
transport: string | WsProvider
14+
transport: LiteralRpc | WsProvider
15+
16+
// Provides metadata instead loading via RPC when initializing the client.
17+
// It's optional since if the RPC under the phala.network domain, we will
18+
// try to preload the metadata via HTTP unless the `noPreloadMetadata` is
19+
// set to true.
20+
metadata?: Record<string, HexString>
21+
noPreloadMetadata?: boolean
1322
} & CreateOptions
1423

1524
export async function getClient(opts: GetClientOptions): Promise<OnChainRegistry> {
16-
const { transport, ...rest } = opts
25+
const { transport, metadata: _metadata, noPreloadMetadata, ...rest } = opts
1726
const provider = typeof transport === 'string' ? new WsProvider(transport) : transport
18-
const api = await ApiPromise.create(options({ provider, noInitWarn: true }))
27+
let metadata = _metadata
28+
if (typeof transport === 'string' && !metadata && transport.indexOf('phala.network/') !== -1 && !noPreloadMetadata) {
29+
metadata = await fetchMetadata(transport)
30+
}
31+
const api = await ApiPromise.create(options({ provider, noInitWarn: true, metadata }))
1932
return await OnChainRegistry.create(api, rest)
2033
}
2134

frontend/packages/sdk/src/ha/ack-first.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export function ackFirst() {
4141
try {
4242
return await Promise.any(pairs.map(([workerId, endpoint]) => ack(workerId, endpoint)))
4343
} catch (_err) {
44-
throw new Error('No worker available.')
44+
throw new Error(`No worker available: ${_err}`)
4545
}
4646
}
4747
}

frontend/packages/sdk/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export { ackFirst } from './ha/ack-first'
1717
export * from './ha/periodicity-checker'
1818
export * from './ha/fixture'
1919
export * from './factory_functions'
20+
export * from './utils/fetchMetadata'
2021

2122
export const pruntimeRpc = pruntime_rpc
2223
export type PhactoryAPI = pruntime_rpc.PhactoryAPI
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import fetch from 'cross-fetch'
2+
3+
async function requestRpc(http: string, body: string) {
4+
return fetch(http, {
5+
method: 'POST',
6+
body,
7+
headers: { 'content-type': 'application/json' },
8+
}).then((resp) => resp.json())
9+
}
10+
11+
export type LiteralRpc = `ws://${string}` | `wss://${string}`
12+
13+
export async function fetchMetadata(rpc: LiteralRpc) {
14+
const http = rpc
15+
.replace('wss://', 'https://')
16+
.replace('ws://', 'http://')
17+
.replace('ws:/', 'http://')
18+
.replace('wss:/', 'https://')
19+
const [blockHashResp, specResp, metadataResp] = await Promise.all([
20+
requestRpc(http, '{"id":1,"jsonrpc":"2.0","method":"chain_getBlockHash","params":[0]}'),
21+
requestRpc(http, '{"id":2,"jsonrpc":"2.0","method":"state_getRuntimeVersion","params":[]}'),
22+
requestRpc(http, '{"id":3,"jsonrpc":"2.0","method":"state_getMetadata","params":[]}'),
23+
])
24+
const id = `${blockHashResp.result}-${specResp.result.specVersion}`
25+
26+
return {
27+
[id]: metadataResp.result,
28+
}
29+
}

0 commit comments

Comments
 (0)