Skip to content

Contracts

The SDK supports two ways to interact with Phala contract:

  • Contract Instances. The @polkadot/api-contract compatible class PinkContractPromise.
  • 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 SystemContract
SystemContract
>({
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.