@gardenfi/orderbook 3.0.1-beta.1 → 3.0.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.cjs CHANGED
@@ -1 +1 @@
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(),i={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,i),i}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 i=await a.Fetcher.get(this.apiBaseUrl,{headers:{"Content-Type":"application/json",...t.val}});return i.result?(i.result.blacklist_pairs.push("*:* -> bnbchain:btcb","bnbchain:btcb -> *:*","*:* -> botanix:btc","botanix:btc -> *:*"),i.result.whitelist_overrides.push("bitcoin:btc -> bnbchain:btcb","botanix:btc -> bnbchain:btcb","bnbchain:btcb -> bitcoin:btc","bnbchain:btcb -> botanix:btc","bitcoin:btc -> botanix:btc","botanix:btc -> bitcoin:btc"),a.Ok(this.setPolicy(i.result))):a.Err(`API Error: ${i.error}`)}catch(t){return a.Err(`Failed to load policy: ${t}`)}}async isValidRoute(e,t){const i=await this.loadPolicy();if(!i.ok||e.toString()===t.toString())return!1;const{sortedIsolationRules:s,sortedBlacklistRules:r,sortedWhitelistRules:n}=this.preprocessRules(i.val),c=this.findMatchingRule(e,s);if(c&&!this.matchesRuleDestination(t,c))return!1;const l=this.findMatchingRule(t,s);return l&&l.rule.direction==="<->"&&!this.matchesRuleSource(e,l)?!1:this.matchesRuleList(e,t,r)?!!this.matchesRuleList(e,t,n):i.val.default==="open"}async getValidDestinations(e,t){const i=[];for(const s of t)await this.isValidRoute(e,s)&&i.push(s);return i}async getAllValidRoutes(e){const t=[];for(const i of e)for(const s of e)await this.isValidRoute(i,s)&&t.push({from:i,to:s});return t}preprocessRules(e){const t=e.isolation_groups.map(r=>this.parseRule(r)).sort((r,n)=>n.specificity-r.specificity),i=e.blacklist_pairs.map(r=>this.parseRule(r)).sort((r,n)=>n.specificity-r.specificity),s=e.whitelist_overrides.map(r=>this.parseRule(r)).sort((r,n)=>n.specificity-r.specificity);return{sortedIsolationRules:t,sortedBlacklistRules:i,sortedWhitelistRules:s}}parseRule(e){const i=e.includes("<->")?"<->":"->",[s,r]=e.split(i).map(n=>n.trim());return{pattern:e,fromPattern:s,toPattern:r,direction:i,specificity:this.calculateSpecificity(s,r)}}calculateSpecificity(e,t){const i=s=>{const r=s.toLowerCase();return r==="*"?0:r.includes("*")?1:2};return i(e)*10+i(t)}findMatchingRule(e,t){for(const i of t){if(this.matchesAssetPattern(e,i.fromPattern))return{rule:i,matchedAs:"from"};if(i.direction==="<->"&&this.matchesAssetPattern(e,i.toPattern))return{rule:i,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,i){return i.some(s=>this.matchesRule(e,t,s))}matchesRule(e,t,i){const s=this.matchesAssetPattern(e,i.fromPattern)&&this.matchesAssetPattern(t,i.toPattern);if(i.direction==="<->"){const r=this.matchesAssetPattern(e,i.toPattern)&&this.matchesAssetPattern(t,i.fromPattern);return s||r}return s}matchesAssetPattern(e,t){const[i="",s=""]=t.split(":").map(c=>c.trim().toLowerCase()),r=i===""||i==="*"||i===e.chain.toLowerCase(),n=s===""||s==="*"||s===e.symbol.toLowerCase();return r&&n}async buildRouteMatrix(e){const t={};for(const i of e){const s=[];for(const r of e)await this.isValidRoute(i,r)&&s.push(r);t[i.toString()]=s}return t}};o.POLICY_CACHE_KEY="route_policy";let u=o;exports.RouteValidator=u;
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/index11.js CHANGED
@@ -1,19 +1,19 @@
1
- import { ApiKey as f, Url as b, Ok as u, Err as l, Fetcher as p } from "@gardenfi/utils";
2
- import d from "node-cache";
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
3
  const a = class a {
4
4
  constructor(e, t) {
5
- this.policy = new d({
5
+ this.policy = new m({
6
6
  stdTTL: 36e3,
7
7
  // 10 hours in seconds
8
8
  checkperiod: 3600
9
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 b(e) : this.apiBaseUrl = e;
10
+ }), typeof t == "string" ? this.auth = new f(t) : this.auth = t, typeof e == "string" ? this.apiBaseUrl = new p(e) : this.apiBaseUrl = e;
11
11
  }
12
12
  getPolicy() {
13
13
  return this.policy.get(a.POLICY_CACHE_KEY);
14
14
  }
15
15
  setPolicy(e) {
16
- const t = this.getPolicy(), i = {
16
+ const t = this.getPolicy(), s = {
17
17
  default: e.default || (t == null ? void 0 : t.default) || "open",
18
18
  isolation_groups: [
19
19
  .../* @__PURE__ */ new Set([
@@ -34,7 +34,7 @@ const a = class a {
34
34
  ])
35
35
  ]
36
36
  };
37
- return this.policy.set(a.POLICY_CACHE_KEY, i), i;
37
+ return this.policy.set(a.POLICY_CACHE_KEY, s), s;
38
38
  }
39
39
  /**
40
40
  * Loads the current route policy, cached or via API.
@@ -46,7 +46,7 @@ const a = class a {
46
46
  const t = await this.auth.getAuthHeaders();
47
47
  if (!t.ok)
48
48
  return l(`Failed to get auth headers: ${t.error}`);
49
- const i = await p.get(
49
+ const s = await d.get(
50
50
  this.apiBaseUrl,
51
51
  {
52
52
  headers: {
@@ -55,19 +55,7 @@ const a = class a {
55
55
  }
56
56
  }
57
57
  );
58
- return i.result ? (i.result.blacklist_pairs.push(
59
- "*:* -> bnbchain:btcb",
60
- "bnbchain:btcb -> *:*",
61
- "*:* -> botanix:btc",
62
- "botanix:btc -> *:*"
63
- ), i.result.whitelist_overrides.push(
64
- "bitcoin:btc -> bnbchain:btcb",
65
- "botanix:btc -> bnbchain:btcb",
66
- "bnbchain:btcb -> bitcoin:btc",
67
- "bnbchain:btcb -> botanix:btc",
68
- "bitcoin:btc -> botanix:btc",
69
- "botanix:btc -> bitcoin:btc"
70
- ), u(this.setPolicy(i.result))) : l(`API Error: ${i.error}`);
58
+ return s.result ? u(this.setPolicy(s.result)) : l(`API Error: ${s.error}`);
71
59
  } catch (t) {
72
60
  return l(`Failed to load policy: ${t}`);
73
61
  }
@@ -76,89 +64,89 @@ const a = class a {
76
64
  * Checks if a given route is valid based on all route rules.
77
65
  */
78
66
  async isValidRoute(e, t) {
79
- const i = await this.loadPolicy();
80
- if (!i.ok || e.toString() === t.toString()) return !1;
81
- const { sortedIsolationRules: s, sortedBlacklistRules: r, sortedWhitelistRules: n } = this.preprocessRules(i.val), o = this.findMatchingRule(
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(
82
70
  e,
83
- s
71
+ r
84
72
  );
85
73
  if (o && !this.matchesRuleDestination(t, o))
86
74
  return !1;
87
75
  const c = this.findMatchingRule(
88
76
  t,
89
- s
77
+ r
90
78
  );
91
- return c && c.rule.direction === "<->" && !this.matchesRuleSource(e, c) ? !1 : this.matchesRuleList(e, t, r) ? !!this.matchesRuleList(e, t, n) : i.val.default === "open";
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";
92
80
  }
93
81
  /**
94
82
  * Returns all valid destinations for a given source asset.
95
83
  */
96
84
  async getValidDestinations(e, t) {
97
- const i = [];
98
- for (const s of t)
99
- await this.isValidRoute(e, s) && i.push(s);
100
- return i;
85
+ const s = [];
86
+ for (const r of t)
87
+ await this.isValidRoute(e, r) && s.push(r);
88
+ return s;
101
89
  }
102
90
  /**
103
91
  * Returns every valid route (from-to pair) among the provided assets.
104
92
  */
105
93
  async getAllValidRoutes(e) {
106
94
  const t = [];
107
- for (const i of e)
108
- for (const s of e)
109
- await this.isValidRoute(i, s) && t.push({ from: i, to: s });
95
+ for (const s of e)
96
+ for (const r of e)
97
+ await this.isValidRoute(s, r) && t.push({ from: s, to: r });
110
98
  return t;
111
99
  }
112
100
  /**
113
101
  * Turns policy string rules into sorted ParsedRule objects.
114
102
  */
115
103
  preprocessRules(e) {
116
- const t = e.isolation_groups.map((r) => this.parseRule(r)).sort((r, n) => n.specificity - r.specificity), i = e.blacklist_pairs.map((r) => this.parseRule(r)).sort((r, n) => n.specificity - r.specificity), s = e.whitelist_overrides.map((r) => this.parseRule(r)).sort((r, n) => n.specificity - r.specificity);
117
- return { sortedIsolationRules: t, sortedBlacklistRules: i, sortedWhitelistRules: s };
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 };
118
106
  }
119
107
  /**
120
108
  * Parses a rule string (e.g. "ethereum:usdc -> base:usdt") into parts.
121
109
  */
122
110
  parseRule(e) {
123
- const i = e.includes(
111
+ const s = e.includes(
124
112
  "<->"
125
113
  /* Bidirectional */
126
- ) ? "<->" : "->", [s, r] = e.split(i).map((n) => n.trim());
114
+ ) ? "<->" : "->", [r, i] = e.split(s).map((n) => n.trim());
127
115
  return {
128
116
  pattern: e,
129
- fromPattern: s,
130
- toPattern: r,
131
- direction: i,
132
- specificity: this.calculateSpecificity(s, r)
117
+ fromPattern: r,
118
+ toPattern: i,
119
+ direction: s,
120
+ specificity: this.calculateSpecificity(r, i)
133
121
  };
134
122
  }
135
123
  /**
136
124
  * Gives a specificity score to a rule pattern for prioritizing.
137
125
  */
138
126
  calculateSpecificity(e, t) {
139
- const i = (s) => {
140
- const r = s.toLowerCase();
141
- return r === "*" ? 0 : r.includes(
127
+ const s = (r) => {
128
+ const i = r.toLowerCase();
129
+ return i === "*" ? 0 : i.includes(
142
130
  "*"
143
131
  /* Any */
144
132
  ) ? 1 : 2;
145
133
  };
146
- return i(e) * 10 + i(t);
134
+ return s(e) * 10 + s(t);
147
135
  }
148
136
  /**
149
137
  * Finds the first matching rule for an asset given the rule "side".
150
138
  */
151
139
  findMatchingRule(e, t) {
152
- for (const i of t) {
153
- if (this.matchesAssetPattern(e, i.fromPattern))
140
+ for (const s of t) {
141
+ if (this.matchesAssetPattern(e, s.fromPattern))
154
142
  return {
155
- rule: i,
143
+ rule: s,
156
144
  matchedAs: "from"
157
145
  /* From */
158
146
  };
159
- if (i.direction === "<->" && this.matchesAssetPattern(e, i.toPattern))
147
+ if (s.direction === "<->" && this.matchesAssetPattern(e, s.toPattern))
160
148
  return {
161
- rule: i,
149
+ rule: s,
162
150
  matchedAs: "to"
163
151
  /* To */
164
152
  };
@@ -180,34 +168,34 @@ const a = class a {
180
168
  /**
181
169
  * Checks if any rule in a list matches fromAsset and toAsset.
182
170
  */
183
- matchesRuleList(e, t, i) {
184
- return i.some((s) => this.matchesRule(e, t, s));
171
+ matchesRuleList(e, t, s) {
172
+ return s.some((r) => this.matchesRule(e, t, r));
185
173
  }
186
174
  /**
187
175
  * Checks if a rule matches fromAsset and toAsset (forward or backward if bidirectional).
188
176
  */
189
- matchesRule(e, t, i) {
190
- const s = this.matchesAssetPattern(e, i.fromPattern) && this.matchesAssetPattern(t, i.toPattern);
191
- if (i.direction === "<->") {
192
- const r = this.matchesAssetPattern(e, i.toPattern) && this.matchesAssetPattern(t, i.fromPattern);
193
- return s || r;
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;
194
182
  }
195
- return s;
183
+ return r;
196
184
  }
197
185
  /**
198
186
  * Checks if an asset string matches a rule's pattern (wildcards supported).
199
187
  */
200
188
  matchesAssetPattern(e, t) {
201
- const [i = "", s = ""] = t.split(":").map((o) => o.trim().toLowerCase()), r = i === "" || i === "*" || i === e.chain.toLowerCase(), n = s === "" || s === "*" || s === e.symbol.toLowerCase();
202
- return r && n;
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;
203
191
  }
204
192
  async buildRouteMatrix(e) {
205
193
  const t = {};
206
- for (const i of e) {
207
- const s = [];
208
- for (const r of e)
209
- await this.isValidRoute(i, r) && s.push(r);
210
- t[i.toString()] = s;
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;
211
199
  }
212
200
  return t;
213
201
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gardenfi/orderbook",
3
- "version": "3.0.1-beta.1",
3
+ "version": "3.0.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@coral-xyz/anchor": "^0.31.1",
31
- "@gardenfi/utils": "3.0.0-beta.1",
31
+ "@gardenfi/utils": "3.0.0",
32
32
  "bufferutil": "^4.0.8",
33
33
  "node-cache": "^5.1.2",
34
34
  "siwe": "^2.1.4",