Avail
Avail is a Data Availability (DA) layer. In Effectstream, it is often used to store the raw input data of the application cheaply and securely.
1. Configuration (Read)
Network Definition
.buildNetworks(builder =>
builder.addNetwork({
name: "avail",
type: ConfigNetworkType.AVAIL,
nodeUrl: "ws://127.0.0.1:9955/ws",
// ... genesis config
})
)
Sync Protocol
The AVAIL_PARALLEL protocol connects to an Avail Light Client. This allows the node to verify data availability without running a full node.
.addParallel(
(networks) => networks.avail,
(network, deployments) => ({
name: "parallelAvail",
type: ConfigSyncProtocolType.AVAIL_PARALLEL,
rpc: network.nodeUrl,
lightClient: "http://127.0.0.1:7007", // Local light client API
startBlockHeight: 1,
})
)
Primitives
PrimitiveTypeAvailGeneric: Listens for data blobs submitted to a specificAppId.
import { PrimitiveTypeAvailGeneric } from "@effectstream/sm/builtin";
.addPrimitive(
(syncProtocols) => syncProtocols.parallelAvail,
(network, deployments, syncProtocol) => ({
name: "AvailData",
type: PrimitiveTypeAvailGeneric,
appId: 123, // Your Avail App ID
stateMachinePrefix: "avail-data",
})
)
2. Batcher Adapters (Write)
To submit data to Avail, use an adapter that interacts with the Avail SDK or Light Client.
// Conceptual usage
// The adapter would use `avail-js-sdk` to submit data blobs.
const availAdapter = new AvailAdapter(appId, seed, endpoint);
3. Browser Wallets (Connect)
You can connect using WalletMode.AvailJs. This is often used for development with a seed or connecting to specific Avail extensions.
import { walletLogin, WalletMode } from "@effectstream/wallets";
// Note: For Polkadot.js extension wallets, you might also use WalletMode.Polkadot
const result = await walletLogin({
mode: WalletMode.AvailJs,
// For dev mode, you might provide a connection with a keyring seed
seed: "your test seed phrase",
preferBatchedMode: true,
});
if (result.success) {
const wallet = result.result;
console.log("Connected Avail Address:", wallet.walletAddress);
}
4. Cryptography (Verify)
Avail uses the Substrate address format (SS58). You can verify these addresses and signatures using the CryptoManager's Polkadot implementation.
Signing Messages
import { signMessage } from "@effectstream/wallets";
const signature = await signMessage(wallet, "Hello Avail");
Verifying Signatures
import { CryptoManager } from "@effectstream/crypto";
import { AddressType } from "@effectstream/utils";
const crypto = CryptoManager.getCryptoManager(AddressType.AVAIL);
// 1. Verify Avail/Substrate Address
const isValid = crypto.verifyAddress(userAddress);
// 2. Verify Signature (sr25519/ed25519)
const isAuthorized = await crypto.verifySignature(
userAddress,
"Hello Avail",
signature
);
5. Orchestration
Use launchAvail from @effectstream/orchestrator/start-avail. This starts:
- A local Avail Node.
- An Avail Light Client connected to that node.
// in start.ts
processesToLaunch: [
...launchAvail("@my-project/avail-contracts"),
]
NOTE: To use this launcher you need to implement some
deno taskin your project. A working implementation is provided in thetemplate generator,templatesore2e tests.
{
"name": "@e2e/avail-contracts",
...
"tasks": {
"avail-node:start": "deno run -A --unstable-detect-cjs @effectstream/npm-avail-node --dev --rpc-port 9955 --no-telemetry",
"avail-node:wait": "wait-on tcp:9955",
"avail-light-client:deploy": "deno task avail-light-client:clean && deno run -A --unstable-detect-cjs ./deploy.ts",
"avail-light-client:start": "deno run -A --unstable-detect-cjs @effectstream/npm-avail-light-client --config ./config.yml --app-id $AVAIL_APP_ID",
"avail-light-client:wait": "wait-on tcp:7007",
"avail-light-client:clean": "rm -rf ./avail_path"
}
}