danogo-clmm 0.1.1 → 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
@@ -16,20 +16,6 @@ This SDK requires:
16
16
  - A Kupmios provider for blockchain data
17
17
  - An Ogmios instance for transaction submission
18
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
- ```
32
-
33
19
  ## Usage
34
20
 
35
21
  ### Initialization
@@ -43,111 +29,54 @@ const sdk = new DanogoSwap();
43
29
 
44
30
  ### 1. Calculate Swap Output (Quote)
45
31
 
46
- 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.
47
33
 
34
+ #### Examples
48
35
  ```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
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
66
42
  },
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
- }
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
+ });
92
50
  ```
93
51
 
94
52
  ### 2. Submit Swap Transaction
95
53
 
96
- Build and submit a swap transaction using an Evolution client.
54
+ Build and submit a swap transaction across one or more pools.
97
55
 
56
+ #### Examples
98
57
  ```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
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
117
65
  },
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
- }
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
+ });
148
75
  ```
149
76
 
150
- ### 3. Get Pool Info from Ogmios Transaction
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.
78
+
79
+ ### 4. Get Pool Info from Ogmios Transaction
151
80
 
152
81
  Extract pool data directly from an Ogmios transaction object.
153
82
 
@@ -175,7 +104,8 @@ async function main() {
175
104
  rollForward: async ({ block }, requestNext) => {
176
105
  if ("transactions" in block) {
177
106
  for (const tx of block.transactions!) {
178
- const pools = sdk.getPoolsFromOgmiosTx(tx, "your_pool_script_hash");
107
+ const networkId = 0; // 0 for Preprod, 1 for Mainnet
108
+ const pools = sdk.getPoolsFromOgmiosTx(tx, networkId);
179
109
  // your logic with pools
180
110
  }
181
111
  }
@@ -195,4 +125,18 @@ async function main() {
195
125
 
196
126
  await client.resume([checkpoint]);
197
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
+ }
198
142
  ```
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
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(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
  */
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
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(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
  */
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 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{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,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,6 +1,6 @@
1
1
  {
2
2
  "name": "danogo-clmm",
3
- "version": "0.1.1",
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",
@@ -41,4 +41,4 @@
41
41
  "tsup": "^8.0.0",
42
42
  "typescript": "^5.9.2"
43
43
  }
44
- }
44
+ }