@gardenfi/orderbook 3.1.2 → 3.1.3-beta.2

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/index11.js CHANGED
@@ -1,207 +1,188 @@
1
- import { ApiKey as f, Url as p, Ok as u, Err as l, Fetcher as d } from "@gardenfi/utils";
2
- import m from "node-cache";
3
- const a = class a {
4
- constructor(e, t) {
5
- this.policy = new m({
6
- stdTTL: 36e3,
7
- // 10 hours in seconds
8
- checkperiod: 3600
9
- // Check for expired keys every hour
10
- }), typeof t == "string" ? this.auth = new f(t) : this.auth = t, typeof e == "string" ? this.apiBaseUrl = new p(e) : this.apiBaseUrl = e;
11
- }
12
- getPolicy() {
13
- return this.policy.get(a.POLICY_CACHE_KEY);
1
+ import { ApiKey as A, Err as o, Fetcher as y, Ok as g } from "@gardenfi/utils";
2
+ import { RouteValidator as C } from "./index12.js";
3
+ import { Config as b } from "./index4.js";
4
+ import { ChainAsset as r } from "./index8.js";
5
+ import { ensureUrl as l, buildDefaultEndpoint as u, parseAssetNameSymbol as w } from "./index13.js";
6
+ const c = Object.keys(b);
7
+ class I {
8
+ constructor(t, s) {
9
+ this.assets = null, this.chains = null, this.routeMatrix = null, this.isLoading = !1, this.error = null, typeof s == "string" ? this.auth = new A(s) : this.auth = s;
10
+ const e = l(t.baseUrl), a = u(e, "/v2/chains"), i = u(e, "/v2/policy");
11
+ this.urls = {
12
+ base: e,
13
+ assets: l(t.assetsUrl ?? a),
14
+ policy: l(t.policyUrl ?? i)
15
+ }, this.routeValidator = new C(
16
+ this.urls.policy.toString(),
17
+ this.auth
18
+ );
14
19
  }
15
- setPolicy(e) {
16
- const t = this.getPolicy(), s = {
17
- default: e.default || (t == null ? void 0 : t.default) || "open",
18
- isolation_groups: [
19
- .../* @__PURE__ */ new Set([
20
- ...(t == null ? void 0 : t.isolation_groups) || [],
21
- ...e.isolation_groups
22
- ])
23
- ],
24
- blacklist_pairs: [
25
- .../* @__PURE__ */ new Set([
26
- ...(t == null ? void 0 : t.blacklist_pairs) || [],
27
- ...e.blacklist_pairs
28
- ])
29
- ],
30
- whitelist_overrides: [
31
- .../* @__PURE__ */ new Set([
32
- ...(t == null ? void 0 : t.whitelist_overrides) || [],
33
- ...e.whitelist_overrides
34
- ])
35
- ]
36
- };
37
- return this.policy.set(a.POLICY_CACHE_KEY, s), s;
20
+ // ============================================
21
+ // Initialization Methods
22
+ // ============================================
23
+ /**
24
+ * Initialize the AssetManager by fetching all required data
25
+ */
26
+ async initialize() {
27
+ await this.fetchAndSetAssetsAndChains(), await this.routeValidator.loadPolicy();
38
28
  }
39
29
  /**
40
- * Loads the current route policy, cached or via API.
30
+ * Fetch and cache asset and chain data from API
41
31
  */
42
- async loadPolicy() {
43
- const e = this.getPolicy();
44
- if (e) return u(e);
32
+ async fetchAndSetAssetsAndChains() {
45
33
  try {
34
+ this.isLoading = !0, this.error = null;
46
35
  const t = await this.auth.getAuthHeaders();
47
- if (!t.ok)
48
- return l(`Failed to get auth headers: ${t.error}`);
49
- const s = await d.get(
50
- this.apiBaseUrl,
36
+ if (!t.ok) return o("Failed to get auth headers");
37
+ const s = await y.get(
38
+ this.urls.assets,
51
39
  {
52
40
  headers: {
53
- "Content-Type": "application/json",
54
41
  ...t.val
55
42
  }
56
43
  }
57
44
  );
58
- return s.result ? u(this.setPolicy(s.result)) : l(`API Error: ${s.error}`);
45
+ if (!s.result) return o(`Failed to fetch chains data: ${s.error}`);
46
+ const { assets: e, chains: a } = this.processApiData(s.result);
47
+ return this.assets = e, this.chains = a, await this.buildRouteMatrix(), g("AssetManager initialized successfully");
59
48
  } catch (t) {
60
- return l(`Failed to load policy: ${t}`);
49
+ return o(`Failed to fetch assets data: ${t}`);
50
+ } finally {
51
+ this.isLoading = !1;
61
52
  }
62
53
  }
54
+ // ============================================
55
+ // Route Validation Methods
56
+ // ============================================
63
57
  /**
64
- * Checks if a given route is valid based on all route rules.
58
+ * Check if a swap route from one asset to another is valid
65
59
  */
66
- async isValidRoute(e, t) {
67
- const s = await this.loadPolicy();
68
- if (!s.ok || e.toString() === t.toString()) return !1;
69
- const { sortedIsolationRules: r, sortedBlacklistRules: i, sortedWhitelistRules: n } = this.preprocessRules(s.val), o = this.findMatchingRule(
70
- e,
71
- r
72
- );
73
- if (o && !this.matchesRuleDestination(t, o))
74
- return !1;
75
- const c = this.findMatchingRule(
76
- t,
77
- r
60
+ async isRouteValid(t, s) {
61
+ return await this.routeValidator.isValidRoute(
62
+ r.from(t.id),
63
+ r.from(s.id)
78
64
  );
79
- return c && c.rule.direction === "<->" && !this.matchesRuleSource(e, c) ? !1 : this.matchesRuleList(e, t, i) ? !!this.matchesRuleList(e, t, n) : s.val.default === "open";
80
65
  }
81
66
  /**
82
- * Returns all valid destinations for a given source asset.
67
+ * Get all valid destination assets for a given source asset
83
68
  */
84
- async getValidDestinations(e, t) {
85
- const s = [];
86
- for (const r of t)
87
- await this.isValidRoute(e, r) && s.push(r);
88
- return s;
89
- }
69
+ getValidDestinations(t) {
70
+ if (!this.routeMatrix || !this.assets || !t.id)
71
+ return console.warn(
72
+ "Missing routeMatrix, assets, or asset. Returning all assets."
73
+ ), [];
74
+ const s = this.routeMatrix[t.id.toString().toLowerCase()];
75
+ return s ? s.map((e) => {
76
+ const a = e.toString();
77
+ return Object.values(this.assets).find((i) => r.from(i).toString() === a);
78
+ }).filter(Boolean) : [];
79
+ }
80
+ // ============================================
81
+ // Asset Query Methods
82
+ // ============================================
90
83
  /**
91
- * Returns every valid route (from-to pair) among the provided assets.
84
+ * Get asset by chain and token address
92
85
  */
93
- async getAllValidRoutes(e) {
94
- const t = [];
95
- for (const s of e)
96
- for (const r of e)
97
- await this.isValidRoute(s, r) && t.push({ from: s, to: r });
98
- return t;
86
+ getAsset(t) {
87
+ if (!this.assets) return;
88
+ const s = r.from(t).toString();
89
+ return this.assets[s];
99
90
  }
100
91
  /**
101
- * Turns policy string rules into sorted ParsedRule objects.
92
+ * Get all assets for a specific chain
102
93
  */
103
- preprocessRules(e) {
104
- const t = e.isolation_groups.map((i) => this.parseRule(i)).sort((i, n) => n.specificity - i.specificity), s = e.blacklist_pairs.map((i) => this.parseRule(i)).sort((i, n) => n.specificity - i.specificity), r = e.whitelist_overrides.map((i) => this.parseRule(i)).sort((i, n) => n.specificity - i.specificity);
105
- return { sortedIsolationRules: t, sortedBlacklistRules: s, sortedWhitelistRules: r };
94
+ getAssetsByChain(t) {
95
+ return this.assets ? Object.values(this.assets).filter((s) => s.chain === t) : [];
106
96
  }
107
97
  /**
108
- * Parses a rule string (e.g. "ethereum:usdc -> base:usdt") into parts.
98
+ * Search assets by symbol or name
109
99
  */
110
- parseRule(e) {
111
- const s = e.includes(
112
- "<->"
113
- /* Bidirectional */
114
- ) ? "<->" : "->", [r, i] = e.split(s).map((n) => n.trim());
115
- return {
116
- pattern: e,
117
- fromPattern: r,
118
- toPattern: i,
119
- direction: s,
120
- specificity: this.calculateSpecificity(r, i)
121
- };
122
- }
123
- /**
124
- * Gives a specificity score to a rule pattern for prioritizing.
125
- */
126
- calculateSpecificity(e, t) {
127
- const s = (r) => {
128
- const i = r.toLowerCase();
129
- return i === "*" ? 0 : i.includes(
130
- "*"
131
- /* Any */
132
- ) ? 1 : 2;
133
- };
134
- return s(e) * 10 + s(t);
100
+ searchAssets(t) {
101
+ if (!this.assets) return [];
102
+ const s = t.toLowerCase();
103
+ return Object.values(this.assets).filter(
104
+ (e) => e.symbol.toLowerCase().includes(s) || e.name.toLowerCase().includes(s)
105
+ );
135
106
  }
136
107
  /**
137
- * Finds the first matching rule for an asset given the rule "side".
108
+ * Get chain data by chain identifier
138
109
  */
139
- findMatchingRule(e, t) {
140
- for (const s of t) {
141
- if (this.matchesAssetPattern(e, s.fromPattern))
142
- return {
143
- rule: s,
144
- matchedAs: "from"
145
- /* From */
146
- };
147
- if (s.direction === "<->" && this.matchesAssetPattern(e, s.toPattern))
148
- return {
149
- rule: s,
150
- matchedAs: "to"
151
- /* To */
152
- };
153
- }
154
- return null;
110
+ getChain(t) {
111
+ if (this.chains)
112
+ return this.chains[t];
155
113
  }
114
+ // ============================================
115
+ // Private Helper Methods
116
+ // ============================================
156
117
  /**
157
- * Checks if a given toAsset matches the rule's destination side.
118
+ * Build route matrix for fast O(1) route lookups
158
119
  */
159
- matchesRuleDestination(e, t) {
160
- return t.matchedAs === "from" ? this.matchesAssetPattern(e, t.rule.toPattern) : t.rule.direction !== "<->" ? !1 : this.matchesAssetPattern(e, t.rule.fromPattern);
120
+ async buildRouteMatrix() {
121
+ if (!this.assets || !this.routeValidator) return;
122
+ const t = Object.values(this.assets).map((s) => {
123
+ if (!s.id) return null;
124
+ try {
125
+ return r.from(s.id);
126
+ } catch {
127
+ return null;
128
+ }
129
+ }).filter((s) => s !== null);
130
+ this.routeMatrix = await this.routeValidator.buildRouteMatrix(
131
+ t
132
+ );
161
133
  }
162
134
  /**
163
- * Checks if a given fromAsset matches the rule's source side.
135
+ * Process raw API data into structured format
164
136
  */
165
- matchesRuleSource(e, t) {
166
- return t.matchedAs === "to" ? this.matchesAssetPattern(e, t.rule.fromPattern) : t.rule.direction !== "<->" ? !1 : this.matchesAssetPattern(e, t.rule.toPattern);
137
+ processApiData(t) {
138
+ const s = {}, e = {};
139
+ for (const a of t) {
140
+ const i = this.parseChainIdentifier(a.chain);
141
+ if (!i || !c.includes(i))
142
+ continue;
143
+ const h = {
144
+ ...a,
145
+ name: a.name || this.formatChainName(i),
146
+ chain: i
147
+ };
148
+ for (const n of a.assets) {
149
+ const d = r.from(n.id).toString(), { name: f, symbol: m } = w(
150
+ n.name,
151
+ n.id
152
+ ), p = {
153
+ ...n,
154
+ id: r.from(n.id),
155
+ chain: i,
156
+ name: f,
157
+ symbol: m
158
+ };
159
+ s[d] = p, e[i] || (e[i] = h);
160
+ }
161
+ }
162
+ return { assets: s, chains: e };
167
163
  }
168
164
  /**
169
- * Checks if any rule in a list matches fromAsset and toAsset.
165
+ * Parse chain identifier from string
170
166
  */
171
- matchesRuleList(e, t, s) {
172
- return s.some((r) => this.matchesRule(e, t, r));
167
+ parseChainIdentifier(t) {
168
+ return c.includes(t) ? t : null;
173
169
  }
174
170
  /**
175
- * Checks if a rule matches fromAsset and toAsset (forward or backward if bidirectional).
171
+ * Format chain name for display
176
172
  */
177
- matchesRule(e, t, s) {
178
- const r = this.matchesAssetPattern(e, s.fromPattern) && this.matchesAssetPattern(t, s.toPattern);
179
- if (s.direction === "<->") {
180
- const i = this.matchesAssetPattern(e, s.toPattern) && this.matchesAssetPattern(t, s.fromPattern);
181
- return r || i;
182
- }
183
- return r;
173
+ formatChainName(t) {
174
+ return t.split("_").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" ");
184
175
  }
176
+ // ============================================
177
+ // Data Refresh Methods
178
+ // ============================================
185
179
  /**
186
- * Checks if an asset string matches a rule's pattern (wildcards supported).
180
+ * Refresh all data
187
181
  */
188
- matchesAssetPattern(e, t) {
189
- const [s = "", r = ""] = t.split(":").map((o) => o.trim().toLowerCase()), i = s === "" || s === "*" || s === e.chain.toLowerCase(), n = r === "" || r === "*" || r === e.symbol.toLowerCase();
190
- return i && n;
182
+ async refresh() {
183
+ await this.initialize();
191
184
  }
192
- async buildRouteMatrix(e) {
193
- const t = {};
194
- for (const s of e) {
195
- const r = [];
196
- for (const i of e)
197
- await this.isValidRoute(s, i) && r.push(i);
198
- t[s.toString()] = r;
199
- }
200
- return t;
201
- }
202
- };
203
- a.POLICY_CACHE_KEY = "route_policy";
204
- let h = a;
185
+ }
205
186
  export {
206
- h as RouteValidator
187
+ I as AssetManager
207
188
  };
package/dist/index12.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("@gardenfi/utils"),p=require("./index8.cjs");function d(n,t,e){var o;const r=(n??"").trim();if(!r)return{name:"",symbol:""};const i=r.split(":");if(i.length>=2){const u=((o=i[0])==null?void 0:o.trim())||"",m=i.slice(1).join(":").trim()||(e==null?void 0:e.trim())||"";return{name:u,symbol:m}}let s="";if(t)try{s=(typeof t=="string"?p.ChainAsset.from(t):t).symbol.toUpperCase()}catch{}return{name:r,symbol:s||(e==null?void 0:e.trim())||""}}function h(n){return n instanceof c.Url?n:new c.Url(n)}function A(n,t){const e=n.toString().replace(/\/+$/,""),r=t.startsWith("/")?t:`/${t}`;return`${e}${r}`}exports.buildDefaultEndpoint=A;exports.ensureUrl=h;exports.parseAssetNameSymbol=d;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("@gardenfi/utils"),h=require("node-cache"),o=class o{constructor(e,t){this.policy=new h({stdTTL:36e3,checkperiod:3600}),typeof t=="string"?this.auth=new a.ApiKey(t):this.auth=t,typeof e=="string"?this.apiBaseUrl=new a.Url(e):this.apiBaseUrl=e}getPolicy(){return this.policy.get(o.POLICY_CACHE_KEY)}setPolicy(e){const t=this.getPolicy(),s={default:e.default||(t==null?void 0:t.default)||"open",isolation_groups:[...new Set([...(t==null?void 0:t.isolation_groups)||[],...e.isolation_groups])],blacklist_pairs:[...new Set([...(t==null?void 0:t.blacklist_pairs)||[],...e.blacklist_pairs])],whitelist_overrides:[...new Set([...(t==null?void 0:t.whitelist_overrides)||[],...e.whitelist_overrides])]};return this.policy.set(o.POLICY_CACHE_KEY,s),s}async loadPolicy(){const e=this.getPolicy();if(e)return a.Ok(e);try{const t=await this.auth.getAuthHeaders();if(!t.ok)return a.Err(`Failed to get auth headers: ${t.error}`);const s=await a.Fetcher.get(this.apiBaseUrl,{headers:{"Content-Type":"application/json",...t.val}});return s.result?a.Ok(this.setPolicy(s.result)):a.Err(`API Error: ${s.error}`)}catch(t){return a.Err(`Failed to load policy: ${t}`)}}async isValidRoute(e,t){const s=await this.loadPolicy();if(!s.ok||e.toString()===t.toString())return!1;const{sortedIsolationRules:r,sortedBlacklistRules:i,sortedWhitelistRules:n}=this.preprocessRules(s.val),c=this.findMatchingRule(e,r);if(c&&!this.matchesRuleDestination(t,c))return!1;const l=this.findMatchingRule(t,r);return l&&l.rule.direction==="<->"&&!this.matchesRuleSource(e,l)?!1:this.matchesRuleList(e,t,i)?!!this.matchesRuleList(e,t,n):s.val.default==="open"}async getValidDestinations(e,t){const s=[];for(const r of t)await this.isValidRoute(e,r)&&s.push(r);return s}async getAllValidRoutes(e){const t=[];for(const s of e)for(const r of e)await this.isValidRoute(s,r)&&t.push({from:s,to:r});return t}preprocessRules(e){const t=e.isolation_groups.map(i=>this.parseRule(i)).sort((i,n)=>n.specificity-i.specificity),s=e.blacklist_pairs.map(i=>this.parseRule(i)).sort((i,n)=>n.specificity-i.specificity),r=e.whitelist_overrides.map(i=>this.parseRule(i)).sort((i,n)=>n.specificity-i.specificity);return{sortedIsolationRules:t,sortedBlacklistRules:s,sortedWhitelistRules:r}}parseRule(e){const s=e.includes("<->")?"<->":"->",[r,i]=e.split(s).map(n=>n.trim());return{pattern:e,fromPattern:r,toPattern:i,direction:s,specificity:this.calculateSpecificity(r,i)}}calculateSpecificity(e,t){const s=r=>{const i=r.toLowerCase();return i==="*"?0:i.includes("*")?1:2};return s(e)*10+s(t)}findMatchingRule(e,t){for(const s of t){if(this.matchesAssetPattern(e,s.fromPattern))return{rule:s,matchedAs:"from"};if(s.direction==="<->"&&this.matchesAssetPattern(e,s.toPattern))return{rule:s,matchedAs:"to"}}return null}matchesRuleDestination(e,t){return t.matchedAs==="from"?this.matchesAssetPattern(e,t.rule.toPattern):t.rule.direction!=="<->"?!1:this.matchesAssetPattern(e,t.rule.fromPattern)}matchesRuleSource(e,t){return t.matchedAs==="to"?this.matchesAssetPattern(e,t.rule.fromPattern):t.rule.direction!=="<->"?!1:this.matchesAssetPattern(e,t.rule.toPattern)}matchesRuleList(e,t,s){return s.some(r=>this.matchesRule(e,t,r))}matchesRule(e,t,s){const r=this.matchesAssetPattern(e,s.fromPattern)&&this.matchesAssetPattern(t,s.toPattern);if(s.direction==="<->"){const i=this.matchesAssetPattern(e,s.toPattern)&&this.matchesAssetPattern(t,s.fromPattern);return r||i}return r}matchesAssetPattern(e,t){const[s="",r=""]=t.split(":").map(c=>c.trim().toLowerCase()),i=s===""||s==="*"||s===e.chain.toLowerCase(),n=r===""||r==="*"||r===e.symbol.toLowerCase();return i&&n}async buildRouteMatrix(e){const t={};for(const s of e){const r=[];for(const i of e)await this.isValidRoute(s,i)&&r.push(i);t[s.toString()]=r}return t}};o.POLICY_CACHE_KEY="route_policy";let u=o;exports.RouteValidator=u;
package/dist/index12.js CHANGED
@@ -1,31 +1,207 @@
1
- import { Url as p } from "@gardenfi/utils";
2
- import { ChainAsset as c } from "./index8.js";
3
- function $(r, t, n) {
4
- var o;
5
- const e = (r ?? "").trim();
6
- if (!e) return { name: "", symbol: "" };
7
- const i = e.split(":");
8
- if (i.length >= 2) {
9
- const m = ((o = i[0]) == null ? void 0 : o.trim()) || "", u = i.slice(1).join(":").trim() || (n == null ? void 0 : n.trim()) || "";
10
- return { name: m, symbol: u };
11
- }
12
- let s = "";
13
- if (t)
1
+ import { ApiKey as f, Url as p, Ok as u, Err as l, Fetcher as d } from "@gardenfi/utils";
2
+ import m from "node-cache";
3
+ const a = class a {
4
+ constructor(e, t) {
5
+ this.policy = new m({
6
+ stdTTL: 36e3,
7
+ // 10 hours in seconds
8
+ checkperiod: 3600
9
+ // Check for expired keys every hour
10
+ }), typeof t == "string" ? this.auth = new f(t) : this.auth = t, typeof e == "string" ? this.apiBaseUrl = new p(e) : this.apiBaseUrl = e;
11
+ }
12
+ getPolicy() {
13
+ return this.policy.get(a.POLICY_CACHE_KEY);
14
+ }
15
+ setPolicy(e) {
16
+ const t = this.getPolicy(), s = {
17
+ default: e.default || (t == null ? void 0 : t.default) || "open",
18
+ isolation_groups: [
19
+ .../* @__PURE__ */ new Set([
20
+ ...(t == null ? void 0 : t.isolation_groups) || [],
21
+ ...e.isolation_groups
22
+ ])
23
+ ],
24
+ blacklist_pairs: [
25
+ .../* @__PURE__ */ new Set([
26
+ ...(t == null ? void 0 : t.blacklist_pairs) || [],
27
+ ...e.blacklist_pairs
28
+ ])
29
+ ],
30
+ whitelist_overrides: [
31
+ .../* @__PURE__ */ new Set([
32
+ ...(t == null ? void 0 : t.whitelist_overrides) || [],
33
+ ...e.whitelist_overrides
34
+ ])
35
+ ]
36
+ };
37
+ return this.policy.set(a.POLICY_CACHE_KEY, s), s;
38
+ }
39
+ /**
40
+ * Loads the current route policy, cached or via API.
41
+ */
42
+ async loadPolicy() {
43
+ const e = this.getPolicy();
44
+ if (e) return u(e);
14
45
  try {
15
- s = (typeof t == "string" ? c.from(t) : t).symbol.toUpperCase();
16
- } catch {
46
+ const t = await this.auth.getAuthHeaders();
47
+ if (!t.ok)
48
+ return l(`Failed to get auth headers: ${t.error}`);
49
+ const s = await d.get(
50
+ this.apiBaseUrl,
51
+ {
52
+ headers: {
53
+ "Content-Type": "application/json",
54
+ ...t.val
55
+ }
56
+ }
57
+ );
58
+ return s.result ? u(this.setPolicy(s.result)) : l(`API Error: ${s.error}`);
59
+ } catch (t) {
60
+ return l(`Failed to load policy: ${t}`);
61
+ }
62
+ }
63
+ /**
64
+ * Checks if a given route is valid based on all route rules.
65
+ */
66
+ async isValidRoute(e, t) {
67
+ const s = await this.loadPolicy();
68
+ if (!s.ok || e.toString() === t.toString()) return !1;
69
+ const { sortedIsolationRules: r, sortedBlacklistRules: i, sortedWhitelistRules: n } = this.preprocessRules(s.val), o = this.findMatchingRule(
70
+ e,
71
+ r
72
+ );
73
+ if (o && !this.matchesRuleDestination(t, o))
74
+ return !1;
75
+ const c = this.findMatchingRule(
76
+ t,
77
+ r
78
+ );
79
+ return c && c.rule.direction === "<->" && !this.matchesRuleSource(e, c) ? !1 : this.matchesRuleList(e, t, i) ? !!this.matchesRuleList(e, t, n) : s.val.default === "open";
80
+ }
81
+ /**
82
+ * Returns all valid destinations for a given source asset.
83
+ */
84
+ async getValidDestinations(e, t) {
85
+ const s = [];
86
+ for (const r of t)
87
+ await this.isValidRoute(e, r) && s.push(r);
88
+ return s;
89
+ }
90
+ /**
91
+ * Returns every valid route (from-to pair) among the provided assets.
92
+ */
93
+ async getAllValidRoutes(e) {
94
+ const t = [];
95
+ for (const s of e)
96
+ for (const r of e)
97
+ await this.isValidRoute(s, r) && t.push({ from: s, to: r });
98
+ return t;
99
+ }
100
+ /**
101
+ * Turns policy string rules into sorted ParsedRule objects.
102
+ */
103
+ preprocessRules(e) {
104
+ const t = e.isolation_groups.map((i) => this.parseRule(i)).sort((i, n) => n.specificity - i.specificity), s = e.blacklist_pairs.map((i) => this.parseRule(i)).sort((i, n) => n.specificity - i.specificity), r = e.whitelist_overrides.map((i) => this.parseRule(i)).sort((i, n) => n.specificity - i.specificity);
105
+ return { sortedIsolationRules: t, sortedBlacklistRules: s, sortedWhitelistRules: r };
106
+ }
107
+ /**
108
+ * Parses a rule string (e.g. "ethereum:usdc -> base:usdt") into parts.
109
+ */
110
+ parseRule(e) {
111
+ const s = e.includes(
112
+ "<->"
113
+ /* Bidirectional */
114
+ ) ? "<->" : "->", [r, i] = e.split(s).map((n) => n.trim());
115
+ return {
116
+ pattern: e,
117
+ fromPattern: r,
118
+ toPattern: i,
119
+ direction: s,
120
+ specificity: this.calculateSpecificity(r, i)
121
+ };
122
+ }
123
+ /**
124
+ * Gives a specificity score to a rule pattern for prioritizing.
125
+ */
126
+ calculateSpecificity(e, t) {
127
+ const s = (r) => {
128
+ const i = r.toLowerCase();
129
+ return i === "*" ? 0 : i.includes(
130
+ "*"
131
+ /* Any */
132
+ ) ? 1 : 2;
133
+ };
134
+ return s(e) * 10 + s(t);
135
+ }
136
+ /**
137
+ * Finds the first matching rule for an asset given the rule "side".
138
+ */
139
+ findMatchingRule(e, t) {
140
+ for (const s of t) {
141
+ if (this.matchesAssetPattern(e, s.fromPattern))
142
+ return {
143
+ rule: s,
144
+ matchedAs: "from"
145
+ /* From */
146
+ };
147
+ if (s.direction === "<->" && this.matchesAssetPattern(e, s.toPattern))
148
+ return {
149
+ rule: s,
150
+ matchedAs: "to"
151
+ /* To */
152
+ };
17
153
  }
18
- return { name: e, symbol: s || (n == null ? void 0 : n.trim()) || "" };
19
- }
20
- function d(r) {
21
- return r instanceof p ? r : new p(r);
22
- }
23
- function f(r, t) {
24
- const n = r.toString().replace(/\/+$/, ""), e = t.startsWith("/") ? t : `/${t}`;
25
- return `${n}${e}`;
26
- }
154
+ return null;
155
+ }
156
+ /**
157
+ * Checks if a given toAsset matches the rule's destination side.
158
+ */
159
+ matchesRuleDestination(e, t) {
160
+ return t.matchedAs === "from" ? this.matchesAssetPattern(e, t.rule.toPattern) : t.rule.direction !== "<->" ? !1 : this.matchesAssetPattern(e, t.rule.fromPattern);
161
+ }
162
+ /**
163
+ * Checks if a given fromAsset matches the rule's source side.
164
+ */
165
+ matchesRuleSource(e, t) {
166
+ return t.matchedAs === "to" ? this.matchesAssetPattern(e, t.rule.fromPattern) : t.rule.direction !== "<->" ? !1 : this.matchesAssetPattern(e, t.rule.toPattern);
167
+ }
168
+ /**
169
+ * Checks if any rule in a list matches fromAsset and toAsset.
170
+ */
171
+ matchesRuleList(e, t, s) {
172
+ return s.some((r) => this.matchesRule(e, t, r));
173
+ }
174
+ /**
175
+ * Checks if a rule matches fromAsset and toAsset (forward or backward if bidirectional).
176
+ */
177
+ matchesRule(e, t, s) {
178
+ const r = this.matchesAssetPattern(e, s.fromPattern) && this.matchesAssetPattern(t, s.toPattern);
179
+ if (s.direction === "<->") {
180
+ const i = this.matchesAssetPattern(e, s.toPattern) && this.matchesAssetPattern(t, s.fromPattern);
181
+ return r || i;
182
+ }
183
+ return r;
184
+ }
185
+ /**
186
+ * Checks if an asset string matches a rule's pattern (wildcards supported).
187
+ */
188
+ matchesAssetPattern(e, t) {
189
+ const [s = "", r = ""] = t.split(":").map((o) => o.trim().toLowerCase()), i = s === "" || s === "*" || s === e.chain.toLowerCase(), n = r === "" || r === "*" || r === e.symbol.toLowerCase();
190
+ return i && n;
191
+ }
192
+ async buildRouteMatrix(e) {
193
+ const t = {};
194
+ for (const s of e) {
195
+ const r = [];
196
+ for (const i of e)
197
+ await this.isValidRoute(s, i) && r.push(i);
198
+ t[s.toString()] = r;
199
+ }
200
+ return t;
201
+ }
202
+ };
203
+ a.POLICY_CACHE_KEY = "route_policy";
204
+ let h = a;
27
205
  export {
28
- f as buildDefaultEndpoint,
29
- d as ensureUrl,
30
- $ as parseAssetNameSymbol
206
+ h as RouteValidator
31
207
  };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("@gardenfi/utils"),p=require("./index8.cjs");function d(n,t,e){var o;const r=(n??"").trim();if(!r)return{name:"",symbol:""};const i=r.split(":");if(i.length>=2){const u=((o=i[0])==null?void 0:o.trim())||"",m=i.slice(1).join(":").trim()||(e==null?void 0:e.trim())||"";return{name:u,symbol:m}}let s="";if(t)try{s=(typeof t=="string"?p.ChainAsset.from(t):t).symbol.toUpperCase()}catch{}return{name:r,symbol:s||(e==null?void 0:e.trim())||""}}function h(n){return n instanceof c.Url?n:new c.Url(n)}function A(n,t){const e=n.toString().replace(/\/+$/,""),r=t.startsWith("/")?t:`/${t}`;return`${e}${r}`}exports.buildDefaultEndpoint=A;exports.ensureUrl=h;exports.parseAssetNameSymbol=d;
@@ -0,0 +1,31 @@
1
+ import { Url as p } from "@gardenfi/utils";
2
+ import { ChainAsset as c } from "./index8.js";
3
+ function $(r, t, n) {
4
+ var o;
5
+ const e = (r ?? "").trim();
6
+ if (!e) return { name: "", symbol: "" };
7
+ const i = e.split(":");
8
+ if (i.length >= 2) {
9
+ const m = ((o = i[0]) == null ? void 0 : o.trim()) || "", u = i.slice(1).join(":").trim() || (n == null ? void 0 : n.trim()) || "";
10
+ return { name: m, symbol: u };
11
+ }
12
+ let s = "";
13
+ if (t)
14
+ try {
15
+ s = (typeof t == "string" ? c.from(t) : t).symbol.toUpperCase();
16
+ } catch {
17
+ }
18
+ return { name: e, symbol: s || (n == null ? void 0 : n.trim()) || "" };
19
+ }
20
+ function d(r) {
21
+ return r instanceof p ? r : new p(r);
22
+ }
23
+ function f(r, t) {
24
+ const n = r.toString().replace(/\/+$/, ""), e = t.startsWith("/") ? t : `/${t}`;
25
+ return `${n}${e}`;
26
+ }
27
+ export {
28
+ f as buildDefaultEndpoint,
29
+ d as ensureUrl,
30
+ $ as parseAssetNameSymbol
31
+ };
package/dist/index2.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("@gardenfi/utils"),c=require("./index7.cjs"),d=require("./index9.cjs");class l{constructor(o,s){this.url=o,this.auth=s}async createOrder(o){try{const s=await this.auth.getAuthHeaders();if(s.error)return r.Err(s.error);const e=await r.Fetcher.post(this.url.endpoint("/v2/orders"),{body:JSON.stringify(o),headers:{...s.val,"Content-Type":"application/json"}});if(e.error)return r.Err(e.error);if(!e.result)return r.Err("CreateOrder: Unexpected error, result is undefined");const i=c.discriminateOrderResponse(e.result);return i?r.Ok(i):r.Err("CreateOrder: Unable to determine order type from response")}catch(s){return r.Err("CreateOrder Err:",String(s))}}async getOrder(o,s){try{const e=await this.auth.getAuthHeaders();if(e.error)return r.Err(e.error);const i=this.url.endpoint("/v2/orders").endpoint(o),n=await r.Fetcher.get(i,{...s,headers:{...e.val,"Content-Type":"application/json"}});if(n.error)return r.Err(n.error);if(!n.result)return r.Err("GetOrder: Unexpected error, result is undefined");const t=d.ParseOrderStatus(n.result);return r.Ok({...n.result,status:t})}catch(e){return r.Err(`GetOrder: ${e instanceof Error?e.message:String(e)}`)}}async getOrders(o,s){const e=await this.auth.getAuthHeaders();if(e.error)return r.Err(e.error);const n=c.ConstructUrl(this.url,"/v2/orders",o);try{const t=await r.Fetcher.get(n,{...s,headers:{...e.val,"Content-Type":"application/json"}});if(t.error)return r.Err(t.error);if(!t.result)return r.Err("GetAllOrders: Unexpected error, result is undefined");const u=t.result.data.map(a=>({...a,status:d.ParseOrderStatus(a)}));return r.Ok({...t.result,data:u})}catch(t){return r.Err(`GetAllOrders: ${t instanceof Error?t.message:String(t)}`)}}async subscribeOrders(o,s,e,i){let n=!1;const t=async()=>{if(!n){n=!0;try{const a=await this.getOrders(o,i);a.ok?await s(a.val):console.error("Error fetching orders:",a.error)}catch(a){console.error("Error fetching orders:",a)}finally{n=!1}}};await t();const u=setInterval(t,e);return()=>{clearInterval(u)}}}exports.Orderbook=l;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("@gardenfi/utils"),c=require("./index7.cjs"),d=require("./index10.cjs");class l{constructor(o,s){this.url=o,this.auth=s}async createOrder(o){try{const s=await this.auth.getAuthHeaders();if(s.error)return r.Err(s.error);const e=await r.Fetcher.post(this.url.endpoint("/v2/orders"),{body:JSON.stringify(o),headers:{...s.val,"Content-Type":"application/json"}});if(e.error)return r.Err(e.error);if(!e.result)return r.Err("CreateOrder: Unexpected error, result is undefined");const i=c.discriminateOrderResponse(e.result);return i?r.Ok(i):r.Err("CreateOrder: Unable to determine order type from response")}catch(s){return r.Err("CreateOrder Err:",String(s))}}async getOrder(o,s){try{const e=await this.auth.getAuthHeaders();if(e.error)return r.Err(e.error);const i=this.url.endpoint("/v2/orders").endpoint(o),n=await r.Fetcher.get(i,{...s,headers:{...e.val,"Content-Type":"application/json"}});if(n.error)return r.Err(n.error);if(!n.result)return r.Err("GetOrder: Unexpected error, result is undefined");const t=d.ParseOrderStatus(n.result);return r.Ok({...n.result,status:t})}catch(e){return r.Err(`GetOrder: ${e instanceof Error?e.message:String(e)}`)}}async getOrders(o,s){const e=await this.auth.getAuthHeaders();if(e.error)return r.Err(e.error);const n=c.ConstructUrl(this.url,"/v2/orders",o);try{const t=await r.Fetcher.get(n,{...s,headers:{...e.val,"Content-Type":"application/json"}});if(t.error)return r.Err(t.error);if(!t.result)return r.Err("GetAllOrders: Unexpected error, result is undefined");const u=t.result.data.map(a=>({...a,status:d.ParseOrderStatus(a)}));return r.Ok({...t.result,data:u})}catch(t){return r.Err(`GetAllOrders: ${t instanceof Error?t.message:String(t)}`)}}async subscribeOrders(o,s,e,i){let n=!1;const t=async()=>{if(!n){n=!0;try{const a=await this.getOrders(o,i);a.ok?await s(a.val):console.error("Error fetching orders:",a.error)}catch(a){console.error("Error fetching orders:",a)}finally{n=!1}}};await t();const u=setInterval(t,e);return()=>{clearInterval(u)}}}exports.Orderbook=l;
package/dist/index2.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Err as s, Fetcher as d, Ok as c } from "@gardenfi/utils";
2
2
  import { discriminateOrderResponse as h, ConstructUrl as f } from "./index7.js";
3
- import { ParseOrderStatus as l } from "./index9.js";
3
+ import { ParseOrderStatus as l } from "./index10.js";
4
4
  class m {
5
5
  constructor(o, t) {
6
6
  this.url = o, this.auth = t;