@dropfi/xrpl-react 0.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/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # @dropfi/xrpl-react
2
+
3
+ > React context + hook to access DropFi Wallet via `window.xrpl`
4
+
5
+ ## ๐Ÿš€ Features
6
+
7
+ - โœ… Auto-initializes the injected `window.xrpl` provider (extension or mobile)
8
+ - โœ… Provides `connect`, `disconnect`, `sendTransaction`, and `signMessage`
9
+ - โœ… React hook with `address`, `network`, `connectedAccounts`, and more
10
+ - โœ… Compatible with both browser extension and mobile webview injection
11
+
12
+ ---
13
+
14
+ ## ๐Ÿ“ฆ Installation
15
+
16
+ ```bash
17
+ pnpm add @dropfi/xrpl-react
18
+ ```
19
+
20
+ > Requires the DropFi wallet to be injected as `window.xrpl` โ€” via Chrome extension or React Native WebView.
21
+
22
+ ---
23
+
24
+ ## ๐Ÿงช Usage
25
+
26
+ ```tsx
27
+ import { XrplProvider, useXrplReact } from '@dropfi/xrpl-react';
28
+
29
+ export default function App() {
30
+ return (
31
+ <XrplProvider>
32
+ <SomeComponent />
33
+ </XrplProvider>
34
+ );
35
+ }
36
+
37
+ function SomeComponent() {
38
+ const { address, connect, disconnect } = useXrplReact();
39
+
40
+ return (
41
+ <div>
42
+ <p>Address: {address ?? 'Not connected'}</p>
43
+ <button onClick={connect}>Connect Wallet</button>
44
+ <button onClick={disconnect}>Disconnect</button>
45
+ </div>
46
+ );
47
+ }
48
+ ```
49
+
50
+ ---
51
+
52
+ ## ๐Ÿ”Œ API
53
+
54
+ ### `useXrplReact()`
55
+
56
+ Returns:
57
+
58
+ ```ts
59
+ {
60
+ address: string | undefined;
61
+ wallet: string | undefined;
62
+ isConnected: boolean;
63
+ connect: () => Promise<string>;
64
+ disconnect: () => Promise<void>;
65
+ sendTransaction: (tx: any) => Promise<any>;
66
+ signMessage: (message: string) => Promise<{ signature: string }>;
67
+ changeNetwork: (network: string) => Promise<any>;
68
+ connectedAccounts: string[];
69
+ network: string;
70
+ isConnecting: boolean;
71
+ error: string | null;
72
+ initialized: boolean;
73
+ }
74
+ ```
75
+
76
+ ---
77
+
78
+ ## ๐ŸŽง Events
79
+
80
+ These are internally emitted and listened to:
81
+
82
+ - `xrpl_selectedAddress`
83
+ - `xrpl_connectedAccounts`
84
+ - `xrpl_selectedNetwork`
85
+ - `xrpl_disconnect`
86
+
87
+ ---
88
+
89
+ ## ๐Ÿ”’ Requirements
90
+
91
+ Make sure your app runs in an environment where `window.xrpl` is available. This is injected by the DropFi wallet:
92
+
93
+ - Chrome extension
94
+ - React Native mobile app via WebView
95
+
96
+ ---
97
+
98
+ ## ๐Ÿ“„ License
99
+
100
+ MIT ยฉ [Travis Delly](https://github.com/dellybro)
package/dist/index.cjs ADDED
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ XrplProvider: () => XrplProvider,
24
+ useXrplReact: () => useXrplReact
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/provider.tsx
29
+ var import_react = require("react");
30
+ var import_jsx_runtime = require("react/jsx-runtime");
31
+ var XrplContext = (0, import_react.createContext)(null);
32
+ var XrplProvider = ({ config, children }) => {
33
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(XrplContext.Provider, { value: { config }, children });
34
+ };
35
+
36
+ // src/useXrplReact.tsx
37
+ var import_react2 = require("react");
38
+ function useXrplReact() {
39
+ const context = (0, import_react2.useContext)(XrplContext);
40
+ if (!context) {
41
+ throw new Error("useXrplReact must be used within a XrplProvider");
42
+ }
43
+ const [address, setAddress] = (0, import_react2.useState)();
44
+ const [connectedAccounts, setConnectedAccounts] = (0, import_react2.useState)([]);
45
+ const [network, setNetwork] = (0, import_react2.useState)("mainnet");
46
+ const [initialized, setInitialized] = (0, import_react2.useState)(false);
47
+ const [error, setError] = (0, import_react2.useState)(null);
48
+ const [isConnecting, setIsConnecting] = (0, import_react2.useState)(false);
49
+ (0, import_react2.useEffect)(() => {
50
+ if (typeof window === "undefined" || !window.xrpl) return;
51
+ window.xrpl?.initialize?.();
52
+ setInitialized(true);
53
+ }, []);
54
+ (0, import_react2.useEffect)(() => {
55
+ if (typeof window === "undefined" || !window.xrpl) return;
56
+ const handleSelectedNetwork = (val) => setNetwork(val);
57
+ const handleSelectedAddress = (val) => setAddress(val);
58
+ const handleConnectedAccounts = (val) => setConnectedAccounts(val);
59
+ window.xrpl?.on?.("xrpl_selectedNetwork", handleSelectedNetwork);
60
+ window.xrpl?.on?.("xrpl_selectedAddress", handleSelectedAddress);
61
+ window.xrpl?.on?.("xrpl_connectedAccounts", handleConnectedAccounts);
62
+ return () => {
63
+ window.xrpl?.off?.("xrpl_selectedNetwork", handleSelectedNetwork);
64
+ window.xrpl?.off?.("xrpl_selectedAddress", handleSelectedAddress);
65
+ window.xrpl?.off?.("xrpl_connectedAccounts", handleConnectedAccounts);
66
+ };
67
+ }, []);
68
+ const connect = async () => {
69
+ setIsConnecting(true);
70
+ try {
71
+ if (!window.xrpl) throw new Error("No window.xrpl found");
72
+ const response = await window.xrpl.connect();
73
+ setAddress(response);
74
+ return response;
75
+ } catch (err) {
76
+ setError(err.message);
77
+ throw err;
78
+ } finally {
79
+ setIsConnecting(false);
80
+ }
81
+ };
82
+ const disconnect = async () => {
83
+ if (!window.xrpl) throw new Error("No window.xrpl found");
84
+ await window.xrpl.disconnect(address);
85
+ setAddress(void 0);
86
+ };
87
+ const sendTransaction = async (tx) => {
88
+ if (!window.xrpl) throw new Error("No window.xrpl found");
89
+ return await window.xrpl.sendTransaction(tx);
90
+ };
91
+ const changeNetwork = async (network2) => {
92
+ if (!window.xrpl) throw new Error("No window.xrpl found");
93
+ return await window.xrpl.changeNetwork(network2);
94
+ };
95
+ const signMessage = async (message) => {
96
+ if (!window.xrpl) throw new Error("No window.xrpl found");
97
+ const res = await window.xrpl.signMessage(message);
98
+ if (res.error) throw new Error(res.error);
99
+ return res;
100
+ };
101
+ return (0, import_react2.useMemo)(
102
+ () => ({
103
+ address,
104
+ wallet: address,
105
+ isConnected: connectedAccounts.includes(address || ""),
106
+ connect,
107
+ disconnect,
108
+ sendTransaction,
109
+ changeNetwork,
110
+ connectedAccounts,
111
+ network,
112
+ error,
113
+ isConnecting,
114
+ signMessage,
115
+ initialized
116
+ }),
117
+ [address, connectedAccounts, network, error, isConnecting, initialized]
118
+ );
119
+ }
120
+ // Annotate the CommonJS export names for ESM import in node:
121
+ 0 && (module.exports = {
122
+ XrplProvider,
123
+ useXrplReact
124
+ });
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+
3
+ interface XrplProviderConfig {
4
+ }
5
+ interface XrplProviderProps {
6
+ config?: XrplProviderConfig;
7
+ children: React.ReactNode;
8
+ }
9
+ declare const XrplProvider: React.FC<XrplProviderProps>;
10
+
11
+ declare function useXrplReact(): {
12
+ address: string | undefined;
13
+ wallet: string | undefined;
14
+ isConnected: boolean;
15
+ connect: () => Promise<string>;
16
+ disconnect: () => Promise<void>;
17
+ sendTransaction: (tx: any) => Promise<any>;
18
+ changeNetwork: (network: string) => Promise<any>;
19
+ connectedAccounts: string[];
20
+ network: string;
21
+ error: string | null;
22
+ isConnecting: boolean;
23
+ signMessage: (message: string) => Promise<{
24
+ signature: string;
25
+ error?: string;
26
+ }>;
27
+ initialized: boolean;
28
+ };
29
+
30
+ export { XrplProvider, useXrplReact };
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+
3
+ interface XrplProviderConfig {
4
+ }
5
+ interface XrplProviderProps {
6
+ config?: XrplProviderConfig;
7
+ children: React.ReactNode;
8
+ }
9
+ declare const XrplProvider: React.FC<XrplProviderProps>;
10
+
11
+ declare function useXrplReact(): {
12
+ address: string | undefined;
13
+ wallet: string | undefined;
14
+ isConnected: boolean;
15
+ connect: () => Promise<string>;
16
+ disconnect: () => Promise<void>;
17
+ sendTransaction: (tx: any) => Promise<any>;
18
+ changeNetwork: (network: string) => Promise<any>;
19
+ connectedAccounts: string[];
20
+ network: string;
21
+ error: string | null;
22
+ isConnecting: boolean;
23
+ signMessage: (message: string) => Promise<{
24
+ signature: string;
25
+ error?: string;
26
+ }>;
27
+ initialized: boolean;
28
+ };
29
+
30
+ export { XrplProvider, useXrplReact };
package/dist/index.js ADDED
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ XrplProvider: () => XrplProvider,
24
+ useXrplReact: () => useXrplReact
25
+ });
26
+ module.exports = __toCommonJS(src_exports);
27
+
28
+ // src/provider.tsx
29
+ var import_react = require("react");
30
+ var import_jsx_runtime = require("react/jsx-runtime");
31
+ var XrplContext = (0, import_react.createContext)(null);
32
+ var XrplProvider = ({ config, children }) => {
33
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(XrplContext.Provider, { value: { config }, children });
34
+ };
35
+
36
+ // src/useXrplReact.tsx
37
+ var import_react2 = require("react");
38
+ function useXrplReact() {
39
+ const context = (0, import_react2.useContext)(XrplContext);
40
+ if (!context) {
41
+ throw new Error("useXrplReact must be used within a XrplProvider");
42
+ }
43
+ const [address, setAddress] = (0, import_react2.useState)();
44
+ const [connectedAccounts, setConnectedAccounts] = (0, import_react2.useState)([]);
45
+ const [network, setNetwork] = (0, import_react2.useState)("mainnet");
46
+ const [initialized, setInitialized] = (0, import_react2.useState)(false);
47
+ const [error, setError] = (0, import_react2.useState)(null);
48
+ const [isConnecting, setIsConnecting] = (0, import_react2.useState)(false);
49
+ (0, import_react2.useEffect)(() => {
50
+ if (typeof window === "undefined" || !window.xrpl)
51
+ return;
52
+ window.xrpl?.initialize?.();
53
+ setInitialized(true);
54
+ }, []);
55
+ (0, import_react2.useEffect)(() => {
56
+ if (typeof window === "undefined" || !window.xrpl)
57
+ return;
58
+ const handleSelectedNetwork = (val) => setNetwork(val);
59
+ const handleSelectedAddress = (val) => setAddress(val);
60
+ const handleConnectedAccounts = (val) => setConnectedAccounts(val);
61
+ window.xrpl?.on?.("xrpl_selectedNetwork", handleSelectedNetwork);
62
+ window.xrpl?.on?.("xrpl_selectedAddress", handleSelectedAddress);
63
+ window.xrpl?.on?.("xrpl_connectedAccounts", handleConnectedAccounts);
64
+ return () => {
65
+ window.xrpl?.off?.("xrpl_selectedNetwork", handleSelectedNetwork);
66
+ window.xrpl?.off?.("xrpl_selectedAddress", handleSelectedAddress);
67
+ window.xrpl?.off?.("xrpl_connectedAccounts", handleConnectedAccounts);
68
+ };
69
+ }, []);
70
+ const connect = async () => {
71
+ setIsConnecting(true);
72
+ try {
73
+ if (!window.xrpl)
74
+ throw new Error("No window.xrpl found");
75
+ const response = await window.xrpl.connect();
76
+ setAddress(response);
77
+ return response;
78
+ } catch (err) {
79
+ setError(err.message);
80
+ throw err;
81
+ } finally {
82
+ setIsConnecting(false);
83
+ }
84
+ };
85
+ const disconnect = async () => {
86
+ if (!window.xrpl)
87
+ throw new Error("No window.xrpl found");
88
+ await window.xrpl.disconnect(address);
89
+ setAddress(void 0);
90
+ };
91
+ const sendTransaction = async (tx) => {
92
+ if (!window.xrpl)
93
+ throw new Error("No window.xrpl found");
94
+ return await window.xrpl.sendTransaction(tx);
95
+ };
96
+ const changeNetwork = async (network2) => {
97
+ if (!window.xrpl)
98
+ throw new Error("No window.xrpl found");
99
+ return await window.xrpl.changeNetwork(network2);
100
+ };
101
+ const signMessage = async (message) => {
102
+ if (!window.xrpl)
103
+ throw new Error("No window.xrpl found");
104
+ const res = await window.xrpl.signMessage(message);
105
+ if (res.error)
106
+ throw new Error(res.error);
107
+ return res;
108
+ };
109
+ return (0, import_react2.useMemo)(
110
+ () => ({
111
+ address,
112
+ wallet: address,
113
+ isConnected: connectedAccounts.includes(address || ""),
114
+ connect,
115
+ disconnect,
116
+ sendTransaction,
117
+ changeNetwork,
118
+ connectedAccounts,
119
+ network,
120
+ error,
121
+ isConnecting,
122
+ signMessage,
123
+ initialized
124
+ }),
125
+ [address, connectedAccounts, network, error, isConnecting, initialized]
126
+ );
127
+ }
128
+ // Annotate the CommonJS export names for ESM import in node:
129
+ 0 && (module.exports = {
130
+ XrplProvider,
131
+ useXrplReact
132
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,96 @@
1
+ // src/provider.tsx
2
+ import { createContext } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var XrplContext = createContext(null);
5
+ var XrplProvider = ({ config, children }) => {
6
+ return /* @__PURE__ */ jsx(XrplContext.Provider, { value: { config }, children });
7
+ };
8
+
9
+ // src/useXrplReact.tsx
10
+ import { useContext as useContext2, useEffect, useMemo, useState } from "react";
11
+ function useXrplReact() {
12
+ const context = useContext2(XrplContext);
13
+ if (!context) {
14
+ throw new Error("useXrplReact must be used within a XrplProvider");
15
+ }
16
+ const [address, setAddress] = useState();
17
+ const [connectedAccounts, setConnectedAccounts] = useState([]);
18
+ const [network, setNetwork] = useState("mainnet");
19
+ const [initialized, setInitialized] = useState(false);
20
+ const [error, setError] = useState(null);
21
+ const [isConnecting, setIsConnecting] = useState(false);
22
+ useEffect(() => {
23
+ if (typeof window === "undefined" || !window.xrpl) return;
24
+ window.xrpl?.initialize?.();
25
+ setInitialized(true);
26
+ }, []);
27
+ useEffect(() => {
28
+ if (typeof window === "undefined" || !window.xrpl) return;
29
+ const handleSelectedNetwork = (val) => setNetwork(val);
30
+ const handleSelectedAddress = (val) => setAddress(val);
31
+ const handleConnectedAccounts = (val) => setConnectedAccounts(val);
32
+ window.xrpl?.on?.("xrpl_selectedNetwork", handleSelectedNetwork);
33
+ window.xrpl?.on?.("xrpl_selectedAddress", handleSelectedAddress);
34
+ window.xrpl?.on?.("xrpl_connectedAccounts", handleConnectedAccounts);
35
+ return () => {
36
+ window.xrpl?.off?.("xrpl_selectedNetwork", handleSelectedNetwork);
37
+ window.xrpl?.off?.("xrpl_selectedAddress", handleSelectedAddress);
38
+ window.xrpl?.off?.("xrpl_connectedAccounts", handleConnectedAccounts);
39
+ };
40
+ }, []);
41
+ const connect = async () => {
42
+ setIsConnecting(true);
43
+ try {
44
+ if (!window.xrpl) throw new Error("No window.xrpl found");
45
+ const response = await window.xrpl.connect();
46
+ setAddress(response);
47
+ return response;
48
+ } catch (err) {
49
+ setError(err.message);
50
+ throw err;
51
+ } finally {
52
+ setIsConnecting(false);
53
+ }
54
+ };
55
+ const disconnect = async () => {
56
+ if (!window.xrpl) throw new Error("No window.xrpl found");
57
+ await window.xrpl.disconnect(address);
58
+ setAddress(void 0);
59
+ };
60
+ const sendTransaction = async (tx) => {
61
+ if (!window.xrpl) throw new Error("No window.xrpl found");
62
+ return await window.xrpl.sendTransaction(tx);
63
+ };
64
+ const changeNetwork = async (network2) => {
65
+ if (!window.xrpl) throw new Error("No window.xrpl found");
66
+ return await window.xrpl.changeNetwork(network2);
67
+ };
68
+ const signMessage = async (message) => {
69
+ if (!window.xrpl) throw new Error("No window.xrpl found");
70
+ const res = await window.xrpl.signMessage(message);
71
+ if (res.error) throw new Error(res.error);
72
+ return res;
73
+ };
74
+ return useMemo(
75
+ () => ({
76
+ address,
77
+ wallet: address,
78
+ isConnected: connectedAccounts.includes(address || ""),
79
+ connect,
80
+ disconnect,
81
+ sendTransaction,
82
+ changeNetwork,
83
+ connectedAccounts,
84
+ network,
85
+ error,
86
+ isConnecting,
87
+ signMessage,
88
+ initialized
89
+ }),
90
+ [address, connectedAccounts, network, error, isConnecting, initialized]
91
+ );
92
+ }
93
+ export {
94
+ XrplProvider,
95
+ useXrplReact
96
+ };
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@dropfi/xrpl-react",
3
+ "version": "0.1.0",
4
+ "description": "React hooks + provider for DropFi XRPL wallet (extension & mobile)",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.cjs"
15
+ }
16
+ },
17
+ "keywords": [
18
+ "xrpl",
19
+ "react",
20
+ "wallet",
21
+ "dropfi",
22
+ "provider",
23
+ "hook"
24
+ ],
25
+ "author": "Travis Delly",
26
+ "license": "MIT",
27
+ "scripts": {
28
+ "build": "tsup"
29
+ },
30
+ "peerDependencies": {
31
+ "react": ">=17.0.0",
32
+ "react-dom": ">=17.0.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/react": "^18.3.23",
36
+ "tsup": "^8.5.0",
37
+ "typescript": "^5.8.3"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ }
42
+ }