Filecoin wallet provider
:warning: Active development. Unstable. Breaking Changes. You get the point.
This wallet provider module is inspired as a combination between MetaMask's keyring controller and web3.js. It's experimental so it's likely that it will change, drastically. Below is a description of our design decisions, how it's working, and development plan over the coming weeks/months.
Usage
import Filecoin, {
LocalNodeProvider,
} from '@glif/filecoin-wallet-provider'
const config = {
apiAddress: process.env.API_ADDRESS
token: process.env.LOTUS_JWT_TOKEN,
}
const filecoin = new Filecoin(new LocalNodeProvider(config), config)
Methods:
getBalance
Returns a promise that resolves to a javascript bignumber.js object with the accounts balance:
const config = {
apiAddress: process.env.API_ADDRESS
token: process.env.LOTUS_JWT_TOKEN,
}
const filecoin = new Filecoin(new LocalNodeProvider(config), config)
const balance = await filecoin.getBalance(
't1jdlfl73voaiblrvn2yfivvn5ifucwwv5f26nfza',
)
console.log(balance.toString())
getNonce
const config = {
apiAddress: process.env.API_ADDRESS
token: process.env.LOTUS_JWT_TOKEN,
}
const filecoin = new Filecoin(new LocalNodeProvider(config), config)
const nonce = await filecoin.getNonce(
't1jdlfl73voaiblrvn2yfivvn5ifucwwv5f26nfza',
)
console.log(nonce)
sendMessage
Takes a signed message, and resolves a promise whne the transaction is completed (note in the future this should resolve to the SignedMessage cid
).
const config = {
apiAddress: process.env.API_ADDRESS
token: process.env.LOTUS_JWT_TOKEN,
}
const filecoin = new Filecoin(new LocalNodeProvider(config), config)
await filecoin.sendMessage(signedMessage)
Wallet methods exposed from the Provider class (more info below on Provider class)
const config = {
apiAddress: process.env.API_ADDRESS
token: process.env.LOTUS_JWT_TOKEN,
}
const filecoin = new Filecoin(new LocalNodeProvider(config), config)
await filecoin.wallet.sign(message)
await filecoin.wallet.getAccounts()
await filecoin.wallet.newAccount()
Provider class
The Filecoin class takes a required "provider" object that implements 3 methods. It should be easy to create a Provider class for Ledger, Trust, wasm based signing libs...etc.
The below examples show how the Provider class should function using the LocalNodeProvider
as an example.
newAccount
Returns a promise that resolves to the Filecoin address of a new account
const provider = new LocalNodeProvider({
apiAddress: 'http://127.0.0.1:1234/rpc/v0',
token: 'your_lotus_jwt_',
})
const newAccount = await provider.newAccount()
console.log(newAccount)
getAccounts
Returns a promise that resolves to an array of Filecoin addresses
const provider = new LocalNodeProvider({
apiAddress: 'http://127.0.0.1:1234/rpc/v0',
token: 'your_lotus_jwt_',
})
const accounts = await provider.getAccounts()
console.log(accounts)
sign
Returns a promise that resolves to a Filecoin signedMessage
const provider = new LocalNodeProvider({
apiAddress: 'http://127.0.0.1:1234/rpc/v0',
token: 'your_lotus_jwt_',
})
const signedMsg = await provider.sign(path, message)
console.log(signedMsg)
Design decisions & future
At a high level, a simple wallet relies on 2 types of functions:
(1) methods that require access to private keys
(2) methods that do not require access to private keys
For example, signMessage
and getAccounts
are two methods that would require access to a private key, whereas getBalance
, getNonce
, and sendSignedMessage
do not rely on having access to private keys (these are all made up method names).
This naturally lends itself to an architecture that should allow developers to "plug-and-play" their own modules that handle "private key methods", and not have to worry about re-implementing their own "non-private key methods". In other words, a developer should be able to do something like this:
const Filecoin = require('@glif/filecoin-wallet-provider')
const filecoin = new Filecoin()
await filecoin.addWalletProvider(new LedgerWallet())
await filecoin.addWalletProvider(new SimpleJSWallet())
const accounts = await filecoin.listAccounts()
Ideally, each Wallet Class in the above example will follow a simple interface and exposes a few functions, similar to MetaMask's Keyring Class Protocol. We could match this interface with the Wallet
methods in the Lotus jsonrpc (with the exception of balance
and list
because those do not need access to underlying private keys).