@gardenfi/orderbook 2.5.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.js +56 -28
  3. package/dist/index10.cjs +1 -0
  4. package/dist/index10.js +188 -0
  5. package/dist/index11.cjs +1 -0
  6. package/dist/index11.js +219 -0
  7. package/dist/index12.cjs +1 -0
  8. package/dist/index12.js +31 -0
  9. package/dist/index2.cjs +1 -1
  10. package/dist/index2.js +78 -101
  11. package/dist/index3.cjs +1 -1
  12. package/dist/index3.js +2 -57
  13. package/dist/index4.cjs +1 -1
  14. package/dist/index4.js +925 -392
  15. package/dist/index5.cjs +1 -1
  16. package/dist/index5.js +91 -6
  17. package/dist/index6.cjs +1 -0
  18. package/dist/index6.js +18 -0
  19. package/dist/index7.cjs +1 -0
  20. package/dist/index7.js +46 -0
  21. package/dist/index8.cjs +1 -0
  22. package/dist/index8.js +28 -0
  23. package/dist/index9.cjs +1 -0
  24. package/dist/index9.js +31 -0
  25. package/dist/src/index.d.ts +13 -2
  26. package/dist/src/lib/api.d.ts +1 -1
  27. package/dist/src/lib/asset.d.ts +0 -81
  28. package/dist/src/lib/assetManager/AssetManager.d.ts +82 -0
  29. package/dist/src/lib/assetManager/index.d.ts +2 -0
  30. package/dist/src/lib/assetManager/routeValidator/routeValidator.d.ts +76 -0
  31. package/dist/src/lib/assetManager/types.d.ts +39 -0
  32. package/dist/src/lib/assetManager/utils.d.ts +9 -0
  33. package/dist/src/lib/chainAsset/chainAsset.d.ts +19 -0
  34. package/dist/src/lib/constants/asset.d.ts +2028 -0
  35. package/dist/src/lib/constants/asset.types.d.ts +43 -0
  36. package/dist/src/lib/constants/localnetConstants.d.ts +47 -0
  37. package/dist/src/lib/constants/utils.d.ts +15 -0
  38. package/dist/src/lib/orderStatus/orderStatus.d.ts +14 -0
  39. package/dist/src/lib/orderStatus/status.d.ts +0 -0
  40. package/dist/src/lib/orderbook/orderbook.d.ts +15 -22
  41. package/dist/src/lib/orderbook/orderbook.types.d.ts +150 -214
  42. package/dist/src/lib/utils.d.ts +37 -0
  43. package/package.json +3 -2
  44. package/dist/src/lib/constants.d.ts +0 -374
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./index2.cjs"),e=require("./index3.cjs"),t=require("./index4.cjs");exports.Orderbook=s.Orderbook;exports.BlockchainType=e.BlockchainType;exports.Chains=e.Chains;exports.NativeTokenAddress=e.NativeTokenAddress;exports.NetworkType=e.NetworkType;exports.getBlockchainType=e.getBlockchainType;exports.isBitcoin=e.isBitcoin;exports.isEVM=e.isEVM;exports.isEvmNativeToken=e.isEvmNativeToken;exports.isMainnet=e.isMainnet;exports.isNativeToken=e.isNativeToken;exports.isSolana=e.isSolana;exports.isSolanaNativeToken=e.isSolanaNativeToken;exports.isStarknet=e.isStarknet;exports.isSui=e.isSui;exports.isSuiNativeToken=e.isSuiNativeToken;exports.ArbitrumLocalnet=t.ArbitrumLocalnet;exports.ETHStarknetLocalnetAsset=t.ETHStarknetLocalnetAsset;exports.EthereumLocalnet=t.EthereumLocalnet;exports.SOLSolanaLocalnetAsset=t.SOLSolanaLocalnetAsset;exports.STRKStarknetLocalnetAsset=t.STRKStarknetLocalnetAsset;exports.StarknetLocalnet=t.StarknetLocalnet;exports.SupportedAssets=t.SupportedAssets;exports.WBTCArbitrumLocalnetAsset=t.WBTCArbitrumLocalnetAsset;exports.WBTCEthereumLocalnetAsset=t.WBTCEthereumLocalnetAsset;exports.bitcoinRegtestAsset=t.bitcoinRegtestAsset;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./index2.cjs"),n=require("./index3.cjs"),e=require("./index4.cjs"),s=require("./index5.cjs"),a=require("./index6.cjs"),t=require("./index7.cjs"),o=require("./index8.cjs"),i=require("./index9.cjs"),c=require("./index10.cjs"),l=require("./index11.cjs");exports.Orderbook=r.Orderbook;exports.BlockchainType=n.BlockchainType;exports.Assets=e.Assets;exports.Chains=e.Chains;exports.Config=e.Config;exports.NATIVE_TOKENS=e.NATIVE_TOKENS;exports.OrderLifecycle=e.OrderLifecycle;exports.OrderStatus=e.OrderStatus;exports.getBlockchainType=e.getBlockchainType;exports.is=e.is;exports.isBitcoin=e.isBitcoin;exports.isEVM=e.isEVM;exports.isEvmNativeToken=e.isEvmNativeToken;exports.isMainnet=e.isMainnet;exports.isNativeToken=e.isNativeToken;exports.isSolana=e.isSolana;exports.isSolanaNativeToken=e.isSolanaNativeToken;exports.isStarknet=e.isStarknet;exports.isSui=e.isSui;exports.isSuiNativeToken=e.isSuiNativeToken;exports.ArbitrumLocalnet=s.ArbitrumLocalnet;exports.ETHStarknetLocalnetAsset=s.ETHStarknetLocalnetAsset;exports.EthereumLocalnet=s.EthereumLocalnet;exports.SOLSolanaLocalnetAsset=s.SOLSolanaLocalnetAsset;exports.STRKStarknetLocalnetAsset=s.STRKStarknetLocalnetAsset;exports.StarknetLocalnet=s.StarknetLocalnet;exports.WBTCArbitrumLocalnetAsset=s.WBTCArbitrumLocalnetAsset;exports.WBTCEthereumLocalnetAsset=s.WBTCEthereumLocalnetAsset;exports.bitcoinRegtestAsset=s.bitcoinRegtestAsset;exports.buildAssetsWithChain=a.buildAssetsWithChain;exports.ConstructUrl=t.ConstructUrl;exports.discriminateOrderResponse=t.discriminateOrderResponse;exports.getOrderResponseType=t.getOrderResponseType;exports.isBitcoinOrderResponse=t.isBitcoinOrderResponse;exports.isEvmOrderResponse=t.isEvmOrderResponse;exports.isOrder=t.isOrder;exports.isSolanaOrderResponse=t.isSolanaOrderResponse;exports.isStarknetOrderResponse=t.isStarknetOrderResponse;exports.isSuiOrderResponse=t.isSuiOrderResponse;exports.ChainAsset=o.ChainAsset;exports.OrderAction=i.OrderAction;exports.ParseOrderStatus=i.ParseOrderStatus;exports.isCompleted=i.isCompleted;exports.isDeadlinePassed=i.isDeadlinePassed;exports.parseAction=i.parseAction;exports.AssetManager=c.AssetManager;exports.RouteValidator=l.RouteValidator;
package/dist/index.js CHANGED
@@ -1,31 +1,59 @@
1
- import { Orderbook as o } from "./index2.js";
2
- import { BlockchainType as a, Chains as i, NativeTokenAddress as n, NetworkType as r, getBlockchainType as c, isBitcoin as k, isEVM as l, isEvmNativeToken as S, isMainnet as T, isNativeToken as A, isSolana as L, isSolanaNativeToken as m, isStarknet as p, isSui as u, isSuiNativeToken as v } from "./index3.js";
3
- import { ArbitrumLocalnet as h, ETHStarknetLocalnetAsset as B, EthereumLocalnet as E, SOLSolanaLocalnetAsset as b, STRKStarknetLocalnetAsset as d, StarknetLocalnet as f, SupportedAssets as x, WBTCArbitrumLocalnetAsset as y, WBTCEthereumLocalnetAsset as C, bitcoinRegtestAsset as g } from "./index4.js";
1
+ import { Orderbook as s } from "./index2.js";
2
+ import { BlockchainType as o } from "./index3.js";
3
+ import { Assets as n, Chains as a, Config as p, NATIVE_TOKENS as c, OrderLifecycle as l, OrderStatus as d, getBlockchainType as m, is as S, isBitcoin as A, isEVM as O, isEvmNativeToken as T, isMainnet as f, isNativeToken as k, isSolana as u, isSolanaNativeToken as x, isStarknet as L, isSui as R, isSuiNativeToken as h } from "./index4.js";
4
+ import { ArbitrumLocalnet as E, ETHStarknetLocalnetAsset as v, EthereumLocalnet as B, SOLSolanaLocalnetAsset as N, STRKStarknetLocalnetAsset as b, StarknetLocalnet as g, WBTCArbitrumLocalnetAsset as y, WBTCEthereumLocalnetAsset as M, bitcoinRegtestAsset as V } from "./index5.js";
5
+ import { buildAssetsWithChain as K } from "./index6.js";
6
+ import { ConstructUrl as D, discriminateOrderResponse as H, getOrderResponseType as I, isBitcoinOrderResponse as U, isEvmOrderResponse as _, isOrder as j, isSolanaOrderResponse as q, isStarknetOrderResponse as w, isSuiOrderResponse as z } from "./index7.js";
7
+ import { ChainAsset as G } from "./index8.js";
8
+ import { OrderAction as Q, ParseOrderStatus as X, isCompleted as Y, isDeadlinePassed as Z, parseAction as $ } from "./index9.js";
9
+ import { AssetManager as te } from "./index10.js";
10
+ import { RouteValidator as re } from "./index11.js";
4
11
  export {
5
- h as ArbitrumLocalnet,
6
- a as BlockchainType,
7
- i as Chains,
8
- B as ETHStarknetLocalnetAsset,
9
- E as EthereumLocalnet,
10
- n as NativeTokenAddress,
11
- r as NetworkType,
12
- o as Orderbook,
13
- b as SOLSolanaLocalnetAsset,
14
- d as STRKStarknetLocalnetAsset,
15
- f as StarknetLocalnet,
16
- x as SupportedAssets,
12
+ E as ArbitrumLocalnet,
13
+ te as AssetManager,
14
+ n as Assets,
15
+ o as BlockchainType,
16
+ G as ChainAsset,
17
+ a as Chains,
18
+ p as Config,
19
+ D as ConstructUrl,
20
+ v as ETHStarknetLocalnetAsset,
21
+ B as EthereumLocalnet,
22
+ c as NATIVE_TOKENS,
23
+ Q as OrderAction,
24
+ l as OrderLifecycle,
25
+ d as OrderStatus,
26
+ s as Orderbook,
27
+ X as ParseOrderStatus,
28
+ re as RouteValidator,
29
+ N as SOLSolanaLocalnetAsset,
30
+ b as STRKStarknetLocalnetAsset,
31
+ g as StarknetLocalnet,
17
32
  y as WBTCArbitrumLocalnetAsset,
18
- C as WBTCEthereumLocalnetAsset,
19
- g as bitcoinRegtestAsset,
20
- c as getBlockchainType,
21
- k as isBitcoin,
22
- l as isEVM,
23
- S as isEvmNativeToken,
24
- T as isMainnet,
25
- A as isNativeToken,
26
- L as isSolana,
27
- m as isSolanaNativeToken,
28
- p as isStarknet,
29
- u as isSui,
30
- v as isSuiNativeToken
33
+ M as WBTCEthereumLocalnetAsset,
34
+ V as bitcoinRegtestAsset,
35
+ K as buildAssetsWithChain,
36
+ H as discriminateOrderResponse,
37
+ m as getBlockchainType,
38
+ I as getOrderResponseType,
39
+ S as is,
40
+ A as isBitcoin,
41
+ U as isBitcoinOrderResponse,
42
+ Y as isCompleted,
43
+ Z as isDeadlinePassed,
44
+ O as isEVM,
45
+ T as isEvmNativeToken,
46
+ _ as isEvmOrderResponse,
47
+ f as isMainnet,
48
+ k as isNativeToken,
49
+ j as isOrder,
50
+ u as isSolana,
51
+ x as isSolanaNativeToken,
52
+ q as isSolanaOrderResponse,
53
+ L as isStarknet,
54
+ w as isStarknetOrderResponse,
55
+ R as isSui,
56
+ h as isSuiNativeToken,
57
+ z as isSuiOrderResponse,
58
+ $ as parseAction
31
59
  };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("@gardenfi/utils"),y=require("./index11.cjs"),p=require("./index4.cjs"),r=require("./index8.cjs"),o=require("./index12.cjs"),h=Object.keys(p.Config);class g{constructor(t,s){this.assets=null,this.chains=null,this.routeMatrix=null,this.isLoading=!1,this.error=null,typeof s=="string"?this.auth=new n.ApiKey(s):this.auth=s;const e=o.ensureUrl(t.baseUrl),i=o.buildDefaultEndpoint(e,"/v2/chains"),a=o.buildDefaultEndpoint(e,"/v2/policy");this.urls={base:e,assets:o.ensureUrl(t.assetsUrl??i),policy:o.ensureUrl(t.policyUrl??a)},this.routeValidator=new y.RouteValidator(this.urls.policy.toString(),this.auth)}async initialize(){await this.fetchAndSetAssetsAndChains(),await this.routeValidator.loadPolicy()}async fetchAndSetAssetsAndChains(){try{this.isLoading=!0,this.error=null;const t=await this.auth.getAuthHeaders();if(!t.ok)return n.Err("Failed to get auth headers");const s=await n.Fetcher.get(this.urls.assets,{headers:{...t.val}});if(!s.result)return n.Err(`Failed to fetch chains data: ${s.error}`);const{assets:e,chains:i}=this.processApiData(s.result);return this.assets=e,this.chains=i,await this.buildRouteMatrix(),n.Ok("AssetManager initialized successfully")}catch(t){return n.Err(`Failed to fetch assets data: ${t}`)}finally{this.isLoading=!1}}async isRouteValid(t,s){return await this.routeValidator.isValidRoute(r.ChainAsset.from(t.id),r.ChainAsset.from(s.id))}getValidDestinations(t){if(!this.routeMatrix||!this.assets||!t.id)return console.warn("Missing routeMatrix, assets, or asset. Returning all assets."),[];const s=this.routeMatrix[t.id.toString().toLowerCase()];return s?s.map(e=>{const i=e.toString();return Object.values(this.assets).find(a=>r.ChainAsset.from(a).toString()===i)}).filter(Boolean):[]}getAsset(t){if(!this.assets)return;const s=r.ChainAsset.from(t).toString();return this.assets[s]}getAssetsByChain(t){return this.assets?Object.values(this.assets).filter(s=>s.chain===t):[]}searchAssets(t){if(!this.assets)return[];const s=t.toLowerCase();return Object.values(this.assets).filter(e=>e.symbol.toLowerCase().includes(s)||e.name.toLowerCase().includes(s))}getChain(t){if(this.chains)return this.chains[t]}async buildRouteMatrix(){if(!this.assets||!this.routeValidator)return;const t=Object.values(this.assets).map(s=>{if(!s.id)return null;try{return r.ChainAsset.from(s.id)}catch{return null}}).filter(s=>s!==null);this.routeMatrix=await this.routeValidator.buildRouteMatrix(t)}processApiData(t){const s={},e={};for(const i of t){const a=this.parseChainIdentifier(i.chain);if(!a||!h.includes(a))continue;const u={...i,name:this.formatChainName(i.chain),chain:a};for(const l of i.assets){const c=r.ChainAsset.from(l.id).toString(),{name:d,symbol:f}=o.parseAssetNameSymbol(l.name,l.id),A={...l,id:r.ChainAsset.from(l.id),chain:a,name:d,symbol:f};s[c]=A,e[a]||(e[a]=u)}}return{assets:s,chains:e}}parseChainIdentifier(t){return h.includes(t)?t:null}formatChainName(t){return t.split("_").map(s=>s.charAt(0).toUpperCase()+s.slice(1)).join(" ")}async refresh(){await this.initialize()}}exports.AssetManager=g;
@@ -0,0 +1,188 @@
1
+ import { ApiKey as A, Err as o, Fetcher as y, Ok as g } from "@gardenfi/utils";
2
+ import { RouteValidator as C } from "./index11.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 "./index12.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 i = l(t.baseUrl), e = u(i, "/v2/chains"), a = u(i, "/v2/policy");
11
+ this.urls = {
12
+ base: i,
13
+ assets: l(t.assetsUrl ?? e),
14
+ policy: l(t.policyUrl ?? a)
15
+ }, this.routeValidator = new C(
16
+ this.urls.policy.toString(),
17
+ this.auth
18
+ );
19
+ }
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();
28
+ }
29
+ /**
30
+ * Fetch and cache asset and chain data from API
31
+ */
32
+ async fetchAndSetAssetsAndChains() {
33
+ try {
34
+ this.isLoading = !0, this.error = null;
35
+ const t = await this.auth.getAuthHeaders();
36
+ if (!t.ok) return o("Failed to get auth headers");
37
+ const s = await y.get(
38
+ this.urls.assets,
39
+ {
40
+ headers: {
41
+ ...t.val
42
+ }
43
+ }
44
+ );
45
+ if (!s.result) return o(`Failed to fetch chains data: ${s.error}`);
46
+ const { assets: i, chains: e } = this.processApiData(s.result);
47
+ return this.assets = i, this.chains = e, await this.buildRouteMatrix(), g("AssetManager initialized successfully");
48
+ } catch (t) {
49
+ return o(`Failed to fetch assets data: ${t}`);
50
+ } finally {
51
+ this.isLoading = !1;
52
+ }
53
+ }
54
+ // ============================================
55
+ // Route Validation Methods
56
+ // ============================================
57
+ /**
58
+ * Check if a swap route from one asset to another is valid
59
+ */
60
+ async isRouteValid(t, s) {
61
+ return await this.routeValidator.isValidRoute(
62
+ r.from(t.id),
63
+ r.from(s.id)
64
+ );
65
+ }
66
+ /**
67
+ * Get all valid destination assets for a given source asset
68
+ */
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((i) => {
76
+ const e = i.toString();
77
+ return Object.values(this.assets).find((a) => r.from(a).toString() === e);
78
+ }).filter(Boolean) : [];
79
+ }
80
+ // ============================================
81
+ // Asset Query Methods
82
+ // ============================================
83
+ /**
84
+ * Get asset by chain and token address
85
+ */
86
+ getAsset(t) {
87
+ if (!this.assets) return;
88
+ const s = r.from(t).toString();
89
+ return this.assets[s];
90
+ }
91
+ /**
92
+ * Get all assets for a specific chain
93
+ */
94
+ getAssetsByChain(t) {
95
+ return this.assets ? Object.values(this.assets).filter((s) => s.chain === t) : [];
96
+ }
97
+ /**
98
+ * Search assets by symbol or name
99
+ */
100
+ searchAssets(t) {
101
+ if (!this.assets) return [];
102
+ const s = t.toLowerCase();
103
+ return Object.values(this.assets).filter(
104
+ (i) => i.symbol.toLowerCase().includes(s) || i.name.toLowerCase().includes(s)
105
+ );
106
+ }
107
+ /**
108
+ * Get chain data by chain identifier
109
+ */
110
+ getChain(t) {
111
+ if (this.chains)
112
+ return this.chains[t];
113
+ }
114
+ // ============================================
115
+ // Private Helper Methods
116
+ // ============================================
117
+ /**
118
+ * Build route matrix for fast O(1) route lookups
119
+ */
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
+ );
133
+ }
134
+ /**
135
+ * Process raw API data into structured format
136
+ */
137
+ processApiData(t) {
138
+ const s = {}, i = {};
139
+ for (const e of t) {
140
+ const a = this.parseChainIdentifier(e.chain);
141
+ if (!a || !c.includes(a))
142
+ continue;
143
+ const h = {
144
+ ...e,
145
+ name: this.formatChainName(e.chain),
146
+ chain: a
147
+ };
148
+ for (const n of e.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: a,
156
+ name: f,
157
+ symbol: m
158
+ };
159
+ s[d] = p, i[a] || (i[a] = h);
160
+ }
161
+ }
162
+ return { assets: s, chains: i };
163
+ }
164
+ /**
165
+ * Parse chain identifier from string
166
+ */
167
+ parseChainIdentifier(t) {
168
+ return c.includes(t) ? t : null;
169
+ }
170
+ /**
171
+ * Format chain name for display
172
+ */
173
+ formatChainName(t) {
174
+ return t.split("_").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" ");
175
+ }
176
+ // ============================================
177
+ // Data Refresh Methods
178
+ // ============================================
179
+ /**
180
+ * Refresh all data
181
+ */
182
+ async refresh() {
183
+ await this.initialize();
184
+ }
185
+ }
186
+ export {
187
+ I as AssetManager
188
+ };
@@ -0,0 +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;
@@ -0,0 +1,219 @@
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";
3
+ const a = class a {
4
+ constructor(e, t) {
5
+ this.policy = new d({
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 b(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(), i = {
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, i), i;
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);
45
+ try {
46
+ const t = await this.auth.getAuthHeaders();
47
+ if (!t.ok)
48
+ return l(`Failed to get auth headers: ${t.error}`);
49
+ const i = await p.get(
50
+ this.apiBaseUrl,
51
+ {
52
+ headers: {
53
+ "Content-Type": "application/json",
54
+ ...t.val
55
+ }
56
+ }
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}`);
71
+ } catch (t) {
72
+ return l(`Failed to load policy: ${t}`);
73
+ }
74
+ }
75
+ /**
76
+ * Checks if a given route is valid based on all route rules.
77
+ */
78
+ 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(
82
+ e,
83
+ s
84
+ );
85
+ if (o && !this.matchesRuleDestination(t, o))
86
+ return !1;
87
+ const c = this.findMatchingRule(
88
+ t,
89
+ s
90
+ );
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";
92
+ }
93
+ /**
94
+ * Returns all valid destinations for a given source asset.
95
+ */
96
+ 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;
101
+ }
102
+ /**
103
+ * Returns every valid route (from-to pair) among the provided assets.
104
+ */
105
+ async getAllValidRoutes(e) {
106
+ 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 });
110
+ return t;
111
+ }
112
+ /**
113
+ * Turns policy string rules into sorted ParsedRule objects.
114
+ */
115
+ 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 };
118
+ }
119
+ /**
120
+ * Parses a rule string (e.g. "ethereum:usdc -> base:usdt") into parts.
121
+ */
122
+ parseRule(e) {
123
+ const i = e.includes(
124
+ "<->"
125
+ /* Bidirectional */
126
+ ) ? "<->" : "->", [s, r] = e.split(i).map((n) => n.trim());
127
+ return {
128
+ pattern: e,
129
+ fromPattern: s,
130
+ toPattern: r,
131
+ direction: i,
132
+ specificity: this.calculateSpecificity(s, r)
133
+ };
134
+ }
135
+ /**
136
+ * Gives a specificity score to a rule pattern for prioritizing.
137
+ */
138
+ calculateSpecificity(e, t) {
139
+ const i = (s) => {
140
+ const r = s.toLowerCase();
141
+ return r === "*" ? 0 : r.includes(
142
+ "*"
143
+ /* Any */
144
+ ) ? 1 : 2;
145
+ };
146
+ return i(e) * 10 + i(t);
147
+ }
148
+ /**
149
+ * Finds the first matching rule for an asset given the rule "side".
150
+ */
151
+ findMatchingRule(e, t) {
152
+ for (const i of t) {
153
+ if (this.matchesAssetPattern(e, i.fromPattern))
154
+ return {
155
+ rule: i,
156
+ matchedAs: "from"
157
+ /* From */
158
+ };
159
+ if (i.direction === "<->" && this.matchesAssetPattern(e, i.toPattern))
160
+ return {
161
+ rule: i,
162
+ matchedAs: "to"
163
+ /* To */
164
+ };
165
+ }
166
+ return null;
167
+ }
168
+ /**
169
+ * Checks if a given toAsset matches the rule's destination side.
170
+ */
171
+ matchesRuleDestination(e, t) {
172
+ return t.matchedAs === "from" ? this.matchesAssetPattern(e, t.rule.toPattern) : t.rule.direction !== "<->" ? !1 : this.matchesAssetPattern(e, t.rule.fromPattern);
173
+ }
174
+ /**
175
+ * Checks if a given fromAsset matches the rule's source side.
176
+ */
177
+ matchesRuleSource(e, t) {
178
+ return t.matchedAs === "to" ? this.matchesAssetPattern(e, t.rule.fromPattern) : t.rule.direction !== "<->" ? !1 : this.matchesAssetPattern(e, t.rule.toPattern);
179
+ }
180
+ /**
181
+ * Checks if any rule in a list matches fromAsset and toAsset.
182
+ */
183
+ matchesRuleList(e, t, i) {
184
+ return i.some((s) => this.matchesRule(e, t, s));
185
+ }
186
+ /**
187
+ * Checks if a rule matches fromAsset and toAsset (forward or backward if bidirectional).
188
+ */
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;
194
+ }
195
+ return s;
196
+ }
197
+ /**
198
+ * Checks if an asset string matches a rule's pattern (wildcards supported).
199
+ */
200
+ 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;
203
+ }
204
+ async buildRouteMatrix(e) {
205
+ 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;
211
+ }
212
+ return t;
213
+ }
214
+ };
215
+ a.POLICY_CACHE_KEY = "route_policy";
216
+ let h = a;
217
+ export {
218
+ h as RouteValidator
219
+ };
@@ -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"),a=require("./index5.cjs");class O{constructor(c){this.Url=c}async createOrder(c,n){const t=await n.getAuthHeaders();if(t.error)return r.Err(t.error);try{const e=await r.Fetcher.post(this.Url,{body:JSON.stringify(c),headers:{...t.val,"Content-Type":"application/json"}});return e.error?r.Err(e.error):e.result?r.Ok(e.result):r.Err("CreateOrder: Unexpected error, result is undefined")}catch(e){return r.Err("CreateOrder Err:",String(e))}}async getOrder(c,n,t){const e=this.Url.endpoint(n?`/id/${c}/matched`:`/id/${c}/unmatched`);try{const s=await r.Fetcher.get(e,{...t});return s.error?r.Err(s.error):s.result?r.Ok(s.result):r.Err("GetOrder: Unexpected error, result is undefined")}catch(s){return r.Err("GetOrder:",String(s))}}async getMatchedOrders(c,n,t,e){const s=a.ConstructUrl(this.Url,`/user/${c}/matched`,{...t,status:n});try{const u=await r.Fetcher.get(s,{...e});return u.error?r.Err(u.error):u.result?r.Ok(u.result):r.Err("GetMatchedOrders: Unexpected error, result is undefined")}catch(u){return r.Err("GetMatchedOrders:",String(u))}}async getUnMatchedOrders(c,n,t){const e=a.ConstructUrl(this.Url,`/user/${c}/unmatched`,n);try{const s=await r.Fetcher.get(e,{...t});return s.error?r.Err(s.error):s.result?r.Ok(s.result):r.Err("GetUnMatchedOrders: Unexpected error, result is undefined")}catch(s){return r.Err("GetUnMatchedOrders:",String(s))}}async getOrders(c,n,t,e){const s=c?"/matched":"/unmatched",u={page:t==null?void 0:t.page,per_page:t==null?void 0:t.per_page,...n},l=a.ConstructUrl(this.Url,s,u);try{const d=await r.Fetcher.get(l,{...e});return d.error?r.Err(d.error):d.result?r.Ok(d.result):r.Err("GetAllOrders: Unexpected error, result is undefined")}catch(d){return r.Err("GetAllOrders:",String(d))}}async subscribeOrders(c,n,t,e,s="all",u,l){let d=!1;const h=async()=>{if(!d){d=!0;try{const o=n?await this.getMatchedOrders(c,s,u,l):await this.getUnMatchedOrders(c,u,l);o.ok?await e(o.val):console.error("Error fetching orders:",o.error)}catch(o){console.error("Error fetching orders:",o)}finally{d=!1}}};await h();const i=setInterval(h,t);return()=>{clearInterval(i)}}async getOrdersCount(c,n){const t=this.Url.endpoint(`/user/${c}/count`);try{const e=await r.Fetcher.get(t,{...n});return e.error?r.Err(e.error):e.status===r.ApiStatus.Ok&&e.result!==void 0?r.Ok(e.result):r.Err("GetOrdersCount: Unexpected error, result is undefined")}catch(e){return r.Err("GetOrdersCount:",String(e))}}}exports.Orderbook=O;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@gardenfi/utils"),c=require("./index7.cjs"),d=require("./index9.cjs");class l{constructor(n){this.url=n}async createOrder(n,o){try{const t=await o.getAuthHeaders();if(t.error)return e.Err(t.error);const s=await e.Fetcher.post(this.url.endpoint("/v2/orders"),{body:JSON.stringify(n),headers:{...t.val,"Content-Type":"application/json"}});if(s.error)return e.Err(s.error);if(!s.result)return e.Err("CreateOrder: Unexpected error, result is undefined");const r=c.discriminateOrderResponse(s.result);return r?e.Ok(r):e.Err("CreateOrder: Unable to determine order type from response")}catch(t){return e.Err("CreateOrder Err:",String(t))}}async getOrder(n,o){try{const t=this.url.endpoint("/v2/orders").endpoint(n),s=await e.Fetcher.get(t,{...o});if(s.error)return e.Err(s.error);if(!s.result)return e.Err("GetOrder: Unexpected error, result is undefined");const r=d.ParseOrderStatus(s.result);return e.Ok({...s.result,status:r})}catch(t){return e.Err(`GetOrder: ${t instanceof Error?t.message:String(t)}`)}}async getOrders(n,o){const s=c.ConstructUrl(this.url,"/v2/orders",n);try{const r=await e.Fetcher.get(s,{...o});if(r.error)return e.Err(r.error);if(!r.result)return e.Err("GetAllOrders: Unexpected error, result is undefined");const i=r.result.data.map(u=>({...u,status:d.ParseOrderStatus(u)}));return e.Ok({...r.result,data:i})}catch(r){return e.Err(`GetAllOrders: ${r instanceof Error?r.message:String(r)}`)}}async subscribeOrders(n,o,t,s){let r=!1;const i=async()=>{if(!r){r=!0;try{const a=await this.getOrders(n,s);a.ok?await o(a.val):console.error("Error fetching orders:",a.error)}catch(a){console.error("Error fetching orders:",a)}finally{r=!1}}};await i();const u=setInterval(i,t);return()=>{clearInterval(u)}}}exports.Orderbook=l;