Contracts
The SDK supports two ways to interact with Phala contract:
- Contract Instances. The
@polkadot/api-contract
compatible classPinkContractPromise
. - Contract Actions. Inspired by
viem
, a set of functions that can be used to interact with the contract.
PinkContractPromise
PinkContractPromise
is the implementation has same API design as @polkadot/api-contract
and with alternative methods to reduce the boilerplate code.
Instead of instantiate with new
keyword, there is a factory function getContract
to handle that.
import { getContract } from '@phala/sdk'
const contractId = '0x...'
const abi = fs.readFileSync('path/to/your/abi.json', 'utf-8')
const contract = await getContract({
client,
contractId,
abi,
provider,
})
One of disadvantage of @polkadot/api-contract
doesn't support TypeScript well. So if you want a more type-safe way to interact with contract, you can declare typing like this:
contract.ts
import { getContract } from '@phala/sdk'
import { type SystemContract } from './systemContract.d.ts'
const contractId = '0x...'
const abi = fs.readFileSync('path/to/your/systemContract.abi.json', 'utf-8')
const contract = await getContract<import SystemContractSystemContract>({
client,
contractId,
abi,
provider,
})
It requires a significant amount of boilerplate codes, but that workaround currently.
Contract Actions
There are three functions to interact with Phat Contract:
sendPinkQuery
. Call the off-chain query and getting the result immediately.estimateContract
. Estimate the gas fee result for a contract transction.sendPinkCommand
. Send a contract transaction.
import * as fs from 'node'
import { sendPinkQuery, estimateContract, sendPinkCommand } from '@phala/sdk'
const contractId = '0x...'
const abi = fs.readFileSync('path/to/your/abi.json', 'utf-8')
const contractKey = await client.getContractKeyOrFail(contractId)
// Pink Query
const totalBadges = await sendPinkQuery(client, {
address: contractId,
abi,
provider,
functionName: 'getTotalBadges',
})
// Pink Commands / Transactions
const name = `Badge${new Date().getTime()}`
const { request } = await estimateContract(client, {
address: contractId,
contractKey,
abi,
provider,
functionName: 'newBadge',
args: [name],
})
await sendPinkCommand(client, request)
This proposal suggests a more modular approach to interacting with the contract.