account: {$selectedAccount} / chainId: {$chainId}
+account: {$selectedAccount} / chainId: {$chainId}
``` -6. `npm run dev` +6. `npm run dev` -### *X doesn't work after `await defaultEvmStores.setProvider()`* +### _X doesn't work after `await defaultEvmStores.setProvider()`_ It's not sufficient to `await` for the `setProvider` to be certain that other derived stores have been populated. Instead you should subscribe @@ -461,10 +461,10 @@ on ```js import { defaultEvmStores as evm, web3, selectedAccount } from 'svelte-web3' -selectedAccount.subscribe(async $selectedAccount => { - if (!$selectedAccount) return - // do stuff here - // ... +selectedAccount.subscribe(async ($selectedAccount) => { + if (!$selectedAccount) return + // do stuff here + // ... }) onMount(() => { @@ -472,20 +472,18 @@ onMount(() => { }) ``` -### *how to auto-connect on page load?* +### _how to auto-connect on page load?_ It is out of scope of this package to implement this function but it generally depends on the type of provider you are using and a way to store connection information between page loads (for example by using localStorage). - ## Examples If you are using `svelte-web3` to build an open source Dapp, let us know if you want to be listed in this section. - ### Svelte basic example (using Vite) Please check [examples/svelte-vite-template-web3 on github](https://github.com/clbrge/svelte-web3/tree/master/examples/svelte-vite-template-web3). @@ -500,7 +498,6 @@ Please check [examples/sveltekit-app-template-web3 on github](https://github.com Please check [examples/svelte-app-template-web3 on github](https://github.com/clbrge/svelte-web3/tree/master/examples/svelte-app-template-web3). - Contains demos to use the default store and multi stores. ### Sapper basic example (based on webpack template) @@ -509,9 +506,8 @@ Contains demos to use the default store and multi stores. Please check [examples/sapper-app-template-web3 on github](https://github.com/clbrge/svelte-web3/tree/master/examples/sapper-app-template-web3). - ### tradingstrategy.ai presented at EthLisbon 2021 A website presented in EthLisbon 2021, used svelte-web3 (version 2) for building the frontend. : -* Tutorial: https://tradingstrategy.ai/blog/building-cryptocurrency-website +- Tutorial: https://tradingstrategy.ai/blog/building-cryptocurrency-website diff --git a/package.json b/package.json index d8efaee..19becad 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ }, "scripts": { "update-chains": "node ./scripts/update-chains.mjs", - "lint": "prettier-standard --lint 'src/**/*.js'", + "format": "prettier --plugin-search-dir . --write .", "build": "rollup -c" }, "prettier": "prettier-config-standard", @@ -47,9 +47,7 @@ "web3": "1.9.0" }, "lint-staged": { - "*": [ - "prettier-standard --lint" - ] + "*.{js,json,md}": "prettier --write" }, "release-it": { "github": { diff --git a/rollup.config.mjs b/rollup.config.mjs index eeb580b..1c5f147 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -1,16 +1,16 @@ -import dts from "rollup-plugin-dts"; +import dts from 'rollup-plugin-dts' export default [ { - input: "./src/stores.js", + input: './src/stores.js', output: [ - { file: "dist/index.mjs", format: "es" }, - { file: "dist/index.js", format: "umd", name: "web3store" }, + { file: 'dist/index.mjs', format: 'es' }, + { file: 'dist/index.js', format: 'umd', name: 'web3store' } ] }, { - input: "./src/svelte-web3.d.ts", - output: [{ file: "dist/svelte-web3.d.ts", format: "es" }], - plugins: [dts()], - }, + input: './src/svelte-web3.d.ts', + output: [{ file: 'dist/svelte-web3.d.ts', format: 'es' }], + plugins: [dts()] + } ] diff --git a/scripts/update-chains.mjs b/scripts/update-chains.mjs index 9caefd4..091df30 100644 --- a/scripts/update-chains.mjs +++ b/scripts/update-chains.mjs @@ -3,22 +3,22 @@ import fetch from 'node-fetch' import { writeFile } from 'fs/promises' const run = async () => { - const res = await fetch('https://chainid.network/chains.json') const chains = await res.json() - if (!chains.map( c => c.name ).includes('Ethereum Mainnet')) { + if (!chains.map((c) => c.name).includes('Ethereum Mainnet')) { throw new Error('something wrong... check!') } - await writeFile('./src/chains.js', ` + await writeFile( + './src/chains.js', + ` const chains = ${util.inspect(chains, { depth: null, maxArrayLength: null })} export default chains ` -) - + ) } run() diff --git a/src/stores.js b/src/stores.js index 24c211f..35ce513 100644 --- a/src/stores.js +++ b/src/stores.js @@ -40,7 +40,8 @@ const getWindowEthereum = () => { } // always get chainId as number -const alwaysNumber = n => Web3.utils.isHex(n) ? Web3.utils.hexToNumber(n) : n +const alwaysNumber = (n) => + Web3.utils.isHex(n) ? Web3.utils.hexToNumber(n) : n export const createStore = () => { const { emit, get, subscribe, assign, deleteAll } = proxied() @@ -73,10 +74,11 @@ export const createStore = () => { emit() } - const accountsChangedHandler = accounts => switch1193Provider({ accounts }) - const chainChangedHandler = chainId => switch1193Provider({ chainId: alwaysNumber(chainId) }) + const accountsChangedHandler = (accounts) => switch1193Provider({ accounts }) + const chainChangedHandler = (chainId) => + switch1193Provider({ chainId: alwaysNumber(chainId) }) // TODO better error support ? - const disconnectHandler = error => switch1193Provider({ error }) + const disconnectHandler = (error) => switch1193Provider({ error }) const init = () => { loadWeb3() @@ -160,7 +162,9 @@ export const createStore = () => { } const setBrowserProvider = () => { - console.warn('[svelte-web3] setBrowserProvider is deprecated. Please use setProvider() without argument instead.') + console.warn( + '[svelte-web3] setBrowserProvider is deprecated. Please use setProvider() without argument instead.' + ) return setProvider() } @@ -199,7 +203,7 @@ const allStores = {} const noData = { rpc: [], explorers: [{}], faucets: [], nativeCurrency: {} } -const getData = id => { +const getData = (id) => { if (!id || !Web3.utils) return noData if (Web3.utils.isHexStrict(id)) id = Web3.utils.hexToNumber(id) for (const data of chains) { @@ -210,35 +214,35 @@ const getData = id => { const subStoreNames = ['web3', 'selectedAccount', 'connected', 'chainId'] -export const makeEvmStores = name => { +export const makeEvmStores = (name) => { const evmStore = (allStores[name] = createStore()) const registry = createContractStore() const target = {} - allStores[name].web3 = derived(evmStore, $evmStore => { + allStores[name].web3 = derived(evmStore, ($evmStore) => { if (!$evmStore.web3) return { utils: Web3.utils, version: Web3.version } return $evmStore.web3 }) allStores[name].selectedAccount = derived( evmStore, - $evmStore => $evmStore.selectedAccount + ($evmStore) => $evmStore.selectedAccount ) allStores[name].connected = derived( evmStore, - $evmStore => $evmStore.connected + ($evmStore) => $evmStore.connected ) - allStores[name].chainId = derived(evmStore, $evmStore => $evmStore.chainId) - allStores[name].chainData = derived(evmStore, $evmStore => + allStores[name].chainId = derived(evmStore, ($evmStore) => $evmStore.chainId) + allStores[name].chainData = derived(evmStore, ($evmStore) => $evmStore.chainId ? getData($evmStore.chainId) : {} ) allStores[name].evmProviderType = derived( evmStore, - $evmStore => $evmStore.evmProviderType + ($evmStore) => $evmStore.evmProviderType ) - allStores[name].walletType = derived(evmStore, $evmStore => { + allStores[name].walletType = derived(evmStore, ($evmStore) => { if (!$evmStore.eipProvider) return null if (typeof $evmStore.eipProvider === 'string') return $evmStore.eipProvider if ($evmStore.eipProvider.isNiftyWallet) return 'Nifty' @@ -253,18 +257,22 @@ export const makeEvmStores = name => { }) allStores[name].contracts = derived( - [ evmStore, registry ], - ([ $evmStore, $registry ]) => { + [evmStore, registry], + ([$evmStore, $registry]) => { if (!$evmStore.connected) return target for (let key of Object.keys($registry)) { - target[key] = new $evmStore.web3.eth.Contract($registry[key][1], $registry[key][0], $registry[key][2]) + target[key] = new $evmStore.web3.eth.Contract( + $registry[key][1], + $registry[key][0], + $registry[key][2] + ) } return target } ) // force one subscribtion on $contracts so it's defined via proxy - allStores[name].contracts.subscribe(()=>{}) + allStores[name].contracts.subscribe(() => {}) return new Proxy(allStores[name], { get: function (internal, property) { @@ -297,7 +305,7 @@ export const makeEvmStores = name => { }) } -export const getChainStore = name => { +export const getChainStore = (name) => { if (!allStores[name]) throw new Error(`[svelte-web3] chain store ${name} does not exist`) return allStores[name] @@ -307,7 +315,8 @@ loadWeb3() export { chains as allChainsData } -export const getChainDataByChainId = id => (chains.filter(o => o.chainId === id) || [{}])[0] +export const getChainDataByChainId = (id) => + (chains.filter((o) => o.chainId === id) || [{}])[0] export const defaultEvmStores = makeEvmStores('default') @@ -326,10 +335,12 @@ export const walletType = allStores.default.walletType // TODO legacy makeContractStore to be removed export const makeContractStore = (abi, address, defaults = {}) => - console.warn('[svelte-web3] makeContractStore is deprecated. Please use the new $contracts store') - derived([web3, connected], ([$web3, $connected]) => { - if ($connected && $web3.eth) { - return new $web3.eth.Contract(abi, address, defaults) - } - return null - }) + console.warn( + '[svelte-web3] makeContractStore is deprecated. Please use the new $contracts store' + ) +derived([web3, connected], ([$web3, $connected]) => { + if ($connected && $web3.eth) { + return new $web3.eth.Contract(abi, address, defaults) + } + return null +}) diff --git a/src/svelte-web3.d.ts b/src/svelte-web3.d.ts index 9a6bef7..a88e066 100644 --- a/src/svelte-web3.d.ts +++ b/src/svelte-web3.d.ts @@ -1,146 +1,146 @@ -import { Readable } from "svelte/store"; -import Web3 from "web3"; -import { provider } from "web3-core"; -import { ContractOptions, Contract } from "web3-eth-contract"; +import { Readable } from 'svelte/store' +import Web3 from 'web3' +import { provider } from 'web3-core' +import { ContractOptions, Contract } from 'web3-eth-contract' -declare module "svelte-web3" { - /** - * JavaScript CAIP-2 representation object. - * @see https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md - */ - interface ChainData { - name: string; - chain: string; - network: string; - rpc: string[]; - faucets: string[]; - nativeCurrency: { - name: string; - symbol: string; - decimals: number; - }; - infoURL: string; - shortName: string; - chainId: number; - networkId: number; - icon: string; - explorers: { - name: string; - url: string; - icon: string; - standard: string; - }[]; +declare module 'svelte-web3' { + /** + * JavaScript CAIP-2 representation object. + * @see https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md + */ + interface ChainData { + name: string + chain: string + network: string + rpc: string[] + faucets: string[] + nativeCurrency: { + name: string + symbol: string + decimals: number } + infoURL: string + shortName: string + chainId: number + networkId: number + icon: string + explorers: { + name: string + url: string + icon: string + standard: string + }[] + } - interface ChainStore { - /** - * Enables a connection with the current window provider. - * Note that your code need to be in browser context when setProvider is running. - * So you may want to use onMount when using Sapper or Sveltekit. - * @param provider An url string or a valid provider object (as returned by web3Modal or WalletConnect for example) - * @param index Select another account than the default when possible. - */ - setProvider(provider?: provider, index?: string): Promise