@multiplatform.one/web3 6.0.3 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/connectkit/web3Bridge.cjs +1 -1
- package/dist/cjs/connectkit/web3Bridge.native.js +1 -1
- package/dist/cjs/connectkit/web3Bridge.native.js.map +1 -1
- package/dist/cjs/providers/WalletProvider.cjs +7 -11
- package/dist/cjs/providers/WalletProvider.native.js +10 -9
- package/dist/cjs/providers/WalletProvider.native.js.map +1 -1
- package/dist/cjs/providers/walletConfig.cjs +23 -0
- package/dist/cjs/providers/walletConfig.native.js +27 -0
- package/dist/cjs/providers/walletConfig.native.js.map +1 -1
- package/dist/cjs/providers/walletConfig.spec.cjs +44 -0
- package/dist/cjs/providers/walletConfig.spec.native.js +57 -0
- package/dist/cjs/providers/walletConfig.spec.native.js.map +1 -0
- package/dist/esm/connectkit/web3Bridge.mjs +1 -1
- package/dist/esm/connectkit/web3Bridge.mjs.map +1 -1
- package/dist/esm/connectkit/web3Bridge.native.js +1 -1
- package/dist/esm/connectkit/web3Bridge.native.js.map +1 -1
- package/dist/esm/providers/WalletProvider.mjs +10 -14
- package/dist/esm/providers/WalletProvider.mjs.map +1 -1
- package/dist/esm/providers/WalletProvider.native.js +14 -13
- package/dist/esm/providers/WalletProvider.native.js.map +1 -1
- package/dist/esm/providers/walletConfig.mjs +24 -2
- package/dist/esm/providers/walletConfig.mjs.map +1 -1
- package/dist/esm/providers/walletConfig.native.js +28 -2
- package/dist/esm/providers/walletConfig.native.js.map +1 -1
- package/dist/esm/providers/walletConfig.spec.mjs +45 -0
- package/dist/esm/providers/walletConfig.spec.mjs.map +1 -0
- package/dist/esm/providers/walletConfig.spec.native.js +55 -0
- package/dist/esm/providers/walletConfig.spec.native.js.map +1 -0
- package/dist/jsx/connectkit/web3Bridge.mjs +1 -1
- package/dist/jsx/connectkit/web3Bridge.mjs.map +1 -1
- package/dist/jsx/connectkit/web3Bridge.native.js +1 -1
- package/dist/jsx/connectkit/web3Bridge.native.js.map +1 -1
- package/dist/jsx/providers/WalletProvider.mjs +10 -14
- package/dist/jsx/providers/WalletProvider.mjs.map +1 -1
- package/dist/jsx/providers/WalletProvider.native.js +10 -9
- package/dist/jsx/providers/WalletProvider.native.js.map +1 -1
- package/dist/jsx/providers/walletConfig.mjs +24 -2
- package/dist/jsx/providers/walletConfig.mjs.map +1 -1
- package/dist/jsx/providers/walletConfig.native.js +27 -0
- package/dist/jsx/providers/walletConfig.native.js.map +1 -1
- package/dist/jsx/providers/walletConfig.spec.mjs +45 -0
- package/dist/jsx/providers/walletConfig.spec.mjs.map +1 -0
- package/dist/jsx/providers/walletConfig.spec.native.js +57 -0
- package/dist/jsx/providers/walletConfig.spec.native.js.map +1 -0
- package/package.json +4 -4
- package/src/connectkit/web3Bridge.tsx +8 -2
- package/src/providers/WalletProvider.native.tsx +22 -12
- package/src/providers/WalletProvider.tsx +11 -12
- package/src/providers/walletConfig.spec.ts +42 -0
- package/src/providers/walletConfig.ts +38 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { hardhat, mainnet, sepolia } from "wagmi/chains";
|
|
3
|
+
import { defaultChains, resolveChains } from "./walletConfig.mjs";
|
|
4
|
+
const base = {
|
|
5
|
+
walletConnectProjectId: "",
|
|
6
|
+
appName: "test"
|
|
7
|
+
};
|
|
8
|
+
describe("resolveChains", () => {
|
|
9
|
+
it("filters testnets by default", () => {
|
|
10
|
+
const chains = resolveChains(base);
|
|
11
|
+
expect(chains.map(c => c.id)).not.toContain(sepolia.id);
|
|
12
|
+
expect(chains[0].id).toBe(mainnet.id);
|
|
13
|
+
});
|
|
14
|
+
it("keeps testnets when enableTestnets is on", () => {
|
|
15
|
+
const chains = resolveChains({
|
|
16
|
+
...base,
|
|
17
|
+
enableTestnets: true
|
|
18
|
+
});
|
|
19
|
+
expect(chains.map(c => c.id)).toContain(sepolia.id);
|
|
20
|
+
expect(chains).toHaveLength(defaultChains.length);
|
|
21
|
+
});
|
|
22
|
+
it("prepends the hardhat dev chain as the default when localnet is on", () => {
|
|
23
|
+
const chains = resolveChains({
|
|
24
|
+
...base,
|
|
25
|
+
localnet: true
|
|
26
|
+
});
|
|
27
|
+
expect(chains[0].id).toBe(hardhat.id);
|
|
28
|
+
expect(chains[0].rpcUrls.default.http[0]).toBe("http://127.0.0.1:8545");
|
|
29
|
+
expect(chains.filter(c => c.id === hardhat.id)).toHaveLength(1);
|
|
30
|
+
expect(chains.map(c => c.id)).toContain(mainnet.id);
|
|
31
|
+
});
|
|
32
|
+
it("honours a custom localnet RPC url (emulator host addresses)", () => {
|
|
33
|
+
const chains = resolveChains({
|
|
34
|
+
...base,
|
|
35
|
+
localnet: true,
|
|
36
|
+
localnetRpcUrl: "http://10.0.2.2:8545"
|
|
37
|
+
});
|
|
38
|
+
expect(chains[0].id).toBe(hardhat.id);
|
|
39
|
+
expect(chains[0].rpcUrls.default.http[0]).toBe("http://10.0.2.2:8545");
|
|
40
|
+
});
|
|
41
|
+
it("does not add the dev chain when localnet is off", () => {
|
|
42
|
+
expect(resolveChains(base).map(c => c.id)).not.toContain(hardhat.id);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=walletConfig.spec.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["describe","expect","it","hardhat","mainnet","sepolia","defaultChains","resolveChains","base","walletConnectProjectId","appName","chains","map","c","id","not","toContain","toBe","enableTestnets","toHaveLength","length","localnet","rpcUrls","default","http","filter","localnetRpcUrl"],"sources":["../../../src/providers/walletConfig.spec.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,EAAUC,MAAA,EAAQC,EAAA,QAAU;AACrC,SAASC,OAAA,EAASC,OAAA,EAASC,OAAA,QAAe;AAC1C,SAASC,aAAA,EAAeC,aAAA,QAAsC;AAE9D,MAAMC,IAAA,GAAmB;EAAEC,sBAAA,EAAwB;EAAIC,OAAA,EAAS;AAAO;AAEvEV,QAAA,CAAS,iBAAiB,MAAM;EAC9BE,EAAA,CAAG,+BAA+B,MAAM;IACtC,MAAMS,MAAA,GAASJ,aAAA,CAAcC,IAAI;IACjCP,MAAA,CAAOU,MAAA,CAAOC,GAAA,CAAKC,CAAA,IAAMA,CAAA,CAAEC,EAAE,CAAC,EAAEC,GAAA,CAAIC,SAAA,CAAUX,OAAA,CAAQS,EAAE;IACxDb,MAAA,CAAOU,MAAA,CAAO,CAAC,EAAEG,EAAE,EAAEG,IAAA,CAAKb,OAAA,CAAQU,EAAE;EACtC,CAAC;EAEDZ,EAAA,CAAG,4CAA4C,MAAM;IACnD,MAAMS,MAAA,GAASJ,aAAA,CAAc;MAAE,GAAGC,IAAA;MAAMU,cAAA,EAAgB;IAAK,CAAC;IAC9DjB,MAAA,CAAOU,MAAA,CAAOC,GAAA,CAAKC,CAAA,IAAMA,CAAA,CAAEC,EAAE,CAAC,EAAEE,SAAA,CAAUX,OAAA,CAAQS,EAAE;IACpDb,MAAA,CAAOU,MAAM,EAAEQ,YAAA,CAAab,aAAA,CAAcc,MAAM;EAClD,CAAC;EAEDlB,EAAA,CAAG,qEAAqE,MAAM;IAC5E,MAAMS,MAAA,GAASJ,aAAA,CAAc;MAAE,GAAGC,IAAA;MAAMa,QAAA,EAAU;IAAK,CAAC;IACxDpB,MAAA,CAAOU,MAAA,CAAO,CAAC,EAAEG,EAAE,EAAEG,IAAA,CAAKd,OAAA,CAAQW,EAAE;IACpCb,MAAA,CAAOU,MAAA,CAAO,CAAC,EAAEW,OAAA,CAAQC,OAAA,CAAQC,IAAA,CAAK,CAAC,CAAC,EAAEP,IAAA,CAAK,uBAAuB;IAEtEhB,MAAA,CAAOU,MAAA,CAAOc,MAAA,CAAQZ,CAAA,IAAMA,CAAA,CAAEC,EAAA,KAAOX,OAAA,CAAQW,EAAE,CAAC,EAAEK,YAAA,CAAa,CAAC;IAChElB,MAAA,CAAOU,MAAA,CAAOC,GAAA,CAAKC,CAAA,IAAMA,CAAA,CAAEC,EAAE,CAAC,EAAEE,SAAA,CAAUZ,OAAA,CAAQU,EAAE;EACtD,CAAC;EAEDZ,EAAA,CAAG,+DAA+D,MAAM;IACtE,MAAMS,MAAA,GAASJ,aAAA,CAAc;MAC3B,GAAGC,IAAA;MACHa,QAAA,EAAU;MACVK,cAAA,EAAgB;IAClB,CAAC;IACDzB,MAAA,CAAOU,MAAA,CAAO,CAAC,EAAEG,EAAE,EAAEG,IAAA,CAAKd,OAAA,CAAQW,EAAE;IACpCb,MAAA,CAAOU,MAAA,CAAO,CAAC,EAAEW,OAAA,CAAQC,OAAA,CAAQC,IAAA,CAAK,CAAC,CAAC,EAAEP,IAAA,CAAK,sBAAsB;EACvE,CAAC;EAEDf,EAAA,CAAG,mDAAmD,MAAM;IAC1DD,MAAA,CAAOM,aAAA,CAAcC,IAAI,EAAEI,GAAA,CAAKC,CAAA,IAAMA,CAAA,CAAEC,EAAE,CAAC,EAAEC,GAAA,CAAIC,SAAA,CAAUb,OAAA,CAAQW,EAAE;EACvE,CAAC;AACH,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var import_vitest = require("vitest");
|
|
4
|
+
var import_chains = require("wagmi/chains");
|
|
5
|
+
var import_walletConfig = require("./walletConfig.native.js");
|
|
6
|
+
var base = {
|
|
7
|
+
walletConnectProjectId: "",
|
|
8
|
+
appName: "test"
|
|
9
|
+
};
|
|
10
|
+
(0, import_vitest.describe)("resolveChains", function () {
|
|
11
|
+
(0, import_vitest.it)("filters testnets by default", function () {
|
|
12
|
+
var chains = (0, import_walletConfig.resolveChains)(base);
|
|
13
|
+
(0, import_vitest.expect)(chains.map(function (c) {
|
|
14
|
+
return c.id;
|
|
15
|
+
})).not.toContain(import_chains.sepolia.id);
|
|
16
|
+
(0, import_vitest.expect)(chains[0].id).toBe(import_chains.mainnet.id);
|
|
17
|
+
});
|
|
18
|
+
(0, import_vitest.it)("keeps testnets when enableTestnets is on", function () {
|
|
19
|
+
var chains = (0, import_walletConfig.resolveChains)({
|
|
20
|
+
...base,
|
|
21
|
+
enableTestnets: true
|
|
22
|
+
});
|
|
23
|
+
(0, import_vitest.expect)(chains.map(function (c) {
|
|
24
|
+
return c.id;
|
|
25
|
+
})).toContain(import_chains.sepolia.id);
|
|
26
|
+
(0, import_vitest.expect)(chains).toHaveLength(import_walletConfig.defaultChains.length);
|
|
27
|
+
});
|
|
28
|
+
(0, import_vitest.it)("prepends the hardhat dev chain as the default when localnet is on", function () {
|
|
29
|
+
var chains = (0, import_walletConfig.resolveChains)({
|
|
30
|
+
...base,
|
|
31
|
+
localnet: true
|
|
32
|
+
});
|
|
33
|
+
(0, import_vitest.expect)(chains[0].id).toBe(import_chains.hardhat.id);
|
|
34
|
+
(0, import_vitest.expect)(chains[0].rpcUrls.default.http[0]).toBe("http://127.0.0.1:8545");
|
|
35
|
+
(0, import_vitest.expect)(chains.filter(function (c) {
|
|
36
|
+
return c.id === import_chains.hardhat.id;
|
|
37
|
+
})).toHaveLength(1);
|
|
38
|
+
(0, import_vitest.expect)(chains.map(function (c) {
|
|
39
|
+
return c.id;
|
|
40
|
+
})).toContain(import_chains.mainnet.id);
|
|
41
|
+
});
|
|
42
|
+
(0, import_vitest.it)("honours a custom localnet RPC url (emulator host addresses)", function () {
|
|
43
|
+
var chains = (0, import_walletConfig.resolveChains)({
|
|
44
|
+
...base,
|
|
45
|
+
localnet: true,
|
|
46
|
+
localnetRpcUrl: "http://10.0.2.2:8545"
|
|
47
|
+
});
|
|
48
|
+
(0, import_vitest.expect)(chains[0].id).toBe(import_chains.hardhat.id);
|
|
49
|
+
(0, import_vitest.expect)(chains[0].rpcUrls.default.http[0]).toBe("http://10.0.2.2:8545");
|
|
50
|
+
});
|
|
51
|
+
(0, import_vitest.it)("does not add the dev chain when localnet is off", function () {
|
|
52
|
+
(0, import_vitest.expect)((0, import_walletConfig.resolveChains)(base).map(function (c) {
|
|
53
|
+
return c.id;
|
|
54
|
+
})).not.toContain(import_chains.hardhat.id);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=walletConfig.spec.native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["import_vitest","require","import_chains","import_walletConfig","base","walletConnectProjectId","appName","describe","it","chains","resolveChains","expect","map","c","id","not","toContain","sepolia","toBe","mainnet","enableTestnets","toHaveLength","defaultChains","length","localnet","hardhat","rpcUrls","default","http","filter"],"sources":["../../../src/providers/walletConfig.spec.ts"],"sourcesContent":[null],"mappings":"AAAA,YAAS;;AACT,IAAAA,aAAS,GAASC,OAAS;AAC3B,IAAAC,aAAS,GAAAD,OAAe;AAExB,IAAAE,mBAA2B,GAAAF,OAAA,2BAA4B;AAEvD,IAAAG,IAAA,GAAS;EACPC,sBAAG;EACDC,OAAA,EAAM;AACN;AACA,IAAAN,aAAO,CAAOO,QAAO,iBAAe;EACtC,CAAC,GAAAP,aAAA,CAAAQ,EAAA;IAED,IAAGC,MAAA,OAAAN,mBAAA,CAAAO,aAA4C,EAAMN,IAAA;IACnD,IAAAJ,aAAe,CAAAW,MAAA,EAAAF,MAAgB,CAAAG,GAAG,WAAMC,CAAA;MACxC,OAAOA,CAAA,CAAAC,EAAA;IACP,IAAAC,GAAO,CAAAC,SAAQ,CAAAd,aAAa,CAAAe,OAAA,CAAAH,EAAc;IAC3C,IAAAd,aAAA,CAAAW,MAAA,EAAAF,MAAA,IAAAK,EAAA,EAAAI,IAAA,CAAAhB,aAAA,CAAAiB,OAAA,CAAAL,EAAA;EAED;EACE,IAAAd,aAAe,CAAAQ,EAAA,4CAAyC;IACxD,IAAAC,MAAO,IAAO,CAAC,EAAEN,mBAAmB,CAAAO,aAAA;MACpC,GAAAN,IAAO;MAEPgB,cAAc;IACd;IACD,IAAApB,aAAA,CAAAW,MAAA,EAAAF,MAAA,CAAAG,GAAA,WAAAC,CAAA;MAEE,OAAAA,CAAA,CAAAC,EAAA;IACD,IAAAE,SAAM,CAAAd,aAAS,CAAAe,OAAc,CAAAH,EAAA;IAAA,EAC3B,EAAAd,aAAG,CAAAW,MAAA,EAAAF,MAAA,EAAAY,YAAA,CAAAlB,mBAAA,CAAAmB,aAAA,CAAAC,MAAA;EAAA;EACO,IACVvB,aAAA,CAAAQ,EAAgB;IAClB,IAACC,MAAA,OAAAN,mBAAA,CAAAO,aAAA;MACD,GAAAN,IAAO;MACPoB,QAAO;IACR;IAED,CAAG,GAAAxB,aAAA,CAAAW,MAAA,EAAAF,MAAA,IAAAK,EAAA,EAAAI,IAAA,CAAAhB,aAAyD,CAAAuB,OAAA,CAAAX,EAAA;IAC1D,IAAAd,aAAO,CAAAW,MAAc,EAAIF,MAAO,IAAAiB,OAAW,CAAAC,OAAM,CAAAC,IAAA,GAAU,EAAAV,IAAA,wBAAU;IACtE,IAAAlB,aAAA,CAAAW,MAAA,EAAAF,MAAA,CAAAoB,MAAA,WAAAhB,CAAA;MACF,OAAAA,CAAA,CAAAC,EAAA,KAAAZ,aAAA,CAAAuB,OAAA,CAAAX,EAAA","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/web3",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Web3 wallet integration for multiplatform.one ecosystem with ConnectKit and wagmi",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"connectkit",
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"tamagui": "2.0.0-rc.41",
|
|
80
80
|
"viem": "^2.48.7",
|
|
81
81
|
"wagmi": "^3.6.9",
|
|
82
|
-
"@multiplatform.one/
|
|
83
|
-
"@multiplatform.one/
|
|
82
|
+
"@multiplatform.one/connectkit": "6.1.0",
|
|
83
|
+
"@multiplatform.one/gpg": "6.1.0"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@tamagui/build": "2.0.0-rc.41",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"vite": "^8.0.10",
|
|
98
98
|
"vite-plugin-singlefile": "^2.3.3",
|
|
99
99
|
"vitest": "^4.1.5",
|
|
100
|
-
"@multiplatform.one/config": "6.0
|
|
100
|
+
"@multiplatform.one/config": "6.1.0"
|
|
101
101
|
},
|
|
102
102
|
"peerDependencies": {
|
|
103
103
|
"@tanstack/react-query": "^5.62.0",
|
|
@@ -80,8 +80,14 @@ export const Web3ModalBridge: React.FC<Web3ModalBridgeProps> = ({
|
|
|
80
80
|
useEffect(() => {
|
|
81
81
|
if (isConnected) {
|
|
82
82
|
// Skip the redirect/close when already on PROFILE or the SIWE screen
|
|
83
|
-
// (must be &&: with || the predicate was a tautology and always fired)
|
|
84
|
-
|
|
83
|
+
// (must be &&: with || the predicate was a tautology and always fired),
|
|
84
|
+
// or on the GPG screen — wagmi's async auto-reconnect must not hijack
|
|
85
|
+
// (or close) an in-progress GPG sign-in.
|
|
86
|
+
if (
|
|
87
|
+
context.route !== routes.PROFILE &&
|
|
88
|
+
context.route !== routes.SIGNINWITHETHEREUM &&
|
|
89
|
+
context.route !== routes.SIGNINWITHGPG
|
|
90
|
+
) {
|
|
85
91
|
if (signInWithEthereum && !context.options?.disableSiweRedirect) {
|
|
86
92
|
context.setRoute(routes.SIGNINWITHETHEREUM);
|
|
87
93
|
} else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
2
2
|
import type { PropsWithChildren } from "react";
|
|
3
3
|
import { createContext, useContext, useEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
4
|
-
import { AppState, Linking, StyleSheet, View } from "react-native";
|
|
4
|
+
import { AppState, Linking, Platform, StyleSheet, View } from "react-native";
|
|
5
5
|
import { WebView, type WebViewMessageEvent, type WebViewProps } from "react-native-webview";
|
|
6
6
|
import { http, WagmiProvider, createConfig } from "wagmi";
|
|
7
7
|
import { BridgeClient } from "../bridge/BridgeClient";
|
|
@@ -11,7 +11,7 @@ import { createPostMessageTransport } from "../bridge/postMessageTransport";
|
|
|
11
11
|
import { parseWalletReturn, shouldOpenExternally } from "./native/deepLink";
|
|
12
12
|
import { buildConfigInjection, buildInjectScript } from "./native/inject";
|
|
13
13
|
import { initialVisibility, nextVisibility } from "./native/visibility";
|
|
14
|
-
import { type Web3Config, Web3ConfigContext,
|
|
14
|
+
import { type Web3Config, Web3ConfigContext, resolveChains } from "./walletConfig";
|
|
15
15
|
|
|
16
16
|
type WebViewSource = NonNullable<WebViewProps["source"]>;
|
|
17
17
|
|
|
@@ -114,14 +114,25 @@ export function WalletProvider({
|
|
|
114
114
|
}, [bridge]);
|
|
115
115
|
|
|
116
116
|
const wagmiConfig = useMemo(() => {
|
|
117
|
-
|
|
117
|
+
// Same chain resolution as web (testnet filter + optional localnet dev
|
|
118
|
+
// chain) -- on native, pass localnetRpcUrl with the host address the
|
|
119
|
+
// device/emulator can reach (e.g. http://10.0.2.2:8545 on Android).
|
|
120
|
+
const chains = resolveChains(web3Config);
|
|
121
|
+
const transports = Object.fromEntries(chains.map((chain) => [chain.id, http()]));
|
|
118
122
|
return createConfig({
|
|
119
|
-
chains
|
|
123
|
+
chains,
|
|
120
124
|
transports,
|
|
121
125
|
connectors: [createBridgeConnector(bridge)],
|
|
122
126
|
multiInjectedProviderDiscovery: false,
|
|
123
127
|
});
|
|
124
|
-
|
|
128
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
129
|
+
}, [
|
|
130
|
+
bridge,
|
|
131
|
+
web3Config.chains,
|
|
132
|
+
web3Config.enableTestnets,
|
|
133
|
+
web3Config.localnet,
|
|
134
|
+
web3Config.localnetRpcUrl,
|
|
135
|
+
]);
|
|
125
136
|
|
|
126
137
|
const solanaValue = useMemo<SolanaWalletContextValue>(
|
|
127
138
|
() => ({ bridge: solana, publicKey, connected: publicKey !== null }),
|
|
@@ -131,13 +142,12 @@ export function WalletProvider({
|
|
|
131
142
|
const onMessage = (event: WebViewMessageEvent) => transport.receive(event.nativeEvent.data);
|
|
132
143
|
|
|
133
144
|
// No inline HTML fallback: the bundle is too large for WKWebView source={{html}}.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
145
|
+
// Fall back to the documented dev setup (a static server on :8099 serving
|
|
146
|
+
// @multiplatform.one/web3/assets/webview.html; Android emulators reach the
|
|
147
|
+
// host at 10.0.2.2) instead of crashing the whole app shell when the config
|
|
148
|
+
// didn't carry a URL.
|
|
149
|
+
const defaultWebViewUrl = `http://${Platform.OS === "android" ? "10.0.2.2" : "localhost"}:8099/webview.html`;
|
|
150
|
+
const resolvedSource = webViewSource ?? { uri: web3Config.webViewUrl || defaultWebViewUrl };
|
|
141
151
|
|
|
142
152
|
return (
|
|
143
153
|
<Web3ConfigContext.Provider value={web3Config}>
|
|
@@ -6,7 +6,7 @@ import { useMemo } from "react";
|
|
|
6
6
|
import type { Chain } from "viem";
|
|
7
7
|
import { WagmiProvider, createConfig, http } from "wagmi";
|
|
8
8
|
import { createMockConnector } from "./mockConnector";
|
|
9
|
-
import { type Web3Config, Web3ConfigContext,
|
|
9
|
+
import { type Web3Config, Web3ConfigContext, resolveChains } from "./walletConfig";
|
|
10
10
|
|
|
11
11
|
export interface WalletProviderProps extends PropsWithChildren {
|
|
12
12
|
config: Web3Config;
|
|
@@ -34,21 +34,19 @@ export function WalletProvider({
|
|
|
34
34
|
appDescription = "Connect your wallet",
|
|
35
35
|
appUrl = isWeb && typeof window !== "undefined" ? window.location.origin : "",
|
|
36
36
|
appIcon,
|
|
37
|
-
chains
|
|
37
|
+
chains,
|
|
38
38
|
enableTestnets = false,
|
|
39
|
+
localnet = false,
|
|
40
|
+
localnetRpcUrl,
|
|
39
41
|
mockWallet = false,
|
|
40
42
|
} = web3Config;
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return chains;
|
|
49
|
-
}
|
|
50
|
-
return filtered as unknown as readonly [Chain, ...Chain[]];
|
|
51
|
-
}, [chains, enableTestnets]);
|
|
44
|
+
// Testnet filter + optional localnet dev chain (prepended -> default chain).
|
|
45
|
+
const activeChains = useMemo(
|
|
46
|
+
() => resolveChains(web3Config),
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
[chains, enableTestnets, localnet, localnetRpcUrl],
|
|
49
|
+
);
|
|
52
50
|
|
|
53
51
|
const wagmiConfig = useMemo(() => {
|
|
54
52
|
const chainIds = activeChains.map((chain) => chain.id).join(",");
|
|
@@ -59,6 +57,7 @@ export function WalletProvider({
|
|
|
59
57
|
appIcon,
|
|
60
58
|
walletConnectProjectId,
|
|
61
59
|
chainIds,
|
|
60
|
+
localnetRpcUrl,
|
|
62
61
|
mockWallet,
|
|
63
62
|
});
|
|
64
63
|
const cached = wagmiConfigCache.get(cacheKey);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { hardhat, mainnet, sepolia } from "wagmi/chains";
|
|
3
|
+
import { defaultChains, resolveChains, type Web3Config } from "./walletConfig";
|
|
4
|
+
|
|
5
|
+
const base: Web3Config = { walletConnectProjectId: "", appName: "test" };
|
|
6
|
+
|
|
7
|
+
describe("resolveChains", () => {
|
|
8
|
+
it("filters testnets by default", () => {
|
|
9
|
+
const chains = resolveChains(base);
|
|
10
|
+
expect(chains.map((c) => c.id)).not.toContain(sepolia.id);
|
|
11
|
+
expect(chains[0].id).toBe(mainnet.id);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("keeps testnets when enableTestnets is on", () => {
|
|
15
|
+
const chains = resolveChains({ ...base, enableTestnets: true });
|
|
16
|
+
expect(chains.map((c) => c.id)).toContain(sepolia.id);
|
|
17
|
+
expect(chains).toHaveLength(defaultChains.length);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("prepends the hardhat dev chain as the default when localnet is on", () => {
|
|
21
|
+
const chains = resolveChains({ ...base, localnet: true });
|
|
22
|
+
expect(chains[0].id).toBe(hardhat.id);
|
|
23
|
+
expect(chains[0].rpcUrls.default.http[0]).toBe("http://127.0.0.1:8545");
|
|
24
|
+
// still exactly one localnet entry ahead of the regular chains
|
|
25
|
+
expect(chains.filter((c) => c.id === hardhat.id)).toHaveLength(1);
|
|
26
|
+
expect(chains.map((c) => c.id)).toContain(mainnet.id);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("honours a custom localnet RPC url (emulator host addresses)", () => {
|
|
30
|
+
const chains = resolveChains({
|
|
31
|
+
...base,
|
|
32
|
+
localnet: true,
|
|
33
|
+
localnetRpcUrl: "http://10.0.2.2:8545",
|
|
34
|
+
});
|
|
35
|
+
expect(chains[0].id).toBe(hardhat.id);
|
|
36
|
+
expect(chains[0].rpcUrls.default.http[0]).toBe("http://10.0.2.2:8545");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("does not add the dev chain when localnet is off", () => {
|
|
40
|
+
expect(resolveChains(base).map((c) => c.id)).not.toContain(hardhat.id);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContext, useContext } from "react";
|
|
2
2
|
import type { Chain } from "viem";
|
|
3
|
-
import { arbitrum, base, mainnet, optimism, polygon, sepolia } from "wagmi/chains";
|
|
3
|
+
import { arbitrum, base, hardhat, mainnet, optimism, polygon, sepolia } from "wagmi/chains";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Shared config seam for both platform variants of WalletProvider. Keeping the
|
|
@@ -25,14 +25,51 @@ export interface Web3Config {
|
|
|
25
25
|
appIcon?: string;
|
|
26
26
|
chains?: readonly [Chain, ...Chain[]];
|
|
27
27
|
enableTestnets?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Add the local dev chain (hardhat, chain 31337, `make localnet`) and make it
|
|
30
|
+
* the DEFAULT chain, so dev builds point at the local node out of the box.
|
|
31
|
+
*/
|
|
32
|
+
localnet?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Local EVM JSON-RPC endpoint when `localnet` is on. Defaults to hardhat's
|
|
35
|
+
* http://127.0.0.1:8545 -- emulators need the host address instead (e.g.
|
|
36
|
+
* http://10.0.2.2:8545 on Android).
|
|
37
|
+
*/
|
|
38
|
+
localnetRpcUrl?: string;
|
|
28
39
|
/** Solana JSON-RPC endpoint (native bridge + web). */
|
|
29
40
|
solanaRpcUrl?: string;
|
|
41
|
+
/** Sui JSON-RPC endpoint (native bridge + web). */
|
|
42
|
+
suiRpcUrl?: string;
|
|
30
43
|
/** E2E only (native): route connect through the in-WebView mock wallet. */
|
|
31
44
|
mockWallet?: boolean;
|
|
32
45
|
/** Native: URL serving the wallet WebView HTML (preferred over the inline string). */
|
|
33
46
|
webViewUrl?: string;
|
|
34
47
|
}
|
|
35
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the active chain list for a Web3Config: apply the testnet filter,
|
|
51
|
+
* then (when `localnet` is on) prepend the hardhat dev chain so it becomes
|
|
52
|
+
* wagmi's default chain. Shared by the web and native WalletProviders so both
|
|
53
|
+
* platforms point at the same networks.
|
|
54
|
+
*/
|
|
55
|
+
export function resolveChains(config: Web3Config): readonly [Chain, ...Chain[]] {
|
|
56
|
+
const {
|
|
57
|
+
chains = defaultChains,
|
|
58
|
+
enableTestnets = false,
|
|
59
|
+
localnet = false,
|
|
60
|
+
localnetRpcUrl,
|
|
61
|
+
} = config;
|
|
62
|
+
let active: Chain[] = enableTestnets ? [...chains] : chains.filter((chain) => !chain.testnet);
|
|
63
|
+
if (active.length === 0) active = [...chains];
|
|
64
|
+
if (localnet) {
|
|
65
|
+
const local: Chain = localnetRpcUrl
|
|
66
|
+
? { ...hardhat, rpcUrls: { default: { http: [localnetRpcUrl] } } }
|
|
67
|
+
: hardhat;
|
|
68
|
+
active = [local, ...active.filter((chain) => chain.id !== hardhat.id)];
|
|
69
|
+
}
|
|
70
|
+
return active as unknown as readonly [Chain, ...Chain[]];
|
|
71
|
+
}
|
|
72
|
+
|
|
36
73
|
export const Web3ConfigContext = createContext<Web3Config | null>(null);
|
|
37
74
|
|
|
38
75
|
export function useWeb3Config(): Web3Config {
|