Methods
The dApp protocol is in alpha, please join our Discord to follow the latest updates or email Dimitry.
Connect Wallet
const accounts = await window.chia.request({ method: "requestAccounts" });console.log(accounts?.[0]))
Get chainId
window.chia.request({ method: 'chainId' })
Get Current Accounts
const accounts = await window.chia.request({ method: "accounts" });console.log(accounts?.[0]))
Switch chains
const params = { chainId: '0x01', // '0x01' mainnet, '0x02' testnet10}window.chia.request({ method: 'walletSwitchChain', params })
Transfer
const params = { "to": "xch1458padpp4yw30nz9r63z9ty0ay7ju7xg8z0gjq2ekxumapmgprpqtaum28", "amount": "100000000", "memos": ["0x68656c6c6f2063686961", ], // hex string, "hello chia".encode("utf-8) "assetId": "",};window.chia.request({ method: "transfer", params });
Take offer
window.chia.request({method: 'takeOffer', params: {offer: 'offerxxxx'})
Create offer
const params = { requestAssets: [ { amount: 1000, assetId: '', }, ], offerAssets: [ { assetId: 'c5de266e7ec6ab97e3ab6d6d11719ae3b35ee252bbcd6244524109b4503e846a', amount: 100000, }, ],}window.chia.request({ method: 'createOffer', params })// nft example, offer 1xch reqeust nftwindow.chia.request({ method: 'createOffer', params: { requestAssets: [ { assetId: 'nft1xqertsxveqgs23gh99d66sz28tnd6uv6ewqwas03rfulp56wel4qhscljk', amount: 1 } ], offerAssets: [ { assetId: '', amount: 1000000000000 } ] }})
getPublicKeys
Defined in CHiP-0002. API returns the public keys managed by the wallet.
window.chia.request({ method: 'getPublicKeys' }) .then(console.log)
signMessage
Defined in CHiP-0002. Sign the message encoded as a hex string using the private key associated with the public key.
The internal implementation in the wallet is bls_sign(private_key, sha256("\x18Chia Signed Message:\n" + len(message) + message))
.
To prevent replay attacks, dApps should add the current networkId
and timestamp
into the message.
If the dApp doesn't care which chain they're on, they can include the timestamp
only.
function stringToHex(string) { const bytes = new TextEncoder().encode(string) return "0x" + Array.from(bytes, byte => byte.toString(16).padStart(2, "0")).join('')}window.chia.request({ method: 'getPublicKeys' }) .then(function(publicKeys) { const message = 'hello chia' const hexMessage = stringToHex(message) const params = { publicKey: publicKeys[0], message: hexMessage } window.chia.request({ method: 'signMessage', params }) .then(console.log) })
how to verify signature
- Python
import hashlibfrom blspy import PrivateKey, G1Element, G2Element, AugSchemeMPLdef formatMessage(message: bytes): prefix = f"\u0018Chia Signed Message:\n{len(message)}".encode("utf-8") return hashlib.sha256(prefix + message).digest()def fromHex(hex: str) -> bytes: if hex.startswith("0x"): hex = hex[2:] return bytes.fromhex(hex)def verify(message: bytes, publicKey: str, signature: str): syntheticMessage = formatMessage(message) publicKey = G1Element.from_bytes(fromHex(publicKey)) signature = G2Element.from_bytes(fromHex(signature)) print('verified: ', AugSchemeMPL.verify(publicKey, syntheticMessage, signature))verify( "hello chia".encode("utf-8"), "0x858024f64b04a9abc6622a61e2c823b78a43d219c502719d12a78fd6cad5daa31f80254b1803689a9433960c609f9b92", "0x8ee997eb62ad11a9b781d123862d3fe9cfb65a7862c1e0a86618c739119d636a85722e87bdbc3da4cd5a1676dc3836c617a2b176e91dd7b8f8d126fbec509d751e2f811db009a01d0a4438b3c2eaf99b51b76d805700405564b9fc7b52a29625")
- nodejs
const loadBls = require("bls-signatures");const crypto = require("crypto");(async () => { const BLS = await loadBls(); const encoder = new TextEncoder('utf-8') function formatMessage(message) { const prefix = `\u0018Chia Signed Message:\n${message.length}`; const hash = crypto.createHash('sha256'); hash.update(encoder.encode(prefix)) hash.update(message) return hash.digest('hex') } function hexToBytes(hex) { if (hex.startsWith("0x")) { hex = hex.slice(2); } const bytes = Uint8Array.from(hex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))); return bytes } function verify(message, publicKey, signature) { const syntheticMessage = formatMessage(message); publicKey = BLS.G1Element.from_bytes(hexToBytes(publicKey)); signature = BLS.G2Element.from_bytes(hexToBytes(signature)); console.log("verified: ", BLS.AugSchemeMPL.verify(publicKey, hexToBytes(syntheticMessage), signature)); } verify(encoder.encode("hello chia"), "0x858024f64b04a9abc6622a61e2c823b78a43d219c502719d12a78fd6cad5daa31f80254b1803689a9433960c609f9b92", "0x8ee997eb62ad11a9b781d123862d3fe9cfb65a7862c1e0a86618c739119d636a85722e87bdbc3da4cd5a1676dc3836c617a2b176e91dd7b8f8d126fbec509d751e2f811db009a01d0a4438b3c2eaf99b51b76d805700405564b9fc7b52a29625");})();
Typescript Interface
type Amount = string | number;type HexString = string;export interface Coin { parent_coin_info: string; puzzle_hash: string; amount: number;}export interface CoinSpend { coin: Coin; puzzle_reveal: HexString solution: HexString}export interface SpendBundle { coin_spends: CoinSpend[] aggregated_signature: HexString}interface TakeOfferParams { offer: string;}interface AssetAmount { assetId: string; amount: Amount,}interface TransferParams { to: string; amount: Amount; assetId: string; memos?: HexString[];}interface CreateOfferParams { offerAssets: AssetAmount[]; requestAssets: AssetAmount[]; fee?: number; // mojo}export interface Wallet { accounts(): Promise<string[]> chainId(): Promise<string> requestAccounts(): Promise<string[]> walletSwitchChain(params: {chainId: string}): Promise<null> transfer(params: TransferParams): Promise<{ id: string; }> takeOffer(params: TakeOfferParams): Promise<{ id: string; }> createOffer(params: CreateOfferParams): Promise<{ id: string; offer: string; }> getPublicKeys(params?: {limit?: number, offset?: number}): HexString[] signMessage(params: {message: HexString, publicKey: HexString}): HexString}