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 nft
window.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 hashlib
from blspy import PrivateKey, G1Element, G2Element, AugSchemeMPL
def 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
}