@rockerone/xprnkit 0.3.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/LICENSE +21 -0
- package/README.md +1100 -0
- package/build/components/identity/index.d.ts +4 -0
- package/build/components/identity/index.js +4 -0
- package/build/components/identity/xprn-avatar.d.ts +8 -0
- package/build/components/identity/xprn-avatar.js +23 -0
- package/build/components/identity/xprn-identity.d.ts +9 -0
- package/build/components/identity/xprn-identity.js +30 -0
- package/build/components/identity/xprn-session-actor.d.ts +4 -0
- package/build/components/identity/xprn-session-actor.js +13 -0
- package/build/components/identity/xprn-session-name.d.ts +4 -0
- package/build/components/identity/xprn-session-name.js +14 -0
- package/build/components/index.d.ts +5 -0
- package/build/components/index.js +5 -0
- package/build/components/swap/index.d.ts +46 -0
- package/build/components/swap/index.js +9 -0
- package/build/components/swap/xprn-swap-button.d.ts +5 -0
- package/build/components/swap/xprn-swap-button.js +21 -0
- package/build/components/swap/xprn-swap-field.d.ts +6 -0
- package/build/components/swap/xprn-swap-field.js +69 -0
- package/build/components/swap/xprn-swap-fields-group.d.ts +6 -0
- package/build/components/swap/xprn-swap-fields-group.js +16 -0
- package/build/components/swap/xprn-swap-fields.d.ts +4 -0
- package/build/components/swap/xprn-swap-fields.js +10 -0
- package/build/components/swap/xprn-swap-layout.d.ts +7 -0
- package/build/components/swap/xprn-swap-layout.js +21 -0
- package/build/components/swap/xprn-swap-markets-selector.d.ts +4 -0
- package/build/components/swap/xprn-swap-markets-selector.js +31 -0
- package/build/components/swap/xprn-swap-markets.d.ts +8 -0
- package/build/components/swap/xprn-swap-markets.js +93 -0
- package/build/components/swap/xprn-swap-pair-selector.d.ts +7 -0
- package/build/components/swap/xprn-swap-pair-selector.js +37 -0
- package/build/components/swap/xprn-swap-provider.d.ts +35 -0
- package/build/components/swap/xprn-swap-provider.js +187 -0
- package/build/components/swap/xprn-swap-side-button.d.ts +6 -0
- package/build/components/swap/xprn-swap-side-button.js +22 -0
- package/build/components/swap/xprn-swap.d.ts +9 -0
- package/build/components/swap/xprn-swap.js +12 -0
- package/build/components/ui/dropdown.d.ts +27 -0
- package/build/components/ui/dropdown.js +36 -0
- package/build/components/ui/input.d.ts +5 -0
- package/build/components/ui/input.js +8 -0
- package/build/components/ui/select.d.ts +13 -0
- package/build/components/ui/select.js +27 -0
- package/build/components/xprn-container.d.ts +9 -0
- package/build/components/xprn-container.js +15 -0
- package/build/components/xprn-session.d.ts +11 -0
- package/build/components/xprn-session.js +21 -0
- package/build/components/xprn-transaction.d.ts +23 -0
- package/build/components/xprn-transaction.js +58 -0
- package/build/global.css +1138 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +3 -0
- package/build/interfaces/proton_wrap.d.ts +141 -0
- package/build/interfaces/proton_wrap.js +81 -0
- package/build/interfaces/service-status.d.ts +1 -0
- package/build/interfaces/service-status.js +1 -0
- package/build/interfaces/transaction-error-message.d.ts +5 -0
- package/build/interfaces/transaction-error-message.js +1 -0
- package/build/lib/utils.d.ts +2 -0
- package/build/lib/utils.js +5 -0
- package/build/providers/XPRNProvider.d.ts +59 -0
- package/build/providers/XPRNProvider.js +336 -0
- package/build/utils/index.d.ts +2 -0
- package/build/utils/index.js +2 -0
- package/build/utils/token-precision.d.ts +1 -0
- package/build/utils/token-precision.js +22 -0
- package/build/utils/transaction-errors.d.ts +2 -0
- package/build/utils/transaction-errors.js +15 -0
- package/package.json +49 -0
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
type proton_wrap_Actions = {
|
|
2
|
+
"deladdress": {
|
|
3
|
+
index: number;
|
|
4
|
+
};
|
|
5
|
+
"deladdress2": {
|
|
6
|
+
index: number;
|
|
7
|
+
};
|
|
8
|
+
"generateauth": {
|
|
9
|
+
protonAccount: string;
|
|
10
|
+
time: {};
|
|
11
|
+
};
|
|
12
|
+
"saveaddress": {
|
|
13
|
+
address: {
|
|
14
|
+
index: number;
|
|
15
|
+
account: string;
|
|
16
|
+
coin: string;
|
|
17
|
+
wallet: string;
|
|
18
|
+
address: string;
|
|
19
|
+
address_hash: {};
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
"saveaddress2": {
|
|
23
|
+
address: {
|
|
24
|
+
index: number;
|
|
25
|
+
account: string;
|
|
26
|
+
chain: string;
|
|
27
|
+
address: string;
|
|
28
|
+
address_hash: {};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
"wrapfinish": {
|
|
32
|
+
wrap_hash: {};
|
|
33
|
+
status: string;
|
|
34
|
+
};
|
|
35
|
+
"wrapfinish2": {
|
|
36
|
+
wrap_hash: {};
|
|
37
|
+
status: string;
|
|
38
|
+
};
|
|
39
|
+
"wrapprocess": {
|
|
40
|
+
wrap_hash: {};
|
|
41
|
+
};
|
|
42
|
+
"wrapprocess2": {
|
|
43
|
+
wrap_hash: {};
|
|
44
|
+
};
|
|
45
|
+
"wrapsetconf": {
|
|
46
|
+
wrap_hash: {};
|
|
47
|
+
confirmations: number;
|
|
48
|
+
};
|
|
49
|
+
"wrapsetconf2": {
|
|
50
|
+
wrap_hash: {};
|
|
51
|
+
confirmations: number;
|
|
52
|
+
};
|
|
53
|
+
"wrapstart": {
|
|
54
|
+
balance: {};
|
|
55
|
+
txid: string;
|
|
56
|
+
coin: string;
|
|
57
|
+
wallet: string;
|
|
58
|
+
deposit_address: string;
|
|
59
|
+
confirmations: number;
|
|
60
|
+
};
|
|
61
|
+
"wrapstart2": {
|
|
62
|
+
balance: {};
|
|
63
|
+
id: string;
|
|
64
|
+
txid: string;
|
|
65
|
+
chain: string;
|
|
66
|
+
deposit_address: string;
|
|
67
|
+
confirmations: number;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
export declare const proton_wrap: {
|
|
71
|
+
deladdress: (authorization: Authorization[], data: proton_wrap_Actions["deladdress"]) => XPRAction<"deladdress">;
|
|
72
|
+
deladdress2: (authorization: Authorization[], data: proton_wrap_Actions["deladdress2"]) => XPRAction<"deladdress2">;
|
|
73
|
+
generateauth: (authorization: Authorization[], data: proton_wrap_Actions["generateauth"]) => XPRAction<"generateauth">;
|
|
74
|
+
saveaddress: (authorization: Authorization[], data: proton_wrap_Actions["saveaddress"]) => XPRAction<"saveaddress">;
|
|
75
|
+
saveaddress2: (authorization: Authorization[], data: proton_wrap_Actions["saveaddress2"]) => XPRAction<"saveaddress2">;
|
|
76
|
+
wrapfinish: (authorization: Authorization[], data: proton_wrap_Actions["wrapfinish"]) => XPRAction<"wrapfinish">;
|
|
77
|
+
wrapfinish2: (authorization: Authorization[], data: proton_wrap_Actions["wrapfinish2"]) => XPRAction<"wrapfinish2">;
|
|
78
|
+
wrapprocess: (authorization: Authorization[], data: proton_wrap_Actions["wrapprocess"]) => XPRAction<"wrapprocess">;
|
|
79
|
+
wrapprocess2: (authorization: Authorization[], data: proton_wrap_Actions["wrapprocess2"]) => XPRAction<"wrapprocess2">;
|
|
80
|
+
wrapsetconf: (authorization: Authorization[], data: proton_wrap_Actions["wrapsetconf"]) => XPRAction<"wrapsetconf">;
|
|
81
|
+
wrapsetconf2: (authorization: Authorization[], data: proton_wrap_Actions["wrapsetconf2"]) => XPRAction<"wrapsetconf2">;
|
|
82
|
+
wrapstart: (authorization: Authorization[], data: proton_wrap_Actions["wrapstart"]) => XPRAction<"wrapstart">;
|
|
83
|
+
wrapstart2: (authorization: Authorization[], data: proton_wrap_Actions["wrapstart2"]) => XPRAction<"wrapstart2">;
|
|
84
|
+
};
|
|
85
|
+
type proton_wrap_Tables = {
|
|
86
|
+
"Address": {
|
|
87
|
+
index: number;
|
|
88
|
+
account: string;
|
|
89
|
+
coin: string;
|
|
90
|
+
wallet: string;
|
|
91
|
+
address: string;
|
|
92
|
+
address_hash: {};
|
|
93
|
+
};
|
|
94
|
+
"Address2": {
|
|
95
|
+
index: number;
|
|
96
|
+
account: string;
|
|
97
|
+
chain: string;
|
|
98
|
+
address: string;
|
|
99
|
+
address_hash: {};
|
|
100
|
+
};
|
|
101
|
+
"Wrap": {
|
|
102
|
+
index: number;
|
|
103
|
+
proton_account: string;
|
|
104
|
+
balance: {};
|
|
105
|
+
txid: string;
|
|
106
|
+
coin: string;
|
|
107
|
+
wallet: string;
|
|
108
|
+
deposit_address: string;
|
|
109
|
+
status: string;
|
|
110
|
+
confirmations: number;
|
|
111
|
+
finish_txid: {};
|
|
112
|
+
wrap_hash: {};
|
|
113
|
+
};
|
|
114
|
+
"Wrap2": {
|
|
115
|
+
index: number;
|
|
116
|
+
proton_account: string;
|
|
117
|
+
balance: {};
|
|
118
|
+
id: string;
|
|
119
|
+
txid: string;
|
|
120
|
+
chain: string;
|
|
121
|
+
deposit_address: string;
|
|
122
|
+
status: string;
|
|
123
|
+
confirmations: number;
|
|
124
|
+
finish_txid: {};
|
|
125
|
+
wrap_hash: {};
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
export type Authorization = {
|
|
129
|
+
actor: string;
|
|
130
|
+
permission: "active" | "owner" | string;
|
|
131
|
+
};
|
|
132
|
+
export type XPRAction<A extends keyof (proton_wrap_Actions)> = {
|
|
133
|
+
account: 'proton.wrap';
|
|
134
|
+
name: A;
|
|
135
|
+
authorization: Authorization[];
|
|
136
|
+
data: proton_wrap_Actions[A];
|
|
137
|
+
};
|
|
138
|
+
export type Tables<TableName extends keyof (proton_wrap_Tables)> = proton_wrap_Tables[TableName];
|
|
139
|
+
export type Actions<ActionName extends keyof (proton_wrap_Actions)> = proton_wrap_Actions[ActionName];
|
|
140
|
+
export declare function proton_wrap_actionParams<ActionName extends keyof (proton_wrap_Actions)>(actionPrams: proton_wrap_Actions[ActionName]): (object | number | string | number[] | string[])[];
|
|
141
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export const proton_wrap = {
|
|
2
|
+
deladdress: (authorization, data) => ({
|
|
3
|
+
account: 'proton.wrap',
|
|
4
|
+
name: 'deladdress',
|
|
5
|
+
authorization,
|
|
6
|
+
data
|
|
7
|
+
}),
|
|
8
|
+
deladdress2: (authorization, data) => ({
|
|
9
|
+
account: 'proton.wrap',
|
|
10
|
+
name: 'deladdress2',
|
|
11
|
+
authorization,
|
|
12
|
+
data
|
|
13
|
+
}),
|
|
14
|
+
generateauth: (authorization, data) => ({
|
|
15
|
+
account: 'proton.wrap',
|
|
16
|
+
name: 'generateauth',
|
|
17
|
+
authorization,
|
|
18
|
+
data
|
|
19
|
+
}),
|
|
20
|
+
saveaddress: (authorization, data) => ({
|
|
21
|
+
account: 'proton.wrap',
|
|
22
|
+
name: 'saveaddress',
|
|
23
|
+
authorization,
|
|
24
|
+
data
|
|
25
|
+
}),
|
|
26
|
+
saveaddress2: (authorization, data) => ({
|
|
27
|
+
account: 'proton.wrap',
|
|
28
|
+
name: 'saveaddress2',
|
|
29
|
+
authorization,
|
|
30
|
+
data
|
|
31
|
+
}),
|
|
32
|
+
wrapfinish: (authorization, data) => ({
|
|
33
|
+
account: 'proton.wrap',
|
|
34
|
+
name: 'wrapfinish',
|
|
35
|
+
authorization,
|
|
36
|
+
data
|
|
37
|
+
}),
|
|
38
|
+
wrapfinish2: (authorization, data) => ({
|
|
39
|
+
account: 'proton.wrap',
|
|
40
|
+
name: 'wrapfinish2',
|
|
41
|
+
authorization,
|
|
42
|
+
data
|
|
43
|
+
}),
|
|
44
|
+
wrapprocess: (authorization, data) => ({
|
|
45
|
+
account: 'proton.wrap',
|
|
46
|
+
name: 'wrapprocess',
|
|
47
|
+
authorization,
|
|
48
|
+
data
|
|
49
|
+
}),
|
|
50
|
+
wrapprocess2: (authorization, data) => ({
|
|
51
|
+
account: 'proton.wrap',
|
|
52
|
+
name: 'wrapprocess2',
|
|
53
|
+
authorization,
|
|
54
|
+
data
|
|
55
|
+
}),
|
|
56
|
+
wrapsetconf: (authorization, data) => ({
|
|
57
|
+
account: 'proton.wrap',
|
|
58
|
+
name: 'wrapsetconf',
|
|
59
|
+
authorization,
|
|
60
|
+
data
|
|
61
|
+
}),
|
|
62
|
+
wrapsetconf2: (authorization, data) => ({
|
|
63
|
+
account: 'proton.wrap',
|
|
64
|
+
name: 'wrapsetconf2',
|
|
65
|
+
authorization,
|
|
66
|
+
data
|
|
67
|
+
}),
|
|
68
|
+
wrapstart: (authorization, data) => ({
|
|
69
|
+
account: 'proton.wrap',
|
|
70
|
+
name: 'wrapstart',
|
|
71
|
+
authorization,
|
|
72
|
+
data
|
|
73
|
+
}),
|
|
74
|
+
wrapstart2: (authorization, data) => ({
|
|
75
|
+
account: 'proton.wrap',
|
|
76
|
+
name: 'wrapstart2',
|
|
77
|
+
authorization,
|
|
78
|
+
data
|
|
79
|
+
})
|
|
80
|
+
};
|
|
81
|
+
export function proton_wrap_actionParams(actionPrams) { return Object.values(actionPrams); }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type ServiceStatus = 'idle' | 'pending' | 'success' | 'fail';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Link, LinkSession, ProtonWebLink } from "@proton/web-sdk";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { JsonRpc } from "@proton/js";
|
|
4
|
+
export type XPRNAuthentication = {
|
|
5
|
+
actor: string;
|
|
6
|
+
publicKey: string;
|
|
7
|
+
data?: any;
|
|
8
|
+
};
|
|
9
|
+
export type XPRNProfile = {
|
|
10
|
+
displayName: string;
|
|
11
|
+
avatar?: string;
|
|
12
|
+
authentication?: XPRNAuthentication;
|
|
13
|
+
isKyc: boolean;
|
|
14
|
+
};
|
|
15
|
+
export type XPRNSession = {
|
|
16
|
+
actor: string;
|
|
17
|
+
session: LinkSession;
|
|
18
|
+
link: ProtonWebLink | Link;
|
|
19
|
+
profile: XPRNProfile | null;
|
|
20
|
+
authentication: XPRNAuthentication | null;
|
|
21
|
+
};
|
|
22
|
+
export type XPRProviderConfig = {
|
|
23
|
+
chainId: string;
|
|
24
|
+
endpoints: string[];
|
|
25
|
+
dAppName: string;
|
|
26
|
+
requesterAccount: string;
|
|
27
|
+
requesterLogo?: string;
|
|
28
|
+
authenticationUrl?: string;
|
|
29
|
+
enforceAuthentication?: boolean;
|
|
30
|
+
apiMode: "testnet" | "mainnet";
|
|
31
|
+
restoreSession?: boolean;
|
|
32
|
+
};
|
|
33
|
+
type XPRNProviderProps = {
|
|
34
|
+
children: React.ReactNode | React.ReactNode[];
|
|
35
|
+
config: XPRProviderConfig;
|
|
36
|
+
};
|
|
37
|
+
type XPRNProviderContext = {
|
|
38
|
+
session: LinkSession | null;
|
|
39
|
+
link: ProtonWebLink | null;
|
|
40
|
+
profile: XPRNProfile | null;
|
|
41
|
+
rpc: JsonRpc | null;
|
|
42
|
+
txErrorsStack: null;
|
|
43
|
+
authentication: XPRNAuthentication | null;
|
|
44
|
+
authenticate: (success: (res: any) => void, fail: (e: any) => void, actor?: string) => void;
|
|
45
|
+
addTransactionError: (rawMessage: string) => void;
|
|
46
|
+
connect: (restore?: boolean, silent?: boolean, onSession?: (session: LinkSession) => void, onProfile?: (profile: XPRNProfile) => void) => void;
|
|
47
|
+
disconnect: (actor?: string) => void;
|
|
48
|
+
getActiveSession: () => XPRNSession | null;
|
|
49
|
+
listSessions: () => XPRNSession[];
|
|
50
|
+
setActiveSession: (actor: string) => void;
|
|
51
|
+
removeSession: (actor: string) => Promise<void>;
|
|
52
|
+
getAllProfiles: () => XPRNProfile[];
|
|
53
|
+
switchSession: (actor: string) => void;
|
|
54
|
+
getSessionById: (actor: string) => XPRNSession | null;
|
|
55
|
+
getSessionByActor: (actor: string) => XPRNSession | null;
|
|
56
|
+
};
|
|
57
|
+
export declare const XPRNProvider: React.FunctionComponent<XPRNProviderProps>;
|
|
58
|
+
export declare function useXPRN(): XPRNProviderContext;
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { ApiClass } from "@proton/api";
|
|
4
|
+
import ConnectWallet from "@proton/web-sdk";
|
|
5
|
+
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
6
|
+
import { JsonRpc } from "@proton/js";
|
|
7
|
+
import { parseTransactionErrorMessage } from "../utils";
|
|
8
|
+
import { proton_wrap } from "../interfaces/proton_wrap";
|
|
9
|
+
const XPRNContext = React.createContext({
|
|
10
|
+
session: null,
|
|
11
|
+
link: null,
|
|
12
|
+
profile: null,
|
|
13
|
+
rpc: null,
|
|
14
|
+
txErrorsStack: null,
|
|
15
|
+
connect: () => { },
|
|
16
|
+
disconnect: () => { },
|
|
17
|
+
addTransactionError(rawMessage) { },
|
|
18
|
+
authentication: null,
|
|
19
|
+
authenticate: () => { },
|
|
20
|
+
getActiveSession: () => null,
|
|
21
|
+
listSessions: () => [],
|
|
22
|
+
setActiveSession: () => { },
|
|
23
|
+
removeSession: async () => { },
|
|
24
|
+
getAllProfiles: () => [],
|
|
25
|
+
switchSession: () => { },
|
|
26
|
+
getSessionById: () => null,
|
|
27
|
+
getSessionByActor: () => null,
|
|
28
|
+
});
|
|
29
|
+
export const XPRNProvider = ({ children, config, }) => {
|
|
30
|
+
// Multi-session state management
|
|
31
|
+
const [sessions, setSessions] = useState(new Map());
|
|
32
|
+
const [activeSessionId, setActiveSessionId] = useState(null);
|
|
33
|
+
// Keep for backward compatibility and other features
|
|
34
|
+
const [jsonRpc, setJsonPrc] = useState(new JsonRpc(config.endpoints));
|
|
35
|
+
const [errorsStack, setErrorStack] = useState();
|
|
36
|
+
const onSessionRef = useRef();
|
|
37
|
+
const onProfileRef = useRef();
|
|
38
|
+
// Computed values from active session for backward compatibility
|
|
39
|
+
const activeSession = activeSessionId ? sessions.get(activeSessionId) : null;
|
|
40
|
+
const session = activeSession?.session || null;
|
|
41
|
+
const link = activeSession?.link || null;
|
|
42
|
+
const profile = activeSession?.profile || null;
|
|
43
|
+
const authentication = activeSession?.authentication || null;
|
|
44
|
+
// Session management methods
|
|
45
|
+
const getActiveSession = useCallback(() => {
|
|
46
|
+
return activeSession || null;
|
|
47
|
+
}, [activeSession]);
|
|
48
|
+
const listSessions = useCallback(() => {
|
|
49
|
+
return Array.from(sessions.values());
|
|
50
|
+
}, [sessions]);
|
|
51
|
+
const setActiveSession = useCallback((actor) => {
|
|
52
|
+
if (sessions.has(actor)) {
|
|
53
|
+
setActiveSessionId(actor);
|
|
54
|
+
// Store in localStorage for persistence
|
|
55
|
+
if (typeof window !== "undefined") {
|
|
56
|
+
localStorage.setItem("xprn_active_session_actor", actor);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.warn(`Session with actor ${actor} not found`);
|
|
61
|
+
}
|
|
62
|
+
}, [sessions]);
|
|
63
|
+
const switchSession = useCallback((actor) => {
|
|
64
|
+
setActiveSession(actor);
|
|
65
|
+
}, [setActiveSession]);
|
|
66
|
+
const getSessionById = useCallback((actor) => {
|
|
67
|
+
return sessions.get(actor) || null;
|
|
68
|
+
}, [sessions]);
|
|
69
|
+
const getSessionByActor = useCallback((actor) => {
|
|
70
|
+
return sessions.get(actor) || null;
|
|
71
|
+
}, [sessions]);
|
|
72
|
+
const removeSession = useCallback(async (actor) => {
|
|
73
|
+
const sessionToRemove = sessions.get(actor);
|
|
74
|
+
if (!sessionToRemove) {
|
|
75
|
+
console.warn(`Session with actor ${actor} not found`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Remove session from the link
|
|
79
|
+
try {
|
|
80
|
+
await sessionToRemove.link.removeSession(config.requesterAccount, sessionToRemove.session.auth, sessionToRemove.session.chainId);
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
console.error("Error removing session from link:", e);
|
|
84
|
+
}
|
|
85
|
+
// Remove from sessions map
|
|
86
|
+
setSessions(prev => {
|
|
87
|
+
const newSessions = new Map(prev);
|
|
88
|
+
newSessions.delete(actor);
|
|
89
|
+
return newSessions;
|
|
90
|
+
});
|
|
91
|
+
// If this was the active session, clear it
|
|
92
|
+
if (activeSessionId === actor) {
|
|
93
|
+
setActiveSessionId(null);
|
|
94
|
+
if (typeof window !== "undefined") {
|
|
95
|
+
localStorage.removeItem("xprn_active_session_actor");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}, [sessions, activeSessionId, config]);
|
|
99
|
+
const getAllProfiles = useCallback(() => {
|
|
100
|
+
return Array.from(sessions.values())
|
|
101
|
+
.map(s => s.profile)
|
|
102
|
+
.filter((p) => p !== null);
|
|
103
|
+
}, [sessions]);
|
|
104
|
+
const connect = useCallback((restoreSession, onSession, onProfile) => {
|
|
105
|
+
console.log("restoreSession", restoreSession);
|
|
106
|
+
ConnectWallet({
|
|
107
|
+
linkOptions: {
|
|
108
|
+
endpoints: config.endpoints,
|
|
109
|
+
restoreSession: restoreSession || false,
|
|
110
|
+
},
|
|
111
|
+
selectorOptions: {
|
|
112
|
+
appName: config.dAppName,
|
|
113
|
+
},
|
|
114
|
+
transportOptions: {
|
|
115
|
+
requestAccount: config.requesterAccount,
|
|
116
|
+
},
|
|
117
|
+
}).then(res => {
|
|
118
|
+
onSessionRef.current = onSession;
|
|
119
|
+
onProfileRef.current = onProfile;
|
|
120
|
+
if (res.link && res.session) {
|
|
121
|
+
const actor = res.session.auth.actor.toString();
|
|
122
|
+
// Create initial session object with null profile
|
|
123
|
+
const newSession = {
|
|
124
|
+
actor,
|
|
125
|
+
session: res.session,
|
|
126
|
+
link: res.link,
|
|
127
|
+
profile: null,
|
|
128
|
+
authentication: null,
|
|
129
|
+
};
|
|
130
|
+
// Add to sessions map and set as active
|
|
131
|
+
setSessions(prev => {
|
|
132
|
+
const newSessions = new Map(prev);
|
|
133
|
+
newSessions.set(actor, newSession);
|
|
134
|
+
return newSessions;
|
|
135
|
+
});
|
|
136
|
+
// Auto-switch to newly connected session
|
|
137
|
+
setActiveSessionId(actor);
|
|
138
|
+
if (typeof window !== "undefined") {
|
|
139
|
+
localStorage.setItem("xprn_active_session_actor", actor);
|
|
140
|
+
}
|
|
141
|
+
// Fetch profile data
|
|
142
|
+
const api = new ApiClass(config.apiMode && config.apiMode == "testnet"
|
|
143
|
+
? "proton-test"
|
|
144
|
+
: "proton");
|
|
145
|
+
api.getProtonAvatar(actor).then(profileRes => {
|
|
146
|
+
if (profileRes) {
|
|
147
|
+
const xprProfile = {
|
|
148
|
+
displayName: profileRes.name,
|
|
149
|
+
avatar: `${profileRes.avatar}`,
|
|
150
|
+
isKyc: profileRes.kyc.length > 0 || false,
|
|
151
|
+
};
|
|
152
|
+
// Update session with profile
|
|
153
|
+
setSessions(prev => {
|
|
154
|
+
const newSessions = new Map(prev);
|
|
155
|
+
const existingSession = newSessions.get(actor);
|
|
156
|
+
if (existingSession) {
|
|
157
|
+
newSessions.set(actor, {
|
|
158
|
+
...existingSession,
|
|
159
|
+
profile: xprProfile,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return newSessions;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}, [config]);
|
|
169
|
+
const disconnect = useCallback(async (actor) => {
|
|
170
|
+
// If actor is provided, disconnect that specific session
|
|
171
|
+
// Otherwise, disconnect the active session
|
|
172
|
+
const targetActor = actor || activeSessionId;
|
|
173
|
+
if (!targetActor) {
|
|
174
|
+
console.warn("No session to disconnect");
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
await removeSession(targetActor);
|
|
178
|
+
}, [activeSessionId, removeSession]);
|
|
179
|
+
const addTxError = useCallback((message) => {
|
|
180
|
+
const mutatedMessages = errorsStack && errorsStack.length >= 0 ? [...errorsStack] : [];
|
|
181
|
+
mutatedMessages.push(parseTransactionErrorMessage(message));
|
|
182
|
+
setErrorStack(mutatedMessages);
|
|
183
|
+
}, [errorsStack, setErrorStack]);
|
|
184
|
+
const authenticate = useCallback((success, fail, actor) => {
|
|
185
|
+
// Use provided actor or active session
|
|
186
|
+
const targetActor = actor || activeSessionId;
|
|
187
|
+
if (!targetActor) {
|
|
188
|
+
fail(new Error("No session available for authentication"));
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const targetSession = sessions.get(targetActor);
|
|
192
|
+
if (!targetSession) {
|
|
193
|
+
fail(new Error(`Session not found for actor: ${targetActor}`));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (!config.authenticationUrl) {
|
|
197
|
+
fail(new Error("Authentication URL not configured"));
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const authenticationAction = proton_wrap.generateauth([
|
|
201
|
+
{
|
|
202
|
+
actor: targetSession.session.auth.actor.toString(),
|
|
203
|
+
permission: targetSession.session.auth.permission.toString(),
|
|
204
|
+
},
|
|
205
|
+
], {
|
|
206
|
+
protonAccount: targetSession.session.auth.actor.toString(),
|
|
207
|
+
time: new Date().toISOString().slice(0, -1),
|
|
208
|
+
});
|
|
209
|
+
try {
|
|
210
|
+
targetSession.session
|
|
211
|
+
.transact({ actions: [authenticationAction] }, { broadcast: false })
|
|
212
|
+
.then(res => {
|
|
213
|
+
const identityProofBody = {
|
|
214
|
+
signer: {
|
|
215
|
+
actor: targetSession.session.auth.actor,
|
|
216
|
+
permission: targetSession.session.auth.permission,
|
|
217
|
+
public_key: targetSession.session.publicKey,
|
|
218
|
+
},
|
|
219
|
+
transaction: res.resolvedTransaction,
|
|
220
|
+
signatures: res.signatures,
|
|
221
|
+
};
|
|
222
|
+
if (config.authenticationUrl)
|
|
223
|
+
fetch(config.authenticationUrl, {
|
|
224
|
+
method: "post",
|
|
225
|
+
body: JSON.stringify(identityProofBody),
|
|
226
|
+
})
|
|
227
|
+
.then(res => res.json())
|
|
228
|
+
.then(authRes => {
|
|
229
|
+
const authData = {
|
|
230
|
+
publicKey: targetSession.session.publicKey.toString(),
|
|
231
|
+
actor: targetSession.session.auth.actor.toString(),
|
|
232
|
+
data: authRes,
|
|
233
|
+
};
|
|
234
|
+
// Update session with authentication data
|
|
235
|
+
setSessions(prev => {
|
|
236
|
+
const newSessions = new Map(prev);
|
|
237
|
+
const existingSession = newSessions.get(targetActor);
|
|
238
|
+
if (existingSession) {
|
|
239
|
+
newSessions.set(targetActor, {
|
|
240
|
+
...existingSession,
|
|
241
|
+
authentication: authData,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return newSessions;
|
|
245
|
+
});
|
|
246
|
+
success(authRes);
|
|
247
|
+
})
|
|
248
|
+
.catch(fail);
|
|
249
|
+
})
|
|
250
|
+
.catch(fail);
|
|
251
|
+
}
|
|
252
|
+
catch (e) {
|
|
253
|
+
fail(e);
|
|
254
|
+
}
|
|
255
|
+
}, [activeSessionId, sessions, config]);
|
|
256
|
+
// Handle authentication for active session
|
|
257
|
+
useEffect(() => {
|
|
258
|
+
if (session && activeSessionId) {
|
|
259
|
+
const currentSession = sessions.get(activeSessionId);
|
|
260
|
+
if (currentSession && !currentSession.authentication) {
|
|
261
|
+
if (config.enforceAuthentication && config.authenticationUrl) {
|
|
262
|
+
authenticate(() => { }, () => { });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (session && onSessionRef.current) {
|
|
267
|
+
onSessionRef.current(session);
|
|
268
|
+
onSessionRef.current = undefined; // Reset the ref
|
|
269
|
+
}
|
|
270
|
+
}, [session, activeSessionId, sessions, authenticate, config]);
|
|
271
|
+
// Handle profile callbacks
|
|
272
|
+
useEffect(() => {
|
|
273
|
+
if (profile && onProfileRef.current) {
|
|
274
|
+
onProfileRef.current(profile);
|
|
275
|
+
onProfileRef.current = undefined; // Reset the ref
|
|
276
|
+
}
|
|
277
|
+
}, [profile]);
|
|
278
|
+
// Session restoration - only restore active session
|
|
279
|
+
useEffect(() => {
|
|
280
|
+
if (sessions.size === 0 && config.restoreSession) {
|
|
281
|
+
// Check if there's a stored active session
|
|
282
|
+
if (typeof window !== "undefined") {
|
|
283
|
+
const storedActiveActor = localStorage.getItem("xprn_active_session_actor");
|
|
284
|
+
if (storedActiveActor) {
|
|
285
|
+
// Try to restore the session
|
|
286
|
+
connect(true);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}, [sessions.size, config.restoreSession, connect]);
|
|
291
|
+
const providerValue = useMemo(() => {
|
|
292
|
+
return {
|
|
293
|
+
// Backward compatibility - active session values
|
|
294
|
+
session,
|
|
295
|
+
link,
|
|
296
|
+
profile,
|
|
297
|
+
rpc: jsonRpc,
|
|
298
|
+
addTransactionError: addTxError,
|
|
299
|
+
connect,
|
|
300
|
+
disconnect,
|
|
301
|
+
authenticate,
|
|
302
|
+
authentication,
|
|
303
|
+
// Multi-session management methods
|
|
304
|
+
getActiveSession,
|
|
305
|
+
listSessions,
|
|
306
|
+
setActiveSession,
|
|
307
|
+
removeSession,
|
|
308
|
+
getAllProfiles,
|
|
309
|
+
switchSession,
|
|
310
|
+
getSessionById,
|
|
311
|
+
getSessionByActor,
|
|
312
|
+
};
|
|
313
|
+
}, [
|
|
314
|
+
session,
|
|
315
|
+
link,
|
|
316
|
+
profile,
|
|
317
|
+
jsonRpc,
|
|
318
|
+
addTxError,
|
|
319
|
+
connect,
|
|
320
|
+
disconnect,
|
|
321
|
+
authenticate,
|
|
322
|
+
authentication,
|
|
323
|
+
getActiveSession,
|
|
324
|
+
listSessions,
|
|
325
|
+
setActiveSession,
|
|
326
|
+
removeSession,
|
|
327
|
+
getAllProfiles,
|
|
328
|
+
switchSession,
|
|
329
|
+
getSessionById,
|
|
330
|
+
getSessionByActor,
|
|
331
|
+
]);
|
|
332
|
+
return (_jsx(XPRNContext.Provider, { value: providerValue, children: children }));
|
|
333
|
+
};
|
|
334
|
+
export function useXPRN() {
|
|
335
|
+
return useContext(XPRNContext);
|
|
336
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function toPrecision(value: number, precision: number, mode?: 'ceil' | 'floor' | 'round' | 'none', forceDecimal?: boolean): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function toPrecision(value, precision, mode = 'ceil', forceDecimal = true) {
|
|
2
|
+
const multiplier = Math.pow(10, precision);
|
|
3
|
+
let powValue = value * multiplier;
|
|
4
|
+
switch (mode) {
|
|
5
|
+
case 'ceil':
|
|
6
|
+
powValue = Math.ceil(powValue);
|
|
7
|
+
break;
|
|
8
|
+
case 'floor':
|
|
9
|
+
powValue = Math.floor(powValue);
|
|
10
|
+
break;
|
|
11
|
+
case 'round':
|
|
12
|
+
powValue = Math.round(powValue);
|
|
13
|
+
break;
|
|
14
|
+
case 'none':
|
|
15
|
+
powValue = Math.ceil(powValue);
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
const mutatedValue = powValue / multiplier;
|
|
19
|
+
if (forceDecimal)
|
|
20
|
+
return mutatedValue.toFixed(precision);
|
|
21
|
+
return mutatedValue.toString();
|
|
22
|
+
}
|