danogo-clmm 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Danogo Swap SDK
1
+ # Danogo CLMM SDK
2
2
 
3
3
  An SDK to calculate and execute swaps on the Danogo liquidity platform on the Cardano network.
4
4
 
@@ -12,151 +12,90 @@ npm install danogo-clmm
12
12
 
13
13
  This SDK requires:
14
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
18
-
19
- ### ⚠️ TypeScript Compatibility Note
20
-
21
- The dependency `@evolution-sdk/evolution` currently ships with some TypeScript type definitions that may cause compilation errors in strict projects.
22
-
23
- If you encounter type errors originating from `node_modules/@evolution-sdk/evolution`, you can safely enable the following option in your `tsconfig.json`:
24
-
25
- ```json
26
- {
27
- "compilerOptions": {
28
- "skipLibCheck": true
29
- }
30
- }
31
- ```
15
+ - `@evolution-sdk/evolution` version `0.32.2` for wallet management and transaction building
16
+ - A Kupmios provider for blockchain data and transaction submission
32
17
 
33
18
  ## Usage
34
19
 
35
20
  ### Initialization
36
21
 
37
- Initialize the SDK.
22
+ Initialize the SDK and the Evolution client.
38
23
  ```typescript
39
- import DanogoSwap from "danogo-clmm";
40
-
41
- const sdk = new DanogoSwap();
24
+ import DanogoClmm from "danogo-clmm";
25
+ import { client, preprod } from "@evolution-sdk/evolution";
26
+
27
+ const danogoClmm = new DanogoClmm();
28
+
29
+ const evolutionClient = client(preprod)
30
+ .withKupmios({
31
+ kupoUrl: "your_kupo_url",
32
+ ogmiosUrl: "your_ogmios_url",
33
+ })
34
+ .withSeed({
35
+ mnemonic: "your_seed_phrase",
36
+ accountIndex: 0,
37
+ });
42
38
  ```
43
39
 
44
40
  ### 1. Calculate Swap Output (Quote)
45
41
 
46
- Calculate the expected output of a swap without submitting a transaction. This is useful for UI previews or checking rates.
42
+ Calculate the expected output of a swap without submitting a transaction. You can swap through one or more pools to get better price execution.
47
43
 
44
+ #### Examples
48
45
  ```typescript
49
- import DanogoSwap from "danogo-clmm";
50
- import { createClient } from "@evolution-sdk/evolution";
51
-
52
- const sdk = new DanogoSwap();
53
-
54
- async function main() {
55
- const client = createClient({
56
- network: "preprod", // your network
57
- provider: {
58
- type: "kupmios", // recommend kupmios
59
- kupoUrl: "your_kupo_url",
60
- ogmiosUrl: "your_ogmios_url",
61
- },
62
- wallet: {
63
- type: "seed",
64
- mnemonic: "your seed phrase",
65
- accountIndex: 0, // your accountIndex
46
+ const quote = await danogoClmm.calculateSwapOut(evolutionClient, {
47
+ pools: [
48
+ {
49
+ poolOutRef: pool1OutRef,
50
+ deltaAmount: 5_000_000n,
51
+ stakingOutRef: staking1OutRef // required if pool contains ADA and swap for the first time in current epoch
66
52
  },
67
- });
68
-
69
- const quoteRequest: QuoteSwapRequest = {
70
- poolOutRef: new TransactionInput.TransactionInput({
71
- transactionId: TransactionHash.fromHex("your_tx_hash"),
72
- index: 0n,
73
- }),
74
- deltaAmount: -3_000_000n, // Positive: User sells X -> Buy Y, Negative: User sells Y -> Buy X
75
- protocolConfigOutRef: new TransactionInput.TransactionInput({
76
- transactionId: TransactionHash.fromHex("your_tx_hash"),
77
- index: 0n,
78
- }),
79
- stakingOutRef: new TransactionInput.TransactionInput({ // if pool contains ADA
80
- transactionId: TransactionHash.fromHex("your_tx_hash"),
81
- index: 1n,
82
- }),
83
- };
84
-
85
- try {
86
- const expectedOutput = await sdk.calculateSwapOut(client, quoteRequest);
87
- console.log(`Expected output amount: ${expectedOutput}`);
88
- } catch (error) {
89
- console.error("Calculation failed", error);
90
- }
91
- }
53
+ {
54
+ poolOutRef: pool2OutRef,
55
+ deltaAmount: 5_000_000n,
56
+ stakingOutRef: staking2OutRef // required if pool contains ADA and swap for the first time in current epoch
57
+ }
58
+ ]
59
+ });
92
60
  ```
93
61
 
94
62
  ### 2. Submit Swap Transaction
95
63
 
96
- Build and submit a swap transaction using an Evolution client.
64
+ Build and submit a swap transaction across one or more pools.
97
65
 
66
+ #### Examples
98
67
  ```typescript
99
- import DanogoSwap from "danogo-clmm";
100
- import { createClient, TransactionInput, TransactionHash } from "@evolution-sdk/evolution";
101
-
102
- const sdk = new DanogoSwap();
103
-
104
- async function main() {
105
- // 1. Initialize client with your provider
106
- const client = createClient({
107
- network: "preprod", // your network
108
- provider: {
109
- type: "kupmios", // recommend kupmios
110
- kupoUrl: "your_kupo_url",
111
- ogmiosUrl: "your_ogmios_url",
112
- },
113
- wallet: {
114
- type: "seed",
115
- mnemonic: "your seed phrase",
116
- accountIndex: 0, // your accountIndex
68
+ const txHash = await danogoClmm.submitSwap(evolutionClient, {
69
+ pools: [
70
+ {
71
+ poolOutRef: pool1OutRef,
72
+ deltaAmount: 5_000_000n,
73
+ minOutChangeAmount: 4_500_000n, // retrieve from calculateSwapOut to avoid slippage
74
+ stakingOutRef: staking1OutRef // required if pool contains ADA and swap for the first time in current epoch
117
75
  },
118
- });
119
-
120
- const swapRequest: SwapRequest = {
121
- poolOutRef: new TransactionInput.TransactionInput({
122
- transactionId: TransactionHash.fromHex("your_tx_hash"),
123
- index: 0n,
124
- }),
125
- deltaAmount: -3_000_000n, // Positive: User sells X -> Buy Y, Negative: User sells Y -> Buy X
126
- minOutChangeAmount: 10000n, // Minimum amount of token received to accept
127
- poolScriptOutRef: new TransactionInput.TransactionInput({
128
- transactionId: TransactionHash.fromHex("your_tx_hash"),
129
- index: 0n,
130
- }),
131
- protocolConfigOutRef: new TransactionInput.TransactionInput({
132
- transactionId: TransactionHash.fromHex("your_tx_hash"),
133
- index: 0n,
134
- }),
135
- stakingOutRef: new TransactionInput.TransactionInput({ // if pool contains ADA
136
- transactionId: TransactionHash.fromHex("your_tx_hash"),
137
- index: 1n,
138
- }),
139
- };
140
-
141
- try {
142
- const txHash = await sdk.submitSwap(client, swapRequest);
143
- console.log(`Transaction submitted: ${txHash}`);
144
- } catch (error) {
145
- console.error("Swap failed", error);
146
- }
147
- }
76
+ {
77
+ poolOutRef: pool2OutRef,
78
+ deltaAmount: 5_000_000n,
79
+ minOutChangeAmount: 4_500_000n, // retrieve from calculateSwapOut to avoid slippage
80
+ stakingOutRef: staking2OutRef // required if pool contains ADA and swap for the first time in current epoch
81
+ }
82
+ ],
83
+ protocolConfigOutRef: protocolConfigRef
84
+ });
148
85
  ```
149
86
 
150
- ### 3. Get Pool Info from Ogmios Transaction
87
+ > `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.
88
+
89
+ ### 4. Get Pool Info from Ogmios Transaction
151
90
 
152
91
  Extract pool data directly from an Ogmios transaction object.
153
92
 
154
93
  ```typescript
155
- import DanogoSwap from "danogo-clmm";
94
+ import DanogoClmm from "danogo-clmm";
156
95
  import { createChainSynchronizationClient, createInteractionContext } from "@cardano-ogmios/client";
157
96
  import { Point } from "@cardano-ogmios/schema";
158
97
 
159
- const sdk = new DanogoSwap();
98
+ const danogoClmm = new DanogoClmm();
160
99
 
161
100
  async function main() {
162
101
  const context = await createInteractionContext(
@@ -175,7 +114,8 @@ async function main() {
175
114
  rollForward: async ({ block }, requestNext) => {
176
115
  if ("transactions" in block) {
177
116
  for (const tx of block.transactions!) {
178
- const pools = sdk.getPoolsFromOgmiosTx(tx, "your_pool_script_hash");
117
+ const networkId = 0; // 0 for Preprod, 1 for Mainnet
118
+ const pools = danogoClmm.getPoolsFromOgmiosTx(tx, networkId);
179
119
  // your logic with pools
180
120
  }
181
121
  }
@@ -195,4 +135,18 @@ async function main() {
195
135
 
196
136
  await client.resume([checkpoint]);
197
137
  }
138
+ ```
139
+
140
+ ### ⚠️ TypeScript Compatibility Note
141
+
142
+ The dependency `@evolution-sdk/evolution` currently ships with some TypeScript type definitions that may cause compilation errors in strict projects.
143
+
144
+ If you encounter type errors originating from `node_modules/@evolution-sdk/evolution`, you can safely enable the following option in your `tsconfig.json`:
145
+
146
+ ```json
147
+ {
148
+ "compilerOptions": {
149
+ "skipLibCheck": true
150
+ }
151
+ }
198
152
  ```
package/dist/sdk.d.mts CHANGED
@@ -51,42 +51,90 @@ interface ConcentratedPool {
51
51
  totalSwapFee: bigint;
52
52
  }
53
53
  interface SwapRequest {
54
- poolOutRef: TransactionInput.TransactionInput;
55
- poolScriptOutRef: TransactionInput.TransactionInput;
56
- deltaAmount: bigint;
57
- minOutChangeAmount: bigint;
58
- stakingOutRef?: TransactionInput.TransactionInput;
59
- protocolConfigOutRef: TransactionInput.TransactionInput;
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: TransactionInput.TransactionInput;
63
- deltaAmount: bigint;
64
- stakingOutRef?: TransactionInput.TransactionInput;
65
- protocolConfigOutRef: TransactionInput.TransactionInput;
63
+ pools: {
64
+ poolOutRef: TransactionInput.TransactionInput;
65
+ deltaAmount: bigint;
66
+ stakingOutRef?: TransactionInput.TransactionInput;
67
+ }[];
68
+ protocolConfigOutRef?: TransactionInput.TransactionInput;
66
69
  }
67
70
 
68
- declare class DanogoSwap {
71
+ declare class DanogoClmm {
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(client: SigningClient, 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
  *
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
+ *
87
111
  * @param client An initialized SigningClient instance with a connected wallet.
88
- * @param request The swap request object containing pool reference, swap amount, and minimum output.
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
139
  submitSwap(client: SigningClient, request: SwapRequest): Promise<string>;
92
140
  /**
@@ -99,7 +147,7 @@ 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[];
103
151
  /**
104
152
  * Helper function to get the balance of a specific token from user UTXOs
105
153
  */
@@ -114,4 +162,4 @@ declare class DanogoSwap {
114
162
  private getStakingRewards;
115
163
  }
116
164
 
117
- export { type ConcentratedPool, type PoolDatum, type QuoteSwapRequest, type SwapRequest, DanogoSwap as default };
165
+ export { type ConcentratedPool, type PoolDatum, type QuoteSwapRequest, type SwapRequest, DanogoClmm as default };
package/dist/sdk.d.ts CHANGED
@@ -51,42 +51,90 @@ interface ConcentratedPool {
51
51
  totalSwapFee: bigint;
52
52
  }
53
53
  interface SwapRequest {
54
- poolOutRef: TransactionInput.TransactionInput;
55
- poolScriptOutRef: TransactionInput.TransactionInput;
56
- deltaAmount: bigint;
57
- minOutChangeAmount: bigint;
58
- stakingOutRef?: TransactionInput.TransactionInput;
59
- protocolConfigOutRef: TransactionInput.TransactionInput;
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: TransactionInput.TransactionInput;
63
- deltaAmount: bigint;
64
- stakingOutRef?: TransactionInput.TransactionInput;
65
- protocolConfigOutRef: TransactionInput.TransactionInput;
63
+ pools: {
64
+ poolOutRef: TransactionInput.TransactionInput;
65
+ deltaAmount: bigint;
66
+ stakingOutRef?: TransactionInput.TransactionInput;
67
+ }[];
68
+ protocolConfigOutRef?: TransactionInput.TransactionInput;
66
69
  }
67
70
 
68
- declare class DanogoSwap {
71
+ declare class DanogoClmm {
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(client: SigningClient, 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
  *
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
+ *
87
111
  * @param client An initialized SigningClient instance with a connected wallet.
88
- * @param request The swap request object containing pool reference, swap amount, and minimum output.
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
139
  submitSwap(client: SigningClient, request: SwapRequest): Promise<string>;
92
140
  /**
@@ -99,7 +147,7 @@ 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[];
103
151
  /**
104
152
  * Helper function to get the balance of a specific token from user UTXOs
105
153
  */
@@ -114,4 +162,4 @@ declare class DanogoSwap {
114
162
  private getStakingRewards;
115
163
  }
116
164
 
117
- export { type ConcentratedPool, type PoolDatum, type QuoteSwapRequest, type SwapRequest, DanogoSwap as default };
165
+ export { type ConcentratedPool, type PoolDatum, type QuoteSwapRequest, type SwapRequest, DanogoClmm as default };
package/dist/sdk.js CHANGED
@@ -1 +1 @@
1
- var N=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var Z=Object.getOwnPropertyNames;var tt=Object.prototype.hasOwnProperty;var et=(n,e)=>{for(var t in e)N(n,t,{get:e[t],enumerable:!0})},nt=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Z(e))!tt.call(n,o)&&o!==t&&N(n,o,{get:()=>e[o],enumerable:!(r=K(e,o))||r.enumerable});return n};var ot=n=>nt(N({},"__esModule",{value:!0}),n);var at={};et(at,{default:()=>st});module.exports=ot(at);var E=require("@evolution-sdk/evolution"),T=require("@evolution-sdk/evolution/ScriptHash"),d=require("@evolution-sdk/evolution/Assets");var H=require("@evolution-sdk/evolution");function P(n,e){let r=(n>=0n?n:n+(1n<<256n)).toString(16);r.length%2&&(r="0"+r);let o=r.length/2;if(o>e)throw new Error(`Number ${n} requires ${o} bytes, but target length is ${e}.`);let s=new Uint8Array(e),i=e-o;for(let a=0;a<o;a++)s[a+i]=parseInt(r.slice(a*2,a*2+2),16);return s}var O=(n,e,t,r)=>{try{let o=s=>{let i=3n,a=P(r?t:s,1),g=P(s,1),l=P(i,1),u=P(0n,1),f=P(e[0],32),w=a.length+l.length+g.length+u.length+f.length,m=new Uint8Array(w),c=0;m.set(a,c),c+=a.length,m.set(l,c),c+=l.length,m.set(g,c),c+=g.length,m.set(u,c),c+=u.length,m.set(f,c);let y=Buffer.from(m).toString("hex");return H.Data.fromCBORHex("5824"+y)};return{all:s=>{if(!s.length)throw new Error("swapTokensRedeemer batch all called with empty indexedInputs");let i=BigInt(s[0].index);return o(i)},inputs:n}}catch(o){throw console.error("Error creating pool redeemer:",o),o}};var I=require("@evolution-sdk/evolution"),$=require("@evolution-sdk/evolution/InlineDatum"),M=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"))],r=I.Data.constr(0n,[n.sqrtLowerPriceNum,n.sqrtLowerPriceDen]),o=I.Data.constr(0n,[n.sqrtUpperPriceNum,n.sqrtUpperPriceDen]),s=I.Data.constr(0n,[e,t,BigInt(n.lpFeeRate),n.platformFeeX,n.platformFeeY,n.totalSwapFee,r,o,n.minXChange,n.minYChange,n.circulatingLPToken,BigInt(n.lastWithdrawEpoch)]);return new $.InlineDatum({data:s})};var k=n=>{let e;if(typeof n=="string")e=I.CBOR.fromCBORHex(n);else{let s=n.data,i=I.Data.toCBORHex(s);e=I.CBOR.fromCBORHex(i)}let t=e._tag==="Tag"?e.value:e;if(!Array.isArray(t))throw new Error("Invalid datum structure: expected array of fields");let r=s=>{let i=s._tag==="Tag"?s.value:s;if(Array.isArray(i)&&i.length===2){let a=i[0]instanceof Uint8Array?i[0]:new Uint8Array(i[0]),g=i[1]instanceof Uint8Array?i[1]:new Uint8Array(i[1]),l=Buffer.from(a).toString("hex"),u=Buffer.from(g).toString("hex");return l===""&&u===""?"lovelace":l+"."+u}throw new Error("Invalid AssetClass structure")},o=s=>{let i=s._tag==="Tag"?s.value:s;if(Array.isArray(i)&&i.length===2)return{num:BigInt(i[0]),den:BigInt(i[1])};throw new Error("Invalid Ratio structure")};return{tokenX:r(t[0]),tokenY:r(t[1]),lpFeeRate:Number(t[2]),platformFeeX:BigInt(t[3]),platformFeeY:BigInt(t[4]),totalSwapFee:BigInt(t[5]),sqrtLowerPriceNum:o(t[6]).num,sqrtLowerPriceDen:o(t[6]).den,sqrtUpperPriceNum:o(t[7]).num,sqrtUpperPriceDen:o(t[7]).den,minXChange:BigInt(t[8]),minYChange:BigInt(t[9]),circulatingLPToken:BigInt(t[10]),lastWithdrawEpoch:Number(t[11])}},v=n=>{let e,t=I.Data.toCBORHex(n.data);e=I.CBOR.fromCBORHex(t);let r=e._tag==="Tag"?e.value:e;if(!Array.isArray(r))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:BigInt(r[0]),swapFee:BigInt(r[1])}};var A=require("@evolution-sdk/evolution");function R(n){if(n==="lovelace")return{unit:"lovelace"};let e=n.indexOf("."),t=e===-1?n:n.slice(0,e),r=e===-1?"":n.slice(e+1),o=A.Bytes.fromHex(t),s=new A.PolicyId.PolicyId({hash:o}),i=r?A.Bytes.fromHex(r):new Uint8Array(0),a=new A.AssetName.AssetName({bytes:i});return{policyId:s,assetName:a,unit:n}}var _=n=>{if(!n||Object.keys(n).length===0)return[];let e=[];for(let[t,r]of Object.entries(n)){if(t==="ada")continue;let o=[];for(let[s,i]of Object.entries(r))o.push({name:s,value:i});e.push({policyId:t,assets:o})}return e};var V=(n,e)=>{let t=432e6,r=1647899091e3,o=328;return e!==1&&(t=18e5),Math.floor((n-r)/t)+o};function S(n,e,t,r,o=0n,s){let i=r<0n?-r:r,a=t.tokenX==="lovelace"?3000000n+BigInt(t.totalSwapFee):0n,g=BigInt(n)-BigInt(t.platformFeeX)+o-a,l=BigInt(e)-BigInt(t.platformFeeY),u=rt(g,l,[BigInt(t.sqrtLowerPriceNum),BigInt(t.sqrtLowerPriceDen)],[BigInt(t.sqrtUpperPriceNum),BigInt(t.sqrtUpperPriceDen)]),f=j(u[0]*BigInt(t.sqrtUpperPriceDen),u[1]*BigInt(t.sqrtUpperPriceNum))+g,w=j(u[0]*BigInt(t.sqrtLowerPriceNum),u[1]*BigInt(t.sqrtLowerPriceDen))+l;return r>0n?W(i,f,w,l,BigInt(t.lpFeeRate),s):W(i,w,f,g,BigInt(t.lpFeeRate),s)}var W=(n,e,t,r,o,s)=>{let i=10000n,g=n*o/i*BigInt(s)/10000n,l=i-o,u=e*i+n*l,f=e*t,m=(t*u-f*i)/u;if(m>r)throw new Error("pool out exceeded");return[m,g]},rt=(n,e,t,r)=>{let o=t[1]*r[1],s=t[0]*r[0],i=(e*o-n*s)*(e*o-n*s),a=4n*n*e*t[1]*t[1]*r[0]*r[0],g=it(i+a),l=e*o+n*s+g,u=2n*(r[0]*t[1]-r[1]*t[0]);return[l,u]};function it(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 j(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 G(n,e){let r=[...e].sort((o,s)=>o.transactionId===s.transactionId?o.index<s.index?-1:1:o.transactionId<s.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)}var q=class{constructor(){}async calculateSwapOut(e,t){if(!e||!e.address)throw new Error("Please connect a wallet first.");let r=(await e.address()).networkId,o=(await e.getUtxosByOutRef([t.poolOutRef]))[0],s=null;if(t.stakingOutRef&&(s=(await e.getUtxosByOutRef([t.stakingOutRef]))[0]),!o.datumOption)throw new Error("Pool input UTxO does not contain a datum.");let i=(await e.getUtxosByOutRef([t.protocolConfigOutRef]))[0];if(!i.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let a=v(i.datumOption),g=k(o.datumOption),l=R(g.tokenX),u=R(g.tokenY),f=o.assets.lovelace,w=h=>h.unit==="lovelace"?f:(0,d.quantityOf)(o.assets,h.policyId,h.assetName),{rewardAmount:m}=await this.getStakingRewards(e,r,s,l),[c,y]=S(w(l),w(u),g,t.deltaAmount,m,a.platformFeeRate);return c}async submitSwap(e,t){if(!e||!e.address)throw new Error("Please connect a wallet first.");let r=(await e.address()).networkId,o=(await e.getUtxosByOutRef([t.poolOutRef]))[0],s=(await e.getUtxosByOutRef([t.poolScriptOutRef]))[0],i=null;if(t.stakingOutRef&&(i=(await e.getUtxosByOutRef([t.stakingOutRef]))[0]),!o.datumOption)throw new Error("Pool input UTxO does not contain a datum.");let a=(await e.getUtxosByOutRef([t.protocolConfigOutRef]))[0];if(!a.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let g=v(a.datumOption),l=k(o.datumOption),u=R(l.tokenX),f=R(l.tokenY),w=o.assets.lovelace,m=C=>C.unit==="lovelace"?w:(0,d.quantityOf)(o.assets,C.policyId,C.assetName),c=t.deltaAmount,y=c>0?u:f,h=c>0?f:u,p=e.newTx(),x=await this.getUserTokenBalance(e,y),D=c<0n?-c:c;if(x<D)throw new Error(`Insufficient ${y.unit} balance. Required: ${D}, Available: ${x}`);p=p.readFrom({referenceInputs:[s,a]}),i&&(p=p.readFrom({referenceInputs:[i]}));let{rewardAmount:U,stakingRewardAddress:L}=await this.getStakingRewards(e,r,i,u),[B,b]=S(m(u),m(f),l,c,U,g.platformFeeRate);if(B<t.minOutChangeAmount)throw new Error(`Slippage too high. Expected at least ${t.minOutChangeAmount} but got ${B}`);let X=V(Date.now(),r),Q=M({...l,platformFeeX:BigInt(l.platformFeeX)+(y.unit===u.unit?b:0n),platformFeeY:BigInt(l.platformFeeY)+(y.unit===f.unit?b:0n),lastWithdrawEpoch:X,totalSwapFee:BigInt(l.totalSwapFee)+BigInt(g.swapFee)}),z=this.buildDeltaAssets(y,h,c,BigInt(B),BigInt(g.swapFee)),J=(0,d.merge)(o.assets,z);p=p.payToAddress({address:o.address,assets:J,datum:Q}),p=p.attachMetadata({label:674n,metadata:new Map([["msg",["Danogo Liquidity Pair: Swap"]]])});let Y=[s,a];i&&Y.push(i);let F=G(a,Y);return p=p.collectFrom({inputs:[o],redeemer:O([o],[c],F,!1)}),p=p.withdraw({stakeCredential:(0,T.fromScript)(s.scriptRef),amount:0n,redeemer:O([o],[c],F,!0)}),u.unit==="lovelace"&&X>l.lastWithdrawEpoch&&L&&(p=p.withdraw({stakeCredential:(0,T.fromScript)(i.scriptRef),amount:U,redeemer:O([o],[c],F,!1)})),p.setValidity({from:BigInt(Date.now()-12e4),to:BigInt(Date.now()+24e4)}),(await(await(await p.build({debug:!0})).sign()).submit()).toString()}getPoolsFromOgmiosTx(e,t){let r=[];return e.outputs.forEach((o,s)=>{let i=o.value,a=i[t];if(a&&o.datum){for(let[g,l]of Object.entries(a))if(l===1n){let u=t+g,f=`${e.id}#${s}`,w=i.ada.lovelace,m=_(i),c=k(o.datum),y=c.tokenX,h=c.tokenY,p=x=>{if(x==="lovelace"||x==="")return w;let D=x.slice(0,56),U=x.slice(56),B=m.find(b=>b.policyId===D)?.assets.find(b=>b.name===U);return B?B.value:0n};r.push({outRef:f,address:o.address,coin:w,multiAssets:m,validityNft:u,tokenA:y,tokenAReserve:p(y),tokenB:h,tokenBReserve:p(h),lpFeeRate:c.lpFeeRate,priceLowerNum:c.sqrtLowerPriceNum,priceLowerDen:c.sqrtLowerPriceDen,priceUpperNum:c.sqrtUpperPriceNum,priceUpperDen:c.sqrtUpperPriceDen,platformFeeA:c.platformFeeX,platformFeeB:c.platformFeeY,minAChange:c.minXChange,minBChange:c.minYChange,lpTokenTotalSupply:c.circulatingLPToken,lastWithdrawEpoch:c.lastWithdrawEpoch,totalSwapFee:c.totalSwapFee})}}}),r}async getUserTokenBalance(e,t){return(await e.getWalletUtxos()).reduce((o,s)=>o+(t.unit==="lovelace"?s.assets.lovelace:(0,d.quantityOf)(s.assets,t.policyId,t.assetName)||0n),0n)}buildDeltaAssets(e,t,r,o,s){let i=r>0n?r:-r,a;if(e.unit==="lovelace"?a=(0,d.fromLovelace)(i+s):a=(0,d.fromAsset)(e.policyId,e.assetName,i,s),t.unit==="lovelace")a=(0,d.subtractLovelace)(a,o);else{let g=(0,d.fromAsset)(t.policyId,t.assetName,-o);a=(0,d.merge)(a,g)}return a}async getStakingRewards(e,t,r,o){if(o.unit!=="lovelace")return{rewardAmount:0n};let s=new E.RewardAccount.RewardAccount({networkId:t,stakeCredential:(0,T.fromScript)(r.scriptRef)}),i=E.RewardAccount.toBech32(s);return{rewardAmount:(await e.getDelegation(i)).rewards,stakingRewardAddress:i}}},st=q;
1
+ var G=Object.defineProperty;var ut=Object.getOwnPropertyDescriptor;var lt=Object.getOwnPropertyNames;var pt=Object.prototype.hasOwnProperty;var ft=(n,t)=>{for(var e in t)G(n,e,{get:t[e],enumerable:!0})},mt=(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=>mt(G({},"__esModule",{value:!0}),n);var Bt={};ft(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,m=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(m,d),d+=m.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]),m=s[1]instanceof Uint8Array?s[1]:new Uint8Array(s[1]),l=Buffer.from(a).toString("hex"),p=Buffer.from(m).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,m=BigInt(n)-BigInt(e.platformFeeX)+o-a,l=BigInt(t)-BigInt(e.platformFeeY),p=ht(m,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))+m,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,m,BigInt(e.lpFeeRate),i)}var ot=(n,t,e,r,o,i)=>{let s=10000n,m=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,m]},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],m=Pt(s+a),l=t*o+n*i+m,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,m]=bt(i.tokenAAmount,i.tokenBAmount,i.datum,s,i.rewardAmount||0n,e);r.push({poolIndex:o,deltaAmount:s,outputAmount:a,platformFee:m})}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 m=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,m.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,m=(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 f=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;f.stakingOutRef&&(N=(await t.getUtxosByOutRef([f.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,f)=>{let P=e.pools[f].minOutChangeAmount;if(c.outputAmount<P)throw new Error(`Expected swap output at least ${P} but got ${c.outputAmount}`)});let y=A.reduce((c,f)=>c+f.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(m),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)(m.scriptRef),amount:0n,redeemer:v(null,o,d,D)});for(let c=0;c<I.length;c++){let f=I[c],P=A.find(N=>N.poolIndex===c);if(!P)continue;let T=P.deltaAmount,E=P.platformFee,S=et({...f.datum,platformFeeX:BigInt(f.datum.platformFeeX)+(T>0?E:0n),platformFeeY:BigInt(f.datum.platformFeeY)+(T<0?E:0n),lastWithdrawEpoch:U,totalSwapFee:BigInt(f.datum.totalSwapFee)+BigInt(p.swapFee)}),$=this.buildDeltaAssets(T>0?f.tokenA:f.tokenB,T>0?f.tokenB:f.tokenA,T,BigInt(P.outputAmount),BigInt(p.swapFee)),_=(0,b.merge)(f.utxo.assets,$);if(g=g.payToAddress({address:f.utxo.address,assets:_,datum:S}),g=g.collectFrom({inputs:[f.utxo],redeemer:v(f.utxo,o,d,D)}),f.tokenA.unit===x&&U>f.datum.lastWithdrawEpoch&&u[c]){let{stakingRewardAddress:N}=await this.getStakingRewards(t,r,u[c],f.tokenA);N&&(g=g.withdraw({stakeCredential:(0,Y.fromScript)(u[c].scriptRef),amount:f.rewardAmount||0n,redeemer:v(f.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,m)=>{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}#${m}`,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 m=(0,b.fromAsset)(e.policyId,e.assetName,-o);a=(0,b.merge)(a,m)}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{RewardAccount as j}from"@evolution-sdk/evolution";import{fromScript as N}from"@evolution-sdk/evolution/ScriptHash";import{fromAsset as V,merge as G,quantityOf as v,fromLovelace as rt,subtractLovelace as it}from"@evolution-sdk/evolution/Assets";import{Data as K}from"@evolution-sdk/evolution";function A(n,e){let r=(n>=0n?n:n+(1n<<256n)).toString(16);r.length%2&&(r="0"+r);let o=r.length/2;if(o>e)throw new Error(`Number ${n} requires ${o} bytes, but target length is ${e}.`);let s=new Uint8Array(e),i=e-o;for(let a=0;a<o;a++)s[a+i]=parseInt(r.slice(a*2,a*2+2),16);return s}var D=(n,e,t,r)=>{try{let o=s=>{let i=3n,a=A(r?t:s,1),g=A(s,1),l=A(i,1),u=A(0n,1),f=A(e[0],32),d=a.length+l.length+g.length+u.length+f.length,m=new Uint8Array(d),c=0;m.set(a,c),c+=a.length,m.set(l,c),c+=l.length,m.set(g,c),c+=g.length,m.set(u,c),c+=u.length,m.set(f,c);let w=Buffer.from(m).toString("hex");return K.fromCBORHex("5824"+w)};return{all:s=>{if(!s.length)throw new Error("swapTokensRedeemer batch all called with empty indexedInputs");let i=BigInt(s[0].index);return o(i)},inputs:n}}catch(o){throw console.error("Error creating pool redeemer:",o),o}};import{Data as B,CBOR as T}from"@evolution-sdk/evolution";import{InlineDatum as Z}from"@evolution-sdk/evolution/InlineDatum";var X=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"))],r=B.constr(0n,[n.sqrtLowerPriceNum,n.sqrtLowerPriceDen]),o=B.constr(0n,[n.sqrtUpperPriceNum,n.sqrtUpperPriceDen]),s=B.constr(0n,[e,t,BigInt(n.lpFeeRate),n.platformFeeX,n.platformFeeY,n.totalSwapFee,r,o,n.minXChange,n.minYChange,n.circulatingLPToken,BigInt(n.lastWithdrawEpoch)]);return new Z({data:s})};var U=n=>{let e;if(typeof n=="string")e=T.fromCBORHex(n);else{let s=n.data,i=B.toCBORHex(s);e=T.fromCBORHex(i)}let t=e._tag==="Tag"?e.value:e;if(!Array.isArray(t))throw new Error("Invalid datum structure: expected array of fields");let r=s=>{let i=s._tag==="Tag"?s.value:s;if(Array.isArray(i)&&i.length===2){let a=i[0]instanceof Uint8Array?i[0]:new Uint8Array(i[0]),g=i[1]instanceof Uint8Array?i[1]:new Uint8Array(i[1]),l=Buffer.from(a).toString("hex"),u=Buffer.from(g).toString("hex");return l===""&&u===""?"lovelace":l+"."+u}throw new Error("Invalid AssetClass structure")},o=s=>{let i=s._tag==="Tag"?s.value:s;if(Array.isArray(i)&&i.length===2)return{num:BigInt(i[0]),den:BigInt(i[1])};throw new Error("Invalid Ratio structure")};return{tokenX:r(t[0]),tokenY:r(t[1]),lpFeeRate:Number(t[2]),platformFeeX:BigInt(t[3]),platformFeeY:BigInt(t[4]),totalSwapFee:BigInt(t[5]),sqrtLowerPriceNum:o(t[6]).num,sqrtLowerPriceDen:o(t[6]).den,sqrtUpperPriceNum:o(t[7]).num,sqrtUpperPriceDen:o(t[7]).den,minXChange:BigInt(t[8]),minYChange:BigInt(t[9]),circulatingLPToken:BigInt(t[10]),lastWithdrawEpoch:Number(t[11])}},F=n=>{let e,t=B.toCBORHex(n.data);e=T.fromCBORHex(t);let r=e._tag==="Tag"?e.value:e;if(!Array.isArray(r))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:BigInt(r[0]),swapFee:BigInt(r[1])}};import{AssetName as tt,Bytes as Y,PolicyId as et}from"@evolution-sdk/evolution";function b(n){if(n==="lovelace")return{unit:"lovelace"};let e=n.indexOf("."),t=e===-1?n:n.slice(0,e),r=e===-1?"":n.slice(e+1),o=Y.fromHex(t),s=new et.PolicyId({hash:o}),i=r?Y.fromHex(r):new Uint8Array(0),a=new tt.AssetName({bytes:i});return{policyId:s,assetName:a,unit:n}}var H=n=>{if(!n||Object.keys(n).length===0)return[];let e=[];for(let[t,r]of Object.entries(n)){if(t==="ada")continue;let o=[];for(let[s,i]of Object.entries(r))o.push({name:s,value:i});e.push({policyId:t,assets:o})}return e};var _=(n,e)=>{let t=432e6,r=1647899091e3,o=328;return e!==1&&(t=18e5),Math.floor((n-r)/t)+o};function C(n,e,t,r,o=0n,s){let i=r<0n?-r:r,a=t.tokenX==="lovelace"?3000000n+BigInt(t.totalSwapFee):0n,g=BigInt(n)-BigInt(t.platformFeeX)+o-a,l=BigInt(e)-BigInt(t.platformFeeY),u=nt(g,l,[BigInt(t.sqrtLowerPriceNum),BigInt(t.sqrtLowerPriceDen)],[BigInt(t.sqrtUpperPriceNum),BigInt(t.sqrtUpperPriceDen)]),f=M(u[0]*BigInt(t.sqrtUpperPriceDen),u[1]*BigInt(t.sqrtUpperPriceNum))+g,d=M(u[0]*BigInt(t.sqrtLowerPriceNum),u[1]*BigInt(t.sqrtLowerPriceDen))+l;return r>0n?$(i,f,d,l,BigInt(t.lpFeeRate),s):$(i,d,f,g,BigInt(t.lpFeeRate),s)}var $=(n,e,t,r,o,s)=>{let i=10000n,g=n*o/i*BigInt(s)/10000n,l=i-o,u=e*i+n*l,f=e*t,m=(t*u-f*i)/u;if(m>r)throw new Error("pool out exceeded");return[m,g]},nt=(n,e,t,r)=>{let o=t[1]*r[1],s=t[0]*r[0],i=(e*o-n*s)*(e*o-n*s),a=4n*n*e*t[1]*t[1]*r[0]*r[0],g=ot(i+a),l=e*o+n*s+g,u=2n*(r[0]*t[1]-r[1]*t[0]);return[l,u]};function ot(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 M(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 W(n,e){let r=[...e].sort((o,s)=>o.transactionId===s.transactionId?o.index<s.index?-1:1:o.transactionId<s.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)}var S=class{constructor(){}async calculateSwapOut(e,t){if(!e||!e.address)throw new Error("Please connect a wallet first.");let r=(await e.address()).networkId,o=(await e.getUtxosByOutRef([t.poolOutRef]))[0],s=null;if(t.stakingOutRef&&(s=(await e.getUtxosByOutRef([t.stakingOutRef]))[0]),!o.datumOption)throw new Error("Pool input UTxO does not contain a datum.");let i=(await e.getUtxosByOutRef([t.protocolConfigOutRef]))[0];if(!i.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let a=F(i.datumOption),g=U(o.datumOption),l=b(g.tokenX),u=b(g.tokenY),f=o.assets.lovelace,d=y=>y.unit==="lovelace"?f:v(o.assets,y.policyId,y.assetName),{rewardAmount:m}=await this.getStakingRewards(e,r,s,l),[c,w]=C(d(l),d(u),g,t.deltaAmount,m,a.platformFeeRate);return c}async submitSwap(e,t){if(!e||!e.address)throw new Error("Please connect a wallet first.");let r=(await e.address()).networkId,o=(await e.getUtxosByOutRef([t.poolOutRef]))[0],s=(await e.getUtxosByOutRef([t.poolScriptOutRef]))[0],i=null;if(t.stakingOutRef&&(i=(await e.getUtxosByOutRef([t.stakingOutRef]))[0]),!o.datumOption)throw new Error("Pool input UTxO does not contain a datum.");let a=(await e.getUtxosByOutRef([t.protocolConfigOutRef]))[0];if(!a.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let g=F(a.datumOption),l=U(o.datumOption),u=b(l.tokenX),f=b(l.tokenY),d=o.assets.lovelace,m=k=>k.unit==="lovelace"?d:v(o.assets,k.policyId,k.assetName),c=t.deltaAmount,w=c>0?u:f,y=c>0?f:u,p=e.newTx(),I=await this.getUserTokenBalance(e,w),P=c<0n?-c:c;if(I<P)throw new Error(`Insufficient ${w.unit} balance. Required: ${P}, Available: ${I}`);p=p.readFrom({referenceInputs:[s,a]}),i&&(p=p.readFrom({referenceInputs:[i]}));let{rewardAmount:R,stakingRewardAddress:E}=await this.getStakingRewards(e,r,i,u),[h,x]=C(m(u),m(f),l,c,R,g.platformFeeRate);if(h<t.minOutChangeAmount)throw new Error(`Slippage too high. Expected at least ${t.minOutChangeAmount} but got ${h}`);let q=_(Date.now(),r),Q=X({...l,platformFeeX:BigInt(l.platformFeeX)+(w.unit===u.unit?x:0n),platformFeeY:BigInt(l.platformFeeY)+(w.unit===f.unit?x:0n),lastWithdrawEpoch:q,totalSwapFee:BigInt(l.totalSwapFee)+BigInt(g.swapFee)}),z=this.buildDeltaAssets(w,y,c,BigInt(h),BigInt(g.swapFee)),J=G(o.assets,z);p=p.payToAddress({address:o.address,assets:J,datum:Q}),p=p.attachMetadata({label:674n,metadata:new Map([["msg",["Danogo Liquidity Pair: Swap"]]])});let L=[s,a];i&&L.push(i);let O=W(a,L);return p=p.collectFrom({inputs:[o],redeemer:D([o],[c],O,!1)}),p=p.withdraw({stakeCredential:N(s.scriptRef),amount:0n,redeemer:D([o],[c],O,!0)}),u.unit==="lovelace"&&q>l.lastWithdrawEpoch&&E&&(p=p.withdraw({stakeCredential:N(i.scriptRef),amount:R,redeemer:D([o],[c],O,!1)})),p.setValidity({from:BigInt(Date.now()-12e4),to:BigInt(Date.now()+24e4)}),(await(await(await p.build({debug:!0})).sign()).submit()).toString()}getPoolsFromOgmiosTx(e,t){let r=[];return e.outputs.forEach((o,s)=>{let i=o.value,a=i[t];if(a&&o.datum){for(let[g,l]of Object.entries(a))if(l===1n){let u=t+g,f=`${e.id}#${s}`,d=i.ada.lovelace,m=H(i),c=U(o.datum),w=c.tokenX,y=c.tokenY,p=I=>{if(I==="lovelace"||I==="")return d;let P=I.slice(0,56),R=I.slice(56),h=m.find(x=>x.policyId===P)?.assets.find(x=>x.name===R);return h?h.value:0n};r.push({outRef:f,address:o.address,coin:d,multiAssets:m,validityNft:u,tokenA:w,tokenAReserve:p(w),tokenB:y,tokenBReserve:p(y),lpFeeRate:c.lpFeeRate,priceLowerNum:c.sqrtLowerPriceNum,priceLowerDen:c.sqrtLowerPriceDen,priceUpperNum:c.sqrtUpperPriceNum,priceUpperDen:c.sqrtUpperPriceDen,platformFeeA:c.platformFeeX,platformFeeB:c.platformFeeY,minAChange:c.minXChange,minBChange:c.minYChange,lpTokenTotalSupply:c.circulatingLPToken,lastWithdrawEpoch:c.lastWithdrawEpoch,totalSwapFee:c.totalSwapFee})}}}),r}async getUserTokenBalance(e,t){return(await e.getWalletUtxos()).reduce((o,s)=>o+(t.unit==="lovelace"?s.assets.lovelace:v(s.assets,t.policyId,t.assetName)||0n),0n)}buildDeltaAssets(e,t,r,o,s){let i=r>0n?r:-r,a;if(e.unit==="lovelace"?a=rt(i+s):a=V(e.policyId,e.assetName,i,s),t.unit==="lovelace")a=it(a,o);else{let g=V(t.policyId,t.assetName,-o);a=G(a,g)}return a}async getStakingRewards(e,t,r,o){if(o.unit!=="lovelace")return{rewardAmount:0n};let s=new j.RewardAccount({networkId:t,stakeCredential:N(r.scriptRef)}),i=j.toBech32(s);return{rewardAmount:(await e.getDelegation(i)).rewards,stakingRewardAddress:i}}},kt=S;export{kt 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,m=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(m,d),d+=m.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",ft="d8b69fc53637bcfadbc4469083f706bc293f4d9d2296646c5ca167bb",mt="2cafd7c92f7093e5229af274be83dea660b0590b4174bbed79ba662b44fbd1ee#0",Q=18e5,dt="2e19cca74e3badcab26aef7574aa1885ba97228a254ca227ba2f79f2b75fd136#0",gt="04041c3c6ba87b33f2c9eb7f7dbeae3b26003c3e199d438bb99932a2",wt="3775af36f485f9c97101ee5b9b360c34f0f8e12186bc9060f358b7fc8ce468a4#0",v=n=>n===1?{poolScriptOutRef:_(pt),poolScriptHash:ft,protocolScriptOutRef:_(mt)}:{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]),m=s[1]instanceof Uint8Array?s[1]:new Uint8Array(s[1]),l=Buffer.from(a).toString("hex"),p=Buffer.from(m).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,m=BigInt(n)-BigInt(t.platformFeeX)+r-a,l=BigInt(e)-BigInt(t.platformFeeY),p=bt(m,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))+m,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,m,BigInt(t.lpFeeRate),i)}var tt=(n,e,t,o,r,i)=>{let s=10000n,m=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,m]},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],m=ht(s+a),l=e*r+n*i+m,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,m]=yt(i.tokenAAmount,i.tokenBAmount,i.datum,s,i.rewardAmount||0n,t);o.push({poolIndex:r,deltaAmount:s,outputAmount:a,platformFee:m})}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 m=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,m.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,m=(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 f=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;f.stakingOutRef&&(T=(await e.getUtxosByOutRef([f.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,f)=>{let h=t.pools[f].minOutChangeAmount;if(c.outputAmount<h)throw new Error(`Expected swap output at least ${h} but got ${c.outputAmount}`)});let y=A.reduce((c,f)=>c+f.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(m),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(m.scriptRef),amount:0n,redeemer:S(null,r,d,B)});for(let c=0;c<I.length;c++){let f=I[c],h=A.find(T=>T.poolIndex===c);if(!h)continue;let O=h.deltaAmount,U=h.platformFee,C=Z({...f.datum,platformFeeX:BigInt(f.datum.platformFeeX)+(O>0?U:0n),platformFeeY:BigInt(f.datum.platformFeeY)+(O<0?U:0n),lastWithdrawEpoch:D,totalSwapFee:BigInt(f.datum.totalSwapFee)+BigInt(p.swapFee)}),H=this.buildDeltaAssets(O>0?f.tokenA:f.tokenB,O>0?f.tokenB:f.tokenA,O,BigInt(h.outputAmount),BigInt(p.swapFee)),F=st(f.utxo.assets,H);if(g=g.payToAddress({address:f.utxo.address,assets:F,datum:C}),g=g.collectFrom({inputs:[f.utxo],redeemer:S(f.utxo,r,d,B)}),f.tokenA.unit===x&&D>f.datum.lastWithdrawEpoch&&u[c]){let{stakingRewardAddress:T}=await this.getStakingRewards(e,o,u[c],f.tokenA);T&&(g=g.withdraw({stakeCredential:W(u[c].scriptRef),amount:f.rewardAmount||0n,redeemer:S(f.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,m)=>{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}#${m}`,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 m=it(t.policyId,t.assetName,-r);a=st(a,m)}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,6 +1,6 @@
1
1
  {
2
2
  "name": "danogo-clmm",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
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",
@@ -33,12 +33,12 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@cardano-ogmios/client": "^6.14.0",
37
- "@cardano-ogmios/schema": "^6.14.0",
38
- "@evolution-sdk/evolution": "^0.3.31"
36
+ "@cardano-ogmios/client": "6.14.0",
37
+ "@cardano-ogmios/schema": "6.14.0",
38
+ "@evolution-sdk/evolution": "0.3.32"
39
39
  },
40
40
  "devDependencies": {
41
41
  "tsup": "^8.0.0",
42
42
  "typescript": "^5.9.2"
43
43
  }
44
- }
44
+ }