danogo-clmm 0.0.15 → 0.1.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/README.md CHANGED
@@ -8,16 +8,19 @@ An SDK to calculate and execute swaps on the Danogo liquidity platform on the Ca
8
8
  npm install danogo-clmm
9
9
  ```
10
10
 
11
- ## Usage
11
+ ## Prerequisites
12
12
 
13
- ### Prerequisites
13
+ This SDK requires:
14
+ - Node.js 18+
15
+ - `@evolution-sdk/evolution` for wallet management and transaction building
16
+ - A Kupmios provider for blockchain data
17
+ - An Ogmios instance for transaction submission
14
18
 
15
- This SDK relies on `@lucid-evolution/lucid` for wallet management and transaction building.
19
+ ## Usage
16
20
 
17
21
  ### Initialization
18
22
 
19
- Initialize the SDK with the Danogo API URL. Optionally, you can provide a custom pool script hash.
20
-
23
+ Initialize the SDK.
21
24
  ```typescript
22
25
  import DanogoSwap from "danogo-clmm";
23
26
 
@@ -26,137 +29,61 @@ const sdk = new DanogoSwap();
26
29
 
27
30
  ### 1. Calculate Swap Output (Quote)
28
31
 
29
- Calculate the expected output of a swap without submitting a transaction. This is useful for UI previews or checking rates.
32
+ Calculate the expected output of a swap without submitting a transaction. You can swap through one or more pools to get better price execution.
30
33
 
34
+ #### Examples
31
35
  ```typescript
32
- import DanogoSwap from "danogo-clmm";
33
- import { Lucid, Kupmios } from "@lucid-evolution/lucid";
34
-
35
- const sdk = new DanogoSwap();
36
-
37
- async function main() {
38
- const lucid = await Lucid(
39
- new Kupmios("kupo_url", "ogmios_url"),
40
- "Preprod"
41
- );
42
-
43
- const quoteRequest = {
44
- poolOutRef: {
45
- txHash:
46
- "your_tx_hash",
47
- outputIndex: 0, // your index
48
- },
49
- stakingOutRef: {
50
- txHash:
51
- "your_tx_hash",
52
- outputIndex: 1, // your index
53
- },
54
- protocolConfigOutRef: {
55
- txHash:
56
- "your_tx_hash",
57
- outputIndex: 0, // your index
36
+ const quote = await sdk.calculateSwapOut(client, {
37
+ pools: [
38
+ {
39
+ poolOutRef: pool1OutRef,
40
+ deltaAmount: 500_000n,
41
+ stakingOutRef: staking1OutRef // required if pool contains ADA and swap for the first time in an epoch
58
42
  },
59
- deltaAmount: -3000000n, // Positive: User sells X -> Buy Y, Negative: User sells Y -> Buy X
60
- };
61
-
62
- try {
63
- const expectedOutput = await sdk.calculateSwapOut(lucid, quoteRequest);
64
- console.log(`Expected output amount: ${expectedOutput}`);
65
- } catch (error) {
66
- console.error("Calculation failed", error);
67
- }
68
- }
43
+ {
44
+ poolOutRef: pool2OutRef,
45
+ deltaAmount: 500_000n,
46
+ stakingOutRef: staking2OutRef // required if pool contains ADA and swap for the first time in an epoch
47
+ }
48
+ ]
49
+ });
69
50
  ```
70
51
 
71
52
  ### 2. Submit Swap Transaction
72
53
 
73
- Build and submit a swap transaction using a Lucid instance.
54
+ Build and submit a swap transaction across one or more pools.
74
55
 
56
+ #### Examples
75
57
  ```typescript
76
- import DanogoSwap from "danogo-clmm";
77
- import { Lucid, Kupmios } from "@lucid-evolution/lucid";
78
-
79
- const sdk = new DanogoSwap();
80
-
81
- async function main() {
82
- // 1. Initialize Lucid with your provider (recommend Kupmios)
83
- const lucid = await Lucid(
84
- new Kupmios("kupo_url", "ogmios_url"),
85
- "Preprod"
86
- );
87
-
88
- // 2. Select wallet
89
- lucid.selectWallet.fromSeed("your seed phrase");
90
-
91
- const swapRequest = {
92
- poolOutRef: {
93
- txHash:
94
- "your_tx_hash",
95
- outputIndex: 0, // your index
96
- },
97
- poolScriptOutRef: {
98
- txHash:
99
- "your_tx_hash",
100
- outputIndex: 0, // your index
101
- },
102
- protocolConfigOutRef: {
103
- txHash:
104
- "your_tx_hash",
105
- outputIndex: 0, // your index
106
- },
107
- stakingOutRef: {
108
- txHash:
109
- "your_tx_hash",
110
- outputIndex: 1, // your index
58
+ const txHash = await sdk.submitSwap(client, {
59
+ pools: [
60
+ {
61
+ poolOutRef: pool1OutRef,
62
+ deltaAmount: 500_000n,
63
+ minOutChangeAmount: 450_000n,
64
+ stakingOutRef: staking1OutRef // required if pool contains ADA and swap for the first time in an epoch
111
65
  },
112
- deltaAmount: -3000000n, // Positive: User sells X -> Buy Y, Negative: User sells Y -> Buy X
113
- minOutChangeAmount: 10000n, // Minimum amount of token received to accept
114
- }
115
-
116
- try {
117
- const txHash = await sdk.submitSwap(lucid, swapRequest);
118
- console.log(`Transaction submitted: ${txHash}`);
119
- } catch (error) {
120
- console.error("Swap failed", error);
121
- }
122
- }
66
+ {
67
+ poolOutRef: pool2OutRef,
68
+ deltaAmount: 500_000n,
69
+ minOutChangeAmount: 450_000n,
70
+ stakingOutRef: staking2OutRef // required if pool contains ADA and swap for the first time in an epoch
71
+ }
72
+ ],
73
+ protocolConfigOutRef: protocolConfigRef
74
+ });
123
75
  ```
124
76
 
125
- ## ⚠️ Provider Compatibility
126
-
127
- `lucid-evolution` currently raises an error during transaction evaluation.
128
-
129
- This package **only supports the Kupmios provider**.
130
-
131
- ### Required Patch
132
-
133
- Modify the following files:
77
+ > `protocolConfigOutRef` is optional and defaults to the SDK's internal constants. In rare cases where the protocol configuration has updated but the SDK has not yet been updated, you can manually provide the latest `protocolConfigOutRef` in your request. Refer to `src/constants.ts` for the constants.
134
78
 
135
- - `node_modules/@lucid-evolution/provider/dist/index.js`
136
- - `node_modules/@lucid-evolution/provider/dist/index.cjs`
137
-
138
- In the `evaluateTx` method, comment out the `additionalUtxo` line:
139
-
140
- ```javascript
141
- const data = {
142
- jsonrpc: "2.0",
143
- method: "evaluateTransaction",
144
- params: {
145
- transaction: { cbor: tx },
146
- // Comment out the line below:
147
- // additionalUtxo: toOgmiosUTxOs(additionalUTxOs)
148
- },
149
- id: null
150
- };
151
- ```
152
-
153
- ### 3. Get Pool Info from Ogmios Transaction
79
+ ### 4. Get Pool Info from Ogmios Transaction
154
80
 
155
81
  Extract pool data directly from an Ogmios transaction object.
156
82
 
157
83
  ```typescript
158
84
  import DanogoSwap from "danogo-clmm";
159
- import { createInteractionContext, createChainSynchronizationClient } from "@cardano-ogmios/client";
85
+ import { createChainSynchronizationClient, createInteractionContext } from "@cardano-ogmios/client";
86
+ import { Point } from "@cardano-ogmios/schema";
160
87
 
161
88
  const sdk = new DanogoSwap();
162
89
 
@@ -165,9 +92,8 @@ async function main() {
165
92
  console.error,
166
93
  () => console.log("closed"),
167
94
  {
168
- // example with demeter
169
95
  connection: {
170
- host: "ogmios1xxxxxxxxxxxx.cardano-preprod-v6.ogmios-m1.dmtr.host",
96
+ host: "your_ogmios_host",
171
97
  port: 443,
172
98
  tls: true
173
99
  },
@@ -178,16 +104,16 @@ async function main() {
178
104
  rollForward: async ({ block }, requestNext) => {
179
105
  if ("transactions" in block) {
180
106
  for (const tx of block.transactions!) {
181
- const pools = sdk.getPoolsFromOgmiosTx(tx);
182
- // your logic here
107
+ const networkId = 0; // 0 for Preprod, 1 for Mainnet
108
+ const pools = sdk.getPoolsFromOgmiosTx(tx, networkId);
109
+ // your logic with pools
183
110
  }
184
111
  }
185
-
186
112
  requestNext();
187
113
  },
188
114
 
189
115
  rollBackward: async ({ point }, requestNext) => {
190
- // ...
116
+ // handle rollbacks
191
117
  requestNext();
192
118
  },
193
119
  });
@@ -199,4 +125,18 @@ async function main() {
199
125
 
200
126
  await client.resume([checkpoint]);
201
127
  }
128
+ ```
129
+
130
+ ### ⚠️ TypeScript Compatibility Note
131
+
132
+ The dependency `@evolution-sdk/evolution` currently ships with some TypeScript type definitions that may cause compilation errors in strict projects.
133
+
134
+ If you encounter type errors originating from `node_modules/@evolution-sdk/evolution`, you can safely enable the following option in your `tsconfig.json`:
135
+
136
+ ```json
137
+ {
138
+ "compilerOptions": {
139
+ "skipLibCheck": true
140
+ }
141
+ }
202
142
  ```
package/dist/sdk.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { OutRef, LucidEvolution } from '@lucid-evolution/lucid';
1
+ import { TransactionInput, SigningClient } from '@evolution-sdk/evolution';
2
2
  import { Transaction } from '@cardano-ogmios/schema';
3
3
 
4
4
  interface PoolDatum {
@@ -51,44 +51,92 @@ interface ConcentratedPool {
51
51
  totalSwapFee: bigint;
52
52
  }
53
53
  interface SwapRequest {
54
- poolOutRef: OutRef;
55
- poolScriptOutRef: OutRef;
56
- deltaAmount: bigint;
57
- minOutChangeAmount: bigint;
58
- stakingOutRef?: OutRef;
59
- protocolConfigOutRef: OutRef;
54
+ pools: {
55
+ poolOutRef: TransactionInput.TransactionInput;
56
+ deltaAmount: bigint;
57
+ minOutChangeAmount: bigint;
58
+ stakingOutRef?: TransactionInput.TransactionInput;
59
+ }[];
60
+ protocolConfigOutRef?: TransactionInput.TransactionInput;
60
61
  }
61
62
  interface QuoteSwapRequest {
62
- poolOutRef: OutRef;
63
- deltaAmount: bigint;
64
- stakingOutRef?: OutRef;
65
- protocolConfigOutRef: OutRef;
63
+ pools: {
64
+ poolOutRef: TransactionInput.TransactionInput;
65
+ deltaAmount: bigint;
66
+ stakingOutRef?: TransactionInput.TransactionInput;
67
+ }[];
68
+ protocolConfigOutRef?: TransactionInput.TransactionInput;
66
69
  }
67
70
 
68
71
  declare class DanogoSwap {
69
72
  constructor();
70
73
  /**
71
- * Calculates the expected output amount for a swap in a specific liquidity pool.
74
+ * Calculates the expected output amount for a swap across multiple liquidity pools.
72
75
  *
73
- * This function retrieves the latest pool state from the blockchain and performs a local calculation
74
- * to estimate the swap outcome. It does not submit any transaction to the network.
76
+ * This function retrieves the latest pool states from the blockchain and performs routing
77
+ * calculations to estimate the best swap outcome across multiple pools.
75
78
  *
76
- * @param lucid An initialized Lucid instance used to query the blockchain.
79
+ * @param client An initialized SigningClient instance used to query the blockchain.
77
80
  * @param request The quote request object containing pool references and the swap amount.
78
- * - `deltaAmount`: The amount of the input token to swap.
79
- * - Positive (> 0): Swaps Token X for Token Y.
80
- * - Negative (< 0): Swaps Token Y for Token X.
81
- * @returns A promise that resolves to a `bigint` representing the estimated output token amount.
81
+ * - `pools`: Array of pool objects with poolOutRef, deltaAmount, and optional stakingOutRef
82
+ * - `protocolConfigOutRef`: Reference to the protocol configuration UTxO
83
+ * @returns A promise that resolves to a `bigint` representing the estimated total output token amount.
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const quote = await sdk.calculateSwapOut(client, {
88
+ * pools: [
89
+ * {
90
+ * poolOutRef: pool1OutRef,
91
+ * deltaAmount: 500_000n, // 0.5 ADA to pool 1
92
+ * stakingOutRef: staking1OutRef
93
+ * },
94
+ * {
95
+ * poolOutRef: pool2OutRef,
96
+ * deltaAmount: 500_000n, // 0.5 ADA to pool 2
97
+ * stakingOutRef: staking2OutRef
98
+ * }
99
+ * ],
100
+ * protocolConfigOutRef: protocolConfigRef
101
+ * });
102
+ * ```
82
103
  */
83
- calculateSwapOut(lucid: LucidEvolution, request: QuoteSwapRequest): Promise<bigint>;
104
+ calculateSwapOut(client: SigningClient, request: QuoteSwapRequest): Promise<bigint[]>;
84
105
  /**
85
106
  * Builds and submits a swap transaction to the network.
86
107
  *
87
- * @param lucid An initialized Lucid instance with a connected wallet.
88
- * @param request The swap request object containing pool reference, swap amount, and minimum output.
108
+ * This method performs a swap across one or more liquidity pools in a single transaction,
109
+ * potentially splitting the input amount across multiple pools for better price execution.
110
+ *
111
+ * @param client An initialized SigningClient instance with a connected wallet.
112
+ * @param request The swap request object containing pool references, swap amount, and minimum output.
113
+ * - `pools`: Array of pool objects with poolOutRef, deltaAmount, and optional stakingOutRef
114
+ * - `minOutChangeAmount`: Minimum acceptable output amount (slippage protection)
115
+ * - `protocolConfigOutRef`: Reference to the protocol configuration UTxO
89
116
  * @returns A promise that resolves to the transaction hash.
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * const txHash = await sdk.submitSwap(client, {
121
+ * pools: [
122
+ * {
123
+ * poolOutRef: pool1OutRef,
124
+ * deltaAmount: 500_000n, // 0.5 ADA to pool 1
125
+ * stakingOutRef: staking1OutRef
126
+ * },
127
+ * {
128
+ * poolOutRef: pool2OutRef,
129
+ * deltaAmount: 500_000n, // 0.5 ADA to pool 2
130
+ * stakingOutRef: staking2OutRef
131
+ * }
132
+ * ],
133
+ * poolScriptOutRef: poolScriptRef,
134
+ * minOutChangeAmount: 900_000n, // Minimum 0.9 tokens out
135
+ * protocolConfigOutRef: protocolConfigRef
136
+ * });
137
+ * ```
90
138
  */
91
- submitSwap(lucid: LucidEvolution, request: SwapRequest): Promise<string>;
139
+ submitSwap(client: SigningClient, request: SwapRequest): Promise<string>;
92
140
  /**
93
141
  * Extracts concentrated liquidity pool data from a given Ogmios transaction.
94
142
  *
@@ -99,7 +147,19 @@ declare class DanogoSwap {
99
147
  * @param tx The transaction object conforming to the Ogmios schema.
100
148
  * @returns An array of `ConcentratedPool` objects found in the transaction outputs.
101
149
  */
102
- getPoolsFromOgmiosTx(tx: Transaction, poolScriptHash: string): ConcentratedPool[];
150
+ getPoolsFromOgmiosTx(tx: Transaction, networkId: number, poolScriptHash?: string): ConcentratedPool[];
151
+ /**
152
+ * Helper function to get the balance of a specific token from user UTXOs
153
+ */
154
+ private getUserTokenBalance;
155
+ /**
156
+ * Helper function to build delta assets for pool updates
157
+ */
158
+ private buildDeltaAssets;
159
+ /**
160
+ * Helper function to handle staking rewards for ADA pools
161
+ */
162
+ private getStakingRewards;
103
163
  }
104
164
 
105
- export { type ConcentratedPool, type PoolDatum, type SwapRequest, DanogoSwap as default };
165
+ export { type ConcentratedPool, type PoolDatum, type QuoteSwapRequest, type SwapRequest, DanogoSwap as default };
package/dist/sdk.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { OutRef, LucidEvolution } from '@lucid-evolution/lucid';
1
+ import { TransactionInput, SigningClient } from '@evolution-sdk/evolution';
2
2
  import { Transaction } from '@cardano-ogmios/schema';
3
3
 
4
4
  interface PoolDatum {
@@ -51,44 +51,92 @@ interface ConcentratedPool {
51
51
  totalSwapFee: bigint;
52
52
  }
53
53
  interface SwapRequest {
54
- poolOutRef: OutRef;
55
- poolScriptOutRef: OutRef;
56
- deltaAmount: bigint;
57
- minOutChangeAmount: bigint;
58
- stakingOutRef?: OutRef;
59
- protocolConfigOutRef: OutRef;
54
+ pools: {
55
+ poolOutRef: TransactionInput.TransactionInput;
56
+ deltaAmount: bigint;
57
+ minOutChangeAmount: bigint;
58
+ stakingOutRef?: TransactionInput.TransactionInput;
59
+ }[];
60
+ protocolConfigOutRef?: TransactionInput.TransactionInput;
60
61
  }
61
62
  interface QuoteSwapRequest {
62
- poolOutRef: OutRef;
63
- deltaAmount: bigint;
64
- stakingOutRef?: OutRef;
65
- protocolConfigOutRef: OutRef;
63
+ pools: {
64
+ poolOutRef: TransactionInput.TransactionInput;
65
+ deltaAmount: bigint;
66
+ stakingOutRef?: TransactionInput.TransactionInput;
67
+ }[];
68
+ protocolConfigOutRef?: TransactionInput.TransactionInput;
66
69
  }
67
70
 
68
71
  declare class DanogoSwap {
69
72
  constructor();
70
73
  /**
71
- * Calculates the expected output amount for a swap in a specific liquidity pool.
74
+ * Calculates the expected output amount for a swap across multiple liquidity pools.
72
75
  *
73
- * This function retrieves the latest pool state from the blockchain and performs a local calculation
74
- * to estimate the swap outcome. It does not submit any transaction to the network.
76
+ * This function retrieves the latest pool states from the blockchain and performs routing
77
+ * calculations to estimate the best swap outcome across multiple pools.
75
78
  *
76
- * @param lucid An initialized Lucid instance used to query the blockchain.
79
+ * @param client An initialized SigningClient instance used to query the blockchain.
77
80
  * @param request The quote request object containing pool references and the swap amount.
78
- * - `deltaAmount`: The amount of the input token to swap.
79
- * - Positive (> 0): Swaps Token X for Token Y.
80
- * - Negative (< 0): Swaps Token Y for Token X.
81
- * @returns A promise that resolves to a `bigint` representing the estimated output token amount.
81
+ * - `pools`: Array of pool objects with poolOutRef, deltaAmount, and optional stakingOutRef
82
+ * - `protocolConfigOutRef`: Reference to the protocol configuration UTxO
83
+ * @returns A promise that resolves to a `bigint` representing the estimated total output token amount.
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const quote = await sdk.calculateSwapOut(client, {
88
+ * pools: [
89
+ * {
90
+ * poolOutRef: pool1OutRef,
91
+ * deltaAmount: 500_000n, // 0.5 ADA to pool 1
92
+ * stakingOutRef: staking1OutRef
93
+ * },
94
+ * {
95
+ * poolOutRef: pool2OutRef,
96
+ * deltaAmount: 500_000n, // 0.5 ADA to pool 2
97
+ * stakingOutRef: staking2OutRef
98
+ * }
99
+ * ],
100
+ * protocolConfigOutRef: protocolConfigRef
101
+ * });
102
+ * ```
82
103
  */
83
- calculateSwapOut(lucid: LucidEvolution, request: QuoteSwapRequest): Promise<bigint>;
104
+ calculateSwapOut(client: SigningClient, request: QuoteSwapRequest): Promise<bigint[]>;
84
105
  /**
85
106
  * Builds and submits a swap transaction to the network.
86
107
  *
87
- * @param lucid An initialized Lucid instance with a connected wallet.
88
- * @param request The swap request object containing pool reference, swap amount, and minimum output.
108
+ * This method performs a swap across one or more liquidity pools in a single transaction,
109
+ * potentially splitting the input amount across multiple pools for better price execution.
110
+ *
111
+ * @param client An initialized SigningClient instance with a connected wallet.
112
+ * @param request The swap request object containing pool references, swap amount, and minimum output.
113
+ * - `pools`: Array of pool objects with poolOutRef, deltaAmount, and optional stakingOutRef
114
+ * - `minOutChangeAmount`: Minimum acceptable output amount (slippage protection)
115
+ * - `protocolConfigOutRef`: Reference to the protocol configuration UTxO
89
116
  * @returns A promise that resolves to the transaction hash.
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * const txHash = await sdk.submitSwap(client, {
121
+ * pools: [
122
+ * {
123
+ * poolOutRef: pool1OutRef,
124
+ * deltaAmount: 500_000n, // 0.5 ADA to pool 1
125
+ * stakingOutRef: staking1OutRef
126
+ * },
127
+ * {
128
+ * poolOutRef: pool2OutRef,
129
+ * deltaAmount: 500_000n, // 0.5 ADA to pool 2
130
+ * stakingOutRef: staking2OutRef
131
+ * }
132
+ * ],
133
+ * poolScriptOutRef: poolScriptRef,
134
+ * minOutChangeAmount: 900_000n, // Minimum 0.9 tokens out
135
+ * protocolConfigOutRef: protocolConfigRef
136
+ * });
137
+ * ```
90
138
  */
91
- submitSwap(lucid: LucidEvolution, request: SwapRequest): Promise<string>;
139
+ submitSwap(client: SigningClient, request: SwapRequest): Promise<string>;
92
140
  /**
93
141
  * Extracts concentrated liquidity pool data from a given Ogmios transaction.
94
142
  *
@@ -99,7 +147,19 @@ declare class DanogoSwap {
99
147
  * @param tx The transaction object conforming to the Ogmios schema.
100
148
  * @returns An array of `ConcentratedPool` objects found in the transaction outputs.
101
149
  */
102
- getPoolsFromOgmiosTx(tx: Transaction, poolScriptHash: string): ConcentratedPool[];
150
+ getPoolsFromOgmiosTx(tx: Transaction, networkId: number, poolScriptHash?: string): ConcentratedPool[];
151
+ /**
152
+ * Helper function to get the balance of a specific token from user UTXOs
153
+ */
154
+ private getUserTokenBalance;
155
+ /**
156
+ * Helper function to build delta assets for pool updates
157
+ */
158
+ private buildDeltaAssets;
159
+ /**
160
+ * Helper function to handle staking rewards for ADA pools
161
+ */
162
+ private getStakingRewards;
103
163
  }
104
164
 
105
- export { type ConcentratedPool, type PoolDatum, type SwapRequest, DanogoSwap as default };
165
+ export { type ConcentratedPool, type PoolDatum, type QuoteSwapRequest, type SwapRequest, DanogoSwap as default };
package/dist/sdk.js CHANGED
@@ -1 +1 @@
1
- "use strict";var K=Object.create;var k=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var tt=Object.getOwnPropertyNames;var et=Object.getPrototypeOf,nt=Object.prototype.hasOwnProperty;var ot=(n,e)=>{for(var t in e)k(n,t,{get:e[t],enumerable:!0})},X=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of tt(e))!nt.call(n,r)&&r!==t&&k(n,r,{get:()=>e[r],enumerable:!(o=Z(e,r))||o.enumerable});return n};var rt=(n,e,t)=>(t=n!=null?K(et(n)):{},X(e||!n||!n.__esModule?k(t,"default",{value:n,enumerable:!0}):t,n)),it=n=>X(k({},"__esModule",{value:!0}),n);var lt={};ot(lt,{default:()=>ct});module.exports=it(lt);var O=require("@lucid-evolution/lucid");function D(n,e){let o=(n>=0n?n:n+(1n<<256n)).toString(16);o.length%2&&(o="0"+o);let r=o.length/2;if(r>e)throw new Error(`Number ${n} requires ${r} bytes, but target length is ${e}.`);let i=new Uint8Array(e),s=e-r;for(let g=0;g<r;g++)i[g+s]=parseInt(o.slice(g*2,g*2+2),16);return i}var S=(n,e,t,o)=>{try{return{kind:"selected",inputs:n,makeRedeemer:i=>{let s=3n,g=D(o?t:i[0],1),c=D(i[0],1),p=D(s,1),f=D(0n,1),w=D(e[0],32),d=g.length+p.length+c.length+f.length+w.length,l=new Uint8Array(d),a=0;return l.set(g,a),a+=g.length,l.set(p,a),a+=p.length,l.set(c,a),a+=c.length,l.set(f,a),a+=f.length,l.set(w,a),"5824"+Buffer.from(l).toString("hex")}}}catch(r){throw console.error("Error creating pool redeemer:",r),r}};var m=require("@lucid-evolution/lucid");var Y=require("@lucid-evolution/lucid");function M(n,e,t){return Y.Data.to(n,e,t)}var x=rt(require("cbor")),W=n=>{let e=m.Data.Tuple([m.Data.Bytes(),m.Data.Bytes()]),t=m.Data.Tuple([m.Data.Integer(),m.Data.Integer()],{hasConstr:!0}),o=m.Data.Tuple([e,e,m.Data.Integer(),m.Data.Integer(),m.Data.Integer(),m.Data.Integer(),t,t,m.Data.Integer(),m.Data.Integer(),m.Data.Integer(),m.Data.Integer()],{hasConstr:!0}),r=$(n.tokenX),i=$(n.tokenY),s=[r,i,BigInt(n.lpFeeRate),BigInt(n.platformFeeX),BigInt(n.platformFeeY),BigInt(n.totalSwapFee),[BigInt(n.sqrtLowerPriceNum),BigInt(n.sqrtLowerPriceDen)],[BigInt(n.sqrtUpperPriceNum),BigInt(n.sqrtUpperPriceDen)],BigInt(n.minXChange),BigInt(n.minYChange),BigInt(n.circulatingLPToken),BigInt(n.lastWithdrawEpoch)];return M(s,o)};var $=n=>{if(!n)return["",""];try{if(n.includes(".")){let o=n.split(".");return o.length===2?[o[0],o[1]]:[n,""]}let e=n.slice(0,56),t=n.slice(56);return[e,t]}catch(e){throw console.error(`Error parsing token ID "${n}":`,e),new Error(`Failed to parse token ID: ${n}`)}},v=n=>{let e=x.decodeFirstSync(Buffer.from(n,"hex")),t=e instanceof x.Tagged?e.value:e;if(!Array.isArray(t))throw new Error("Invalid datum structure: expected array of fields");let o=i=>{let s=i instanceof x.Tagged?i.value:i;if(Array.isArray(s)&&s.length===2){let g=s[0].toString("hex"),c=s[1].toString("hex");return g+c}throw new Error("Invalid AssetClass structure")},r=i=>{let s=i instanceof x.Tagged?i.value:i;if(Array.isArray(s)&&s.length===2)return{num:s[0],den:s[1]};throw new Error("Invalid Ratio structure")};return{tokenX:o(t[0]),tokenY:o(t[1]),lpFeeRate:Number(t[2]),platformFeeX:t[3].toString(),platformFeeY:t[4].toString(),totalSwapFee:t[5].toString(),sqrtLowerPriceNum:r(t[6]).num,sqrtLowerPriceDen:r(t[6]).den,sqrtUpperPriceNum:r(t[7]).num,sqrtUpperPriceDen:r(t[7]).den,minXChange:t[8].toString(),minYChange:t[9].toString(),circulatingLPToken:t[10].toString(),lastWithdrawEpoch:Number(t[11])}},U=n=>{let e=x.decodeFirstSync(Buffer.from(n,"hex")),t=e instanceof x.Tagged?e.value:e;if(!Array.isArray(t))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:t[0].toString(),swapFee:t[1].toString()}};var j=n=>{if(!n||Object.keys(n).length===0)return[];let e=[];for(let[t,o]of Object.entries(n)){if(t==="ada")continue;let r=[];for(let[i,s]of Object.entries(o))r.push({name:i,value:s});e.push({policyId:t,assets:r})}return e};var Q=(n,e)=>{let t=432e6,o=1647899091e3,r=328;return e!=="Mainnet"&&(t=18e5),Math.floor((n-o)/t)+r};function N(n,e,t,o,r=0n,i){let s=o<0n?-o:o,g=t.tokenX===""?3000000n+BigInt(t.totalSwapFee):0n,c=BigInt(n)-BigInt(t.platformFeeX)+r-g,p=BigInt(e)-BigInt(t.platformFeeY),f=st(c,p,[BigInt(t.sqrtLowerPriceNum),BigInt(t.sqrtLowerPriceDen)],[BigInt(t.sqrtUpperPriceNum),BigInt(t.sqrtUpperPriceDen)]),w=G(f[0]*BigInt(t.sqrtUpperPriceDen),f[1]*BigInt(t.sqrtUpperPriceNum))+c,d=G(f[0]*BigInt(t.sqrtLowerPriceNum),f[1]*BigInt(t.sqrtLowerPriceDen))+p;return o>0n?_(s,w,d,p,BigInt(t.lpFeeRate),i):_(s,d,w,c,BigInt(t.lpFeeRate),i)}var _=(n,e,t,o,r,i)=>{let s=10000n,c=n*r/s*BigInt(i)/10000n,p=s-r,f=e*s+n*p,w=e*t,l=(t*f-w*s)/f;if(l>o)throw new Error("pool out exceeded");return[l,c]},st=(n,e,t,o)=>{let r=t[1]*o[1],i=t[0]*o[0],s=(e*r-n*i)*(e*r-n*i),g=4n*n*e*t[1]*t[1]*o[0]*o[0],c=at(s+g),p=e*r+n*i+c,f=2n*(o[0]*t[1]-o[1]*t[0]);return[p,f]};function at(n){if(n<0n)throw new Error("Square root of negative number");if(n<2n)return n;let e=n,t=e+n/e>>1n;for(;t<e;)e=t,t=e+n/e>>1n;return e}function G(n,e){if(e===0n)throw new Error("Division by zero");let t=n/e;return n%e===0n||n<0n!=e<0n?t:t+1n}function V(n,e){let o=[...e].sort((r,i)=>r.txHash===i.txHash?r.outputIndex-i.outputIndex:r.txHash<i.txHash?-1:1).findIndex(r=>r.txHash===n.txHash&&r.outputIndex===n.outputIndex);if(o===-1)throw new Error("Protocol config out ref not found in reference inputs");return BigInt(o)}var L=class{constructor(){}async calculateSwapOut(e,t){if(!e||!e.wallet())throw new Error("Please connect a wallet first.");let o=(await e.utxosByOutRef([{txHash:t.poolOutRef.txHash,outputIndex:t.poolOutRef.outputIndex}]))[0],r=null;if(t.stakingOutRef&&(r=(await e.utxosByOutRef([{txHash:t.stakingOutRef.txHash,outputIndex:t.stakingOutRef.outputIndex}]))[0]),!o.datum)throw new Error("Pool input UTxO does not contain a datum.");let i=(await e.utxosByOutRef([{txHash:t.protocolConfigOutRef.txHash,outputIndex:t.protocolConfigOutRef.outputIndex}]))[0];if(!i.datum)throw new Error("Protocol config UTxO does not contain a datum.");let s=U(i.datum),g=v(o.datum),c=g.tokenX||"lovelace",p=g.tokenY,f=o.assets.lovelace,w=u=>{if(u==="lovelace")return f;for(let[A,h]of Object.entries(o.assets))if(A===u)return h;return 0n},d=0n,l="";if(c=="lovelace"){l=(0,O.validatorToRewardAddress)(e.config().network,r.scriptRef);try{d=(await e.delegationAt(l)).rewards}catch{d=0n}}let[a,b]=N(w(c),w(p),g,t.deltaAmount,d,s.platformFeeRate);return a}async submitSwap(e,t){if(!e||!e.wallet())throw new Error("Please connect a wallet first.");let o=(await e.utxosByOutRef([{txHash:t.poolOutRef.txHash,outputIndex:t.poolOutRef.outputIndex}]))[0],r=(await e.utxosByOutRef([{txHash:t.poolScriptOutRef.txHash,outputIndex:t.poolScriptOutRef.outputIndex}]))[0],i=null;if(t.stakingOutRef&&(i=(await e.utxosByOutRef([{txHash:t.stakingOutRef.txHash,outputIndex:t.stakingOutRef.outputIndex}]))[0]),!o.datum)throw new Error("Pool input UTxO does not contain a datum.");let s=(await e.utxosByOutRef([{txHash:t.protocolConfigOutRef.txHash,outputIndex:t.protocolConfigOutRef.outputIndex}]))[0];if(!s.datum)throw new Error("Protocol config UTxO does not contain a datum.");let g=U(s.datum),c=v(o.datum),p=c.tokenX||"lovelace",f=c.tokenY,w=o.assets.lovelace,d=R=>{if(R==="lovelace")return w;for(let[E,J]of Object.entries(o.assets))if(E===R)return J;return 0n},l=t.deltaAmount,a=l>0?p:f,b=l>0?f:p,u=e.newTx(),h=(await e.wallet().getUtxos()).reduce((R,E)=>R+(E.assets[a]||0n),0n),F=l<0n?-l:l;if(h<F)throw new Error(`Insufficient ${a} balance. Required: ${F}, Available: ${h}`);u=u.readFrom([r,s]),i&&(u=u.readFrom([i]));let B=0n,T="";if(p=="lovelace"){T=(0,O.validatorToRewardAddress)(e.config().network,i.scriptRef);try{B=(await e.delegationAt(T)).rewards}catch{B=0n}}let[P,y]=N(d(p),d(f),c,l,B,g.platformFeeRate);if(P<t.minOutChangeAmount)throw new Error(`Slippage too high. Expected at least ${t.minOutChangeAmount} but got ${P}`);let q=Q(Date.now(),e.config().network),z=W({...c,platformFeeX:BigInt(c.platformFeeX)+(a===(c.tokenX||"lovelace")?y:0n),platformFeeY:BigInt(c.platformFeeY)+(a===c.tokenY?y:0n),lastWithdrawEpoch:q,totalSwapFee:BigInt(c.totalSwapFee)+BigInt(g.swapFee)}),I={...o.assets};I[a]=I[a]+(l>0n?l:-l),I[b]=BigInt(I[b])-BigInt(P),I.lovelace=BigInt(I.lovelace)+BigInt(g.swapFee),u=u.pay.ToAddressWithData(o.address,{kind:"inline",value:z},I),u=u.attachMetadata(674,{msg:["Danogo Liquidity Pair: Swap"]});let H=[r,s];i&&H.push(i);let C=V(s,H);return u=u.collectFrom([o],S([o],[l],C,!1)),u=u.withdraw((0,O.validatorToRewardAddress)(e.config().network,r.scriptRef),0n,S([o],[l],C,!0)),p==="lovelace"&&q>c.lastWithdrawEpoch&&(u=u.withdraw(T,B,S([o],[l],C,!1))),u=u.validFrom(Date.now()-12e4).validTo(Date.now()+24e4).setMinFee(17000n).addSigner(await e.wallet().address()),await(await(await u.complete({localUPLCEval:!1})).sign.withWallet().complete()).submit()}getPoolsFromOgmiosTx(e,t){let o=[];return e.outputs.forEach((r,i)=>{let s=r.value,g=s[t];if(g&&r.datum){for(let[c,p]of Object.entries(g))if(p===1n){let f=t+c,w=`${e.id}#${i}`,d=s.ada.lovelace,l=j(s),a=v(r.datum),b=a.tokenX,u=a.tokenY,A=h=>{if(h==="lovelace"||h==="")return d;let F=h.slice(0,56),B=h.slice(56),P=l.find(y=>y.policyId===F)?.assets.find(y=>y.name===B);return P?P.value:0n};o.push({outRef:w,address:r.address,coin:d,multiAssets:l,validityNft:f,tokenA:b,tokenAReserve:A(b),tokenB:u,tokenBReserve:A(u),lpFeeRate:a.lpFeeRate,priceLowerNum:a.sqrtLowerPriceNum,priceLowerDen:a.sqrtLowerPriceDen,priceUpperNum:a.sqrtUpperPriceNum,priceUpperDen:a.sqrtUpperPriceDen,platformFeeA:a.platformFeeX,platformFeeB:a.platformFeeY,minAChange:a.minXChange,minBChange:a.minYChange,lpTokenTotalSupply:a.circulatingLPToken,lastWithdrawEpoch:a.lastWithdrawEpoch,totalSwapFee:a.totalSwapFee})}}}),o}},ct=L;
1
+ var G=Object.defineProperty;var ut=Object.getOwnPropertyDescriptor;var lt=Object.getOwnPropertyNames;var pt=Object.prototype.hasOwnProperty;var mt=(n,t)=>{for(var e in t)G(n,e,{get:t[e],enumerable:!0})},ft=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of lt(t))!pt.call(n,o)&&o!==e&&G(n,o,{get:()=>t[o],enumerable:!(r=ut(t,o))||r.enumerable});return n};var dt=n=>ft(G({},"__esModule",{value:!0}),n);var Bt={};mt(Bt,{default:()=>Rt});module.exports=dt(Bt);var z=require("@evolution-sdk/evolution"),Y=require("@evolution-sdk/evolution/ScriptHash"),b=require("@evolution-sdk/evolution/Assets");function C(n,t){let r=(n>=0n?n:n+(1n<<256n)).toString(16);r.length%2&&(r="0"+r);let o=r.length/2;if(o>t)throw new Error(`Number ${n} requires ${o} bytes, but target length is ${t}.`);let i=new Uint8Array(t),s=t-o;for(let a=0;a<o;a++)i[a+s]=parseInt(r.slice(a*2,a*2+2),16);return i}var v=(n,t,e,r)=>{try{let o=(i,s)=>{let a=3n,f=C(n?i:r,1),l=C(a,1),p=t.map((A,y)=>{let R=s.find(h=>h.utxo.transactionId===A.transactionId&&h.utxo.index===A.index);if(!R)throw new Error(`Pool UTxO at ${y} not found in indexedInputs`);if(e[y]===void 0)throw new Error(`deltaAmount for poolOutIdx ${y} is undefined`);let w=C(BigInt(R.index),1),O=C(BigInt(y),1),g=C(e[y],32);return{poolInBytes:w,poolOutBytes:O,amountBytes:g}}),I=2+34*p.length,u=new Uint8Array(I),d=0;u.set(f,d),d+=f.length,u.set(l,d),d+=l.length;for(let A of p)u.set(A.poolInBytes,d),d+=A.poolInBytes.length,u.set(A.poolOutBytes,d),d+=A.poolOutBytes.length,u.set(A.amountBytes,d),d+=A.amountBytes.length;return u};return{all:i=>{if(!i.length)throw new Error("swapTokensRedeemer batch all called with empty indexedInputs");let s=null;if(n&&(s=i.find(a=>a.utxo.transactionId===n.transactionId&&a.utxo.index===n.index),!s))throw new Error("Target pool UTxO is not found in poolInUTxOs");return o(s?.index,i)},inputs:t}}catch(o){throw console.error("Error creating pool redeemer:",o),o}};var B=require("@evolution-sdk/evolution"),tt=require("@evolution-sdk/evolution/InlineDatum");var L=require("@evolution-sdk/evolution"),x="lovelace",J=432e6,gt="64d111b957e7d7848ffdde5149aa77fa4090a7fa1ad0ac108067900614848501#0",wt="d8b69fc53637bcfadbc4469083f706bc293f4d9d2296646c5ca167bb",At="2cafd7c92f7093e5229af274be83dea660b0590b4174bbed79ba662b44fbd1ee#0",K=18e5,It="2e19cca74e3badcab26aef7574aa1885ba97228a254ca227ba2f79f2b75fd136#0",xt="04041c3c6ba87b33f2c9eb7f7dbeae3b26003c3e199d438bb99932a2",yt="3775af36f485f9c97101ee5b9b360c34f0f8e12186bc9060f358b7fc8ce468a4#0",H=n=>n===1?{poolScriptOutRef:q(gt),poolScriptHash:wt,protocolScriptOutRef:q(At)}:{poolScriptOutRef:q(It),poolScriptHash:xt,protocolScriptOutRef:q(yt)},q=n=>{if(!n)return;let[t,e]=n.split("#");return new L.TransactionInput.TransactionInput({transactionId:L.TransactionHash.fromHex(t),index:BigInt(e)})};var et=n=>{let t=[new Uint8Array(Buffer.from(n.tokenX.slice(0,56),"hex")),new Uint8Array(Buffer.from(n.tokenX.slice(57),"hex"))],e=[new Uint8Array(Buffer.from(n.tokenY.slice(0,56),"hex")),new Uint8Array(Buffer.from(n.tokenY.slice(57),"hex"))],r=B.Data.constr(0n,[n.sqrtLowerPriceNum,n.sqrtLowerPriceDen]),o=B.Data.constr(0n,[n.sqrtUpperPriceNum,n.sqrtUpperPriceDen]),i=B.Data.constr(0n,[t,e,BigInt(n.lpFeeRate),n.platformFeeX,n.platformFeeY,n.totalSwapFee,r,o,n.minXChange,n.minYChange,n.circulatingLPToken,BigInt(n.lastWithdrawEpoch)]);return new tt.InlineDatum({data:i})};var X=n=>{let t;if(typeof n=="string")t=B.CBOR.fromCBORHex(n);else{let i=n.data,s=B.Data.toCBORHex(i);t=B.CBOR.fromCBORHex(s)}let e=t._tag==="Tag"?t.value:t;if(!Array.isArray(e))throw new Error("Invalid datum structure: expected array of fields");let r=i=>{let s=i._tag==="Tag"?i.value:i;if(Array.isArray(s)&&s.length===2){let a=s[0]instanceof Uint8Array?s[0]:new Uint8Array(s[0]),f=s[1]instanceof Uint8Array?s[1]:new Uint8Array(s[1]),l=Buffer.from(a).toString("hex"),p=Buffer.from(f).toString("hex");return l===""&&p===""?x:l+"."+p}throw new Error("Invalid AssetClass structure")},o=i=>{let s=i._tag==="Tag"?i.value:i;if(Array.isArray(s)&&s.length===2)return{num:BigInt(s[0]),den:BigInt(s[1])};throw new Error("Invalid Ratio structure")};return{tokenX:r(e[0]),tokenY:r(e[1]),lpFeeRate:Number(e[2]),platformFeeX:BigInt(e[3]),platformFeeY:BigInt(e[4]),totalSwapFee:BigInt(e[5]),sqrtLowerPriceNum:o(e[6]).num,sqrtLowerPriceDen:o(e[6]).den,sqrtUpperPriceNum:o(e[7]).num,sqrtUpperPriceDen:o(e[7]).den,minXChange:BigInt(e[8]),minYChange:BigInt(e[9]),circulatingLPToken:BigInt(e[10]),lastWithdrawEpoch:Number(e[11])}},j=n=>{let t,e=B.Data.toCBORHex(n.data);t=B.CBOR.fromCBORHex(e);let r=t._tag==="Tag"?t.value:t;if(!Array.isArray(r))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:BigInt(r[0]),swapFee:BigInt(r[1])}};var k=require("@evolution-sdk/evolution");function F(n){if(n===x)return{unit:x};let t=n.indexOf("."),e=t===-1?n:n.slice(0,t),r=t===-1?"":n.slice(t+1),o=k.Bytes.fromHex(e),i=new k.PolicyId.PolicyId({hash:o}),s=r?k.Bytes.fromHex(r):new Uint8Array(0),a=new k.AssetName.AssetName({bytes:s});return{policyId:i,assetName:a,unit:n}}var nt=n=>{if(!n||Object.keys(n).length===0)return[];let t=[];for(let[e,r]of Object.entries(n)){if(e==="ada")continue;let o=[];for(let[i,s]of Object.entries(r))o.push({name:i,value:s});t.push({policyId:e,assets:o})}return t};var it=(n,t)=>{let e=J,r=1647899091e3,o=328;return t!==1&&(e=K),Math.floor((n-r)/e)+o};function bt(n,t,e,r,o=0n,i){let s=r<0n?-r:r,a=e.tokenX===x?3000000n+BigInt(e.totalSwapFee):0n,f=BigInt(n)-BigInt(e.platformFeeX)+o-a,l=BigInt(t)-BigInt(e.platformFeeY),p=ht(f,l,[BigInt(e.sqrtLowerPriceNum),BigInt(e.sqrtLowerPriceDen)],[BigInt(e.sqrtUpperPriceNum),BigInt(e.sqrtUpperPriceDen)]),I=rt(p[0]*BigInt(e.sqrtUpperPriceDen),p[1]*BigInt(e.sqrtUpperPriceNum))+f,u=rt(p[0]*BigInt(e.sqrtLowerPriceNum),p[1]*BigInt(e.sqrtLowerPriceDen))+l;return r>0n?ot(s,I,u,l,BigInt(e.lpFeeRate),i):ot(s,u,I,f,BigInt(e.lpFeeRate),i)}var ot=(n,t,e,r,o,i)=>{let s=10000n,f=n*o/s*BigInt(i)/10000n,l=s-o,p=t*s+n*l,I=t*e,d=(e*p-I*s)/p;if(d>r)throw new Error("pool out exceeded");return[d,f]},ht=(n,t,e,r)=>{let o=e[1]*r[1],i=e[0]*r[0],s=(t*o-n*i)*(t*o-n*i),a=4n*n*t*e[1]*e[1]*r[0]*r[0],f=Pt(s+a),l=t*o+n*i+f,p=2n*(r[0]*e[1]-r[1]*e[0]);return[l,p]};function Pt(n){if(n<0n)throw new Error("Square root of negative number");if(n<2n)return n;let t=n,e=t+n/t>>1n;for(;e<t;)t=e,e=t+n/t>>1n;return t}function rt(n,t){if(t===0n)throw new Error("Division by zero");let e=n/t;return n%t===0n||n<0n!=t<0n?e:e+1n}function st(n,t){let r=[...t].sort((o,i)=>o.transactionId===i.transactionId?o.index<i.index?-1:1:o.transactionId<i.transactionId?-1:1).findIndex(o=>o.transactionId===n.transactionId&&o.index===n.index);if(r===-1)throw new Error("Protocol config out ref not found in reference inputs");return BigInt(r)}function V(n,t,e){let r=[];for(let o=0;o<n.length;o++){let i=n[o],s=t[o];if(s===0n)continue;let[a,f]=bt(i.tokenAAmount,i.tokenBAmount,i.datum,s,i.rewardAmount||0n,e);r.push({poolIndex:o,deltaAmount:s,outputAmount:a,platformFee:f})}return r}var Q=class{constructor(){}async calculateSwapOut(t,e){if(!t||!t.address)throw new Error("Please connect a wallet first.");let r=(await t.address()).networkId,o=await Promise.all(e.pools.map(u=>t.getUtxosByOutRef([u.poolOutRef]))),i=H(r),s=e.protocolConfigOutRef??i.protocolScriptOutRef,a=(await t.getUtxosByOutRef([s]))[0];if(!a.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let f=j(a.datumOption),l=await Promise.all(e.pools.map(async(u,d)=>{let A=o[d][0];if(!A.datumOption)throw new Error(`Pool input UTxO ${d} does not contain a datum.`);let y=X(A.datumOption),R=F(y.tokenX),w=F(y.tokenY),O=A.assets.lovelace,g=D=>D.unit===x?O:(0,b.quantityOf)(A.assets,D.policyId,D.assetName),h=null;u.stakingOutRef&&(h=(await t.getUtxosByOutRef([u.stakingOutRef]))[0]);let{rewardAmount:U}=await this.getStakingRewards(t,r,h,R);return{tokenAAmount:g(R),tokenBAmount:g(w),datum:y,rewardAmount:U}})),p=e.pools.map(u=>u.deltaAmount);return V(l,p,f.platformFeeRate).map(u=>u.outputAmount)}async submitSwap(t,e){if(!t||!t.address)throw new Error("Please connect a wallet first.");let r=(await t.address()).networkId,o=await Promise.all(e.pools.map(async c=>(await t.getUtxosByOutRef([c.poolOutRef]))[0])),i=H(r),s=i.poolScriptOutRef,a=e.protocolConfigOutRef??i.protocolScriptOutRef,f=(await t.getUtxosByOutRef([s]))[0],l=(await t.getUtxosByOutRef([a]))[0];if(!l.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let p=j(l.datumOption),I=[],u=[];for(let c=0;c<e.pools.length;c++){let m=e.pools[c],P=o[c];if(!P.datumOption)throw new Error(`Pool input UTxO ${c} does not contain a datum.`);let T=X(P.datumOption),E=F(T.tokenX),S=F(T.tokenY),$=P.assets.lovelace,_=W=>W.unit===x?$:(0,b.quantityOf)(P.assets,W.policyId,W.assetName),N=null;m.stakingOutRef&&(N=(await t.getUtxosByOutRef([m.stakingOutRef]))[0]),u.push(N);let{rewardAmount:ct}=await this.getStakingRewards(t,r,N,E);I.push({tokenAAmount:_(E),tokenBAmount:_(S),datum:T,rewardAmount:ct,utxo:P,tokenA:E,tokenB:S})}let d=e.pools.map(c=>c.deltaAmount),A=V(I,d,p.platformFeeRate);A.forEach((c,m)=>{let P=e.pools[m].minOutChangeAmount;if(c.outputAmount<P)throw new Error(`Expected swap output at least ${P} but got ${c.outputAmount}`)});let y=A.reduce((c,m)=>c+m.deltaAmount,0n),R=e.pools.find(c=>c.deltaAmount!==0n);if(!R)throw new Error("At least one pool must have a non-zero delta amount");let w=R.deltaAmount>0?I[0].tokenA:I[0].tokenB,O=await this.getUserTokenBalance(t,w);if(O<y)throw new Error(`Insufficient ${w.unit} balance. Required: ${y}, Available: ${O}`);let g=t.newTx(),h=[l];h.push(f),u.forEach(c=>{c&&h.push(c)}),g=g.readFrom({referenceInputs:h});let U=it(Date.now(),r),D=st(l,h);g=g.withdraw({stakeCredential:(0,Y.fromScript)(f.scriptRef),amount:0n,redeemer:v(null,o,d,D)});for(let c=0;c<I.length;c++){let m=I[c],P=A.find(N=>N.poolIndex===c);if(!P)continue;let T=P.deltaAmount,E=P.platformFee,S=et({...m.datum,platformFeeX:BigInt(m.datum.platformFeeX)+(T>0?E:0n),platformFeeY:BigInt(m.datum.platformFeeY)+(T<0?E:0n),lastWithdrawEpoch:U,totalSwapFee:BigInt(m.datum.totalSwapFee)+BigInt(p.swapFee)}),$=this.buildDeltaAssets(T>0?m.tokenA:m.tokenB,T>0?m.tokenB:m.tokenA,T,BigInt(P.outputAmount),BigInt(p.swapFee)),_=(0,b.merge)(m.utxo.assets,$);if(g=g.payToAddress({address:m.utxo.address,assets:_,datum:S}),g=g.collectFrom({inputs:[m.utxo],redeemer:v(m.utxo,o,d,D)}),m.tokenA.unit===x&&U>m.datum.lastWithdrawEpoch&&u[c]){let{stakingRewardAddress:N}=await this.getStakingRewards(t,r,u[c],m.tokenA);N&&(g=g.withdraw({stakeCredential:(0,Y.fromScript)(u[c].scriptRef),amount:m.rewardAmount||0n,redeemer:v(m.utxo,o,d,D)}))}}return g=g.attachMetadata({label:674n,metadata:new Map([["msg",["Danogo Multi-Pool Swap"]]])}),g.setValidity({from:BigInt(Date.now()-12e4),to:BigInt(Date.now()+24e4)}),(await(await(await g.build({scriptDataFormat:"array"})).sign()).submit()).toString()}getPoolsFromOgmiosTx(t,e,r){let o=H(e),i=r??o.poolScriptHash;if(!i)throw new Error("Pool script hash is required but not provided or not found for this network.");let s=[];return t.outputs.forEach((a,f)=>{let l=a.value,p=l[i];if(p&&a.datum){for(let[I,u]of Object.entries(p))if(u===1n){let d=r+I,A=`${t.id}#${f}`,y=l.ada.lovelace,R=nt(l),w=X(a.datum),O=w.tokenX,g=w.tokenY,h=U=>{if(U===x)return y;let D=U.slice(0,56),Z=U.slice(56),M=R.find(c=>c.policyId===D)?.assets.find(c=>c.name===Z);return M?M.value:0n};s.push({outRef:A,address:a.address,coin:y,multiAssets:R,validityNft:d,tokenA:O,tokenAReserve:h(O),tokenB:g,tokenBReserve:h(g),lpFeeRate:w.lpFeeRate,priceLowerNum:w.sqrtLowerPriceNum,priceLowerDen:w.sqrtLowerPriceDen,priceUpperNum:w.sqrtUpperPriceNum,priceUpperDen:w.sqrtUpperPriceDen,platformFeeA:w.platformFeeX,platformFeeB:w.platformFeeY,minAChange:w.minXChange,minBChange:w.minYChange,lpTokenTotalSupply:w.circulatingLPToken,lastWithdrawEpoch:w.lastWithdrawEpoch,totalSwapFee:w.totalSwapFee})}}}),s}async getUserTokenBalance(t,e){return(await t.getWalletUtxos()).reduce((o,i)=>o+(e.unit===x?i.assets.lovelace:(0,b.quantityOf)(i.assets,e.policyId,e.assetName)||0n),0n)}buildDeltaAssets(t,e,r,o,i){let s=r>0n?r:-r,a;if(t.unit===x?a=(0,b.fromLovelace)(s+i):a=(0,b.fromAsset)(t.policyId,t.assetName,s,i),e.unit===x)a=(0,b.subtractLovelace)(a,o);else{let f=(0,b.fromAsset)(e.policyId,e.assetName,-o);a=(0,b.merge)(a,f)}return a}async getStakingRewards(t,e,r,o){if(o.unit!==x)return{rewardAmount:0n};let i=new z.RewardAccount.RewardAccount({networkId:e,stakeCredential:(0,Y.fromScript)(r.scriptRef)}),s=z.RewardAccount.toBech32(i);return{rewardAmount:(await t.getDelegation(s)).rewards,stakingRewardAddress:s}}},Rt=Q;
package/dist/sdk.mjs CHANGED
@@ -1 +1 @@
1
- import{validatorToRewardAddress as U}from"@lucid-evolution/lucid";function D(n,e){let o=(n>=0n?n:n+(1n<<256n)).toString(16);o.length%2&&(o="0"+o);let r=o.length/2;if(r>e)throw new Error(`Number ${n} requires ${r} bytes, but target length is ${e}.`);let i=new Uint8Array(e),s=e-r;for(let g=0;g<r;g++)i[g+s]=parseInt(o.slice(g*2,g*2+2),16);return i}var k=(n,e,t,o)=>{try{return{kind:"selected",inputs:n,makeRedeemer:i=>{let s=3n,g=D(o?t:i[0],1),c=D(i[0],1),p=D(s,1),f=D(0n,1),w=D(e[0],32),m=g.length+p.length+c.length+f.length+w.length,l=new Uint8Array(m),a=0;return l.set(g,a),a+=g.length,l.set(p,a),a+=p.length,l.set(c,a),a+=c.length,l.set(f,a),a+=f.length,l.set(w,a),"5824"+Buffer.from(l).toString("hex")}}}catch(r){throw console.error("Error creating pool redeemer:",r),r}};import{Data as d}from"@lucid-evolution/lucid";import{Data as V}from"@lucid-evolution/lucid";function H(n,e,t){return V.to(n,e,t)}import*as x from"cbor";var Y=n=>{let e=d.Tuple([d.Bytes(),d.Bytes()]),t=d.Tuple([d.Integer(),d.Integer()],{hasConstr:!0}),o=d.Tuple([e,e,d.Integer(),d.Integer(),d.Integer(),d.Integer(),t,t,d.Integer(),d.Integer(),d.Integer(),d.Integer()],{hasConstr:!0}),r=X(n.tokenX),i=X(n.tokenY),s=[r,i,BigInt(n.lpFeeRate),BigInt(n.platformFeeX),BigInt(n.platformFeeY),BigInt(n.totalSwapFee),[BigInt(n.sqrtLowerPriceNum),BigInt(n.sqrtLowerPriceDen)],[BigInt(n.sqrtUpperPriceNum),BigInt(n.sqrtUpperPriceDen)],BigInt(n.minXChange),BigInt(n.minYChange),BigInt(n.circulatingLPToken),BigInt(n.lastWithdrawEpoch)];return H(s,o)};var X=n=>{if(!n)return["",""];try{if(n.includes(".")){let o=n.split(".");return o.length===2?[o[0],o[1]]:[n,""]}let e=n.slice(0,56),t=n.slice(56);return[e,t]}catch(e){throw console.error(`Error parsing token ID "${n}":`,e),new Error(`Failed to parse token ID: ${n}`)}},S=n=>{let e=x.decodeFirstSync(Buffer.from(n,"hex")),t=e instanceof x.Tagged?e.value:e;if(!Array.isArray(t))throw new Error("Invalid datum structure: expected array of fields");let o=i=>{let s=i instanceof x.Tagged?i.value:i;if(Array.isArray(s)&&s.length===2){let g=s[0].toString("hex"),c=s[1].toString("hex");return g+c}throw new Error("Invalid AssetClass structure")},r=i=>{let s=i instanceof x.Tagged?i.value:i;if(Array.isArray(s)&&s.length===2)return{num:s[0],den:s[1]};throw new Error("Invalid Ratio structure")};return{tokenX:o(t[0]),tokenY:o(t[1]),lpFeeRate:Number(t[2]),platformFeeX:t[3].toString(),platformFeeY:t[4].toString(),totalSwapFee:t[5].toString(),sqrtLowerPriceNum:r(t[6]).num,sqrtLowerPriceDen:r(t[6]).den,sqrtUpperPriceNum:r(t[7]).num,sqrtUpperPriceDen:r(t[7]).den,minXChange:t[8].toString(),minYChange:t[9].toString(),circulatingLPToken:t[10].toString(),lastWithdrawEpoch:Number(t[11])}},C=n=>{let e=x.decodeFirstSync(Buffer.from(n,"hex")),t=e instanceof x.Tagged?e.value:e;if(!Array.isArray(t))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:t[0].toString(),swapFee:t[1].toString()}};var M=n=>{if(!n||Object.keys(n).length===0)return[];let e=[];for(let[t,o]of Object.entries(n)){if(t==="ada")continue;let r=[];for(let[i,s]of Object.entries(o))r.push({name:i,value:s});e.push({policyId:t,assets:r})}return e};var j=(n,e)=>{let t=432e6,o=1647899091e3,r=328;return e!=="Mainnet"&&(t=18e5),Math.floor((n-o)/t)+r};function E(n,e,t,o,r=0n,i){let s=o<0n?-o:o,g=t.tokenX===""?3000000n+BigInt(t.totalSwapFee):0n,c=BigInt(n)-BigInt(t.platformFeeX)+r-g,p=BigInt(e)-BigInt(t.platformFeeY),f=z(c,p,[BigInt(t.sqrtLowerPriceNum),BigInt(t.sqrtLowerPriceDen)],[BigInt(t.sqrtUpperPriceNum),BigInt(t.sqrtUpperPriceDen)]),w=W(f[0]*BigInt(t.sqrtUpperPriceDen),f[1]*BigInt(t.sqrtUpperPriceNum))+c,m=W(f[0]*BigInt(t.sqrtLowerPriceNum),f[1]*BigInt(t.sqrtLowerPriceDen))+p;return o>0n?$(s,w,m,p,BigInt(t.lpFeeRate),i):$(s,m,w,c,BigInt(t.lpFeeRate),i)}var $=(n,e,t,o,r,i)=>{let s=10000n,c=n*r/s*BigInt(i)/10000n,p=s-r,f=e*s+n*p,w=e*t,l=(t*f-w*s)/f;if(l>o)throw new Error("pool out exceeded");return[l,c]},z=(n,e,t,o)=>{let r=t[1]*o[1],i=t[0]*o[0],s=(e*r-n*i)*(e*r-n*i),g=4n*n*e*t[1]*t[1]*o[0]*o[0],c=J(s+g),p=e*r+n*i+c,f=2n*(o[0]*t[1]-o[1]*t[0]);return[p,f]};function J(n){if(n<0n)throw new Error("Square root of negative number");if(n<2n)return n;let e=n,t=e+n/e>>1n;for(;t<e;)e=t,t=e+n/e>>1n;return e}function W(n,e){if(e===0n)throw new Error("Division by zero");let t=n/e;return n%e===0n||n<0n!=e<0n?t:t+1n}function _(n,e){let o=[...e].sort((r,i)=>r.txHash===i.txHash?r.outputIndex-i.outputIndex:r.txHash<i.txHash?-1:1).findIndex(r=>r.txHash===n.txHash&&r.outputIndex===n.outputIndex);if(o===-1)throw new Error("Protocol config out ref not found in reference inputs");return BigInt(o)}var N=class{constructor(){}async calculateSwapOut(e,t){if(!e||!e.wallet())throw new Error("Please connect a wallet first.");let o=(await e.utxosByOutRef([{txHash:t.poolOutRef.txHash,outputIndex:t.poolOutRef.outputIndex}]))[0],r=null;if(t.stakingOutRef&&(r=(await e.utxosByOutRef([{txHash:t.stakingOutRef.txHash,outputIndex:t.stakingOutRef.outputIndex}]))[0]),!o.datum)throw new Error("Pool input UTxO does not contain a datum.");let i=(await e.utxosByOutRef([{txHash:t.protocolConfigOutRef.txHash,outputIndex:t.protocolConfigOutRef.outputIndex}]))[0];if(!i.datum)throw new Error("Protocol config UTxO does not contain a datum.");let s=C(i.datum),g=S(o.datum),c=g.tokenX||"lovelace",p=g.tokenY,f=o.assets.lovelace,w=u=>{if(u==="lovelace")return f;for(let[A,h]of Object.entries(o.assets))if(A===u)return h;return 0n},m=0n,l="";if(c=="lovelace"){l=U(e.config().network,r.scriptRef);try{m=(await e.delegationAt(l)).rewards}catch{m=0n}}let[a,b]=E(w(c),w(p),g,t.deltaAmount,m,s.platformFeeRate);return a}async submitSwap(e,t){if(!e||!e.wallet())throw new Error("Please connect a wallet first.");let o=(await e.utxosByOutRef([{txHash:t.poolOutRef.txHash,outputIndex:t.poolOutRef.outputIndex}]))[0],r=(await e.utxosByOutRef([{txHash:t.poolScriptOutRef.txHash,outputIndex:t.poolScriptOutRef.outputIndex}]))[0],i=null;if(t.stakingOutRef&&(i=(await e.utxosByOutRef([{txHash:t.stakingOutRef.txHash,outputIndex:t.stakingOutRef.outputIndex}]))[0]),!o.datum)throw new Error("Pool input UTxO does not contain a datum.");let s=(await e.utxosByOutRef([{txHash:t.protocolConfigOutRef.txHash,outputIndex:t.protocolConfigOutRef.outputIndex}]))[0];if(!s.datum)throw new Error("Protocol config UTxO does not contain a datum.");let g=C(s.datum),c=S(o.datum),p=c.tokenX||"lovelace",f=c.tokenY,w=o.assets.lovelace,m=R=>{if(R==="lovelace")return w;for(let[O,Q]of Object.entries(o.assets))if(O===R)return Q;return 0n},l=t.deltaAmount,a=l>0?p:f,b=l>0?f:p,u=e.newTx(),h=(await e.wallet().getUtxos()).reduce((R,O)=>R+(O.assets[a]||0n),0n),F=l<0n?-l:l;if(h<F)throw new Error(`Insufficient ${a} balance. Required: ${F}, Available: ${h}`);u=u.readFrom([r,s]),i&&(u=u.readFrom([i]));let B=0n,T="";if(p=="lovelace"){T=U(e.config().network,i.scriptRef);try{B=(await e.delegationAt(T)).rewards}catch{B=0n}}let[P,y]=E(m(p),m(f),c,l,B,g.platformFeeRate);if(P<t.minOutChangeAmount)throw new Error(`Slippage too high. Expected at least ${t.minOutChangeAmount} but got ${P}`);let L=j(Date.now(),e.config().network),G=Y({...c,platformFeeX:BigInt(c.platformFeeX)+(a===(c.tokenX||"lovelace")?y:0n),platformFeeY:BigInt(c.platformFeeY)+(a===c.tokenY?y:0n),lastWithdrawEpoch:L,totalSwapFee:BigInt(c.totalSwapFee)+BigInt(g.swapFee)}),I={...o.assets};I[a]=I[a]+(l>0n?l:-l),I[b]=BigInt(I[b])-BigInt(P),I.lovelace=BigInt(I.lovelace)+BigInt(g.swapFee),u=u.pay.ToAddressWithData(o.address,{kind:"inline",value:G},I),u=u.attachMetadata(674,{msg:["Danogo Liquidity Pair: Swap"]});let q=[r,s];i&&q.push(i);let v=_(s,q);return u=u.collectFrom([o],k([o],[l],v,!1)),u=u.withdraw(U(e.config().network,r.scriptRef),0n,k([o],[l],v,!0)),p==="lovelace"&&L>c.lastWithdrawEpoch&&(u=u.withdraw(T,B,k([o],[l],v,!1))),u=u.validFrom(Date.now()-12e4).validTo(Date.now()+24e4).setMinFee(17000n).addSigner(await e.wallet().address()),await(await(await u.complete({localUPLCEval:!1})).sign.withWallet().complete()).submit()}getPoolsFromOgmiosTx(e,t){let o=[];return e.outputs.forEach((r,i)=>{let s=r.value,g=s[t];if(g&&r.datum){for(let[c,p]of Object.entries(g))if(p===1n){let f=t+c,w=`${e.id}#${i}`,m=s.ada.lovelace,l=M(s),a=S(r.datum),b=a.tokenX,u=a.tokenY,A=h=>{if(h==="lovelace"||h==="")return m;let F=h.slice(0,56),B=h.slice(56),P=l.find(y=>y.policyId===F)?.assets.find(y=>y.name===B);return P?P.value:0n};o.push({outRef:w,address:r.address,coin:m,multiAssets:l,validityNft:f,tokenA:b,tokenAReserve:A(b),tokenB:u,tokenBReserve:A(u),lpFeeRate:a.lpFeeRate,priceLowerNum:a.sqrtLowerPriceNum,priceLowerDen:a.sqrtLowerPriceDen,priceUpperNum:a.sqrtUpperPriceNum,priceUpperDen:a.sqrtUpperPriceDen,platformFeeA:a.platformFeeX,platformFeeB:a.platformFeeY,minAChange:a.minXChange,minBChange:a.minYChange,lpTokenTotalSupply:a.circulatingLPToken,lastWithdrawEpoch:a.lastWithdrawEpoch,totalSwapFee:a.totalSwapFee})}}}),o}},ht=N;export{ht as default};
1
+ import{RewardAccount as rt}from"@evolution-sdk/evolution";import{fromScript as W}from"@evolution-sdk/evolution/ScriptHash";import{fromAsset as it,merge as st,quantityOf as G,fromLovelace as Pt,subtractLovelace as Rt}from"@evolution-sdk/evolution/Assets";function N(n,e){let o=(n>=0n?n:n+(1n<<256n)).toString(16);o.length%2&&(o="0"+o);let r=o.length/2;if(r>e)throw new Error(`Number ${n} requires ${r} bytes, but target length is ${e}.`);let i=new Uint8Array(e),s=e-r;for(let a=0;a<r;a++)i[a+s]=parseInt(o.slice(a*2,a*2+2),16);return i}var S=(n,e,t,o)=>{try{let r=(i,s)=>{let a=3n,f=N(n?i:o,1),l=N(a,1),p=e.map((A,y)=>{let P=s.find(b=>b.utxo.transactionId===A.transactionId&&b.utxo.index===A.index);if(!P)throw new Error(`Pool UTxO at ${y} not found in indexedInputs`);if(t[y]===void 0)throw new Error(`deltaAmount for poolOutIdx ${y} is undefined`);let w=N(BigInt(P.index),1),R=N(BigInt(y),1),g=N(t[y],32);return{poolInBytes:w,poolOutBytes:R,amountBytes:g}}),I=2+34*p.length,u=new Uint8Array(I),d=0;u.set(f,d),d+=f.length,u.set(l,d),d+=l.length;for(let A of p)u.set(A.poolInBytes,d),d+=A.poolInBytes.length,u.set(A.poolOutBytes,d),d+=A.poolOutBytes.length,u.set(A.amountBytes,d),d+=A.amountBytes.length;return u};return{all:i=>{if(!i.length)throw new Error("swapTokensRedeemer batch all called with empty indexedInputs");let s=null;if(n&&(s=i.find(a=>a.utxo.transactionId===n.transactionId&&a.utxo.index===n.index),!s))throw new Error("Target pool UTxO is not found in poolInUTxOs");return r(s?.index,i)},inputs:e}}catch(r){throw console.error("Error creating pool redeemer:",r),r}};import{Data as k,CBOR as Y}from"@evolution-sdk/evolution";import{InlineDatum as At}from"@evolution-sdk/evolution/InlineDatum";import{TransactionHash as ut,TransactionInput as lt}from"@evolution-sdk/evolution";var x="lovelace",z=432e6,pt="64d111b957e7d7848ffdde5149aa77fa4090a7fa1ad0ac108067900614848501#0",mt="d8b69fc53637bcfadbc4469083f706bc293f4d9d2296646c5ca167bb",ft="2cafd7c92f7093e5229af274be83dea660b0590b4174bbed79ba662b44fbd1ee#0",Q=18e5,dt="2e19cca74e3badcab26aef7574aa1885ba97228a254ca227ba2f79f2b75fd136#0",gt="04041c3c6ba87b33f2c9eb7f7dbeae3b26003c3e199d438bb99932a2",wt="3775af36f485f9c97101ee5b9b360c34f0f8e12186bc9060f358b7fc8ce468a4#0",v=n=>n===1?{poolScriptOutRef:_(pt),poolScriptHash:mt,protocolScriptOutRef:_(ft)}:{poolScriptOutRef:_(dt),poolScriptHash:gt,protocolScriptOutRef:_(wt)},_=n=>{if(!n)return;let[e,t]=n.split("#");return new lt.TransactionInput({transactionId:ut.fromHex(e),index:BigInt(t)})};var Z=n=>{let e=[new Uint8Array(Buffer.from(n.tokenX.slice(0,56),"hex")),new Uint8Array(Buffer.from(n.tokenX.slice(57),"hex"))],t=[new Uint8Array(Buffer.from(n.tokenY.slice(0,56),"hex")),new Uint8Array(Buffer.from(n.tokenY.slice(57),"hex"))],o=k.constr(0n,[n.sqrtLowerPriceNum,n.sqrtLowerPriceDen]),r=k.constr(0n,[n.sqrtUpperPriceNum,n.sqrtUpperPriceDen]),i=k.constr(0n,[e,t,BigInt(n.lpFeeRate),n.platformFeeX,n.platformFeeY,n.totalSwapFee,o,r,n.minXChange,n.minYChange,n.circulatingLPToken,BigInt(n.lastWithdrawEpoch)]);return new At({data:i})};var q=n=>{let e;if(typeof n=="string")e=Y.fromCBORHex(n);else{let i=n.data,s=k.toCBORHex(i);e=Y.fromCBORHex(s)}let t=e._tag==="Tag"?e.value:e;if(!Array.isArray(t))throw new Error("Invalid datum structure: expected array of fields");let o=i=>{let s=i._tag==="Tag"?i.value:i;if(Array.isArray(s)&&s.length===2){let a=s[0]instanceof Uint8Array?s[0]:new Uint8Array(s[0]),f=s[1]instanceof Uint8Array?s[1]:new Uint8Array(s[1]),l=Buffer.from(a).toString("hex"),p=Buffer.from(f).toString("hex");return l===""&&p===""?x:l+"."+p}throw new Error("Invalid AssetClass structure")},r=i=>{let s=i._tag==="Tag"?i.value:i;if(Array.isArray(s)&&s.length===2)return{num:BigInt(s[0]),den:BigInt(s[1])};throw new Error("Invalid Ratio structure")};return{tokenX:o(t[0]),tokenY:o(t[1]),lpFeeRate:Number(t[2]),platformFeeX:BigInt(t[3]),platformFeeY:BigInt(t[4]),totalSwapFee:BigInt(t[5]),sqrtLowerPriceNum:r(t[6]).num,sqrtLowerPriceDen:r(t[6]).den,sqrtUpperPriceNum:r(t[7]).num,sqrtUpperPriceDen:r(t[7]).den,minXChange:BigInt(t[8]),minYChange:BigInt(t[9]),circulatingLPToken:BigInt(t[10]),lastWithdrawEpoch:Number(t[11])}},M=n=>{let e,t=k.toCBORHex(n.data);e=Y.fromCBORHex(t);let o=e._tag==="Tag"?e.value:e;if(!Array.isArray(o))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:BigInt(o[0]),swapFee:BigInt(o[1])}};import{AssetName as It,Bytes as J,PolicyId as xt}from"@evolution-sdk/evolution";function E(n){if(n===x)return{unit:x};let e=n.indexOf("."),t=e===-1?n:n.slice(0,e),o=e===-1?"":n.slice(e+1),r=J.fromHex(t),i=new xt.PolicyId({hash:r}),s=o?J.fromHex(o):new Uint8Array(0),a=new It.AssetName({bytes:s});return{policyId:i,assetName:a,unit:n}}var K=n=>{if(!n||Object.keys(n).length===0)return[];let e=[];for(let[t,o]of Object.entries(n)){if(t==="ada")continue;let r=[];for(let[i,s]of Object.entries(o))r.push({name:i,value:s});e.push({policyId:t,assets:r})}return e};var nt=(n,e)=>{let t=z,o=1647899091e3,r=328;return e!==1&&(t=Q),Math.floor((n-o)/t)+r};function yt(n,e,t,o,r=0n,i){let s=o<0n?-o:o,a=t.tokenX===x?3000000n+BigInt(t.totalSwapFee):0n,f=BigInt(n)-BigInt(t.platformFeeX)+r-a,l=BigInt(e)-BigInt(t.platformFeeY),p=bt(f,l,[BigInt(t.sqrtLowerPriceNum),BigInt(t.sqrtLowerPriceDen)],[BigInt(t.sqrtUpperPriceNum),BigInt(t.sqrtUpperPriceDen)]),I=et(p[0]*BigInt(t.sqrtUpperPriceDen),p[1]*BigInt(t.sqrtUpperPriceNum))+f,u=et(p[0]*BigInt(t.sqrtLowerPriceNum),p[1]*BigInt(t.sqrtLowerPriceDen))+l;return o>0n?tt(s,I,u,l,BigInt(t.lpFeeRate),i):tt(s,u,I,f,BigInt(t.lpFeeRate),i)}var tt=(n,e,t,o,r,i)=>{let s=10000n,f=n*r/s*BigInt(i)/10000n,l=s-r,p=e*s+n*l,I=e*t,d=(t*p-I*s)/p;if(d>o)throw new Error("pool out exceeded");return[d,f]},bt=(n,e,t,o)=>{let r=t[1]*o[1],i=t[0]*o[0],s=(e*r-n*i)*(e*r-n*i),a=4n*n*e*t[1]*t[1]*o[0]*o[0],f=ht(s+a),l=e*r+n*i+f,p=2n*(o[0]*t[1]-o[1]*t[0]);return[l,p]};function ht(n){if(n<0n)throw new Error("Square root of negative number");if(n<2n)return n;let e=n,t=e+n/e>>1n;for(;t<e;)e=t,t=e+n/e>>1n;return e}function et(n,e){if(e===0n)throw new Error("Division by zero");let t=n/e;return n%e===0n||n<0n!=e<0n?t:t+1n}function ot(n,e){let o=[...e].sort((r,i)=>r.transactionId===i.transactionId?r.index<i.index?-1:1:r.transactionId<i.transactionId?-1:1).findIndex(r=>r.transactionId===n.transactionId&&r.index===n.index);if(o===-1)throw new Error("Protocol config out ref not found in reference inputs");return BigInt(o)}function $(n,e,t){let o=[];for(let r=0;r<n.length;r++){let i=n[r],s=e[r];if(s===0n)continue;let[a,f]=yt(i.tokenAAmount,i.tokenBAmount,i.datum,s,i.rewardAmount||0n,t);o.push({poolIndex:r,deltaAmount:s,outputAmount:a,platformFee:f})}return o}var j=class{constructor(){}async calculateSwapOut(e,t){if(!e||!e.address)throw new Error("Please connect a wallet first.");let o=(await e.address()).networkId,r=await Promise.all(t.pools.map(u=>e.getUtxosByOutRef([u.poolOutRef]))),i=v(o),s=t.protocolConfigOutRef??i.protocolScriptOutRef,a=(await e.getUtxosByOutRef([s]))[0];if(!a.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let f=M(a.datumOption),l=await Promise.all(t.pools.map(async(u,d)=>{let A=r[d][0];if(!A.datumOption)throw new Error(`Pool input UTxO ${d} does not contain a datum.`);let y=q(A.datumOption),P=E(y.tokenX),w=E(y.tokenY),R=A.assets.lovelace,g=B=>B.unit===x?R:G(A.assets,B.policyId,B.assetName),b=null;u.stakingOutRef&&(b=(await e.getUtxosByOutRef([u.stakingOutRef]))[0]);let{rewardAmount:D}=await this.getStakingRewards(e,o,b,P);return{tokenAAmount:g(P),tokenBAmount:g(w),datum:y,rewardAmount:D}})),p=t.pools.map(u=>u.deltaAmount);return $(l,p,f.platformFeeRate).map(u=>u.outputAmount)}async submitSwap(e,t){if(!e||!e.address)throw new Error("Please connect a wallet first.");let o=(await e.address()).networkId,r=await Promise.all(t.pools.map(async c=>(await e.getUtxosByOutRef([c.poolOutRef]))[0])),i=v(o),s=i.poolScriptOutRef,a=t.protocolConfigOutRef??i.protocolScriptOutRef,f=(await e.getUtxosByOutRef([s]))[0],l=(await e.getUtxosByOutRef([a]))[0];if(!l.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let p=M(l.datumOption),I=[],u=[];for(let c=0;c<t.pools.length;c++){let m=t.pools[c],h=r[c];if(!h.datumOption)throw new Error(`Pool input UTxO ${c} does not contain a datum.`);let O=q(h.datumOption),U=E(O.tokenX),C=E(O.tokenY),H=h.assets.lovelace,F=X=>X.unit===x?H:G(h.assets,X.policyId,X.assetName),T=null;m.stakingOutRef&&(T=(await e.getUtxosByOutRef([m.stakingOutRef]))[0]),u.push(T);let{rewardAmount:ct}=await this.getStakingRewards(e,o,T,U);I.push({tokenAAmount:F(U),tokenBAmount:F(C),datum:O,rewardAmount:ct,utxo:h,tokenA:U,tokenB:C})}let d=t.pools.map(c=>c.deltaAmount),A=$(I,d,p.platformFeeRate);A.forEach((c,m)=>{let h=t.pools[m].minOutChangeAmount;if(c.outputAmount<h)throw new Error(`Expected swap output at least ${h} but got ${c.outputAmount}`)});let y=A.reduce((c,m)=>c+m.deltaAmount,0n),P=t.pools.find(c=>c.deltaAmount!==0n);if(!P)throw new Error("At least one pool must have a non-zero delta amount");let w=P.deltaAmount>0?I[0].tokenA:I[0].tokenB,R=await this.getUserTokenBalance(e,w);if(R<y)throw new Error(`Insufficient ${w.unit} balance. Required: ${y}, Available: ${R}`);let g=e.newTx(),b=[l];b.push(f),u.forEach(c=>{c&&b.push(c)}),g=g.readFrom({referenceInputs:b});let D=nt(Date.now(),o),B=ot(l,b);g=g.withdraw({stakeCredential:W(f.scriptRef),amount:0n,redeemer:S(null,r,d,B)});for(let c=0;c<I.length;c++){let m=I[c],h=A.find(T=>T.poolIndex===c);if(!h)continue;let O=h.deltaAmount,U=h.platformFee,C=Z({...m.datum,platformFeeX:BigInt(m.datum.platformFeeX)+(O>0?U:0n),platformFeeY:BigInt(m.datum.platformFeeY)+(O<0?U:0n),lastWithdrawEpoch:D,totalSwapFee:BigInt(m.datum.totalSwapFee)+BigInt(p.swapFee)}),H=this.buildDeltaAssets(O>0?m.tokenA:m.tokenB,O>0?m.tokenB:m.tokenA,O,BigInt(h.outputAmount),BigInt(p.swapFee)),F=st(m.utxo.assets,H);if(g=g.payToAddress({address:m.utxo.address,assets:F,datum:C}),g=g.collectFrom({inputs:[m.utxo],redeemer:S(m.utxo,r,d,B)}),m.tokenA.unit===x&&D>m.datum.lastWithdrawEpoch&&u[c]){let{stakingRewardAddress:T}=await this.getStakingRewards(e,o,u[c],m.tokenA);T&&(g=g.withdraw({stakeCredential:W(u[c].scriptRef),amount:m.rewardAmount||0n,redeemer:S(m.utxo,r,d,B)}))}}return g=g.attachMetadata({label:674n,metadata:new Map([["msg",["Danogo Multi-Pool Swap"]]])}),g.setValidity({from:BigInt(Date.now()-12e4),to:BigInt(Date.now()+24e4)}),(await(await(await g.build({scriptDataFormat:"array"})).sign()).submit()).toString()}getPoolsFromOgmiosTx(e,t,o){let r=v(t),i=o??r.poolScriptHash;if(!i)throw new Error("Pool script hash is required but not provided or not found for this network.");let s=[];return e.outputs.forEach((a,f)=>{let l=a.value,p=l[i];if(p&&a.datum){for(let[I,u]of Object.entries(p))if(u===1n){let d=o+I,A=`${e.id}#${f}`,y=l.ada.lovelace,P=K(l),w=q(a.datum),R=w.tokenX,g=w.tokenY,b=D=>{if(D===x)return y;let B=D.slice(0,56),V=D.slice(56),L=P.find(c=>c.policyId===B)?.assets.find(c=>c.name===V);return L?L.value:0n};s.push({outRef:A,address:a.address,coin:y,multiAssets:P,validityNft:d,tokenA:R,tokenAReserve:b(R),tokenB:g,tokenBReserve:b(g),lpFeeRate:w.lpFeeRate,priceLowerNum:w.sqrtLowerPriceNum,priceLowerDen:w.sqrtLowerPriceDen,priceUpperNum:w.sqrtUpperPriceNum,priceUpperDen:w.sqrtUpperPriceDen,platformFeeA:w.platformFeeX,platformFeeB:w.platformFeeY,minAChange:w.minXChange,minBChange:w.minYChange,lpTokenTotalSupply:w.circulatingLPToken,lastWithdrawEpoch:w.lastWithdrawEpoch,totalSwapFee:w.totalSwapFee})}}}),s}async getUserTokenBalance(e,t){return(await e.getWalletUtxos()).reduce((r,i)=>r+(t.unit===x?i.assets.lovelace:G(i.assets,t.policyId,t.assetName)||0n),0n)}buildDeltaAssets(e,t,o,r,i){let s=o>0n?o:-o,a;if(e.unit===x?a=Pt(s+i):a=it(e.policyId,e.assetName,s,i),t.unit===x)a=Rt(a,r);else{let f=it(t.policyId,t.assetName,-r);a=st(a,f)}return a}async getStakingRewards(e,t,o,r){if(r.unit!==x)return{rewardAmount:0n};let i=new rt.RewardAccount({networkId:t,stakeCredential:W(o.scriptRef)}),s=rt.toBech32(i);return{rewardAmount:(await e.getDelegation(s)).rewards,stakingRewardAddress:s}}},Qt=j;export{Qt as default};
package/package.json CHANGED
@@ -1,22 +1,31 @@
1
1
  {
2
2
  "name": "danogo-clmm",
3
- "version": "0.0.15",
3
+ "version": "0.1.2",
4
4
  "description": "An SDK to calculate and execute swaps on the Danogo liquidity platform.",
5
5
  "main": "./dist/sdk.js",
6
6
  "module": "./dist/sdk.mjs",
7
7
  "types": "./dist/sdk.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/sdk.mjs",
11
+ "require": "./dist/sdk.js"
12
+ }
13
+ },
8
14
  "files": [
9
15
  "dist",
10
16
  "README.md"
11
17
  ],
12
18
  "keywords": [
13
19
  "cardano",
14
- "danogo",
20
+ "dano-finance",
15
21
  "swap",
16
22
  "clmm"
17
23
  ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/dano-finance/clmm-sdk"
27
+ },
18
28
  "scripts": {
19
- "start": "tsc && node dist/main.js",
20
29
  "build": "tsup src/sdk.ts --format cjs,esm --dts --minify --clean --no-splitting",
21
30
  "prepublishOnly": "npm run build"
22
31
  },
@@ -24,16 +33,12 @@
24
33
  "access": "public"
25
34
  },
26
35
  "dependencies": {
27
- "@lucid-evolution/lucid": "0.4.29",
28
- "axios": "^1.13.2",
29
- "cbor": "^10.0.11"
36
+ "@cardano-ogmios/client": "^6.14.0",
37
+ "@cardano-ogmios/schema": "^6.14.0",
38
+ "@evolution-sdk/evolution": "^0.3.31"
30
39
  },
31
40
  "devDependencies": {
32
41
  "tsup": "^8.0.0",
33
- "ts-node": "^10.9.2",
34
42
  "typescript": "^5.9.2"
35
- },
36
- "peerDependencies": {
37
- "@lucid-evolution/lucid": "0.4.29"
38
43
  }
39
- }
44
+ }