@zerohash-sdk/fund-js 1.4.0 → 1.4.3
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 +68 -58
- package/dist/index.d.ts +18 -3
- package/dist/index.js +45 -29
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,158 +1,166 @@
|
|
|
1
|
-
# @zerohash-sdk/
|
|
1
|
+
# @zerohash-sdk/fund-js
|
|
2
2
|
|
|
3
|
-
A JavaScript SDK that enables frontend applications to seamlessly integrate with the Connect
|
|
3
|
+
A JavaScript SDK that enables frontend applications to seamlessly integrate with the Connect Fund product.
|
|
4
4
|
|
|
5
|
-
Connect
|
|
5
|
+
Connect Fund provides a secure, customizable flow for funding accounts via crypto deposits directly within your application.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
9
|
### Via NPM (recommended)
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install @zerohash-sdk/
|
|
12
|
+
npm install @zerohash-sdk/fund-js
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
```javascript
|
|
16
|
-
import {
|
|
16
|
+
import { Fund } from '@zerohash-sdk/fund-js';
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
### Via CDN
|
|
20
20
|
|
|
21
|
-
You can import the script in your HTML file and use the `
|
|
21
|
+
You can import the script in your HTML file and use the `Fund` class provided by it.
|
|
22
22
|
|
|
23
23
|
```html
|
|
24
24
|
<script
|
|
25
25
|
type="module"
|
|
26
|
-
src="https://sdk.connect.xyz/
|
|
26
|
+
src="https://sdk.connect.xyz/fund-web/index.js"
|
|
27
27
|
></script>
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Or import directly in your JavaScript code:
|
|
31
31
|
|
|
32
32
|
```javascript
|
|
33
|
-
import {
|
|
33
|
+
import { Fund } from 'https://sdk.connect.xyz/fund-web/index.js';
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Getting Started
|
|
37
37
|
|
|
38
|
-
Follow these simple steps to integrate Connect
|
|
38
|
+
Follow these simple steps to integrate Connect Fund into your frontend application:
|
|
39
39
|
|
|
40
|
-
### 1. Import the
|
|
40
|
+
### 1. Import the Fund module
|
|
41
41
|
|
|
42
42
|
```javascript
|
|
43
|
-
import {
|
|
43
|
+
import { Fund } from '@zerohash-sdk/fund-js';
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
### 1.1 Or import via CDN
|
|
47
47
|
|
|
48
48
|
```javascript
|
|
49
|
-
import {
|
|
49
|
+
import { Fund } from 'https://sdk.connect.xyz/fund-web/index.js';
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
### 2. Initialize and render the widget
|
|
53
53
|
|
|
54
54
|
```javascript
|
|
55
|
-
// Create a
|
|
56
|
-
const
|
|
55
|
+
// Create a Fund instance with configuration
|
|
56
|
+
const fund = new Fund({
|
|
57
57
|
jwt: 'your-jwt-token', // Obtain this from your backend
|
|
58
58
|
env: 'prod', // or 'cert' for testing
|
|
59
59
|
theme: 'auto', // 'auto' (default), 'light', or 'dark'
|
|
60
|
-
onCompleted: ({
|
|
61
|
-
console.log('
|
|
60
|
+
onCompleted: ({ assetSymbol, amount, network, depositAddress }) => {
|
|
61
|
+
console.log('Fund completed:', amount, assetSymbol, network, depositAddress);
|
|
62
62
|
},
|
|
63
63
|
onError: ({ errorCode, reason }) => {
|
|
64
|
-
console.error('
|
|
64
|
+
console.error('Fund error:', errorCode, 'Reason:', reason);
|
|
65
65
|
},
|
|
66
66
|
onClose: () => {
|
|
67
|
-
console.log('
|
|
67
|
+
console.log('Fund widget closed');
|
|
68
68
|
},
|
|
69
69
|
onEvent: ({ type, data }) => {
|
|
70
70
|
console.log('Event received:', type, data);
|
|
71
71
|
},
|
|
72
72
|
onLoaded: () => {
|
|
73
|
-
console.log('
|
|
73
|
+
console.log('Fund widget loaded and ready');
|
|
74
74
|
},
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
// Render the widget to a container element
|
|
78
|
-
const container = document.getElementById('
|
|
79
|
-
await
|
|
78
|
+
const container = document.getElementById('fund-container');
|
|
79
|
+
await fund.render(container);
|
|
80
80
|
|
|
81
81
|
// Update configuration dynamically
|
|
82
|
-
|
|
82
|
+
fund.updateConfig({
|
|
83
83
|
jwt: 'new-jwt-token',
|
|
84
84
|
theme: 'dark',
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
// Check if rendered
|
|
88
|
-
if (
|
|
88
|
+
if (fund.isRendered()) {
|
|
89
89
|
console.log('Widget is active');
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// Clean up when done
|
|
93
|
-
|
|
93
|
+
fund.destroy();
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
### 2.1 Using TypeScript (optional)
|
|
97
97
|
|
|
98
98
|
```typescript
|
|
99
|
-
import {
|
|
99
|
+
import { Fund, FundConfig } from '@zerohash-sdk/fund-js';
|
|
100
100
|
|
|
101
|
-
const config:
|
|
101
|
+
const config: FundConfig = {
|
|
102
102
|
jwt: 'your-jwt-token',
|
|
103
103
|
env: 'cert',
|
|
104
104
|
theme: 'dark',
|
|
105
|
-
onCompleted: ({
|
|
106
|
-
console.log(`
|
|
105
|
+
onCompleted: ({ assetSymbol, amount }) => {
|
|
106
|
+
console.log(`Funded ${amount} ${assetSymbol}`);
|
|
107
107
|
},
|
|
108
108
|
onError: ({ errorCode, reason }) => {
|
|
109
109
|
console.error(errorCode, reason);
|
|
110
110
|
},
|
|
111
111
|
};
|
|
112
112
|
|
|
113
|
-
const
|
|
114
|
-
await
|
|
113
|
+
const fund = new Fund(config);
|
|
114
|
+
await fund.render(document.getElementById('fund-container')!);
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
## API Reference
|
|
118
118
|
|
|
119
119
|
### Configuration
|
|
120
120
|
|
|
121
|
-
| Prop | Type
|
|
122
|
-
| ------------- |
|
|
123
|
-
| `jwt` | `string`
|
|
124
|
-
| `env` | `"prod" \| "cert" \| "dev" \| "local"`
|
|
125
|
-
| `theme` | `"auto" \| "light" \| "dark"`
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
121
|
+
| Prop | Type | Required | Default | Description |
|
|
122
|
+
| ------------- | ------------------------------------------------------------ | -------- | -------- | -------------------------------------------------- |
|
|
123
|
+
| `jwt` | `string` | Yes | - | JWT token for authentication with Connect |
|
|
124
|
+
| `env` | `"prod" \| "cert" \| "dev" \| "local"` | No | `"prod"` | Target environment |
|
|
125
|
+
| `theme` | `"auto" \| "light" \| "dark"` | No | `"auto"` | Theme mode for the interface |
|
|
126
|
+
| `isPay` | `boolean` | No | `false` | Run the SDK in Pay mode (see notes below) |
|
|
127
|
+
| `onCompleted` | `({ assetSymbol, amount, network, depositAddress }) => void` | No | - | Callback when the fund flow completes successfully |
|
|
128
|
+
| `onError` | `({ errorCode, reason }) => void` | No | - | Callback for error events |
|
|
129
|
+
| `onClose` | `() => void` | No | - | Callback when the widget is closed |
|
|
130
|
+
| `onEvent` | `({ type, data }) => void` | No | - | Callback for general events |
|
|
131
|
+
| `onLoaded` | `() => void` | No | - | Callback when the widget is loaded and ready |
|
|
132
|
+
|
|
133
|
+
### Pay mode (`isPay`)
|
|
134
|
+
|
|
135
|
+
When `isPay` is `true`, the Fund SDK runs in Pay mode:
|
|
136
|
+
|
|
137
|
+
- Uses the `pay-sdk` app id and the `app:internal:pay` scope when calling trade-api.
|
|
138
|
+
- Signs the `account_funding_pay` terms agreement.
|
|
131
139
|
|
|
132
140
|
### Constructor
|
|
133
141
|
|
|
134
142
|
```javascript
|
|
135
|
-
new
|
|
143
|
+
new Fund(config: FundConfig)
|
|
136
144
|
```
|
|
137
145
|
|
|
138
|
-
Creates a new
|
|
146
|
+
Creates a new Fund instance with the provided configuration.
|
|
139
147
|
|
|
140
148
|
### Methods
|
|
141
149
|
|
|
142
150
|
#### `render(container: HTMLElement): Promise<void>`
|
|
143
151
|
|
|
144
|
-
Renders the
|
|
152
|
+
Renders the Fund widget to the specified container element.
|
|
145
153
|
|
|
146
154
|
```javascript
|
|
147
|
-
await
|
|
155
|
+
await fund.render(document.getElementById('fund-container'));
|
|
148
156
|
```
|
|
149
157
|
|
|
150
|
-
#### `updateConfig(config: Partial<
|
|
158
|
+
#### `updateConfig(config: Partial<FundConfig>): void`
|
|
151
159
|
|
|
152
160
|
Updates the configuration of an already rendered widget.
|
|
153
161
|
|
|
154
162
|
```javascript
|
|
155
|
-
|
|
163
|
+
fund.updateConfig({
|
|
156
164
|
jwt: 'new-token',
|
|
157
165
|
theme: 'dark',
|
|
158
166
|
});
|
|
@@ -163,7 +171,7 @@ cryptoSell.updateConfig({
|
|
|
163
171
|
Removes the widget from the DOM and cleans up resources.
|
|
164
172
|
|
|
165
173
|
```javascript
|
|
166
|
-
|
|
174
|
+
fund.destroy();
|
|
167
175
|
```
|
|
168
176
|
|
|
169
177
|
#### `isRendered(): boolean`
|
|
@@ -171,17 +179,17 @@ cryptoSell.destroy();
|
|
|
171
179
|
Returns whether the widget is currently rendered.
|
|
172
180
|
|
|
173
181
|
```javascript
|
|
174
|
-
if (
|
|
182
|
+
if (fund.isRendered()) {
|
|
175
183
|
// Widget is active
|
|
176
184
|
}
|
|
177
185
|
```
|
|
178
186
|
|
|
179
|
-
#### `getConfig():
|
|
187
|
+
#### `getConfig(): FundConfig`
|
|
180
188
|
|
|
181
189
|
Returns a copy of the current configuration.
|
|
182
190
|
|
|
183
191
|
```javascript
|
|
184
|
-
const config =
|
|
192
|
+
const config = fund.getConfig();
|
|
185
193
|
console.log('Current JWT:', config.jwt);
|
|
186
194
|
```
|
|
187
195
|
|
|
@@ -189,18 +197,20 @@ console.log('Current JWT:', config.jwt);
|
|
|
189
197
|
|
|
190
198
|
### onCompleted
|
|
191
199
|
|
|
192
|
-
Called when the
|
|
200
|
+
Called when the fund flow completes successfully.
|
|
193
201
|
|
|
194
202
|
```javascript
|
|
195
|
-
onCompleted: ({
|
|
196
|
-
//
|
|
197
|
-
//
|
|
203
|
+
onCompleted: ({ assetSymbol, amount, network, depositAddress }) => {
|
|
204
|
+
// assetSymbol: Asset symbol (e.g. 'BTC.BITCOIN')
|
|
205
|
+
// amount: Amount to be deposited as a string
|
|
206
|
+
// network: Network used for the deposit
|
|
207
|
+
// depositAddress: Deposit address for the asset
|
|
198
208
|
};
|
|
199
209
|
```
|
|
200
210
|
|
|
201
211
|
### onError
|
|
202
212
|
|
|
203
|
-
Called when an error occurs in the
|
|
213
|
+
Called when an error occurs in the Fund widget.
|
|
204
214
|
|
|
205
215
|
```javascript
|
|
206
216
|
onError: ({ errorCode, reason }) => {
|
|
@@ -211,7 +221,7 @@ onError: ({ errorCode, reason }) => {
|
|
|
211
221
|
|
|
212
222
|
### onClose
|
|
213
223
|
|
|
214
|
-
Called when the
|
|
224
|
+
Called when the Fund widget is closed by the user.
|
|
215
225
|
|
|
216
226
|
```javascript
|
|
217
227
|
onClose: () => {
|
|
@@ -221,7 +231,7 @@ onClose: () => {
|
|
|
221
231
|
|
|
222
232
|
### onEvent
|
|
223
233
|
|
|
224
|
-
Called for general events from the
|
|
234
|
+
Called for general events from the Fund widget.
|
|
225
235
|
|
|
226
236
|
```javascript
|
|
227
237
|
onEvent: ({ type, data }) => {
|
|
@@ -232,7 +242,7 @@ onEvent: ({ type, data }) => {
|
|
|
232
242
|
|
|
233
243
|
### onLoaded
|
|
234
244
|
|
|
235
|
-
Called when the
|
|
245
|
+
Called when the Fund widget has fully loaded and is ready for user interaction.
|
|
236
246
|
|
|
237
247
|
```javascript
|
|
238
248
|
onLoaded: () => {
|
package/dist/index.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ declare interface BaseConfig<TEvent = AppEvent> extends CommonCallbacks<TEvent>
|
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Theme mode
|
|
39
|
-
* @default '
|
|
39
|
+
* @default 'light'
|
|
40
40
|
*
|
|
41
41
|
* Available themes:
|
|
42
42
|
* - `'auto'` - Automatically detect system preference (light/dark mode)
|
|
@@ -200,7 +200,11 @@ declare abstract class BaseJsSdk<Config extends BaseConfig<never> = BaseConfig>
|
|
|
200
200
|
return import.meta.env['VITE_SCRIPT_URL'] || this.scriptUrls[this.getEnvironment()];
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
// Route EU partners (region claim in JWT) to EU-hosted assets without
|
|
204
|
+
// changing the public `env` contract — falls back to the configured env
|
|
205
|
+
// when no EU URL is registered for that environment.
|
|
206
|
+
const effectiveEnv = resolveEnvByRegion(this.getEnvironment(), this.config.jwt);
|
|
207
|
+
return this.scriptUrls[effectiveEnv] ?? this.scriptUrls[this.getEnvironment()];
|
|
204
208
|
}
|
|
205
209
|
|
|
206
210
|
private async loadScript() {
|
|
@@ -362,7 +366,7 @@ declare type ErrorPayload = {
|
|
|
362
366
|
* const fund = new Fund({
|
|
363
367
|
* jwt: 'your-jwt-token',
|
|
364
368
|
* env: 'prod',
|
|
365
|
-
* theme: '
|
|
369
|
+
* theme: 'light',
|
|
366
370
|
* onCompleted: ({ assetSymbol, amount }) => console.log('Deposited', amount, assetSymbol),
|
|
367
371
|
* onClose: () => console.log('Closed'),
|
|
368
372
|
* onError: ({ errorCode, reason }) => console.error(errorCode, reason),
|
|
@@ -441,6 +445,17 @@ declare type FundCompletedData = {
|
|
|
441
445
|
};
|
|
442
446
|
|
|
443
447
|
export declare interface FundConfig extends BaseConfig<FundEvent>, FundCallbacks {
|
|
448
|
+
/**
|
|
449
|
+
* Runs the SDK in Pay mode.
|
|
450
|
+
*
|
|
451
|
+
* - Uses the `pay-sdk` app id and `app:internal:pay` scope when talking to trade-api.
|
|
452
|
+
* - Signs the `account_funding_pay` terms agreement.
|
|
453
|
+
* - Polls deposit status by `transactionId` (single-deposit endpoint) instead of
|
|
454
|
+
* by `deposit_address` (list endpoint).
|
|
455
|
+
*
|
|
456
|
+
* @default false
|
|
457
|
+
*/
|
|
458
|
+
isPay?: boolean;
|
|
444
459
|
}
|
|
445
460
|
|
|
446
461
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
1
|
+
const d = "production", h = "JWT token is required and must be a string.", l = (r) => {
|
|
2
|
+
if (!r || typeof r != "string")
|
|
3
|
+
return null;
|
|
4
|
+
const e = r.split(".");
|
|
5
|
+
if (e.length < 2)
|
|
6
|
+
return null;
|
|
7
|
+
try {
|
|
8
|
+
const n = e[1].replace(/-/g, "+").replace(/_/g, "/"), t = n + "===".slice(0, (4 - n.length % 4) % 4), i = typeof atob < "u" ? atob(t) : Buffer.from(t, "base64").toString("utf-8"), a = JSON.parse(i)?.payload?.region;
|
|
9
|
+
if (typeof a != "string")
|
|
10
|
+
return null;
|
|
11
|
+
const s = a.toLowerCase();
|
|
12
|
+
return s === "us" || s === "eu" ? s : null;
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}, u = (r, e) => l(e) !== "eu" ? r : r === "cert" ? "eu-cert" : r === "prod" ? "eu-prod" : r;
|
|
17
|
+
class p {
|
|
3
18
|
config;
|
|
4
19
|
state;
|
|
5
20
|
scriptLoadingPromise;
|
|
6
21
|
constructor(e) {
|
|
7
22
|
if (!e.jwt || typeof e.jwt != "string")
|
|
8
|
-
throw new Error(
|
|
23
|
+
throw new Error(h);
|
|
9
24
|
this.config = {
|
|
10
25
|
...e,
|
|
11
|
-
env: e.env ||
|
|
26
|
+
env: e.env || d,
|
|
12
27
|
theme: e.theme
|
|
13
28
|
}, this.state = {
|
|
14
29
|
initialized: !1,
|
|
@@ -29,10 +44,10 @@ class c {
|
|
|
29
44
|
throw new Error(this.errorMessages.ALREADY_RENDERED);
|
|
30
45
|
try {
|
|
31
46
|
await this.ensureScriptLoaded();
|
|
32
|
-
const
|
|
33
|
-
e.innerHTML = "", e.appendChild(
|
|
34
|
-
} catch (
|
|
35
|
-
throw console.error("Failed to render widget:",
|
|
47
|
+
const n = this.createWebComponent();
|
|
48
|
+
e.innerHTML = "", e.appendChild(n), this.state.container = e, this.state.element = n, this.state.initialized = !0;
|
|
49
|
+
} catch (n) {
|
|
50
|
+
throw console.error("Failed to render widget:", n), n;
|
|
36
51
|
}
|
|
37
52
|
}
|
|
38
53
|
/**
|
|
@@ -43,9 +58,9 @@ class c {
|
|
|
43
58
|
updateConfig(e) {
|
|
44
59
|
if (!this.state.initialized || !this.state.element)
|
|
45
60
|
throw new Error(this.errorMessages.NOT_RENDERED);
|
|
46
|
-
const
|
|
61
|
+
const n = this.state.element;
|
|
47
62
|
Object.entries(e).forEach(([t, i]) => {
|
|
48
|
-
i && (this.config[t] = i,
|
|
63
|
+
i && (this.config[t] = i, n[t] = i);
|
|
49
64
|
});
|
|
50
65
|
}
|
|
51
66
|
/**
|
|
@@ -69,7 +84,7 @@ class c {
|
|
|
69
84
|
return { ...this.config };
|
|
70
85
|
}
|
|
71
86
|
getEnvironment() {
|
|
72
|
-
return this.config.env ||
|
|
87
|
+
return this.config.env || d;
|
|
73
88
|
}
|
|
74
89
|
getScriptId() {
|
|
75
90
|
return `${this.webComponentTag}-script-${this.getEnvironment()}`;
|
|
@@ -81,20 +96,21 @@ class c {
|
|
|
81
96
|
return customElements.get(this.webComponentTag);
|
|
82
97
|
}
|
|
83
98
|
getScriptUrl() {
|
|
84
|
-
|
|
99
|
+
const e = u(this.getEnvironment(), this.config.jwt);
|
|
100
|
+
return this.scriptUrls[e] ?? this.scriptUrls[this.getEnvironment()];
|
|
85
101
|
}
|
|
86
102
|
async loadScript() {
|
|
87
103
|
if (!this.isScriptLoaded()) {
|
|
88
104
|
if (this.scriptLoadingPromise)
|
|
89
105
|
return this.scriptLoadingPromise;
|
|
90
|
-
this.scriptLoadingPromise = new Promise((e,
|
|
106
|
+
this.scriptLoadingPromise = new Promise((e, n) => {
|
|
91
107
|
const t = document.createElement("script");
|
|
92
108
|
t.id = this.getScriptId(), t.src = this.getScriptUrl(), t.type = "module", t.async = !0, t.onload = () => {
|
|
93
109
|
setTimeout(() => {
|
|
94
|
-
this.getWebComponent() ? e() :
|
|
110
|
+
this.getWebComponent() ? e() : n(new Error(this.errorMessages.WEB_COMPONENT_NOT_DEFINED));
|
|
95
111
|
}, 0);
|
|
96
112
|
}, t.onerror = () => {
|
|
97
|
-
this.scriptLoadingPromise = void 0,
|
|
113
|
+
this.scriptLoadingPromise = void 0, n(new Error(`${this.errorMessages.SCRIPT_LOAD_FAILED} (${this.getEnvironment()})`));
|
|
98
114
|
}, document.head.appendChild(t);
|
|
99
115
|
});
|
|
100
116
|
try {
|
|
@@ -107,14 +123,14 @@ class c {
|
|
|
107
123
|
}
|
|
108
124
|
async waitForWebComponent(e = 5e3) {
|
|
109
125
|
if (!this.getWebComponent())
|
|
110
|
-
return new Promise((
|
|
126
|
+
return new Promise((n, t) => {
|
|
111
127
|
const i = setTimeout(() => {
|
|
112
128
|
t(new Error(`Timeout waiting for ${this.webComponentTag} to be defined`));
|
|
113
129
|
}, e);
|
|
114
130
|
customElements.whenDefined(this.webComponentTag).then(() => {
|
|
115
|
-
clearTimeout(i),
|
|
116
|
-
}).catch((
|
|
117
|
-
clearTimeout(i), t(
|
|
131
|
+
clearTimeout(i), n();
|
|
132
|
+
}).catch((o) => {
|
|
133
|
+
clearTimeout(i), t(o);
|
|
118
134
|
});
|
|
119
135
|
});
|
|
120
136
|
}
|
|
@@ -131,16 +147,16 @@ class c {
|
|
|
131
147
|
}
|
|
132
148
|
createWebComponent() {
|
|
133
149
|
const e = document.createElement(this.webComponentTag);
|
|
134
|
-
return Object.entries(this.config).forEach(([
|
|
135
|
-
t && (e[
|
|
150
|
+
return Object.entries(this.config).forEach(([n, t]) => {
|
|
151
|
+
t && (e[n] = t);
|
|
136
152
|
}), e;
|
|
137
153
|
}
|
|
138
154
|
}
|
|
139
|
-
var
|
|
140
|
-
(function(
|
|
141
|
-
|
|
142
|
-
})(
|
|
143
|
-
class
|
|
155
|
+
var c;
|
|
156
|
+
(function(r) {
|
|
157
|
+
r.NETWORK_ERROR = "network_error", r.AUTH_ERROR = "auth_error", r.NOT_FOUND_ERROR = "not_found_error", r.VALIDATION_ERROR = "validation_error", r.SERVER_ERROR = "server_error", r.CLIENT_ERROR = "client_error", r.UNKNOWN_ERROR = "unknown_error";
|
|
158
|
+
})(c || (c = {}));
|
|
159
|
+
class m extends p {
|
|
144
160
|
errorMessages = {
|
|
145
161
|
ALREADY_RENDERED: "Fund widget is already rendered. Call destroy() before rendering again.",
|
|
146
162
|
NOT_RENDERED: "Fund widget is not rendered. Call render() first.",
|
|
@@ -194,7 +210,7 @@ class h extends c {
|
|
|
194
210
|
}
|
|
195
211
|
}
|
|
196
212
|
export {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
213
|
+
c as ErrorCode,
|
|
214
|
+
m as Fund,
|
|
215
|
+
m as default
|
|
200
216
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(i,
|
|
1
|
+
(function(i,o){typeof exports=="object"&&typeof module<"u"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(i=typeof globalThis<"u"?globalThis:i||self,o(i.Fund={}))})(this,(function(i){"use strict";const o="production",h="JWT token is required and must be a string.",l=n=>{if(!n||typeof n!="string")return null;const e=n.split(".");if(e.length<2)return null;try{const r=e[1].replace(/-/g,"+").replace(/_/g,"/"),t=r+"===".slice(0,(4-r.length%4)%4),s=typeof atob<"u"?atob(t):Buffer.from(t,"base64").toString("utf-8"),u=JSON.parse(s)?.payload?.region;if(typeof u!="string")return null;const d=u.toLowerCase();return d==="us"||d==="eu"?d:null}catch{return null}},p=(n,e)=>l(e)!=="eu"?n:n==="cert"?"eu-cert":n==="prod"?"eu-prod":n;class f{config;state;scriptLoadingPromise;constructor(e){if(!e.jwt||typeof e.jwt!="string")throw new Error(h);this.config={...e,env:e.env||o,theme:e.theme},this.state={initialized:!1,scriptLoaded:!1,container:null,element:null}}async render(e){if(!e||!(e instanceof HTMLElement))throw new Error(this.errorMessages.INVALID_CONTAINER);if(this.state.initialized)throw new Error(this.errorMessages.ALREADY_RENDERED);try{await this.ensureScriptLoaded();const r=this.createWebComponent();e.innerHTML="",e.appendChild(r),this.state.container=e,this.state.element=r,this.state.initialized=!0}catch(r){throw console.error("Failed to render widget:",r),r}}updateConfig(e){if(!this.state.initialized||!this.state.element)throw new Error(this.errorMessages.NOT_RENDERED);const r=this.state.element;Object.entries(e).forEach(([t,s])=>{s&&(this.config[t]=s,r[t]=s)})}destroy(){this.state.initialized&&(this.state.element&&this.state.element.parentNode&&this.state.element.parentNode.removeChild(this.state.element),this.state.container&&(this.state.container.innerHTML=""),this.state.container=null,this.state.element=null,this.state.initialized=!1)}isRendered(){return this.state.initialized}getConfig(){return{...this.config}}getEnvironment(){return this.config.env||o}getScriptId(){return`${this.webComponentTag}-script-${this.getEnvironment()}`}isScriptLoaded(){return!!document.getElementById(this.getScriptId())}getWebComponent(){return customElements.get(this.webComponentTag)}getScriptUrl(){const e=p(this.getEnvironment(),this.config.jwt);return this.scriptUrls[e]??this.scriptUrls[this.getEnvironment()]}async loadScript(){if(!this.isScriptLoaded()){if(this.scriptLoadingPromise)return this.scriptLoadingPromise;this.scriptLoadingPromise=new Promise((e,r)=>{const t=document.createElement("script");t.id=this.getScriptId(),t.src=this.getScriptUrl(),t.type="module",t.async=!0,t.onload=()=>{setTimeout(()=>{this.getWebComponent()?e():r(new Error(this.errorMessages.WEB_COMPONENT_NOT_DEFINED))},0)},t.onerror=()=>{this.scriptLoadingPromise=void 0,r(new Error(`${this.errorMessages.SCRIPT_LOAD_FAILED} (${this.getEnvironment()})`))},document.head.appendChild(t)});try{await this.scriptLoadingPromise}catch(e){throw this.scriptLoadingPromise=void 0,e}return this.scriptLoadingPromise}}async waitForWebComponent(e=5e3){if(!this.getWebComponent())return new Promise((r,t)=>{const s=setTimeout(()=>{t(new Error(`Timeout waiting for ${this.webComponentTag} to be defined`))},e);customElements.whenDefined(this.webComponentTag).then(()=>{clearTimeout(s),r()}).catch(c=>{clearTimeout(s),t(c)})})}async ensureScriptLoaded(){if(!this.state.scriptLoaded)try{await this.loadScript(),await this.waitForWebComponent(),this.state.scriptLoaded=!0}catch(e){throw console.error("Failed to load Connect script:",e),e}}createWebComponent(){const e=document.createElement(this.webComponentTag);return Object.entries(this.config).forEach(([r,t])=>{t&&(e[r]=t)}),e}}i.ErrorCode=void 0,(function(n){n.NETWORK_ERROR="network_error",n.AUTH_ERROR="auth_error",n.NOT_FOUND_ERROR="not_found_error",n.VALIDATION_ERROR="validation_error",n.SERVER_ERROR="server_error",n.CLIENT_ERROR="client_error",n.UNKNOWN_ERROR="unknown_error"})(i.ErrorCode||(i.ErrorCode={}));class a extends f{errorMessages={ALREADY_RENDERED:"Fund widget is already rendered. Call destroy() before rendering again.",NOT_RENDERED:"Fund widget is not rendered. Call render() first.",INVALID_CONTAINER:"Invalid container element provided.",SCRIPT_LOAD_FAILED:"Failed to load the Connect Fund script.",WEB_COMPONENT_NOT_DEFINED:"Web component is not defined. Script may not be loaded."};scriptUrls={local:"http://localhost:5173/fund-web/index.js",dev:"https://connect-sdk.dev.0hash.com/fund-web/index.js",cert:"https://sdk.sandbox.connect.xyz/fund-web/index.js",prod:"https://sdk.connect.xyz/fund-web/index.js",sandbox:"https://sdk.sandbox.connect.xyz/fund-web/index.js",production:"https://sdk.connect.xyz/fund-web/index.js"};webComponentTag="zerohash-fund";render(e){return super.render(e)}updateConfig(e){return super.updateConfig(e)}getConfig(){return super.getConfig()}isRendered(){return super.isRendered()}destroy(){return super.destroy()}}i.Fund=a,i.default=a,Object.defineProperties(i,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|