Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS-SDK: 0.6.x release channel #1492

Draft
wants to merge 101 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
783bbe9
imp(jssdk): supported speicified SS58Prefix when convert ether addres…
Leechael Nov 10, 2023
10a4a37
imp(jssdk): allows to set the message for the pubkey recover sign req…
Leechael Nov 10, 2023
c853dbc
feat(jssdk): createEip712StructedDataSubstrateCall
Leechael Nov 10, 2023
6f78772
imp(jssdk): typing for WalletClient
Leechael Nov 10, 2023
71e2312
feat(jssdk): unstable_WalletClientSigner
Leechael Nov 10, 2023
9318ae5
feat(jssdk): Added signCertificate to unstable_WalletClientSigner
Leechael Nov 10, 2023
25920b4
refactor(jssdk): signers
Leechael Nov 10, 2023
4c21af5
feat(jssdk): made PinkContractPromise works with unstable_WalletClien…
Leechael Nov 10, 2023
d6defbb
refactor(jssdk): rename to provider avoid unecccessary cognition conf…
Leechael Nov 11, 2023
1231537
imp(jssdk): added customize submittable tranform support for Provider…
Leechael Nov 11, 2023
7ffa3bf
feat(jssdk): added adjustStake support for provider
Leechael Nov 11, 2023
cf1bcc5
feat(jssdk): ensure PinkBlueprint, PinkCode, PinkContract supports to…
Leechael Nov 11, 2023
084047c
imp(jssdk): make InkCodeSubmittableResult.waitFinalized more flexiable
Leechael Nov 11, 2023
6aaeafd
chore(jssdk): bump beta version to 0.6.0-nightly-20231114
Leechael Nov 14, 2023
eac9d87
chore: renaming: compactPubkey -> compressedPubkey
Leechael Nov 16, 2023
9a9cdf3
chore(jssdk): bump beta version to 0.6.0-nightly-20231116
Leechael Nov 16, 2023
4d547d7
imp(jssdk): typing for getContract
Leechael Nov 16, 2023
f57b219
imp(jssdk): typing & certificateData cache inside EvmAccountMappingPr…
Leechael Nov 16, 2023
b25e0ff
feat(jssdk): support setup metadata cache with getClient
Leechael Nov 22, 2023
3bf32d7
fix(jssdk): the ttl for signCertificate not works
Leechael Nov 22, 2023
69a06cf
dependencies(jssdk): @polkadot/extension-inject, @polkadot/ui-keyring…
Leechael Nov 22, 2023
d7fb5b4
feat(jssdk): unstable_UIKeyringProvider
Leechael Nov 22, 2023
71f081e
imp(jssdk): provider typing
Leechael Nov 22, 2023
2b148bd
chore(jssdk): set the minimal engine version to node >= 18
Leechael Nov 22, 2023
3448846
chore(jssdk): bump beta version to 0.6.0-nightly-20231122
Leechael Nov 22, 2023
a0dac1a
chore(jssdk): fix linting
Leechael Nov 22, 2023
b2dc7cb
chore(jssdk): bump beta version to 0.6.0-nightly-20231125
Leechael Nov 24, 2023
6900350
fix(jssdk): type inference
Leechael Nov 26, 2023
4191195
chore(jssdk): bump beta version to 0.6.0-nightly-20231127
Leechael Nov 27, 2023
4fe70bd
chore(jssdk): remove unused variable
Leechael Dec 6, 2023
b5b797d
dependencies: update polkadot related packages
Leechael Dec 8, 2023
9a2c52d
chore(jssdk): bump beta version to 0.6.0-20231208
Leechael Dec 8, 2023
5e84d54
feat(jssdk): Added KeyringPairProvider
Leechael Dec 25, 2023
b4b3b06
chore(jssdk): remove unstable_ prefix
Leechael Dec 25, 2023
88c1189
chore(jssdk): move typing declarations
Leechael Dec 25, 2023
682f0d6
feat(jssdk): optional provider for PinkContractPromise
Leechael Dec 25, 2023
60438db
feat(jssdk): the proxy approach q & exec for PinkContractPromise
Leechael Dec 26, 2023
5bb3402
imp(jssdk): caching the proxy object
Leechael Dec 26, 2023
94381ae
feat(jssdk): typing for the q & exec proxy
Leechael Dec 26, 2023
6071661
feat(jssdk): ReMap for PinkContractPromise type hinting
Leechael Dec 26, 2023
96ddba5
chore(jssdk): types for SystemContract
Leechael Dec 26, 2023
a1e8d66
feat(jssdk): redesign the q & exec named arguments design
Leechael Dec 26, 2023
f89fe81
feat(jssdk): added optional provider in getContract function
Leechael Dec 26, 2023
da6ac60
imp(jssdk): typing
Leechael Dec 27, 2023
afd906c
fix(jssdk): the origin not matched in q proxy
Leechael Dec 27, 2023
b9e9256
chore(jssdk): export type SupportedWallet
Leechael Dec 27, 2023
d6597f2
imp(jssdk): expose account from UIKeyringProvider
Leechael Dec 28, 2023
bbe987f
feat(jssdk): added isEvmAccountMappingSupported to OnChainRegistry
Leechael Dec 28, 2023
f411719
fix(jssdk): typing dependencies
Leechael Dec 28, 2023
d81a302
imp(jssdk): prefer returns new instance in withProvider
Leechael Dec 29, 2023
5277a98
fix(jssdk): the type infer of getContract is incorrect
Leechael Dec 29, 2023
0861ab9
fix(jssdk): initialization error
Leechael Dec 29, 2023
519dc28
chore(jssdk):formatting
Leechael Dec 29, 2023
9e912b2
fix(jssdk): type infer for PinkContractSubmittableResult is incorrect
Leechael Dec 29, 2023
5462625
feat(jssdk): expose certificate state from Provider
Leechael Dec 29, 2023
11b65d0
feat(jssdk): added optional waitUntil to PinkContractPromise.exec Proxy
Leechael Dec 30, 2023
be1fe64
imp(sdk): waitUntil -> waitFinalized
Leechael Dec 30, 2023
7e23e1f
feat(jssdk): evm address converter implementation
Leechael Jan 4, 2024
4e71d8b
feat(jssdk): converter function that get evm address from a mapped su…
Leechael Jan 4, 2024
75ad339
chore(jssdk): formatting
Leechael Jan 4, 2024
b38106e
feat(jssdk): choose evm account mapping converter based on runtime co…
Leechael Jan 4, 2024
134b346
fix(jssdk): typing
Leechael Jan 4, 2024
a837add
fix(jssdk): set default value in constructor
Leechael Jan 4, 2024
622dbfc
chore(jssdk): clean up
Leechael Jan 4, 2024
6508cc1
feat(jssdk): EvmAccountMappingProvider: read ss58 prefix from chain
Leechael Jan 5, 2024
f11017a
refactor(jssdk): move account instance out
Leechael Jan 5, 2024
d9939fb
test(jssdk): test case for recoverPubkey
Leechael Jan 5, 2024
b665fb1
refactor(jssdk): better naming & file structure
Leechael Jan 5, 2024
f3c4110
imp(jssdk): AddressConverter can set converter explicitly and support…
Leechael Jan 5, 2024
6c717e1
imp(jssdk): choose converter based on EIP712version
Leechael Jan 5, 2024
9406e45
chore(jssdk): typing
Leechael Jan 5, 2024
0f7fce9
chore(jssdk): formatting & keep linter happy
Leechael Jan 5, 2024
5ba0ca0
chore(jssdk): keep a address encode test for ss58format = 30
Leechael Jan 5, 2024
84c5416
chore(jssdk): bump beta version to 0.6.0-beta.10
Leechael Jan 5, 2024
efd6906
fix(jssdk): fix typing
Leechael Jan 11, 2024
558f233
fix(jssdk): type infer
Leechael Jan 12, 2024
33fc2ad
fix(jssdk): increase the numbers of retrieve error logs for tx error …
Leechael Jan 12, 2024
91571df
fix(jssdk): incorrect default ss58 prefix
Leechael Jan 26, 2024
aed38ed
chore(jssdk): bump beta version to 0.6.0-beta.14
Leechael Jan 26, 2024
46e5cad
feat(jssdk): remove check on PinkContract initialization
Leechael Feb 2, 2024
794fae8
imp(jssdk): added Error in PinkContractPromise when remotePubkey is m…
Leechael Feb 2, 2024
13a2091
imp(jssdk): allows use HttpTransport with getClient
Leechael Feb 22, 2024
4941d92
chore(jssdk): bump beta version to 0.6.0-beta.15
Leechael Feb 22, 2024
5a50dc6
refactor(jssdk): WorkerAgreementKey
Leechael Feb 23, 2024
e3c3fa5
refactor(jssdk): toAbi
Leechael Feb 23, 2024
bd8c7b4
refactor(jssdk): pinkQuery
Leechael Feb 23, 2024
63d7ed0
refactor(jssdk): pinkQuery returns InkResponse instead raw payload
Leechael Feb 23, 2024
7e3074b
feat(jssdk): sendPinkQuery
Leechael Feb 23, 2024
ab56ef4
feat(jssdk): estimateContract
Leechael Feb 23, 2024
7e8ef09
feat(jssdk): sendPinkCommand
Leechael Feb 23, 2024
7766792
chore(jssdk): bump beta version to 0.6.0-beta.16
Leechael Feb 28, 2024
8c76d0b
Merge pull request #1551 from Phala-Network/feat-jssdk-contract-actions
Leechael Mar 14, 2024
ef24209
dependencies(jssdk): update the minimal node version requirement
Leechael Mar 12, 2024
5a3ebf3
imp(jssdk): the isReady only turns true when corelative system contra…
Leechael Mar 13, 2024
a596f97
imp(jssdk): returns undefined instead null
Leechael Mar 13, 2024
0120080
chore(jssdk): deprecated mark & type hint for bigint
Leechael Mar 13, 2024
561a5e2
chore(jssdk): deprecated mark
Leechael Mar 13, 2024
346f32b
imp(jssdk): breaking-change - API change
Leechael Mar 15, 2024
49e6b31
fix(jssdk): typing
Leechael Mar 15, 2024
246b794
chore(jssdk): bump beta version to 0.6.0-beta.19
Leechael Mar 15, 2024
1b27553
Merge pull request #1552 from Phala-Network/feat-jssdk-misc-features-…
Leechael Mar 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions frontend/packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@phala/sdk",
"version": "0.5.10",
"version": "0.6.0-beta.19",
"description": "Phala Phat Contract JS SDK",
"license": "Apache-2.0",
"author": [
Expand All @@ -9,7 +9,7 @@
"homepage": "https://github.com/Phala-Network/phala-blockchain/tree/master/frontend/packages/sdk#readme",
"repository": {
"type": "git",
"url": "https://github.com/Phala-Network/phala-blockchain.git",
"url": "git+https://github.com/Phala-Network/phala-blockchain.git",
"directory": "frontend/packages/sdk"
},
"bugs": {
Expand Down Expand Up @@ -55,16 +55,22 @@
"test:ci": "vitest --run"
},
"dependencies": {
"@polkadot/api": "^10.9.1",
"@polkadot/api-contract": "^10.9.1",
"@polkadot/keyring": "^12.3.2",
"@polkadot/types": "^10.9.1",
"@polkadot/types-augment": "^10.9.1",
"@polkadot/util": "^12.3.2",
"@polkadot/util-crypto": "^12.3.2",
"@polkadot/api": "~10.11.1",
"@polkadot/api-contract": "~10.11.1",
"@polkadot/types": "~10.11.1",
"@polkadot/types-codec": "~10.11.1",
"@polkadot/types-augment": "~10.11.1",
"@polkadot/networks": "~12.6.1",
"@polkadot/keyring": "~12.6.1",
"@polkadot/util": "~12.6.1",
"@polkadot/util-crypto": "~12.6.1",
"@polkadot/extension-inject": "~0.46.6",
"@polkadot/ui-keyring": "~3.6.4",
"@polkadot/ui-settings": "~3.6.4",
"browserify-cipher": "^1.0.1",
"cross-fetch": "^4.0.0",
"protobufjs": "^7.2.4",
"ramda": "^0.29.1",
"randombytes": "^2.1.0",
"rxjs": "^7.8.1",
"viem": "^1.5.0"
Expand All @@ -73,6 +79,7 @@
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"@types/node": "^20.4.1",
"@types/ramda": "^0.29.9",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.6.0",
"@vitest/coverage-v8": "^0.34.4",
Expand All @@ -96,7 +103,7 @@
"vitest": "^0.34.6"
},
"engines": {
"node": ">=16"
"node": ">=18.14"
},
"prettier": {
"semi": false,
Expand Down
60 changes: 45 additions & 15 deletions frontend/packages/sdk/src/OnChainRegistry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { type ApiPromise, Keyring } from '@polkadot/api'
import { type KeyringPair } from '@polkadot/keyring/types'
import type { Result, U64 } from '@polkadot/types'
import { Enum, Map, Option, Text, U8aFixed, Vec } from '@polkadot/types'
import { AccountId } from '@polkadot/types/interfaces'
import { BN } from '@polkadot/util'
Expand All @@ -9,9 +8,11 @@ import systemAbi from './abis/system.json'
import { PinkContractPromise } from './contracts/PinkContract'
import { PinkLoggerContractPromise } from './contracts/PinkLoggerContract'
import { type PhalaTypesVersionedWorkerEndpoints, ackFirst } from './ha/ack-first'
import { KeyringPairProvider } from './providers/KeyringPairProvider'
import { type CertificateData, signCertificate } from './pruntime/certificate'
import createPruntimeClient from './pruntime/createPruntimeClient'
import { pruntime_rpc } from './pruntime/proto'
import type { SystemContract } from './types'

export class UnexpectedEndpointError extends Error {}

Expand Down Expand Up @@ -85,7 +86,7 @@ export class OnChainRegistry {
#alice: KeyringPair | undefined
#cert: CertificateData | undefined

#systemContract: PinkContractPromise | undefined
#systemContract: SystemContract | undefined
#loggerContract: PinkLoggerContractPromise | undefined

constructor(api: ApiPromise) {
Expand Down Expand Up @@ -113,7 +114,7 @@ export class OnChainRegistry {
}

get phactory() {
if (!this.#ready || !this.#phactory) {
if (!this.#phactory) {
throw new Error('You need initialize OnChainRegistry first.')
}
return this.#phactory
Expand Down Expand Up @@ -183,11 +184,14 @@ export class OnChainRegistry {
public async getClusterInfoById(clusterId: string) {
const result = (await this.api.query.phalaPhatContracts.clusters(clusterId)) as Option<ClusterInfo>
if (result.isNone) {
return null
return undefined
}
return result.unwrap()
}

/**
* @deprecated
*/
public async getClusters(clusterId?: string) {
if (clusterId) {
const result = (await this.api.query.phalaPhatContracts.clusters(clusterId)) as Option<ClusterInfo>
Expand All @@ -200,6 +204,9 @@ export class OnChainRegistry {
}
}

/**
* @deprecated
*/
public async getEndpoints(workerId?: U8aFixed | string) {
if (workerId) {
if (typeof workerId !== 'string') {
Expand All @@ -214,6 +221,9 @@ export class OnChainRegistry {
})
}

/**
* @deprecated
*/
public async getClusterWorkers(clusterId?: string): Promise<WorkerInfo[]> {
let _clusterId = clusterId || this.clusterId
if (!_clusterId) {
Expand Down Expand Up @@ -264,8 +274,16 @@ export class OnChainRegistry {
if (systemContractId) {
const systemContractKey = await this.getContractKey(systemContractId)
if (systemContractKey) {
this.#systemContract = new PinkContractPromise(this.api, this, systemAbi, systemContractId, systemContractKey)
this.#loggerContract = await PinkLoggerContractPromise.create(this.api, this, this.#systemContract)
const provider = await KeyringPairProvider.create(this.api, this.alice)
this.#systemContract = new PinkContractPromise(
this.api,
this,
systemAbi,
systemContractId,
systemContractKey,
provider
)
this.#loggerContract = await PinkLoggerContractPromise.create(this)
} else {
throw new Error(`System contract not found: ${systemContractId}`)
}
Expand Down Expand Up @@ -311,8 +329,8 @@ export class OnChainRegistry {
v1: [endpoint],
},
}
this.#ready = true
await this.prepareSystemOrThrows(clusterInfo)
this.#ready = true
return
}

Expand Down Expand Up @@ -361,8 +379,8 @@ export class OnChainRegistry {
v1: [phactory.endpoint],
},
}
this.#ready = true
await this.prepareSystemOrThrows(clusterInfo)
this.#ready = true
} else {
throw new Error(`Unknown strategy: ${args[0].strategy}`)
}
Expand Down Expand Up @@ -406,8 +424,8 @@ export class OnChainRegistry {
default: pruntimeURL,
},
}
this.#ready = true
await this.prepareSystemOrThrows(clusterInfo)
this.#ready = true
} else {
const worker = args[0] as WorkerInfo
const clusterInfo = await this.getClusterInfoById(worker.clusterId)
Expand All @@ -418,8 +436,8 @@ export class OnChainRegistry {
this.clusterId = worker.clusterId
this.clusterInfo = clusterInfo
this.workerInfo = worker
this.#ready = true
await this.prepareSystemOrThrows(clusterInfo)
this.#ready = true
}
return
}
Expand Down Expand Up @@ -509,8 +527,16 @@ export class OnChainRegistry {
if (systemContractId) {
const systemContractKey = await this.getContractKey(systemContractId)
if (systemContractKey) {
this.#systemContract = new PinkContractPromise(this.api, this, systemAbi, systemContractId, systemContractKey)
this.#loggerContract = await PinkLoggerContractPromise.create(this.api, this, this.#systemContract)
const provider = await KeyringPairProvider.create(this.api, this.alice)
this.#systemContract = new PinkContractPromise(
this.api,
this,
systemAbi,
systemContractId,
systemContractKey,
provider
)
this.#loggerContract = await PinkLoggerContractPromise.create(this)
} else {
throw new Error(`System contract not found: ${systemContractId}`)
}
Expand Down Expand Up @@ -556,12 +582,12 @@ export class OnChainRegistry {
system.query['system::freeBalanceOf'](cert.address, { cert }, address),
])
return {
total: (totalBalanceOf as Result<U64, any>).asOk.toBn(),
free: (freeBalanceOf as Result<U64, any>).asOk.toBn(),
total: totalBalanceOf.asOk,
free: freeBalanceOf.asOk,
}
}

transferToCluster(address: string | AccountId, amount: number | string | BN) {
transferToCluster(address: string | AccountId, amount: number | string | BN | bigint) {
return this.api.tx.phalaPhatContracts.transferToCluster(amount, this.clusterId, address)
}

Expand All @@ -579,4 +605,8 @@ export class OnChainRegistry {
get pruntimeURL() {
return this.workerInfo?.endpoints.default
}

get isEvmAccountMappingSupported() {
return !!this.api.consts?.evmAccountMapping?.eip712Name
}
}
4 changes: 2 additions & 2 deletions frontend/packages/sdk/src/abis/fetchers.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { type Bool } from '@polkadot/types'
import fetch from 'cross-fetch'
import { type PinkContractPromise } from '../contracts/PinkContract'
import { type OnChainRegistry } from '../OnChainRegistry'
import { type CertificateData } from '../pruntime/certificate'
import { type SystemContract } from '../types'

const OFFICIAL_ARTIFACTS_URL = 'https://phala-network.github.io/phat-contract-artifacts'

export interface CheckCodeHashExistsEnv {
systemContract: PinkContractPromise
systemContract: SystemContract
cert: CertificateData
}

Expand Down
99 changes: 99 additions & 0 deletions frontend/packages/sdk/src/actions/estimateContract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { convertWeight } from '@polkadot/api-contract/base/util'
import type { ContractCallOutcome } from '@polkadot/api-contract/types'
import type { ContractExecResult } from '@polkadot/types/interfaces'
import { BN_ZERO } from '@polkadot/util'
import type { OnChainRegistry } from '../OnChainRegistry'
import { phalaTypes } from '../options'
import { InkQueryMessage } from '../pruntime/coders'
import { pinkQuery } from '../pruntime/pinkQuery'
import { WorkerAgreementKey } from '../pruntime/WorkerAgreementKey'
import type { FrameSystemAccountInfo, LooseNumber } from '../types'
import { toAbi } from '../utils/abi/toAbi'
import { BN_MAX_SUPPLY } from '../utils/constants'
import { SendPinkCommandParameters } from './sendPinkCommand'
import { SendPinkQueryParameters } from './sendPinkQuery'

export type EstimateContractParameters<T> = SendPinkQueryParameters<T> & {
contractKey: string
deposit?: LooseNumber
transfer?: LooseNumber
}

export type EstimateContractResult = Omit<ContractCallOutcome, 'output'> & {
request: SendPinkCommandParameters
}

export async function estimateContract(
client: OnChainRegistry,
parameters: EstimateContractParameters<any[]>
): Promise<EstimateContractResult> {
const { address, functionName, provider, deposit, transfer } = parameters
if (!client.workerInfo?.pubkey) {
throw new Error('Worker pubkey not found')
}

const abi = toAbi(parameters.abi)
const args = parameters.args || []

const message = abi.findMessage(functionName)
if (!message) {
throw new Error(`Message not found: ${functionName}`)
}
const encodedArgs = message.toU8a(args)
const inkMessage = InkQueryMessage(address, encodedArgs, deposit || BN_MAX_SUPPLY, transfer, true)
const argument = new WorkerAgreementKey(client.workerInfo.pubkey)

const cert = await provider.signCertificate()

const [clusterBalance, onchainBalance, inkResponse] = await Promise.all([
client.getClusterBalance(provider.address),
client.api.query.system.account<FrameSystemAccountInfo>(provider.address),
pinkQuery(client.phactory, argument, inkMessage.toHex(), cert),
])

if (inkResponse.result.isErr) {
// @FIXME: not sure this is enough as not yet tested
throw new Error(`InkResponse Error: ${inkResponse.result.asErr.toString()}`)
}
if (!inkResponse.result.asOk.isInkMessageReturn) {
// @FIXME: not sure this is enough as not yet tested
throw new Error(`Unexpected InkMessageReturn: ${inkResponse.result.asOk.toJSON()?.toString()}`)
}
const { debugMessage, gasConsumed, gasRequired, result, storageDeposit } = phalaTypes.createType<ContractExecResult>(
'ContractExecResult',
inkResponse.result.asOk.asInkMessageReturn.toString()
)

const { gasPrice } = client.clusterInfo ?? {}
if (!gasPrice) {
throw new Error('No Gas Price or deposit Per Byte from cluster info.')
}

// calculate the total costs
const gasLimit = gasRequired.refTime.toBn()
const storageDepositFee = storageDeposit.isCharge ? storageDeposit.asCharge.toBn() : BN_ZERO
const minRequired = gasLimit.mul(gasPrice).add(storageDepositFee)

// Auto deposit.
let autoDeposit = undefined
if (clusterBalance.free.lt(minRequired)) {
const deposit = minRequired.sub(clusterBalance.free)
if (onchainBalance.data.free.lt(deposit)) {
throw new Error(`Not enough balance to pay for gas and storage deposit: ${minRequired.toNumber()}`)
}
autoDeposit = deposit
}

return {
debugMessage: debugMessage,
gasConsumed: gasConsumed,
gasRequired: gasRequired && !convertWeight(gasRequired).v1Weight.isZero() ? gasRequired : gasConsumed,
result,
storageDeposit,
request: {
...parameters,
gasLimit,
deposit: autoDeposit,
},
}
}
Loading
Loading