Spaces:
Runtime error
sidebar_position: 5
How to Integrate sCrypt Service
Before interacting with a sCrypt
contract, we must create a contract instance representing the latest state of the contract on chain. Such an instance can be created by calling the fromTx
method. However, this means your application needs to track and record all contract-related transactions, especially for a stateful contract.
An easier alternative is to leverage sCrypt
infrastructure service, which tracks such transactions, so you can focus on your application logic.
Get Your API Key
Step 1: Create Your Free Account
Go to the sCrypt homepage to create your free account.
Step 2: Get API Key
Sign in and click on the copy icon to copy your API Key.
Integration
Once you have an API key, you can easily integrate sCrypt service into your app by following these simple steps.
Step 1: Initialize Client
You can pass the API key, along with network
, to the Scrypt.init
function to initialize an sCrypt client in your app.
import { Scrypt, bsv } from 'scrypt-ts'
Scrypt.init({
apiKey: 'YOUR_API_KEY',
network: bsv.Networks.testnet,
})
Step 2: Connect ScryptProvider
with your signer
Connect signer to ScryptProvider
, the required provider to use sCrypt service.
const signer = new TestWallet(myPrivateKey)
await signer.connect(new ScryptProvider())
Step 3: Get Contract ID
Each contract is uniquely identified by the transaction that deploy it and the output it is in, which we regard as its ID.
const counter = new Counter(0n)
// connect signer
await counter.connect(signer)
const balance = 1
const deployTx = await counter.deploy(balance)
console.log('contract Counter deployed: ', deployTx.id)
const contractId = {
/** The deployment transaction id */
txId: deployTx.id,
/** The output index */
outputIndex: 0,
}
You can usually get the ID of a contract from its creator, who publicizes it so others can interact with it.
Step 4: Get Contract Instance
Once you have the contract ID, you can easily create a contract instance as follows.
const currentInstance = await Scrypt.contractApi.getLatestInstance(
Counter,
contractId
)
// connect signer
await currentInstance.connect(signer)
For a stateless contract, the instance points to the deployment tx; for a stateful one, it points to the latest tip in a chain of txs, which sCrypt service tracks automatically.
Interact with the Contract
Once you have the instance after following the steps above, you can easily read from the contract, write to it, and listen to it.
Read
You read an instance's properties using the dot operator, like any other object.
// read @prop count
console.log(counter.count)
:::note Reading does NOT broadcast a transaction to the blockchain. :::
Write
To update a contract instance, you call its public method as before, which writes to the blockchain by broadcasting a transaction.
// call the method of current instance to apply the updates on chain
const { tx } = await currentInstance.methods.incrementOnChain()
console.log(`Counter contract called, tx: ${tx.id}`)
Listen to Events
Often, your app needs to be notified when a contract gets called and updated. It is essential to be able to listen to such events in real time that can alert your app whenever something relevant occurs on chain. For example, in your front-end, you can refresh the web page to show the user the latest state of a contract, upon event notifications.
With the sCrypt
service, you can easily subscribe to a contract's events by its contract ID, using the Scrypt.contractApi.subscribe
method. It takes two parameters:
options: SubscribeOptions<T>
: it includes a contract class, a contract ID, and a optional list of method names monitored.
interface SubscribeOptions<T> {
clazz: new (...args: any) => T;
id: ContractId;
methodNames?: Array<string>;
}
If methodNames
is set, you will be notified only when public functions in the list are called. Otherwise, you will be notified when ANY public function is called.
callback: (event: ContractCalledEvent<T>) => void
: a callback funciton upon receiving notifications.
ContractCalledEvent<T>
contains relevant information on how the contract is called:
methodName: string
, which public method is calledargs: SupportedParamType[]
, arguments the public method is called withtx: bsv.Transaction
, transaction where contract is called fromnexts: Array[T]
, includes the new contract instances created by this call. If a stateful contract is called,nexts
contains the contract instances containing the new state generated by this call. You can read the latest state from the new contract instance to, e.g., display the new state to users. If a stateless contract is called,nexts
is empty.
Below is an example of listening to events when incrementOnChain
method is called.
const subscription = Scrypt.contractApi.subscribe({
clazz: Counter, // contract class
id: contractId, // contract id
methodNames: ['incrementOnChain']
}, (event: ContractCalledEvent<Counter>) => {
// callback when receiving a notification
console.log(`${event.methodName} is called with args: ${event.args}`)
});