@b3dotfun/sdk 0.0.23-alpha.10 → 0.0.23-alpha.12
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/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/cjs/bondkit/bondkitToken.d.ts +6 -0
- package/dist/cjs/bondkit/bondkitToken.js +72 -1
- package/dist/cjs/bondkit/bondkitTokenFactory.d.ts +11 -0
- package/dist/cjs/bondkit/bondkitTokenFactory.js +82 -2
- package/dist/cjs/bondkit/components/TradingView.d.ts +3 -0
- package/dist/cjs/bondkit/components/TradingView.js +296 -0
- package/dist/cjs/bondkit/components/config/cdn.d.ts +42 -0
- package/dist/cjs/bondkit/components/config/cdn.js +63 -0
- package/dist/cjs/bondkit/components/index.d.ts +5 -0
- package/dist/cjs/bondkit/components/index.js +25 -0
- package/dist/cjs/bondkit/components/types.d.ts +8 -0
- package/dist/cjs/bondkit/components/types.js +5 -0
- package/dist/cjs/bondkit/components/utils/cdn-loader.d.ts +24 -0
- package/dist/cjs/bondkit/components/utils/cdn-loader.js +73 -0
- package/dist/cjs/bondkit/components/utils/format.d.ts +4 -0
- package/dist/cjs/bondkit/components/utils/format.js +31 -0
- package/dist/cjs/bondkit/index.d.ts +1 -0
- package/dist/cjs/bondkit/index.js +7 -0
- package/dist/cjs/global-account/react/components/ui/scroll-area.js +1 -1
- package/dist/cjs/global-account/react/components/ui/tooltip.d.ts +1 -1
- package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/esm/bondkit/bondkitToken.d.ts +6 -0
- package/dist/esm/bondkit/bondkitToken.js +72 -1
- package/dist/esm/bondkit/bondkitTokenFactory.d.ts +11 -0
- package/dist/esm/bondkit/bondkitTokenFactory.js +82 -2
- package/dist/esm/bondkit/components/TradingView.d.ts +3 -0
- package/dist/esm/bondkit/components/TradingView.js +294 -0
- package/dist/esm/bondkit/components/config/cdn.d.ts +42 -0
- package/dist/esm/bondkit/components/config/cdn.js +55 -0
- package/dist/esm/bondkit/components/index.d.ts +5 -0
- package/dist/esm/bondkit/components/index.js +4 -0
- package/dist/esm/bondkit/components/types.d.ts +8 -0
- package/dist/esm/bondkit/components/types.js +4 -0
- package/dist/esm/bondkit/components/utils/cdn-loader.d.ts +24 -0
- package/dist/esm/bondkit/components/utils/cdn-loader.js +66 -0
- package/dist/esm/bondkit/components/utils/format.d.ts +4 -0
- package/dist/esm/bondkit/components/utils/format.js +28 -0
- package/dist/esm/bondkit/index.d.ts +1 -0
- package/dist/esm/bondkit/index.js +2 -0
- package/dist/esm/global-account/react/components/ui/scroll-area.js +1 -1
- package/dist/esm/global-account/react/components/ui/tooltip.d.ts +1 -1
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/types/bondkit/bondkitToken.d.ts +6 -0
- package/dist/types/bondkit/bondkitTokenFactory.d.ts +11 -0
- package/dist/types/bondkit/components/TradingView.d.ts +3 -0
- package/dist/types/bondkit/components/config/cdn.d.ts +42 -0
- package/dist/types/bondkit/components/index.d.ts +5 -0
- package/dist/types/bondkit/components/types.d.ts +8 -0
- package/dist/types/bondkit/components/utils/cdn-loader.d.ts +24 -0
- package/dist/types/bondkit/components/utils/format.d.ts +4 -0
- package/dist/types/bondkit/index.d.ts +1 -0
- package/dist/types/global-account/react/components/ui/tooltip.d.ts +1 -1
- package/package.json +7 -2
- package/src/bondkit/bondkitToken.ts +75 -1
- package/src/bondkit/bondkitTokenFactory.ts +86 -4
- package/src/bondkit/components/TradingView.tsx +341 -0
- package/src/bondkit/components/config/cdn.ts +63 -0
- package/src/bondkit/components/index.ts +5 -0
- package/src/bondkit/components/types.ts +9 -0
- package/src/bondkit/components/utils/cdn-loader.ts +77 -0
- package/src/bondkit/components/utils/format.ts +36 -0
- package/src/bondkit/index.ts +3 -0
- package/src/global-account/react/components/ui/scroll-area.tsx +2 -2
- package/src/global-account/react/components/ui/tooltip.tsx +1 -1
|
@@ -8,8 +8,8 @@ export declare const useGenerateSigMintData: ({ recipientAddress, contractAddres
|
|
|
8
8
|
payload: any;
|
|
9
9
|
collection: {
|
|
10
10
|
description?: string | undefined;
|
|
11
|
-
metadata?: {} | undefined;
|
|
12
11
|
status?: "DRAFT" | "ACTIVE" | "INACTIVE" | undefined;
|
|
12
|
+
metadata?: {} | undefined;
|
|
13
13
|
createdAt?: string | undefined;
|
|
14
14
|
updatedAt?: string | undefined;
|
|
15
15
|
logoURI?: string | undefined;
|
|
@@ -16,8 +16,14 @@ export declare class BondkitToken {
|
|
|
16
16
|
private rpcUrl;
|
|
17
17
|
private apiEndpoint;
|
|
18
18
|
private walletClientInstance;
|
|
19
|
+
private connectedProvider?;
|
|
19
20
|
constructor(contractAddress: string, walletKey?: string);
|
|
20
21
|
connect(provider?: EIP1193Provider): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Connects using an EIP-1193 provider and requests accounts, selecting the first one.
|
|
24
|
+
* Enables frontend wallet flows without requiring a private key.
|
|
25
|
+
*/
|
|
26
|
+
connectWithProvider(provider: EIP1193Provider): Promise<boolean>;
|
|
21
27
|
private handleError;
|
|
22
28
|
name(): Promise<string | undefined>;
|
|
23
29
|
symbol(): Promise<string | undefined>;
|
|
@@ -44,6 +44,7 @@ class BondkitToken {
|
|
|
44
44
|
connect(provider) {
|
|
45
45
|
try {
|
|
46
46
|
const transport = provider ? (0, viem_1.custom)(provider) : (0, viem_1.http)(this.rpcUrl);
|
|
47
|
+
this.connectedProvider = provider;
|
|
47
48
|
this.walletClientInstance = (0, viem_1.createWalletClient)({
|
|
48
49
|
chain: this.chain,
|
|
49
50
|
transport,
|
|
@@ -65,6 +66,53 @@ class BondkitToken {
|
|
|
65
66
|
return false;
|
|
66
67
|
}
|
|
67
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Connects using an EIP-1193 provider and requests accounts, selecting the first one.
|
|
71
|
+
* Enables frontend wallet flows without requiring a private key.
|
|
72
|
+
*/
|
|
73
|
+
async connectWithProvider(provider) {
|
|
74
|
+
try {
|
|
75
|
+
const transport = (0, viem_1.custom)(provider);
|
|
76
|
+
this.connectedProvider = provider;
|
|
77
|
+
// Try to request accounts (prompt user if needed)
|
|
78
|
+
let addresses = [];
|
|
79
|
+
try {
|
|
80
|
+
const result = await provider.request({ method: "eth_requestAccounts" });
|
|
81
|
+
if (Array.isArray(result))
|
|
82
|
+
addresses = result;
|
|
83
|
+
}
|
|
84
|
+
catch (requestErr) {
|
|
85
|
+
try {
|
|
86
|
+
const result = await provider.request({ method: "eth_accounts" });
|
|
87
|
+
if (Array.isArray(result))
|
|
88
|
+
addresses = result;
|
|
89
|
+
}
|
|
90
|
+
catch (_) {
|
|
91
|
+
// ignore
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const selectedAccount = (addresses?.[0] ?? undefined);
|
|
95
|
+
this.walletClientInstance = (0, viem_1.createWalletClient)({
|
|
96
|
+
chain: this.chain,
|
|
97
|
+
transport,
|
|
98
|
+
account: selectedAccount,
|
|
99
|
+
});
|
|
100
|
+
this.publicClient = (0, viem_1.createPublicClient)({
|
|
101
|
+
chain: this.chain,
|
|
102
|
+
transport,
|
|
103
|
+
});
|
|
104
|
+
this.contract = (0, viem_1.getContract)({
|
|
105
|
+
address: this.contractAddress,
|
|
106
|
+
abi: abis_1.BondkitTokenABI,
|
|
107
|
+
client: this.walletClientInstance,
|
|
108
|
+
});
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.error("Connection failed:", error);
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
68
116
|
async handleError(error, context) {
|
|
69
117
|
const defaultMessage = context ? `Error in ${context}:` : "An error occurred:";
|
|
70
118
|
console.error(defaultMessage, error);
|
|
@@ -301,7 +349,30 @@ class BondkitToken {
|
|
|
301
349
|
// --- Write Methods --- //
|
|
302
350
|
async executeWrite(functionName, args, options) {
|
|
303
351
|
if (!this.walletClientInstance.account && !this.walletKey) {
|
|
304
|
-
|
|
352
|
+
// Try to resolve an account from a connected EIP-1193 provider on-demand
|
|
353
|
+
if (this.connectedProvider) {
|
|
354
|
+
try {
|
|
355
|
+
const addresses = (await this.connectedProvider.request({ method: "eth_accounts" }));
|
|
356
|
+
const selectedAccount = (addresses?.[0] ?? undefined);
|
|
357
|
+
if (selectedAccount) {
|
|
358
|
+
const transport = (0, viem_1.custom)(this.connectedProvider);
|
|
359
|
+
this.walletClientInstance = (0, viem_1.createWalletClient)({
|
|
360
|
+
chain: this.chain,
|
|
361
|
+
transport,
|
|
362
|
+
account: selectedAccount,
|
|
363
|
+
});
|
|
364
|
+
this.contract = (0, viem_1.getContract)({
|
|
365
|
+
address: this.contractAddress,
|
|
366
|
+
abi: abis_1.BondkitTokenABI,
|
|
367
|
+
client: this.walletClientInstance,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
catch (_) { }
|
|
372
|
+
}
|
|
373
|
+
if (!this.walletClientInstance.account && !this.walletKey) {
|
|
374
|
+
throw new Error("Wallet key not set or client not connected for write operation.");
|
|
375
|
+
}
|
|
305
376
|
}
|
|
306
377
|
const accountToUse = this.walletKey ? (0, accounts_1.privateKeyToAccount)(this.walletKey) : this.walletClientInstance.account;
|
|
307
378
|
if (!accountToUse)
|
|
@@ -9,8 +9,19 @@ export declare class BondkitTokenFactory {
|
|
|
9
9
|
private walletKey?;
|
|
10
10
|
private rpcUrl;
|
|
11
11
|
private walletClientInstance;
|
|
12
|
+
private connectedProvider?;
|
|
12
13
|
constructor(chainId: SupportedChainId, walletKey?: string);
|
|
13
14
|
connect(provider?: EIP1193Provider): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Connects using an EIP-1193 provider and requests accounts, selecting the first one.
|
|
17
|
+
* Enables frontend wallet flows without requiring a private key.
|
|
18
|
+
*/
|
|
19
|
+
connectWithProvider(provider: EIP1193Provider): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Ensure we have an account set for write operations.
|
|
22
|
+
* If not, try to resolve from a connected provider and reinitialize the client.
|
|
23
|
+
*/
|
|
24
|
+
private ensureWriteAccount;
|
|
14
25
|
private handleError;
|
|
15
26
|
/**
|
|
16
27
|
* Deploys a new Bondkit token using the factory.
|
|
@@ -37,6 +37,7 @@ class BondkitTokenFactory {
|
|
|
37
37
|
connect(provider) {
|
|
38
38
|
try {
|
|
39
39
|
const transport = provider ? (0, viem_1.custom)(provider) : (0, viem_1.http)(this.rpcUrl);
|
|
40
|
+
this.connectedProvider = provider;
|
|
40
41
|
this.walletClientInstance = (0, viem_1.createWalletClient)({
|
|
41
42
|
chain: this.chain,
|
|
42
43
|
transport,
|
|
@@ -58,6 +59,79 @@ class BondkitTokenFactory {
|
|
|
58
59
|
return false;
|
|
59
60
|
}
|
|
60
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Connects using an EIP-1193 provider and requests accounts, selecting the first one.
|
|
64
|
+
* Enables frontend wallet flows without requiring a private key.
|
|
65
|
+
*/
|
|
66
|
+
async connectWithProvider(provider) {
|
|
67
|
+
try {
|
|
68
|
+
const transport = (0, viem_1.custom)(provider);
|
|
69
|
+
this.connectedProvider = provider;
|
|
70
|
+
// Request accounts; fall back to eth_accounts if user already connected
|
|
71
|
+
let addresses = [];
|
|
72
|
+
try {
|
|
73
|
+
const result = await provider.request({ method: "eth_requestAccounts" });
|
|
74
|
+
if (Array.isArray(result))
|
|
75
|
+
addresses = result;
|
|
76
|
+
}
|
|
77
|
+
catch (requestErr) {
|
|
78
|
+
try {
|
|
79
|
+
const result = await provider.request({ method: "eth_accounts" });
|
|
80
|
+
if (Array.isArray(result))
|
|
81
|
+
addresses = result;
|
|
82
|
+
}
|
|
83
|
+
catch (_) { }
|
|
84
|
+
}
|
|
85
|
+
const selectedAccount = (addresses?.[0] ?? undefined);
|
|
86
|
+
this.walletClientInstance = (0, viem_1.createWalletClient)({
|
|
87
|
+
chain: this.chain,
|
|
88
|
+
transport,
|
|
89
|
+
account: selectedAccount,
|
|
90
|
+
});
|
|
91
|
+
this.publicClient = (0, viem_1.createPublicClient)({
|
|
92
|
+
chain: this.chain,
|
|
93
|
+
transport,
|
|
94
|
+
});
|
|
95
|
+
this.contract = (0, viem_1.getContract)({
|
|
96
|
+
address: this.contractAddress,
|
|
97
|
+
abi: abis_1.BondkitTokenFactoryABI,
|
|
98
|
+
client: this.walletClientInstance,
|
|
99
|
+
});
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
console.error("Connection failed:", error);
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Ensure we have an account set for write operations.
|
|
109
|
+
* If not, try to resolve from a connected provider and reinitialize the client.
|
|
110
|
+
*/
|
|
111
|
+
async ensureWriteAccount() {
|
|
112
|
+
if (this.walletClientInstance.account || this.walletKey)
|
|
113
|
+
return;
|
|
114
|
+
if (!this.connectedProvider)
|
|
115
|
+
return;
|
|
116
|
+
try {
|
|
117
|
+
const addresses = (await this.connectedProvider.request({ method: "eth_accounts" }));
|
|
118
|
+
const selectedAccount = (addresses?.[0] ?? undefined);
|
|
119
|
+
if (selectedAccount) {
|
|
120
|
+
const transport = (0, viem_1.custom)(this.connectedProvider);
|
|
121
|
+
this.walletClientInstance = (0, viem_1.createWalletClient)({
|
|
122
|
+
chain: this.chain,
|
|
123
|
+
transport,
|
|
124
|
+
account: selectedAccount,
|
|
125
|
+
});
|
|
126
|
+
this.contract = (0, viem_1.getContract)({
|
|
127
|
+
address: this.contractAddress,
|
|
128
|
+
abi: abis_1.BondkitTokenFactoryABI,
|
|
129
|
+
client: this.walletClientInstance,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (_) { }
|
|
134
|
+
}
|
|
61
135
|
// TODO: Implement a more generic handleError based on leaderboards-sdk style if common errors are identified
|
|
62
136
|
async handleError(error, context) {
|
|
63
137
|
const defaultMessage = context ? `Error in ${context}:` : "An error occurred:";
|
|
@@ -73,7 +147,10 @@ class BondkitTokenFactory {
|
|
|
73
147
|
*/
|
|
74
148
|
async deployBondkitToken(configArg) {
|
|
75
149
|
if (!this.walletClientInstance.account && !this.walletKey) {
|
|
76
|
-
|
|
150
|
+
await this.ensureWriteAccount();
|
|
151
|
+
if (!this.walletClientInstance.account && !this.walletKey) {
|
|
152
|
+
throw new Error("Wallet key not set or client not connected with an account.");
|
|
153
|
+
}
|
|
77
154
|
}
|
|
78
155
|
if (!bondkitTokenCreatedEventAbi) {
|
|
79
156
|
throw new Error("BondkitTokenCreated event ABI not found.");
|
|
@@ -173,7 +250,10 @@ class BondkitTokenFactory {
|
|
|
173
250
|
*/
|
|
174
251
|
async transferOwnership(newOwner) {
|
|
175
252
|
if (!this.walletClientInstance.account && !this.walletKey) {
|
|
176
|
-
|
|
253
|
+
await this.ensureWriteAccount();
|
|
254
|
+
if (!this.walletClientInstance.account && !this.walletKey) {
|
|
255
|
+
throw new Error("Wallet key not set or client not connected with an account for write operation.");
|
|
256
|
+
}
|
|
177
257
|
}
|
|
178
258
|
try {
|
|
179
259
|
const accountToUse = this.walletKey ? (0, accounts_1.privateKeyToAccount)(this.walletKey) : this.walletClientInstance.account;
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const cdn_loader_1 = require("./utils/cdn-loader");
|
|
6
|
+
const format_1 = require("./utils/format");
|
|
7
|
+
const lucide_react_1 = require("lucide-react");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
// TradingView will be available on window after loading from CDN
|
|
10
|
+
// Datafeed will be implemented inline
|
|
11
|
+
// Mock loading overlay - replace with your actual loading component
|
|
12
|
+
const GifLoadingOverlay = ({ className }) => ((0, jsx_runtime_1.jsx)("div", { className: `absolute inset-0 flex items-center justify-center bg-white/50 backdrop-blur-sm ${className || ""}`, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-secondary-grey h-8 w-8 animate-spin" }) }));
|
|
13
|
+
const TradingView = ({ className, tokenAddress, tokenSymbol }) => {
|
|
14
|
+
const theme = "light";
|
|
15
|
+
// Use token info for the current trade
|
|
16
|
+
const currentTrade = {
|
|
17
|
+
product_id: tokenAddress && tokenSymbol ? `${tokenSymbol}-${tokenAddress}` : "BONDKIT",
|
|
18
|
+
};
|
|
19
|
+
const [tradingViewDefaultInterval, setTradingViewDefaultInterval] = (0, react_1.useState)("60");
|
|
20
|
+
const [tradingViewTimezone, setTradingViewTimezone] = (0, react_1.useState)("");
|
|
21
|
+
const chartContainerRef = (0, react_1.useRef)(null);
|
|
22
|
+
const tvWidgetRef = (0, react_1.useRef)(null);
|
|
23
|
+
const [chartLoaded, setChartLoaded] = (0, react_1.useState)(false);
|
|
24
|
+
const [showLoading, setShowLoading] = (0, react_1.useState)(true);
|
|
25
|
+
const [librariesLoaded, setLibrariesLoaded] = (0, react_1.useState)(false);
|
|
26
|
+
const isChangingInterval = (0, react_1.useRef)(false);
|
|
27
|
+
// Load TradingView libraries from CDN
|
|
28
|
+
(0, react_1.useEffect)(() => {
|
|
29
|
+
const loadLibraries = async () => {
|
|
30
|
+
try {
|
|
31
|
+
// Load TradingView charting library
|
|
32
|
+
await (0, cdn_loader_1.loadScriptFromCDN)("/static/charting_library/charting_library.js");
|
|
33
|
+
setLibrariesLoaded(true);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error("Failed to load TradingView libraries:", error);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
loadLibraries();
|
|
40
|
+
}, []);
|
|
41
|
+
(0, react_1.useEffect)(() => {
|
|
42
|
+
if (!chartContainerRef.current || !librariesLoaded)
|
|
43
|
+
return;
|
|
44
|
+
// Create UDF-compatible datafeed that mimics the original UDFCompatibleDatafeed
|
|
45
|
+
const createUDFDatafeed = (baseUrl) => {
|
|
46
|
+
return {
|
|
47
|
+
onReady: (callback) => {
|
|
48
|
+
// Fetch configuration from UDF config endpoint
|
|
49
|
+
fetch(`${baseUrl}/config`)
|
|
50
|
+
.then(response => response.json())
|
|
51
|
+
.then(config => callback(config))
|
|
52
|
+
.catch(() => {
|
|
53
|
+
// Fallback configuration if config endpoint fails
|
|
54
|
+
callback({
|
|
55
|
+
supported_resolutions: ["1", "5", "15", "30", "60", "1D", "1W", "1M"],
|
|
56
|
+
supports_group_request: false,
|
|
57
|
+
supports_marks: false,
|
|
58
|
+
supports_search: false,
|
|
59
|
+
supports_timescale_marks: false,
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
searchSymbols: () => { },
|
|
64
|
+
resolveSymbol: (symbolName, onSymbolResolvedCallback) => {
|
|
65
|
+
// Try to fetch symbol info from UDF endpoint
|
|
66
|
+
fetch(`${baseUrl}/symbols?symbol=${symbolName}`)
|
|
67
|
+
.then(response => response.json())
|
|
68
|
+
.then(symbolInfo => onSymbolResolvedCallback(symbolInfo))
|
|
69
|
+
.catch(() => {
|
|
70
|
+
// Fallback symbol info
|
|
71
|
+
onSymbolResolvedCallback({
|
|
72
|
+
name: symbolName,
|
|
73
|
+
ticker: symbolName,
|
|
74
|
+
description: symbolName,
|
|
75
|
+
type: "crypto",
|
|
76
|
+
session: "24x7",
|
|
77
|
+
timezone: "Etc/UTC",
|
|
78
|
+
exchange: "BONDKIT",
|
|
79
|
+
minmov: 1,
|
|
80
|
+
pricescale: 10000,
|
|
81
|
+
has_intraday: true,
|
|
82
|
+
supported_resolutions: ["1", "5", "15", "30", "60", "1D", "1W", "1M"],
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
getBars: async (symbolInfo, resolution, periodParams, onHistoryCallback) => {
|
|
87
|
+
try {
|
|
88
|
+
const { from, to, countback } = periodParams;
|
|
89
|
+
// Build URL with parameters matching production
|
|
90
|
+
const params = new URLSearchParams({
|
|
91
|
+
symbol: symbolInfo.ticker,
|
|
92
|
+
resolution: resolution,
|
|
93
|
+
from: from.toString(),
|
|
94
|
+
to: to.toString(),
|
|
95
|
+
currencyCode: "ETH",
|
|
96
|
+
});
|
|
97
|
+
// Add countback if provided
|
|
98
|
+
if (countback) {
|
|
99
|
+
params.append("countback", countback.toString());
|
|
100
|
+
}
|
|
101
|
+
const response = await fetch(`${baseUrl}/history?${params}`);
|
|
102
|
+
if (!response.ok) {
|
|
103
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
104
|
+
}
|
|
105
|
+
const data = await response.json();
|
|
106
|
+
if (data.s === "ok" && data.t && data.t.length > 0) {
|
|
107
|
+
const bars = data.t.map((time, index) => ({
|
|
108
|
+
time: parseInt(time) * 1000, // Convert string to number, then to milliseconds
|
|
109
|
+
open: parseFloat(data.o[index]), // Parse string to number
|
|
110
|
+
high: parseFloat(data.h[index]),
|
|
111
|
+
low: parseFloat(data.l[index]),
|
|
112
|
+
close: parseFloat(data.c[index]),
|
|
113
|
+
volume: data.v ? parseFloat(data.v[index]) : 0, // Parse volume string to number
|
|
114
|
+
}));
|
|
115
|
+
onHistoryCallback(bars, { noData: false });
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
onHistoryCallback([], { noData: true });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error("Error fetching bars:", error);
|
|
123
|
+
onHistoryCallback([], { noData: true });
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
subscribeBars: () => { },
|
|
127
|
+
unsubscribeBars: () => { },
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
const datafeed = createUDFDatafeed("https://b3-udf-worker.sean-430.workers.dev/bondkit/udf");
|
|
131
|
+
// Calculate timeframe for last 2 days
|
|
132
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
133
|
+
const twoDaysAgo = currentTime - 2 * 24 * 60 * 60; // 2 days in seconds
|
|
134
|
+
const widgetOptions = {
|
|
135
|
+
timeframe: { from: twoDaysAgo, to: currentTime }, // Show last 2 days
|
|
136
|
+
symbol: currentTrade?.product_id || "BONDKIT",
|
|
137
|
+
datafeed: datafeed,
|
|
138
|
+
interval: tradingViewDefaultInterval,
|
|
139
|
+
container: chartContainerRef.current,
|
|
140
|
+
library_path: "https://cdn.b3.fun/static/charting_library/",
|
|
141
|
+
locale: "en",
|
|
142
|
+
disabled_features: [
|
|
143
|
+
"use_localstorage_for_settings",
|
|
144
|
+
"header_symbol_search",
|
|
145
|
+
"save_chart_properties_to_local_storage",
|
|
146
|
+
"header_compare",
|
|
147
|
+
"vert_touch_drag_scroll",
|
|
148
|
+
],
|
|
149
|
+
enabled_features: ["study_templates", "hide_left_toolbar_by_default"],
|
|
150
|
+
charts_storage_url: "https://saveload.tradingview.com",
|
|
151
|
+
charts_storage_api_version: "1.1",
|
|
152
|
+
client_id: "tradingview.com",
|
|
153
|
+
user_id: "public_user_id",
|
|
154
|
+
fullscreen: false,
|
|
155
|
+
autosize: true,
|
|
156
|
+
timezone: (tradingViewTimezone || getTimezone()),
|
|
157
|
+
debug: true,
|
|
158
|
+
// Configure time frame buttons in the bottom left
|
|
159
|
+
time_frames: [
|
|
160
|
+
{
|
|
161
|
+
text: "5m",
|
|
162
|
+
resolution: "5",
|
|
163
|
+
description: "5 days in 5 minute intervals",
|
|
164
|
+
title: "5m",
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
text: "1h",
|
|
168
|
+
resolution: "60",
|
|
169
|
+
description: "1 week in 1 hour intervals",
|
|
170
|
+
title: "1h",
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
text: "1d",
|
|
174
|
+
resolution: "1D",
|
|
175
|
+
description: "1 month in 1 day intervals",
|
|
176
|
+
title: "1d",
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
text: "1w",
|
|
180
|
+
resolution: "1W",
|
|
181
|
+
description: "6 months in 1 week intervals",
|
|
182
|
+
title: "1w",
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
overrides: {
|
|
186
|
+
"paneProperties.background": "#FFFFFF",
|
|
187
|
+
"paneProperties.backgroundType": "solid",
|
|
188
|
+
"mainSeriesProperties.candleStyle.upColor": "#4AD50D",
|
|
189
|
+
"mainSeriesProperties.candleStyle.borderUpColor": "#4AD50D",
|
|
190
|
+
"mainSeriesProperties.candleStyle.downColor": "#F04438",
|
|
191
|
+
"mainSeriesProperties.candleStyle.borderDownColor": "#F04438",
|
|
192
|
+
"scalesProperties.fontSize": 10,
|
|
193
|
+
},
|
|
194
|
+
studies_overrides: {
|
|
195
|
+
"volume.volume.color.0": "#80231C",
|
|
196
|
+
"volume.volume.color.1": "#215611",
|
|
197
|
+
},
|
|
198
|
+
loading_screen: {
|
|
199
|
+
backgroundColor: "transparent",
|
|
200
|
+
},
|
|
201
|
+
custom_css_url: "/custom-css/tradingview.css",
|
|
202
|
+
custom_font_family: "'Roboto', sans-serif",
|
|
203
|
+
toolbar_bg: "#FFFFFF",
|
|
204
|
+
theme: "light",
|
|
205
|
+
custom_formatters: {
|
|
206
|
+
priceFormatterFactory: () => {
|
|
207
|
+
return {
|
|
208
|
+
format: (price) => {
|
|
209
|
+
if (price < 0.0001) {
|
|
210
|
+
return (0, format_1.formatNumberSmall)(price, true);
|
|
211
|
+
}
|
|
212
|
+
return price.toFixed(4);
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
const tvWidget = new window.TradingView.widget(widgetOptions);
|
|
219
|
+
tvWidgetRef.current = tvWidget;
|
|
220
|
+
tvWidget.onChartReady(() => {
|
|
221
|
+
setShowLoading(false);
|
|
222
|
+
setChartLoaded(true);
|
|
223
|
+
// Subscribe to interval changes
|
|
224
|
+
tvWidget
|
|
225
|
+
.activeChart()
|
|
226
|
+
.onIntervalChanged()
|
|
227
|
+
.subscribe(null, (interval) => {
|
|
228
|
+
isChangingInterval.current = true;
|
|
229
|
+
setTradingViewDefaultInterval(interval);
|
|
230
|
+
// Reset the flag after a short delay
|
|
231
|
+
setTimeout(() => {
|
|
232
|
+
isChangingInterval.current = false;
|
|
233
|
+
}, 300);
|
|
234
|
+
});
|
|
235
|
+
// Subscribe to timezone changes
|
|
236
|
+
tvWidget
|
|
237
|
+
.activeChart()
|
|
238
|
+
.getTimezoneApi()
|
|
239
|
+
.onTimezoneChanged()
|
|
240
|
+
.subscribe(null, (timezone) => {
|
|
241
|
+
setTradingViewTimezone(timezone);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
return () => {
|
|
245
|
+
if (tvWidgetRef.current) {
|
|
246
|
+
tvWidgetRef.current.remove();
|
|
247
|
+
tvWidgetRef.current = null;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
}, [theme, librariesLoaded]);
|
|
251
|
+
(0, react_1.useEffect)(() => {
|
|
252
|
+
if (chartLoaded &&
|
|
253
|
+
currentTrade?.product_id &&
|
|
254
|
+
tvWidgetRef.current &&
|
|
255
|
+
!isChangingInterval.current // Only check symbol if we're not changing interval
|
|
256
|
+
) {
|
|
257
|
+
try {
|
|
258
|
+
const currentSymbol = tvWidgetRef.current.symbolInterval()?.symbol;
|
|
259
|
+
const targetSymbol = currentTrade.product_id;
|
|
260
|
+
// Check if symbols are different (handle both normal and contract address formats)
|
|
261
|
+
const isSameSymbol = currentSymbol === targetSymbol ||
|
|
262
|
+
(currentSymbol && targetSymbol && currentSymbol.split("-")[1] === targetSymbol.split("-")[1]); // Compare contract addresses
|
|
263
|
+
if (!isSameSymbol) {
|
|
264
|
+
setShowLoading(true);
|
|
265
|
+
try {
|
|
266
|
+
tvWidgetRef.current?.setSymbol?.(targetSymbol, tradingViewDefaultInterval, () => {
|
|
267
|
+
setShowLoading(false);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
catch (e) {
|
|
271
|
+
console.error("Error setting symbol:", e);
|
|
272
|
+
setShowLoading(false);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
console.error("Error checking symbol:", error);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}, [chartLoaded, currentTrade?.product_id, tradingViewDefaultInterval]);
|
|
281
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: `relative h-[600px] w-full ${className || ""}`, children: [(0, jsx_runtime_1.jsx)("div", { className: "h-full w-full", ref: chartContainerRef }), showLoading && !isChangingInterval.current && (0, jsx_runtime_1.jsx)(GifLoadingOverlay, {})] }));
|
|
282
|
+
};
|
|
283
|
+
exports.default = TradingView;
|
|
284
|
+
const getTimezone = () => {
|
|
285
|
+
// Simple timezone detection
|
|
286
|
+
try {
|
|
287
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
288
|
+
if (timezone === "Asia/Saigon") {
|
|
289
|
+
return "Asia/Ho_Chi_Minh";
|
|
290
|
+
}
|
|
291
|
+
return timezone;
|
|
292
|
+
}
|
|
293
|
+
catch (e) {
|
|
294
|
+
return "UTC";
|
|
295
|
+
}
|
|
296
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDN Configuration
|
|
3
|
+
* Configure your CDN URLs here
|
|
4
|
+
*/
|
|
5
|
+
export declare const CDN_CONFIG: {
|
|
6
|
+
readonly baseUrl: string;
|
|
7
|
+
readonly chartingLibrary: {
|
|
8
|
+
readonly basePath: "/static/charting_library";
|
|
9
|
+
readonly files: {
|
|
10
|
+
readonly main: "/charting_library.js";
|
|
11
|
+
readonly esm: "/charting_library.esm.js";
|
|
12
|
+
readonly cjs: "/charting_library.cjs.js";
|
|
13
|
+
readonly standalone: "/charting_library.standalone.js";
|
|
14
|
+
readonly types: "/charting_library.d.ts";
|
|
15
|
+
readonly bundles: "/bundles";
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
readonly datafeeds: {
|
|
19
|
+
readonly basePath: "/static/datafeeds";
|
|
20
|
+
readonly udf: "/udf/src/udf-compatible-datafeed.js";
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Get full CDN URL for a resource
|
|
25
|
+
*/
|
|
26
|
+
export declare function getCDNUrl(path: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Get TradingView library path for widget configuration
|
|
29
|
+
*/
|
|
30
|
+
export declare function getTradingViewLibraryPath(): string;
|
|
31
|
+
/**
|
|
32
|
+
* Check if CDN is enabled (useful for development)
|
|
33
|
+
*/
|
|
34
|
+
export declare function isCDNEnabled(): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Check if we're using a custom CDN domain vs the default R2 URL
|
|
37
|
+
*/
|
|
38
|
+
export declare function isUsingCustomDomain(): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Get library path - Always use CDN since static files are removed
|
|
41
|
+
*/
|
|
42
|
+
export declare function getLibraryPath(): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CDN Configuration
|
|
4
|
+
* Configure your CDN URLs here
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.CDN_CONFIG = void 0;
|
|
8
|
+
exports.getCDNUrl = getCDNUrl;
|
|
9
|
+
exports.getTradingViewLibraryPath = getTradingViewLibraryPath;
|
|
10
|
+
exports.isCDNEnabled = isCDNEnabled;
|
|
11
|
+
exports.isUsingCustomDomain = isUsingCustomDomain;
|
|
12
|
+
exports.getLibraryPath = getLibraryPath;
|
|
13
|
+
exports.CDN_CONFIG = {
|
|
14
|
+
// Base CDN URL - will use your custom domain or R2 public URL
|
|
15
|
+
baseUrl: process.env.NEXT_PUBLIC_CDN_URL || "https://cdn.b3.fun",
|
|
16
|
+
// TradingView charting library paths
|
|
17
|
+
chartingLibrary: {
|
|
18
|
+
basePath: "/static/charting_library",
|
|
19
|
+
files: {
|
|
20
|
+
main: "/charting_library.js",
|
|
21
|
+
esm: "/charting_library.esm.js",
|
|
22
|
+
cjs: "/charting_library.cjs.js",
|
|
23
|
+
standalone: "/charting_library.standalone.js",
|
|
24
|
+
types: "/charting_library.d.ts",
|
|
25
|
+
bundles: "/bundles",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
// Datafeeds paths
|
|
29
|
+
datafeeds: {
|
|
30
|
+
basePath: "/static/datafeeds",
|
|
31
|
+
udf: "/udf/src/udf-compatible-datafeed.js",
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Get full CDN URL for a resource
|
|
36
|
+
*/
|
|
37
|
+
function getCDNUrl(path) {
|
|
38
|
+
return `${exports.CDN_CONFIG.baseUrl}${path}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get TradingView library path for widget configuration
|
|
42
|
+
*/
|
|
43
|
+
function getTradingViewLibraryPath() {
|
|
44
|
+
return getCDNUrl(exports.CDN_CONFIG.chartingLibrary.basePath + "/");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check if CDN is enabled (useful for development)
|
|
48
|
+
*/
|
|
49
|
+
function isCDNEnabled() {
|
|
50
|
+
return process.env.NODE_ENV === "production" || process.env.NEXT_PUBLIC_FORCE_CDN === "true";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if we're using a custom CDN domain vs the default R2 URL
|
|
54
|
+
*/
|
|
55
|
+
function isUsingCustomDomain() {
|
|
56
|
+
return !!process.env.NEXT_PUBLIC_CDN_URL;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get library path - Always use CDN since static files are removed
|
|
60
|
+
*/
|
|
61
|
+
function getLibraryPath() {
|
|
62
|
+
return getTradingViewLibraryPath();
|
|
63
|
+
}
|