diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..36bf9b4
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,24 @@
+# Contributing to svelte-web3
+
+Thanks for your interest in improving svelte-web3! We welcome
+contributions of all kinds: from discussion to documentation to
+bugfixes to feature improvements.
+
+Please review this document to help to streamline the process and save
+everyone's precious time.
+
+## Issues
+
+No software is bug-free. So, if you got an issue, follow these steps:
+
+- Search the [issue list](https://github.com/clbrge/svelte-web3/issues) for current and old issues.
+ - If you find an existing issue, please UPVOTE the issue by adding a "thumbs-up reaction". We use this to help prioritize issues!
+- If none of that is helping, create an issue with the following information:
+ - Clear title (shorter is better).
+ - Describe the issue in clear language.
+ - Share error logs, screenshots and etc.
+ - To speed up the issue fixing process, send us a sample repo with the issue you faced:
+
+## Pull Requests (PRs)
+
+We welcome all contributions. There are many ways you can help us. This is few of those ways:
diff --git a/README.md b/README.md
index 87f6452..f44c3e2 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,19 @@
----
# svelte-web3
Use the [web3.js library](https://web3js.readthedocs.io/) as a
-collection of [readable svelte stores](https://svelte.dev/tutorial/readable-stores)
-for Svelte, Sapper or Sveltekit.
+collection of [readable Svelte stores](https://svelte.dev/tutorial/readable-stores)
+for Svelte, Sapper or SvelteKit.
+
+If you prefer to use the [ethers.js
+library](https://docs.ethers.io/v5/) to intereact with EVM, you may be
+interested by our sister package
+[svelte-ethers-store](https://www.npmjs.com/package/svelte-ethers-store).
+
+### Community
+
+For additional help or discussion, join us [in our
+Discord](https://discord.gg/7yXuwDwaHF).
## Installation
@@ -20,93 +29,147 @@ npm i svelte-web3
```
-## Basic usage (defaultstore connected to one chain)
+This step is necessary for now because the Web3.js library doesn't
+play well with bundlers (webpack, vite, snowpack, etc), thus we cannot
+simply add a dependency in package.json.
+
+
+## Basic usage (default stores connected to one chain)
+
+### Derived stores
+
+This library creates a set of readable Svelte stores that are
+automatically updated when a new connection happens, or when the chain
+or the selected account change. You can import them directly in any
+Svelte or JavaScript files :
+
+```js
+import { connected, web3, selectedAccount, chainId, chainData } from 'svelte-web3'
+```
+
+ * connected: store value is true a connection has been set up.
+ * web3: store value is a Web3.js instance when connected.
+ * selectedAccount: store value is the current selected account (when connected).
+ * chainId: store value is the current chainId when connected.
+ * chainData: store value is the current blokchain CAIP-2 data (when connected), see below.
-Import the `defaultChainStore` main connection helper and needed derived Svelte stores (see list below):
+For these stores to be useful in your Svelte application, a connection to an EVM
+blockchain first need to established . The abstract helper
+`defaultEvmStores` can be used to initiate the connection and automatically
+instanciate all stores.
```js
-import { defaultChainStore, web3, selectedAccount, connected, chainData } from 'svelte-web3'
+import { defaultEvmStores } from 'svelte-web3'
```
-:exclamation: `defaultChainStore` was named before `ethStore`. The
+:exclamation: `defaultEvmStores` was named before `defaultChainStore`. The
former naming still works but will be removed in later versions of
`svelte-web3` package. Please update your code!
-### Connection with the browser provider (wallets like metamask)
+### Connection with the browser provider (eg wallets like Metamask)
-To enable a connection with the current window provider:
+To enable a connection with the current window provider, simply call
+`setBrowserProvider` on the library abstract helper:
```js
-defaultChainStore.setBrowserProvider()
+defaultEvmStores.setBrowserProvider()
```
-Please note that your code need to be in browser context when
-`setBrowserProvider` is running. So you may want to use `onMount` when
-using Sapper or Sveltekit. Similarly, you cannot use
-`setBrowserProvider` in SSR context.
+Please note that `setBrowserProvider` can only to be executed in a browser
+context. So you may want to use `onMount` when using Sapper or
+SvelteKit. Similarly, you cannot use `setBrowserProvider` in SSR
+context.
```js
onMount(
() => {
// add a test to return in SSR context
- defaultChainStore.setBrowserProvider()
+ defaultEvmStores.setBrowserProvider()
}
)
```
### Connection with other providers (ws, http, Web3Modal, Walletconnect, etc)
-To enable connection using an url string or a valid provider object
-(as returned by web3Modal or WalletConnect for example):
+To enable connection using an URL string or a valid provider object
+(for example as returned by web3Modal or WalletConnect):
```js
-defaultChainStore.setProvider()
+defaultEvmStores.setProvider()
```
Please check `examples/svelte-app-template-web3/src/Web3Modal.svelte` in github.
+### Using the stores
-### Forcing a disconnect (and event subscriptions from a provider)
+After a connection has been established, you may import the stores
+anywhere in your application. Most of the time, you should use the `$`
+prefix Svelte notation to access the stores values.
-Simply call the function `close` directly on the store. For example with the default store:
-```js
-defaultChainStore.close()
+```html
+
+
+{#if !$connected}
+
+
My application is not yet connected
+
+{:else}
+
+
Connected to chain with id {$chainId}
+
+{/if}
```
-### Using the Web3 instance $web3 after the connection
+### Using the Web3 API
-If a connection is successful, you can access the instantiated web3.js
-using the `$` svelte store syntax :
+Likewise use the `$` prefix Svelte notation to access its instance and
+use the full Web3.js API. (beware, in the Web3.js library
+documentation, instances are always noted as `web3`, without `$`, but
+in the context of `svelte-web3`, `web3` is the Svelte store itself,
+not it's value).
```js
-$web3.eth.getBalance()
+ import { web3, selectedAccount } from 'svelte-web3'
+
+ // ...
+
+ const { name, chainId } = await $web3.eth.getChainId()
+
+ const balance = await $web3.eth.getBalance('0x0000000000000000000000000000000000000000') : ''
```
-The whole Web3.js API is now usable in the `
+
+
balance =
+
+```
+
## Simultaneous multi chain usage
You can also using the library to create several stores, each
@@ -185,15 +266,15 @@ connection to the same chain througth the browser wallet and
simultaneously with Infura; or many stores each connected to a
different chains at the same time.
-In this case, use the `makeChainStore` factory function as below :
+In this case, use the `makeEvmStores` factory function as below :
```js
- import { makeChainStore } from 'svelte-web3'
+ import { makeEvmStores } from 'svelte-web3'
- let ethStore, web3, connected, selectedAccount, chainId, chainData
- ({ web3, connected, selectedAccount, chainId, chainData, ...ethStore } = makeChainStore(''))
+ let evmStores, web3, connected, selectedAccount, chainId, chainData
+ ({ web3, connected, selectedAccount, chainId, chainData, ...evmStores } = makeEvmStores(''))
- ethStore.setProvider('https://rpc.slock.it/goerli')
+ evmStores.setProvider('https://rpc.slock.it/goerli')
```
`` can be an arbitrary name to be able to retrieve the store with the function `getChainStore`
@@ -203,21 +284,21 @@ without reinitializing the conection:
```js
import { getChainStore } from 'svelte-web3'
- let ethStore, web3, connected, selectedAccount, chainId, chainData
- ({ web3, connected, selectedAccount, chainId, chainData, ...ethStore } = getChainStore(''))
+ let evmStores, web3, connected, selectedAccount, chainId, chainData
+ ({ web3, connected, selectedAccount, chainId, chainData, ...evmStores } = getChainStore(''))
```
The `web3` store and all other derived stores will work the same way as with the default store.
-If you want to use the different chain stores in the same svelte file
+If you want to use the different chain stores in the same Svelte file
(not advised, it's better to use subcomponents), you may renamed the
stores this way :
```js
- let ethStore_A, web3_A, ethStore_B, web3_B
+ let evmStores_A, web3_A, evmStores_B, web3_B
- ({ web3: web3_A, ...ethStore_A } = makeChainStore(''))
- ({ web3: web3_B, ...ethStore_B } = makeChainStore(''))
+ ({ web3: web3_A, ...evmStores_A } = makeEvmStores(''))
+ ({ web3: web3_B, ...evmStores_B } = makeEvmStores(''))
```
## Examples
@@ -225,20 +306,29 @@ stores this way :
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 (based on rollup template)
-Please check `examples/svelte-app-template-web3` in github.
+Please check [`examples/svelte-app-template-web3` in github]
+(https://github.com/clbrge/svelte-web3/tree/master/examples/svelte-app-template-web3).
+
+Contains demos to use the default store and multi stores.
+
+### SvelteKit basic example
-Contain both sub-examples to use the default store and multi stores.
+Please check [`examples/sveltekit-app-template-web3` in github]
+(https://github.com/clbrge/svelte-web3/tree/master/examples/sveltekit-app-template-web3).
### Sapper basic example (based on webpack template)
-Please check `examples/sapper-app-template-web3` in github.
+Please check [`examples/sapper-app-template-web3` in github]
+(https://github.com/clbrge/svelte-web3/tree/master/examples/sapper-app-template-web3).
+Please check `examples/sapper-app-template-web3` in github.
### tradingstrategy.ai presented at EthLisbon 2021
-A website presented in EthLisbon 2021, used svelte-web3 for building the frontend. :
+A website presented in EthLisbon 2021, used svelte-web3 (version 2) for building the frontend. :
* The page is live here: https://tradingstrategy.ai/strategy/ethlisbon
* Source code : https://github.com/tradingstrategy-ai/frontend/blob/master/src/lib/web3/Investor.svelte
diff --git a/examples/sapper-app-template-web3/README.md b/examples/sapper-app-template-web3/README.md
index 8dc7474..ce25b7c 100644
--- a/examples/sapper-app-template-web3/README.md
+++ b/examples/sapper-app-template-web3/README.md
@@ -2,9 +2,11 @@
The default template for setting up a [Sapper](https://github.com/sveltejs/sapper) project. Can use either Rollup or webpack as bundler.
+## Please note
-## Getting started
+Sapper is no longer being actively developed. You may be interested in using Sapper's succesor, [SvelteKit](https://kit.svelte.dev/) for new projects.
+## Getting started
### Using `degit`
diff --git a/examples/sapper-app-template-web3/package.json b/examples/sapper-app-template-web3/package.json
index 63e324f..d52eebd 100644
--- a/examples/sapper-app-template-web3/package.json
+++ b/examples/sapper-app-template-web3/package.json
@@ -11,15 +11,15 @@
"dependencies": {
"compression": "^1.7.1",
"polka": "next",
- "sirv": "^1.0.0",
- "svelte-web3": "^1.3.4"
+ "sirv": "^1.0.0"
},
"devDependencies": {
- "file-loader": "^6.0.0",
+ "svelte-web3": "file:../../",
"sapper": "^0.28.0",
"svelte": "^3.17.3",
- "svelte-loader": "^2.9.0",
- "webpack": "^4.7.0",
+ "file-loader": "^6.0.0",
+ "svelte-loader": "^3.0.0",
+ "webpack": "^4.46.0",
"webpack-modules": "^1.0.0"
}
}
diff --git a/examples/sapper-app-template-web3/scripts/setupTypeScript.js b/examples/sapper-app-template-web3/scripts/setupTypeScript.js
index 68e5b56..fb5cbdf 100644
--- a/examples/sapper-app-template-web3/scripts/setupTypeScript.js
+++ b/examples/sapper-app-template-web3/scripts/setupTypeScript.js
@@ -194,12 +194,10 @@ function updateWebpackConfig() {
/entry: config\.serviceworker\.entry\(\)/,
`entry: { 'service-worker': config.serviceworker.entry()['service-worker'].replace(/\\.js$/, '.ts') }`
],
- // Add preprocess to the svelte config, this is tricky because there's no easy signifier.
- // Instead we look for 'hydratable: true,'
[
- /hydratable: true(?!,\n\s*preprocess)/g,
- 'hydratable: true,\n\t\t\t\t\t\t\tpreprocess: sveltePreprocess({ sourceMap: dev })'
- ],
+ /loader: 'svelte-loader',\n\t\t\t\t\t\toptions: {/g,
+ 'loader: \'svelte-loader\',\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tpreprocess: sveltePreprocess({ sourceMap: dev }),'
+ ],
// Add TypeScript rules for client and server
[
/module: {\n\s*rules: \[\n\s*(?!{\n\s*test: \/\\\.ts\$\/)/g,
diff --git a/examples/sapper-app-template-web3/src/ambient.d.ts b/examples/sapper-app-template-web3/src/ambient.d.ts
index ec71cae..a26164d 100644
--- a/examples/sapper-app-template-web3/src/ambient.d.ts
+++ b/examples/sapper-app-template-web3/src/ambient.d.ts
@@ -10,30 +10,30 @@
*/
declare module "*.gif" {
const value: string;
- export = value;
+ export default value;
}
declare module "*.jpg" {
const value: string;
- export = value;
+ export default value;
}
declare module "*.jpeg" {
const value: string;
- export = value;
+ export default value;
}
declare module "*.png" {
const value: string;
- export = value;
+ export default value;
}
declare module "*.svg" {
const value: string;
- export = value;
+ export default value;
}
declare module "*.webp" {
const value: string;
- export = value;
+ export default value;
}
diff --git a/examples/sapper-app-template-web3/src/routes/web3test.svelte b/examples/sapper-app-template-web3/src/routes/web3test.svelte
index f0cb7dd..1a50574 100644
--- a/examples/sapper-app-template-web3/src/routes/web3test.svelte
+++ b/examples/sapper-app-template-web3/src/routes/web3test.svelte
@@ -1,13 +1,13 @@
+
+
+
+
+
+
diff --git a/examples/sveltekit-app-template-web3/src/lib/header/svelte-logo.svg b/examples/sveltekit-app-template-web3/src/lib/header/svelte-logo.svg
new file mode 100644
index 0000000..49492a8
--- /dev/null
+++ b/examples/sveltekit-app-template-web3/src/lib/header/svelte-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/examples/sveltekit-app-template-web3/src/routes/__layout.svelte b/examples/sveltekit-app-template-web3/src/routes/__layout.svelte
new file mode 100644
index 0000000..51316ff
--- /dev/null
+++ b/examples/sveltekit-app-template-web3/src/routes/__layout.svelte
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/sveltekit-app-template-web3/src/routes/about.svelte b/examples/sveltekit-app-template-web3/src/routes/about.svelte
new file mode 100644
index 0000000..569d3e1
--- /dev/null
+++ b/examples/sveltekit-app-template-web3/src/routes/about.svelte
@@ -0,0 +1,50 @@
+
+
+
+ About
+
+
+
+
About this app
+
+
+ This is a SvelteKit app. You can make your own by typing the
+ following into your command line and following the prompts:
+
+
+
+
npm init svelte@next
+
+
+ The page you're looking at is purely static HTML, with no client-side interactivity needed.
+ Because of that, we don't need to load any JavaScript. Try viewing the page's source, or opening
+ the devtools network panel and reloading.
+
+
+
+ The TODOs page illustrates SvelteKit's data loading and form handling. Try using
+ it with JavaScript disabled!
+
+
+
+
+
+
diff --git a/examples/sveltekit-app-template-web3/src/routes/todos/[uid].json.js b/examples/sveltekit-app-template-web3/src/routes/todos/[uid].json.js
new file mode 100644
index 0000000..4373f20
--- /dev/null
+++ b/examples/sveltekit-app-template-web3/src/routes/todos/[uid].json.js
@@ -0,0 +1,14 @@
+import { api } from './_api';
+
+// PATCH /todos/:uid.json
+export const patch = async (request) => {
+ return api(request, `todos/${request.locals.userid}/${request.params.uid}`, {
+ text: request.body.get('text'),
+ done: request.body.has('done') ? !!request.body.get('done') : undefined
+ });
+};
+
+// DELETE /todos/:uid.json
+export const del = async (request) => {
+ return api(request, `todos/${request.locals.userid}/${request.params.uid}`);
+};
diff --git a/examples/sveltekit-app-template-web3/src/routes/todos/_api.js b/examples/sveltekit-app-template-web3/src/routes/todos/_api.js
new file mode 100644
index 0000000..9dc73ad
--- /dev/null
+++ b/examples/sveltekit-app-template-web3/src/routes/todos/_api.js
@@ -0,0 +1,45 @@
+/*
+ This module is used by the /todos.json and /todos/[uid].json
+ endpoints to make calls to api.svelte.dev, which stores todos
+ for each user. The leading underscore indicates that this is
+ a private module, _not_ an endpoint — visiting /todos/_api
+ will net you a 404 response.
+
+ (The data on the todo app will expire periodically; no
+ guarantees are made. Don't use it to organise your life.)
+*/
+
+const base = 'https://api.svelte.dev';
+
+export async function api(request, resource, data) {
+ // user must have a cookie set
+ if (!request.locals.userid) {
+ return { status: 401 };
+ }
+
+ const res = await fetch(`${base}/${resource}`, {
+ method: request.method,
+ headers: {
+ 'content-type': 'application/json'
+ },
+ body: data && JSON.stringify(data)
+ });
+
+ // if the request came from a