To benefit from Fadroma, the blockchain must be roughly OOP-shaped: "smart contract" is understood as a persistent stateful entity with a constructor (init procedure) and callable read-only and read-write transaction methods.
You will also probably need to implement the methods for sending and querying the native tokens that are used to pay transaction fees.
# in your lab directory:
git clone --recursive git@github.com:hackbg/fadroma.git
cd fadroma
Note the --recursive flag and the SSH clone.
If the chain you're adding is already accessible through
a supported client library (such as secretjs or @cosmjs/stargate),
skip this step and continue with the corresponding library package.[^0]
If you want to add support for a chain that uses its own client library,
create a new package in a subdirectory of connect/:
# in the repo root:
mkdir connect/newchain
echo "{}" > connect/newchain/package.json
peerDependency.// in connect/newchain/package.json
{
"name": "@fadroma/newchain",
"version": "0.1.0",
"type": "module",
"main": "newchain.ts",
"dependencies": {
"@fadroma/agent": "..."
},
"peerDependencies": {
"newchainjs": "^1.2.3"
}
}
@fadroma/connect,
alongside preferred version of the original client library:// in connect/package.json
{
"name": "@fadroma/connect",
"//": "..."
"dependencies": {
"//": "...",
"@fadroma/newchain": "workspace:^0.x",
"newchainjs": "^1.2.3"
"//": "..."
}
}
Using peerDependencies lets the downstream update the
client library independently of the one that we use
for testing.
// in connect/connect.ts:
// ...
export * as NewChain from '@fadroma/newchain'
// ...
The reexport means users can either depend on @fadroma/connect
for immediate full access to all supported chains, OR they can
depend only on a particular subpackage and not download the
dependencies for any of the others.
[^0]: Whether @fadroma/eth would be based on web3/ethers/viem;
whether we would want to support one or more of those; and whether
that would be 1 or 3 connector modules is an open-ended question.
Having set up your connector package, you should now implement the
Chain, Agent, and Bundle classes defined by @fadroma/agent:
// in connect/newchain/newchain.ts
// (or e.g. connect/cw/cw-newchain.ts if using @cosmjs/stargate)
import { Chain, Agent, Bundle, bindChainSupport } from '@fadroma/agent'
Chain should be a stateless representation for the whole chain
(user would create one instance for each mainnet, testnet, etc.
that they want to connect to during the application run).
// in connect/newchain/newchain.ts etc.
class NewChain extends Chain {
// TODO add example
}
Agent is a wrapper binding a wallet to an API client.
The upload and instantiate methods allow contracts to
be created, and execute and query to transact with them.
// in connect/newchain/newchain.ts etc.
class NewAgent extends Agent {
// TODO add example
}
Bundle may be implemented if client-side transaction batching
is to be supported. This is the basis for exporting things like
multisig transactions to be manually signed and broadcast.
// in connect/newchain/newchain.ts etc.
class NewBundle extends Bundle {
// TODO add example
}
Finally, use bindChainSupport to make sure that
the three implementations are aware of each other.
This line must go after the class definitions:
// in connect/newchain/newchain.ts etc.
bindChainSupport(NewChain, NewAgent, NewBundle)
And that's it! You can now transact, deploy, and use smart contracts on this chain.
Note that it was not needed to extend Client, Contract, or Template to add
support for contracts on the new chain[^2].
[^2]: That sort of thing might only be necessary in the case of a chain that implements custom modifications to its CosmWasm compute module.
TODO