contract-proxy-kit
v3.0.0
Published
Enable batched transactions and contract account interactions using a unique deterministic Gnosis Safe.
Downloads
918
Readme
Contract Proxy Kit
Warning: This documentation is for the 2.x series of the contract proxy kit. For documentation on the 1.x series, go here.
Enable batched transactions and contract account interactions using a unique deterministic Gnosis Safe.
npm install contract-proxy-kit
Resources
Video introduction to Building with Safe Apps SDK & Contract Proxy Kit
Usage
The Contract Proxy Kit package exposes a CPK class:
import CPK from 'contract-proxy-kit'
CPK requires either web3.js or ethers.js to function. Currently the following versions are supported:
- web3.js 1.3
- web3.js 2.0 alpha
- ethers.js 4.0
- ethers.js 5.0
CPK.create
To create a CPK instance, use the static method CPK.create
. This method accepts an options object as a parameter, and will result in a promise which resolves to a CPK instance if successful and rejects with an error otherwise.
This will not deploy a contract on any networks. Rather, the deployment of a proxy gets batched into the first set of transactions when calling CPK#execTransaction.
In order to obtain the proxy address, use the property CPK#address. This address is deterministically derived from the owner address, and accessing the property does not require the proxy to be deployed.
Using with web3.js
To use CPK with web3.js, supply CPK.create
with a Web3 instance as the value of the web3
key. For example:
import CPK, { Web3Adapter } from 'contract-proxy-kit'
import Web3 from 'web3'
const web3 = new Web3(/*...*/)
const ethLibAdapter = new Web3Adapter({ web3 })
const cpk = await CPK.create({ ethLibAdapter })
The proxy owner will be inferred by first trying web3.eth.defaultAccount
, and then trying to select the 0th account from web3.eth.getAccounts
. However, an owner account may also be explicitly set with the ownerAccount
key:
const cpk = await CPK.create({ ethLibAdapter, ownerAccount: '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1' })
Using with ethers.js
To use CPK with ethers.js, supply CPK.create
with the ethers
object and an ethers.js Signer which has an active Provider connection. For example:
import CPK, { EthersAdapter } from 'contract-proxy-kit'
import { ethers } from 'ethers')
const provider = ethers.getDefaultProvider('homestead')
const wallet = ethers.Wallet.createRandom().connect(provider)
const ethLibAdapter = new EthersAdapter({ ethers, signer: wallet })
const cpk = await CPK.create({ ethLibAdapter })
The proxy owner will be the account associated with the signer.
Networks configuration
Regardless of which type of underlying API is being used, the CPK instance will check the ID of the network given by the provider in order to prepare for contract interactions. By default, Ethereum Mainnet (ID 1) and the Rinkeby (ID 4), Goerli (ID 5), and Kovan (ID 42) test networks will have preconfigured addresses for the required contracts:
masterCopyAddress
: Gnosis Safe master copyproxyFactoryAddress
: CPK factorymultiSendAddress
: MultiSend contract for batching transactionsfallbackHandlerAddress
: A fallback handler (DefaultCallbackHandler)
However, address configurations for networks may be added or overridden by supplying a configuration object as the value of the networks
key in the options. For example, adding a configuration for a network with ID (4447) may be done in the following manner:
const cpk = await CPK.create({
// ...otherOptions,
networks: {
4447: {
masterCopyAddress: '0x2C2B9C9a4a25e24B174f26114e8926a9f2128FE4',
proxyFactoryAddress: '0x345cA3e014Aaf5dcA488057592ee47305D9B3e10',
multiSendAddress: '0x8f0483125FCb9aaAEFA9209D8E9d7b9C8B9Fb90F',
fallbackHandlerAddress: '0xAa588d3737B611baFD7bD713445b314BD453a5C8',
},
},
})
Please refer to the migrations/
folder of this package for information on how to deploy the required contracts on a network, and note that these addresses must be available for the connected network in order for CPK creation to be successful.
Salt nonce configuration
The CPK.saltNonce
property is predetermined, but it may be passed in as a parameter to generate new proxies for which the owner controls.
const saltNonce = "<NEW_SALT_NONCE>"
const cpk = await CPK.create({ ethLibAdapter, saltNonce })
Rockside Relay API integration
By default, the CPK will not use any transaction relayer. However, Rockside Relay API can be used to submit all the transactions when the optional property transactionManager
is passed to the CPK constructor with an instance of the class RocksideTxRelayManager
.
const rocksideTxRelayManager = new RocksideTxRelayManager({
speed: RocksideSpeed.Fastest
})
const cpk = await CPK.create({
// ...otherOptions,
transactionManager: rocksideTxRelayManager,
})